| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /////////////////////////////////////////////////////////////////////////////////
- //
- // Photoshop PSD FileType Plugin for Paint.NET
- // http://psdplugin.codeplex.com/
- //
- // This software is provided under the MIT License:
- // Copyright (c) 2006-2007 Frank Blumenberg
- // Copyright (c) 2010-2016 Tao Yue
- //
- // See LICENSE.txt for complete licensing and attribution information.
- //
- /////////////////////////////////////////////////////////////////////////////////
- using System;
- using PDNWrapper;
- namespace PhotoshopFile.Compression
- {
- internal class ZipPredict32Image : ImageData
- {
- private ZipImage zipImage;
- protected override bool AltersWrittenData
- {
- // Prediction will pack the data into a temporary buffer, so the
- // original data will remain unchanged.
- get { return false; }
- }
- public ZipPredict32Image(byte[] zipData, Size size)
- : base(size, 32)
- {
- zipImage = new ZipImage(zipData, size, 32);
- }
- internal override void Read(byte[] buffer)
- {
- if (buffer.Length == 0)
- {
- return;
- }
- var predictedData = new byte[buffer.Length];
- zipImage.Read(predictedData);
- {
- //fixed (byte* ptrData = &predictedData[0])
- //fixed (byte* ptrOutput = &buffer[0])
- {
- Unpredict(predictedData, buffer);
- }
- }
- }
- public override byte[] ReadCompressed()
- {
- return zipImage.ReadCompressed();
- }
- private void Predict(byte[] ptrData, byte[] ptrOutput /*Int32* ptrData, byte* ptrOutput*/)
- {
- int size = sizeof(Int32);
- int inputIndex = 0;
- int outputIndex = 0;
- for (int i = 0; i < Size.Height; i++)
- {
- // Pack together the individual bytes of the 32-bit words, high-order
- // bytes before low-order bytes.
- int offset1 = Size.Width;
- int offset2 = 2 * offset1;
- int offset3 = 3 * offset1;
- //Int32* ptrDataRow = ptrData;
- //Int32* ptrDataRowEnd = ptrDataRow + Size.Width;
- int start = 0, end = Size.Width;
- //while (ptrData < ptrDataRowEnd)
- while (start < end)
- {
- Int32 data = BitConverter.ToInt32(ptrData, inputIndex);
- ptrOutput[start + outputIndex] = (byte)(data >> 24);
- ptrOutput[start + outputIndex + offset1] = (byte)(data >> 16);
- ptrOutput[start + outputIndex + offset2] = (byte)(data >> 8);
- ptrOutput[start + outputIndex + offset3] = (byte)(data);
- //ptrData++;
- //ptrOutput++;
- start++;
- inputIndex += size;
- }
- // Delta-encode the row
- //byte* ptrOutputRow = ptrOutput;
- //byte* ptrOutputRowEnd = ptrOutputRow + BytesPerRow;
- //ptrOutput = ptrOutputRowEnd - 1;
- start = BytesPerRow - 1;
- while (start > 0)
- {
- ptrOutput[start + outputIndex] -= ptrOutput[start + outputIndex - 1];
- start--;
- }
- outputIndex += BytesPerRow;
- // Advance pointer to next row
- //ptrOutput = ptrOutputRowEnd;
- //Debug.Assert(ptrData == ptrDataRowEnd);
- }
- }
- /// <summary>
- /// Unpredicts the raw decompressed image data into a 32-bpp bitmap with
- /// native endianness.
- /// </summary>
- private void Unpredict(byte[] ptrData, byte[] ptrOutput /*byte* ptrData, Int32* ptrOutput*/)
- {
- int inputIndex = 0;
- int outputIndex = 0;
- for (int i = 0; i < Size.Height; i++)
- {
- //byte* ptrDataRow = ptrData;
- //byte* ptrDataRowEnd = ptrDataRow + BytesPerRow;
- // Delta-decode each row
- //ptrData++;
- //while (ptrData < ptrDataRowEnd)
- int startIndex = 1;
- while (startIndex < BytesPerRow)
- {
- //*ptrData += *(ptrData - 1);
- //ptrData++;
- ptrData[inputIndex + startIndex] += ptrData[inputIndex + startIndex - 1];
- startIndex++;
- }
- // Within each row, the individual bytes of the 32-bit words are
- // packed together, high-order bytes before low-order bytes.
- // We now unpack them into words.
- int offset1 = Size.Width;
- int offset2 = 2 * offset1;
- int offset3 = 3 * offset1;
- //ptrData = ptrDataRow;
- //Int32* ptrOutputRowEnd = ptrOutput + Size.Width;
- //while (ptrOutput < ptrOutputRowEnd)
- startIndex = 0;
- while (startIndex < Size.Width)
- {
- Int32 pp = (Int32)ptrData[inputIndex + startIndex] << 24;
- pp |= (Int32)ptrData[inputIndex + startIndex + offset1] << 16;
- pp |= (Int32)ptrData[inputIndex + startIndex + offset2] << 8;
- pp |= (Int32)ptrData[inputIndex + startIndex + offset3];
- byte[] rr = BitConverter.GetBytes(pp);
- for (int k = 0; k < rr.Length; ++k)
- {
- ptrOutput[outputIndex] = rr[k];
- outputIndex++;
- }
- startIndex++;
- //*ptrOutput = *(ptrData) << 24
- // | *(ptrData + offset1) << 16
- // | *(ptrData + offset2) << 8
- // | *(ptrData + offset3);
- //ptrData++;
- //ptrOutput++;
- }
- // Advance pointer to next row
- //ptrData = ptrDataRowEnd;
- //Debug.Assert(ptrOutput == ptrOutputRowEnd);
- inputIndex += BytesPerRow;
- }
- }
- }
- }
|