Singularity/Library/PackageCache/com.unity.2d.psdimporter@6.0.7/Editor/PSDPlugin/PsdFile/Compression/ZipPredict32Image.cs

176 lines
6.2 KiB
C#
Raw Normal View History

2024-05-06 14:45:45 -04:00
/////////////////////////////////////////////////////////////////////////////////
//
// 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;
}
}
}
}