From cff52ba6f53544e99b93949a1478d3579ead4cce Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sat, 5 Dec 2020 20:11:41 +0100 Subject: [PATCH] Remove writing padding bytes, this seems not necessary --- .../Formats/Tiff/TiffEncoderCore.cs | 15 +---- .../Formats/Tiff/Utils/TiffWriter.cs | 57 +++++-------------- 2 files changed, 16 insertions(+), 56 deletions(-) diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs index 6973f21a32..11775bd70b 100644 --- a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs @@ -24,11 +24,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff /// internal sealed class TiffEncoderCore : IImageEncoderInternals { - /// - /// The amount to pad each row by in bytes. - /// - private int padding; - /// /// Used for allocating memory during processing operations. /// @@ -121,10 +116,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff this.SetPhotometricInterpretation(); - short bpp = (short)this.bitsPerPixel; - int bytesPerLine = 4 * (((image.Width * bpp) + 31) / 32); - this.padding = bytesPerLine - (int)(image.Width * (bpp / 8F)); - using (var writer = new TiffWriter(stream, this.memoryAllocator, this.configuration)) { long firstIfdMarker = this.WriteHeader(writer); @@ -172,16 +163,16 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff switch (this.Mode) { case TiffEncodingMode.ColorPalette: - imageDataBytes = writer.WritePalettedRgb(image, this.quantizer, this.padding, this.CompressionType, this.compressionLevel, this.useHorizontalPredictor, out colorMap); + imageDataBytes = writer.WritePalettedRgb(image, this.quantizer, this.CompressionType, this.compressionLevel, this.useHorizontalPredictor, out colorMap); break; case TiffEncodingMode.Gray: - imageDataBytes = writer.WriteGray(image, this.padding, this.CompressionType, this.compressionLevel, this.useHorizontalPredictor); + imageDataBytes = writer.WriteGray(image, this.CompressionType, this.compressionLevel, this.useHorizontalPredictor); break; case TiffEncodingMode.BiColor: imageDataBytes = writer.WriteBiColor(image, this.CompressionType, this.compressionLevel); break; default: - imageDataBytes = writer.WriteRgb(image, this.padding, this.CompressionType, this.compressionLevel, this.useHorizontalPredictor); + imageDataBytes = writer.WriteRgb(image, this.CompressionType, this.compressionLevel, this.useHorizontalPredictor); break; } diff --git a/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs b/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs index e2fca49e83..f08241fbf6 100644 --- a/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs @@ -136,15 +136,14 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils /// /// The pixel data. /// The image to write to the stream. - /// The padding bytes for each row. /// The compression to use. /// The compression level for deflate compression. /// Indicates if horizontal prediction should be used. Should only be used with deflate compression. /// The number of bytes written. - public int WriteRgb(Image image, int padding, TiffEncoderCompression compression, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) + public int WriteRgb(Image image, TiffEncoderCompression compression, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) where TPixel : unmanaged, IPixel { - using IManagedByteBuffer row = this.AllocateRow(image.Width, 3, padding); + using IManagedByteBuffer row = this.memoryAllocator.AllocateManagedByteBuffer(image.Width * 3); Span rowSpan = row.GetSpan(); if (compression == TiffEncoderCompression.Deflate) { @@ -284,19 +283,18 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils /// The pixel data. /// The image to write to the stream. /// The quantizer to use. - /// The padding bytes for each row. /// The compression to use. /// The compression level for deflate compression. /// Indicates if horizontal prediction should be used. Should only be used in combination with deflate or LZW compression. /// The color map. /// The number of bytes written. - public int WritePalettedRgb(Image image, IQuantizer quantizer, int padding, TiffEncoderCompression compression, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor, out IExifValue colorMap) + public int WritePalettedRgb(Image image, IQuantizer quantizer, TiffEncoderCompression compression, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor, out IExifValue colorMap) where TPixel : unmanaged, IPixel { int colorsPerChannel = 256; int colorPaletteSize = colorsPerChannel * 3; int colorPaletteBytes = colorPaletteSize * 2; - using IManagedByteBuffer row = this.AllocateRow(image.Width, 1, padding); + using IManagedByteBuffer row = this.memoryAllocator.AllocateManagedByteBuffer(image.Width); using IQuantizer frameQuantizer = quantizer.CreatePixelSpecificQuantizer(this.configuration); using IndexedImageFrame quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(image.Frames.RootFrame, image.Bounds()); using IMemoryOwner colorPaletteBuffer = this.memoryAllocator.AllocateManagedByteBuffer(colorPaletteBytes); @@ -342,17 +340,17 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils if (compression == TiffEncoderCompression.Deflate) { - return this.WriteDeflateCompressedPalettedRgb(image, quantized, padding, compressionLevel, useHorizontalPredictor); + return this.WriteDeflateCompressedPalettedRgb(image, quantized, compressionLevel, useHorizontalPredictor); } if (compression == TiffEncoderCompression.Lzw) { - return this.WriteLzwCompressedPalettedRgb(image, quantized, padding, useHorizontalPredictor); + return this.WriteLzwCompressedPalettedRgb(image, quantized, useHorizontalPredictor); } if (compression == TiffEncoderCompression.PackBits) { - return this.WritePackBitsCompressedPalettedRgb(image, quantized, padding); + return this.WritePackBitsCompressedPalettedRgb(image, quantized); } // No compression. @@ -362,12 +360,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils ReadOnlySpan pixelSpan = quantized.GetPixelRowSpan(y); this.output.Write(pixelSpan); bytesWritten += pixelSpan.Length; - - for (int i = 0; i < padding; i++) - { - this.output.WriteByte(0); - bytesWritten++; - } } return bytesWritten; @@ -379,11 +371,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils /// The pixel data. /// The image to write to the stream. /// The quantized frame. - /// The padding bytes for each row. /// The compression level for deflate compression. /// Indicates if horizontal prediction should be used. /// The number of bytes written. - public int WriteDeflateCompressedPalettedRgb(Image image, IndexedImageFrame quantized, int padding, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) + public int WriteDeflateCompressedPalettedRgb(Image image, IndexedImageFrame quantized, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) where TPixel : unmanaged, IPixel { using IManagedByteBuffer tmpBuffer = this.memoryAllocator.AllocateManagedByteBuffer(image.Width); @@ -406,11 +397,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils { deflateStream.Write(pixelRow); } - - for (int i = 0; i < padding; i++) - { - deflateStream.WriteByte(0); - } } deflateStream.Flush(); @@ -427,10 +413,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils /// The pixel data. /// The image to write to the stream. /// The quantized frame. - /// The padding bytes for each row. /// Indicates if horizontal prediction should be used. /// The number of bytes written. - public int WriteLzwCompressedPalettedRgb(Image image, IndexedImageFrame quantized, int padding, bool useHorizontalPredictor) + public int WriteLzwCompressedPalettedRgb(Image image, IndexedImageFrame quantized, bool useHorizontalPredictor) where TPixel : unmanaged, IPixel { IMemoryOwner pixelData = this.memoryAllocator.Allocate(image.Width * image.Height); @@ -473,34 +458,21 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils /// 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 WritePackBitsCompressedPalettedRgb(Image image, IndexedImageFrame quantized, int padding) + public int WritePackBitsCompressedPalettedRgb(Image image, IndexedImageFrame quantized) where TPixel : unmanaged, IPixel { // Worst case is that the actual compressed data is larger then the input data. In this case we need 1 additional byte per 127 bytes. int additionalBytes = ((image.Width * 3) / 127) + 1; using IManagedByteBuffer compressedRow = this.memoryAllocator.AllocateManagedByteBuffer((image.Width * 3) + additionalBytes, AllocationOptions.Clean); - using IManagedByteBuffer pixelRowWithPadding = this.memoryAllocator.AllocateManagedByteBuffer((image.Width * 3) + padding, AllocationOptions.Clean); Span compressedRowSpan = compressedRow.GetSpan(); - Span pixelRowWithPaddingSpan = pixelRowWithPadding.GetSpan(); int bytesWritten = 0; for (int y = 0; y < image.Height; y++) { ReadOnlySpan pixelSpan = quantized.GetPixelRowSpan(y); - int size; - if (padding != 0) - { - pixelSpan.CopyTo(pixelRowWithPaddingSpan); - size = PackBitsWriter.PackBits(pixelRowWithPaddingSpan, compressedRowSpan); - } - else - { - size = PackBitsWriter.PackBits(pixelSpan, compressedRowSpan); - } - + int size = PackBitsWriter.PackBits(pixelSpan, compressedRowSpan); this.output.Write(compressedRowSpan.Slice(0, size)); bytesWritten += size; } @@ -513,15 +485,14 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils /// /// The pixel data. /// The image to write to the stream. - /// The padding bytes for each row. /// The compression to use. /// The compression level for deflate compression. /// Indicates if horizontal prediction should be used. Should only be used with deflate or lzw compression. /// The number of bytes written. - public int WriteGray(Image image, int padding, TiffEncoderCompression compression, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) + public int WriteGray(Image image, TiffEncoderCompression compression, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) where TPixel : unmanaged, IPixel { - using IManagedByteBuffer row = this.AllocateRow(image.Width, 1, padding); + using IManagedByteBuffer row = this.memoryAllocator.AllocateManagedByteBuffer(image.Width); Span rowSpan = row.GetSpan(); if (compression == TiffEncoderCompression.Deflate) @@ -831,8 +802,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils return bytesWritten; } - private IManagedByteBuffer AllocateRow(int width, int bytesPerPixel, int padding) => this.memoryAllocator.AllocatePaddedPixelRowBuffer(width, bytesPerPixel, padding); - /// /// Disposes instance, ensuring any unwritten data is flushed. ///