From b5c68397b7cd0e9883fc0d0f12d6194df08d99ce Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Mon, 30 Nov 2020 19:33:33 +0100 Subject: [PATCH] Untangle writing compressed and none compressed color map tiff --- .../Formats/Tiff/Utils/TiffWriter.cs | 69 +++++++++++-------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs b/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs index ea8a9d590..3060430ec 100644 --- a/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs @@ -240,8 +240,6 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils where TPixel : unmanaged, IPixel { 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 IQuantizer frameQuantizer = quantizer.CreatePixelSpecificQuantizer(this.configuration); using IndexedImageFrame quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(image.Frames.RootFrame, image.Bounds()); @@ -286,44 +284,59 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils Value = palette }; + if (compression == TiffEncoderCompression.Deflate) + { + return this.WriteDeflateCompressedPalettedRgb(image, quantized, padding); + } + + // No compression. int bytesWritten = 0; for (int y = 0; y < image.Height; y++) { ReadOnlySpan pixelSpan = quantized.GetPixelRowSpan(y); + this.output.Write(pixelSpan); + bytesWritten += pixelSpan.Length; - if (compression == TiffEncoderCompression.Deflate) - { - deflateStream.Write(pixelSpan); - } - else + for (int i = 0; i < padding; i++) { - // No compression. - this.output.Write(pixelSpan); - bytesWritten += pixelSpan.Length; + this.output.WriteByte(0); + bytesWritten++; } + } + + return bytesWritten; + } + + /// + /// Writes the image data as indices into a color map compressed with deflate compression to the stream. + /// + /// The pixel data. + /// The image to write to the stream. + /// The quantized frame. + /// The padding bytes for each row. + /// The number of bytes written. + public int WriteDeflateCompressedPalettedRgb(Image image, IndexedImageFrame quantized, int padding) + where TPixel : unmanaged, IPixel + { + 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 pixelSpan = quantized.GetPixelRowSpan(y); + deflateStream.Write(pixelSpan); for (int i = 0; i < padding; i++) { - if (compression == TiffEncoderCompression.Deflate) - { - deflateStream.WriteByte(0); - } - else - { - // no compression. - this.output.WriteByte(0); - bytesWritten++; - } + deflateStream.WriteByte(0); } } - if (compression == TiffEncoderCompression.Deflate) - { - deflateStream.Flush(); - byte[] buffer = memoryStream.ToArray(); - this.output.Write(buffer); - bytesWritten += buffer.Length; - } + deflateStream.Flush(); + byte[] buffer = memoryStream.ToArray(); + this.output.Write(buffer); + bytesWritten += buffer.Length; return bytesWritten; } @@ -337,7 +350,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils /// The compression to use. /// The number of bytes written. public int WriteGray(Image image, int padding, TiffEncoderCompression compression) - where TPixel : unmanaged, IPixel + where TPixel : unmanaged, IPixel { using IManagedByteBuffer row = this.AllocateRow(image.Width, 1, padding); Span rowSpan = row.GetSpan();