Browse Source

Fixed spectral block border pixel padding

pull/2120/head
Dmitry Pentin 4 years ago
parent
commit
dd504b2413
  1. 8
      src/ImageSharp/Formats/Jpeg/Components/Encoder/ComponentProcessor.cs
  2. 9
      src/ImageSharp/Formats/Jpeg/Components/Encoder/SpectralConverter{TPixel}.cs
  3. 1
      tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs

8
src/ImageSharp/Formats/Jpeg/Components/Encoder/ComponentProcessor.cs

@ -43,13 +43,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
public void CopyColorBufferToBlocks(int spectralStep)
{
Buffer2D<Block8x8> spectralBuffer = this.component.SpectralBlocks;
// should be this.frame.MaxColorChannelValue
// but 12-bit jpegs are not supported currently
float normalizationValue = -128f;
int destAreaStride = this.ColorBuffer.Width;
int yBlockStart = spectralStep * this.component.SamplingFactors.Height;
Block8x8F workspaceBlock = default;
@ -77,7 +71,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
destAreaStride);
// level shift via -128f
workspaceBlock.AddInPlace(normalizationValue);
workspaceBlock.AddInPlace(-128f);
// FDCT
FastFloatingPointDCT.TransformFDCT(ref workspaceBlock);

9
src/ImageSharp/Formats/Jpeg/Components/Encoder/SpectralConverter{TPixel}.cs

@ -98,9 +98,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
int pixelBufferLastVerticalIndex = this.pixelBuffer.Height - 1;
// Pixel strides must be padded with the last pixel of the stride
int paddingStartIndex = this.pixelBuffer.Width;
int paddedPixelsCount = this.alignedPixelWidth - this.pixelBuffer.Width;
Span<float> rLane = this.redLane.GetSpan();
Span<float> gLane = this.greenLane.GetSpan();
Span<float> bLane = this.blueLane.GetSpan();
for (int yy = start; yy < end; yy++)
{
int y = yy - this.pixelRowCounter;
@ -110,6 +115,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
Span<TPixel> sourceRow = this.pixelBuffer.DangerousGetRowSpan(srcIndex);
PixelOperations<TPixel>.Instance.UnpackIntoRgbPlanes(rLane, gLane, bLane, sourceRow);
rLane.Slice(paddingStartIndex).Fill(rLane[paddingStartIndex - 1]);
gLane.Slice(paddingStartIndex).Fill(gLane[paddingStartIndex - 1]);
bLane.Slice(paddingStartIndex).Fill(bLane[paddingStartIndex - 1]);
// Convert from rgb24 to target pixel type
var values = new JpegColorConverterBase.ComponentValues(this.componentProcessors, y);
this.colorConverter.ConvertFromRgb(values, rLane, gLane, bLane);

1
tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs

@ -148,6 +148,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[WithTestPatternImages(nameof(BitsPerPixel_Quality), 48, 24, PixelTypes.Rgba32)]
[WithTestPatternImages(nameof(BitsPerPixel_Quality), 46, 8, PixelTypes.Rgba32)]
[WithTestPatternImages(nameof(BitsPerPixel_Quality), 51, 7, PixelTypes.Rgba32)]
[WithTestPatternImages(nameof(BitsPerPixel_Quality), 7, 5, PixelTypes.Rgba32)]
public void EncodeBaseline_WithSmallImages_WorksWithDifferentSizes<TPixel>(TestImageProvider<TPixel> provider, JpegEncodingColor colorType, int quality)
where TPixel : unmanaged, IPixel<TPixel> => TestJpegEncoderCore(provider, colorType, quality, comparer: ImageComparer.Tolerant(0.15f));

Loading…
Cancel
Save