| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- /////////////////////////////////////////////////////////////////////////////////
- //
- // 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.Drawing;
- using System.IO.Compression;
- namespace PhotoshopFile.Compression
- {
- public class ZipPredict16Image : ImageData
- {
- private ImageData zipImage;
- protected override bool AltersWrittenData => true;
- public ZipPredict16Image(byte[] zipData, Size size)
- : base(size, 16)
- {
- // 16-bitdepth images are delta-encoded word-by-word. The deltas
- // are thus big-endian and must be reversed for further processing.
- var zipRawImage = new ZipImage(zipData, size, 16);
- zipImage = new EndianReverser(zipRawImage);
- }
- internal override void Read(byte[] buffer)
- {
- if (buffer.Length == 0)
- {
- return;
- }
- zipImage.Read(buffer);
- unsafe
- {
- fixed (byte* ptrData = &buffer[0])
- {
- Unpredict((UInt16*)ptrData);
- }
- }
- }
- public override byte[] ReadCompressed()
- {
- return zipImage.ReadCompressed();
- }
- internal override void WriteInternal(byte[] array)
- {
- if (array.Length == 0)
- {
- return;
- }
- unsafe
- {
- fixed (byte* ptrData = &array[0])
- {
- Predict((UInt16*)ptrData);
- }
- }
- zipImage.WriteInternal(array);
- }
- unsafe private void Predict(UInt16* ptrData)
- {
- // Delta-encode each row
- for (int i = 0; i < Size.Height; i++)
- {
- UInt16* ptrDataRow = ptrData;
- UInt16* ptrDataRowEnd = ptrDataRow + Size.Width;
- // Start with the last column in the row
- ptrData = ptrDataRowEnd - 1;
- while (ptrData > ptrDataRow)
- {
- *ptrData -= *(ptrData - 1);
- ptrData--;
- }
- ptrData = ptrDataRowEnd;
- }
- }
- /// <summary>
- /// Unpredicts the decompressed, native-endian image data.
- /// </summary>
- unsafe private void Unpredict(UInt16* ptrData)
- {
- // Delta-decode each row
- for (int i = 0; i < Size.Height; i++)
- {
- UInt16* ptrDataRowEnd = ptrData + Size.Width;
- // Start with column index 1 on each row
- ptrData++;
- while (ptrData < ptrDataRowEnd)
- {
- *ptrData += *(ptrData - 1);
- ptrData++;
- }
- // Advance pointer to the next row
- ptrData = ptrDataRowEnd;
- }
- }
- }
- }
|