Singularity/Library/PackageCache/com.unity.2d.psdimporter@6.0.7/Editor/PSDPlugin/PsdFile/Compression/ZipImage.cs
2024-05-06 11:45:45 -07:00

102 lines
3.1 KiB
C#

/////////////////////////////////////////////////////////////////////////////////
//
// 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;
using System.IO;
using System.IO.Compression;
namespace PhotoshopFile.Compression
{
internal class ZipImage : ImageData
{
private MemoryStream zipDataStream;
private DeflateStream zipStream;
protected override bool AltersWrittenData
{
get { return false; }
}
public ZipImage(byte[] data, Size size, int bitDepth)
: base(size, bitDepth)
{
if (data == null)
{
InitCompress();
}
else
{
InitDecompress(data);
}
}
private void InitCompress()
{
zipDataStream = new MemoryStream();
// Write 2-byte zlib (RFC 1950) header
//
// CMF Compression Method and flags:
// CM 0:3 = 8 = deflate
// CINFO 4:7 = 4 = undefined, RFC 1950 only defines CINFO = 8
//
// FLG Flags:
// FCHECK 0:4 = 9 = check bits for CMF and FLG
// FDICT 5 = 0 = no preset dictionary
// FLEVEL 6:7 = 2 = default compression level
zipDataStream.WriteByte(0x48);
zipDataStream.WriteByte(0x89);
zipStream = new DeflateStream(zipDataStream, CompressionMode.Compress,
true);
}
private void InitDecompress(byte[] data)
{
zipDataStream = new MemoryStream(data);
// .NET implements Deflate (RFC 1951) but not zlib (RFC 1950),
// so we have to skip the first two bytes.
zipDataStream.ReadByte();
zipDataStream.ReadByte();
zipStream = new DeflateStream(zipDataStream, CompressionMode.Decompress,
true);
}
internal override void Read(byte[] buffer)
{
var bytesToRead = (long)Size.Height * BytesPerRow;
Util.CheckByteArrayLength(bytesToRead);
var bytesRead = zipStream.Read(buffer, 0, (int)bytesToRead);
if (bytesRead != bytesToRead)
{
throw new Exception("ZIP stream was not fully decompressed.");
}
}
public override byte[] ReadCompressed()
{
// Write out the last block. (Flush leaves the last block open.)
zipStream.Close();
// Do not write the zlib header when the image data is empty
var result = (zipDataStream.Length == 2)
? new byte[0]
: zipDataStream.ToArray();
return result;
}
}
}