Skip to content

Commit 114cc43

Browse files
Merge pull request SixLabors#2827 from SixLabors/js/backport-2823
Backport - v3 WEBP : Use Correct Width With AlphaDecoder
2 parents e69a507 + b8fcdda commit 114cc43

File tree

6 files changed

+36
-8
lines changed

6 files changed

+36
-8
lines changed

src/ImageSharp/Formats/Webp/AlphaDecoder.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public void Decode()
181181
else
182182
{
183183
this.LosslessDecoder.DecodeImageData(this.Vp8LDec, this.Vp8LDec.Pixels.Memory.Span);
184-
this.ExtractAlphaRows(this.Vp8LDec);
184+
this.ExtractAlphaRows(this.Vp8LDec, this.Width);
185185
}
186186
}
187187

@@ -255,14 +255,15 @@ public void ExtractPalettedAlphaRows(int lastRow)
255255
/// Once the image-stream is decoded into ARGB color values, the transparency information will be extracted from the green channel of the ARGB quadruplet.
256256
/// </summary>
257257
/// <param name="dec">The VP8L decoder.</param>
258-
private void ExtractAlphaRows(Vp8LDecoder dec)
258+
/// <param name="width">The image width.</param>
259+
private void ExtractAlphaRows(Vp8LDecoder dec, int width)
259260
{
260261
int numRowsToProcess = dec.Height;
261-
int width = dec.Width;
262262
Span<uint> input = dec.Pixels.Memory.Span;
263263
Span<byte> output = this.Alpha.Memory.Span;
264264

265265
// Extract alpha (which is stored in the green plane).
266+
// the final width (!= dec->width_)
266267
int pixelCount = width * numRowsToProcess;
267268
WebpLosslessDecoder.ApplyInverseTransforms(dec, input, this.memoryAllocator);
268269
ExtractGreen(input, output, pixelCount);

src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,11 @@ private static void SubtractGreenFromBlueAndRedScalar(Span<uint> pixelData)
269269
/// </summary>
270270
/// <param name="transform">The transform data contains color table size and the entries in the color table.</param>
271271
/// <param name="pixelData">The pixel data to apply the reverse transform on.</param>
272-
public static void ColorIndexInverseTransform(Vp8LTransform transform, Span<uint> pixelData)
272+
/// <param name="outputSpan">The resulting pixel data with the reversed transformation data.</param>
273+
public static void ColorIndexInverseTransform(
274+
Vp8LTransform transform,
275+
Span<uint> pixelData,
276+
Span<uint> outputSpan)
273277
{
274278
int bitsPerPixel = 8 >> transform.Bits;
275279
int width = transform.XSize;
@@ -282,7 +286,6 @@ public static void ColorIndexInverseTransform(Vp8LTransform transform, Span<uint
282286
int countMask = pixelsPerByte - 1;
283287
int bitMask = (1 << bitsPerPixel) - 1;
284288

285-
uint[] decodedPixelData = new uint[width * height];
286289
int pixelDataPos = 0;
287290
for (int y = 0; y < height; y++)
288291
{
@@ -298,12 +301,12 @@ public static void ColorIndexInverseTransform(Vp8LTransform transform, Span<uint
298301
packedPixels = GetArgbIndex(pixelData[pixelDataPos++]);
299302
}
300303

301-
decodedPixelData[decodedPixels++] = colorMap[(int)(packedPixels & bitMask)];
304+
outputSpan[decodedPixels++] = colorMap[(int)(packedPixels & bitMask)];
302305
packedPixels >>= bitsPerPixel;
303306
}
304307
}
305308

306-
decodedPixelData.AsSpan().CopyTo(pixelData);
309+
outputSpan.CopyTo(pixelData);
307310
}
308311
else
309312
{

src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,7 @@ public static void ApplyInverseTransforms(Vp8LDecoder decoder, Span<uint> pixelD
684684
List<Vp8LTransform> transforms = decoder.Transforms;
685685
for (int i = transforms.Count - 1; i >= 0; i--)
686686
{
687+
// TODO: Review these 1D allocations. They could conceivably exceed limits.
687688
Vp8LTransform transform = transforms[i];
688689
switch (transform.TransformType)
689690
{
@@ -701,7 +702,11 @@ public static void ApplyInverseTransforms(Vp8LDecoder decoder, Span<uint> pixelD
701702
LosslessUtils.ColorSpaceInverseTransform(transform, pixelData);
702703
break;
703704
case Vp8LTransformType.ColorIndexingTransform:
704-
LosslessUtils.ColorIndexInverseTransform(transform, pixelData);
705+
using (IMemoryOwner<uint> output = memoryAllocator.Allocate<uint>(pixelData.Length, AllocationOptions.Clean))
706+
{
707+
LosslessUtils.ColorIndexInverseTransform(transform, pixelData, output.GetSpan());
708+
}
709+
705710
break;
706711
}
707712
}

tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,21 @@ public void WebpDecoder_CanDecode_Issue2763<TPixel>(TestImageProvider<TPixel> pr
514514
image.VerifyEncoder(provider, "webp", string.Empty, encoder);
515515
}
516516

517+
// https://github.com/SixLabors/ImageSharp/issues/2801
518+
[Theory]
519+
[WithFile(Lossy.Issue2801, PixelTypes.Rgba32)]
520+
public void WebpDecoder_CanDecode_Issue2801<TPixel>(TestImageProvider<TPixel> provider)
521+
where TPixel : unmanaged, IPixel<TPixel>
522+
{
523+
WebpEncoder encoder = new()
524+
{
525+
Quality = 100
526+
};
527+
528+
using Image<TPixel> image = provider.GetImage();
529+
image.VerifyEncoder(provider, "webp", string.Empty, encoder, ImageComparer.TolerantPercentage(0.0994F));
530+
}
531+
517532
public static void RunEncodeLossy_WithPeakImage()
518533
{
519534
TestImageProvider<Rgba32> provider = TestImageProvider<Rgba32>.File(TestImageLossyFullPath);

tests/ImageSharp.Tests/TestImages.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,7 @@ public static class Lossy
824824
public const string Issue2257 = "Webp/issues/Issue2257.webp";
825825
public const string Issue2670 = "Webp/issues/Issue2670.webp";
826826
public const string Issue2763 = "Webp/issues/Issue2763.png";
827+
public const string Issue2801 = "Webp/issues/Issue2801.webp";
827828
}
828829
}
829830

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:e90a0d853ddf70d823d8da44eb6c57081e955b1fb7f436a1fd88ca5e5c75a003
3+
size 261212

0 commit comments

Comments
 (0)