Browse Source

Untangle writing compressed and none compressed color map tiff

pull/1570/head
Brian Popow 6 years ago
parent
commit
b5c68397b7
  1. 53
      src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs

53
src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs

@ -240,8 +240,6 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
int colorPaletteSize = 256 * 3 * 2; int colorPaletteSize = 256 * 3 * 2;
using var memoryStream = new MemoryStream();
using var deflateStream = new ZlibDeflateStream(this.memoryAllocator, memoryStream, PngCompressionLevel.Level6); // TODO: make compression level configurable
using IManagedByteBuffer row = this.AllocateRow(image.Width, 1, padding); using IManagedByteBuffer row = this.AllocateRow(image.Width, 1, padding);
using IQuantizer<TPixel> frameQuantizer = quantizer.CreatePixelSpecificQuantizer<TPixel>(this.configuration); using IQuantizer<TPixel> frameQuantizer = quantizer.CreatePixelSpecificQuantizer<TPixel>(this.configuration);
using IndexedImageFrame<TPixel> quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(image.Frames.RootFrame, image.Bounds()); using IndexedImageFrame<TPixel> quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(image.Frames.RootFrame, image.Bounds());
@ -286,44 +284,59 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils
Value = palette Value = palette
}; };
int bytesWritten = 0;
for (int y = 0; y < image.Height; y++)
{
ReadOnlySpan<byte> pixelSpan = quantized.GetPixelRowSpan(y);
if (compression == TiffEncoderCompression.Deflate) if (compression == TiffEncoderCompression.Deflate)
{ {
deflateStream.Write(pixelSpan); return this.WriteDeflateCompressedPalettedRgb(image, quantized, padding);
} }
else
{
// No compression. // No compression.
int bytesWritten = 0;
for (int y = 0; y < image.Height; y++)
{
ReadOnlySpan<byte> pixelSpan = quantized.GetPixelRowSpan(y);
this.output.Write(pixelSpan); this.output.Write(pixelSpan);
bytesWritten += pixelSpan.Length; bytesWritten += pixelSpan.Length;
}
for (int i = 0; i < padding; i++) for (int i = 0; i < padding; i++)
{ {
if (compression == TiffEncoderCompression.Deflate)
{
deflateStream.WriteByte(0);
}
else
{
// no compression.
this.output.WriteByte(0); this.output.WriteByte(0);
bytesWritten++; bytesWritten++;
} }
} }
return bytesWritten;
} }
if (compression == TiffEncoderCompression.Deflate) /// <summary>
/// Writes the image data as indices into a color map compressed with deflate compression to the stream.
/// </summary>
/// <typeparam name="TPixel">The pixel data.</typeparam>
/// <param name="image">The image to write to the stream.</param>
/// <param name="quantized">The quantized frame.</param>
/// <param name="padding">The padding bytes for each row.</param>
/// <returns>The number of bytes written.</returns>
public int WriteDeflateCompressedPalettedRgb<TPixel>(Image<TPixel> image, IndexedImageFrame<TPixel> quantized, int padding)
where TPixel : unmanaged, IPixel<TPixel>
{ {
using var memoryStream = new MemoryStream();
using var deflateStream = new ZlibDeflateStream(this.memoryAllocator, memoryStream, PngCompressionLevel.Level6); // TODO: make compression level configurable
int bytesWritten = 0;
for (int y = 0; y < image.Height; y++)
{
ReadOnlySpan<byte> pixelSpan = quantized.GetPixelRowSpan(y);
deflateStream.Write(pixelSpan);
for (int i = 0; i < padding; i++)
{
deflateStream.WriteByte(0);
}
}
deflateStream.Flush(); deflateStream.Flush();
byte[] buffer = memoryStream.ToArray(); byte[] buffer = memoryStream.ToArray();
this.output.Write(buffer); this.output.Write(buffer);
bytesWritten += buffer.Length; bytesWritten += buffer.Length;
}
return bytesWritten; return bytesWritten;
} }

Loading…
Cancel
Save