diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrPlanarTiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrPlanarTiffColor{TPixel}.cs index 0e411c69db..70578a7442 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrPlanarTiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrPlanarTiffColor{TPixel}.cs @@ -3,6 +3,7 @@ using System; using System.Buffers; +using SixLabors.ImageSharp.Formats.Tiff.Utils; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -35,6 +36,13 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation var color = default(TPixel); int offset = 0; + int widthPadding = 0; + if (this.ycbcrSubSampling != null) + { + // Round to the next integer multiple of horizontalSubSampling. + widthPadding = TiffUtils.PaddingToNextInteger(width, this.ycbcrSubSampling[0]); + } + for (int y = top; y < top + height; y++) { Span pixelRow = pixels.GetRowSpan(y).Slice(left, width); @@ -45,11 +53,18 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation pixelRow[x] = color; offset++; } + + offset += widthPadding; } } private static void ReverseChromaSubSampling(int width, int height, int horizontalSubSampling, int verticalSubSampling, Span planarCb, Span planarCr) { + // If width and height are not multiples of ChromaSubsampleHoriz and ChromaSubsampleVert respectively, + // then the source data will be padded. + width += TiffUtils.PaddingToNextInteger(width, horizontalSubSampling); + height += TiffUtils.PaddingToNextInteger(height, verticalSubSampling); + for (int row = height - 1; row >= 0; row--) { for (int col = width - 1; col >= 0; col--) diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrTiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrTiffColor{TPixel}.cs index f28a2399e8..e31b4984d3 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrTiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrTiffColor{TPixel}.cs @@ -3,6 +3,7 @@ using System; using System.Buffers; +using SixLabors.ImageSharp.Formats.Tiff.Utils; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -46,7 +47,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation if (this.ycbcrSubSampling != null) { // Round to the next integer multiple of horizontalSubSampling. - widthPadding = PaddingToNextInteger(width, this.ycbcrSubSampling[0]); + widthPadding = TiffUtils.PaddingToNextInteger(width, this.ycbcrSubSampling[0]); } for (int y = top; y < top + height; y++) @@ -68,8 +69,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation { // If width and height are not multiples of ChromaSubsampleHoriz and ChromaSubsampleVert respectively, // then the source data will be padded. - width += PaddingToNextInteger(width, horizontalSubSampling); - height += PaddingToNextInteger(height, verticalSubSampling); + width += TiffUtils.PaddingToNextInteger(width, horizontalSubSampling); + height += TiffUtils.PaddingToNextInteger(height, verticalSubSampling); int blockWidth = width / horizontalSubSampling; int blockHeight = height / verticalSubSampling; int cbCrOffsetInBlock = horizontalSubSampling * verticalSubSampling; @@ -97,16 +98,5 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation } } } - - private static int PaddingToNextInteger(int valueToRoundUp, int subSampling) - { - if (valueToRoundUp % subSampling == 0) - { - return 0; - } - - int padding = subSampling - (valueToRoundUp % subSampling); - return padding; - } } } diff --git a/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs b/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs index f2872858cf..4f71fa35c9 100644 --- a/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs +++ b/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs @@ -98,5 +98,22 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils color.FromVector4(colorVector); return color; } + + /// + /// Finds the padding needed to round 'valueToRoundUp' to the next integer multiple of subSampling value. + /// + /// The width or height to round up. + /// The sub sampling. + /// The padding. + public static int PaddingToNextInteger(int valueToRoundUp, int subSampling) + { + if (valueToRoundUp % subSampling == 0) + { + return 0; + } + + int padding = subSampling - (valueToRoundUp % subSampling); + return padding; + } } }