Browse Source

Add width padding for planar ycbcr

pull/1731/head
Brian Popow 5 years ago
parent
commit
2789f6a6a7
  1. 15
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrPlanarTiffColor{TPixel}.cs
  2. 18
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrTiffColor{TPixel}.cs
  3. 17
      src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs

15
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrPlanarTiffColor{TPixel}.cs

@ -3,6 +3,7 @@
using System; using System;
using System.Buffers; using System.Buffers;
using SixLabors.ImageSharp.Formats.Tiff.Utils;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -35,6 +36,13 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
var color = default(TPixel); var color = default(TPixel);
int offset = 0; 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++) for (int y = top; y < top + height; y++)
{ {
Span<TPixel> pixelRow = pixels.GetRowSpan(y).Slice(left, width); Span<TPixel> pixelRow = pixels.GetRowSpan(y).Slice(left, width);
@ -45,11 +53,18 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
pixelRow[x] = color; pixelRow[x] = color;
offset++; offset++;
} }
offset += widthPadding;
} }
} }
private static void ReverseChromaSubSampling(int width, int height, int horizontalSubSampling, int verticalSubSampling, Span<byte> planarCb, Span<byte> planarCr) private static void ReverseChromaSubSampling(int width, int height, int horizontalSubSampling, int verticalSubSampling, Span<byte> planarCb, Span<byte> 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 row = height - 1; row >= 0; row--)
{ {
for (int col = width - 1; col >= 0; col--) for (int col = width - 1; col >= 0; col--)

18
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrTiffColor{TPixel}.cs

@ -3,6 +3,7 @@
using System; using System;
using System.Buffers; using System.Buffers;
using SixLabors.ImageSharp.Formats.Tiff.Utils;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -46,7 +47,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
if (this.ycbcrSubSampling != null) if (this.ycbcrSubSampling != null)
{ {
// Round to the next integer multiple of horizontalSubSampling. // 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++) 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, // If width and height are not multiples of ChromaSubsampleHoriz and ChromaSubsampleVert respectively,
// then the source data will be padded. // then the source data will be padded.
width += PaddingToNextInteger(width, horizontalSubSampling); width += TiffUtils.PaddingToNextInteger(width, horizontalSubSampling);
height += PaddingToNextInteger(height, verticalSubSampling); height += TiffUtils.PaddingToNextInteger(height, verticalSubSampling);
int blockWidth = width / horizontalSubSampling; int blockWidth = width / horizontalSubSampling;
int blockHeight = height / verticalSubSampling; int blockHeight = height / verticalSubSampling;
int cbCrOffsetInBlock = horizontalSubSampling * 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;
}
} }
} }

17
src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs

@ -98,5 +98,22 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils
color.FromVector4(colorVector); color.FromVector4(colorVector);
return color; return color;
} }
/// <summary>
/// Finds the padding needed to round 'valueToRoundUp' to the next integer multiple of subSampling value.
/// </summary>
/// <param name="valueToRoundUp">The width or height to round up.</param>
/// <param name="subSampling">The sub sampling.</param>
/// <returns>The padding.</returns>
public static int PaddingToNextInteger(int valueToRoundUp, int subSampling)
{
if (valueToRoundUp % subSampling == 0)
{
return 0;
}
int padding = subSampling - (valueToRoundUp % subSampling);
return padding;
}
} }
} }

Loading…
Cancel
Save