| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- /////////////////////////////////////////////////////////////////////////////////
- //
- // 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-2017 Tao Yue
- //
- // See LICENSE.txt for complete licensing and attribution information.
- //
- /////////////////////////////////////////////////////////////////////////////////
- using System;
- using System.Diagnostics;
- using System.Drawing;
- namespace PhotoshopFile.Compression
- {
- public class ZipPredict32Image : ImageData
- {
- private ZipImage zipImage;
- // Prediction will pack the data into a temporary buffer, so the
- // original data will remain unchanged.
- protected override bool AltersWrittenData => 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);
- unsafe
- {
- fixed (byte* ptrData = &predictedData[0])
- fixed (byte* ptrOutput = &buffer[0])
- {
- Unpredict(ptrData, (Int32*)ptrOutput);
- }
- }
- }
- public override byte[] ReadCompressed()
- {
- return zipImage.ReadCompressed();
- }
- internal override void WriteInternal(byte[] array)
- {
- if (array.Length == 0)
- {
- return;
- }
- var predictedData = new byte[array.Length];
- unsafe
- {
- fixed (byte* ptrData = &array[0])
- fixed (byte* ptrOutput = &predictedData[0])
- {
- Predict((Int32*)ptrData, ptrOutput);
- }
- }
- zipImage.WriteInternal(predictedData);
- }
- unsafe private void Predict(Int32* ptrData, byte* ptrOutput)
- {
- 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;
- byte* ptrOutputRow = ptrOutput;
- byte* ptrOutputRowEnd = ptrOutputRow + BytesPerRow;
- while (ptrData < ptrDataRowEnd)
- {
- *(ptrOutput) = (byte)(*ptrData >> 24);
- *(ptrOutput + offset1) = (byte)(*ptrData >> 16);
- *(ptrOutput + offset2) = (byte)(*ptrData >> 8);
- *(ptrOutput + offset3) = (byte)(*ptrData);
- ptrData++;
- ptrOutput++;
- }
- // Delta-encode the row
- ptrOutput = ptrOutputRowEnd - 1;
- while (ptrOutput > ptrOutputRow)
- {
- *ptrOutput -= *(ptrOutput - 1);
- ptrOutput--;
- }
- // 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>
- unsafe private void Unpredict(byte* ptrData, Int32* ptrOutput)
- {
- for (int i = 0; i < Size.Height; i++)
- {
- byte* ptrDataRow = ptrData;
- byte* ptrDataRowEnd = ptrDataRow + BytesPerRow;
- // Delta-decode each row
- ptrData++;
- while (ptrData < ptrDataRowEnd)
- {
- *ptrData += *(ptrData - 1);
- ptrData++;
- }
- // 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)
- {
- *ptrOutput = *(ptrData) << 24
- | *(ptrData + offset1) << 16
- | *(ptrData + offset2) << 8
- | *(ptrData + offset3);
- ptrData++;
- ptrOutput++;
- }
- // Advance pointer to next row
- ptrData = ptrDataRowEnd;
- Debug.Assert(ptrOutput == ptrOutputRowEnd);
- }
- }
- }
- }
|