Browse Source

Fix an issue reading the transformations and fixed the testimages accordingly

pull/1552/head
Brian Popow 7 years ago
parent
commit
2e8109515c
  1. 91
      src/ImageSharp/Formats/WebP/WebPLosslessDecoder.cs
  2. 19
      tests/ImageSharp.Tests/Formats/WebP/WebPDecoderTests.cs
  3. 29
      tests/ImageSharp.Tests/TestImages.cs

91
src/ImageSharp/Formats/WebP/WebPLosslessDecoder.cs

@ -88,9 +88,22 @@ namespace SixLabors.ImageSharp.Formats.WebP
private uint[] DecodeImageStream(Vp8LDecoder decoder, int xSize, int ySize, bool isLevel0)
{
int numberOfTransformsPresent = 0;
if (isLevel0)
{
this.ReadTransformations(xSize, ySize, decoder);
decoder.Transforms = new List<Vp8LTransform>(WebPConstants.MaxNumberOfTransforms);
// Next bit indicates, if a transformation is present.
while (this.bitReader.ReadBit())
{
if (numberOfTransformsPresent > WebPConstants.MaxNumberOfTransforms)
{
WebPThrowHelper.ThrowImageFormatException($"The maximum number of transforms of {WebPConstants.MaxNumberOfTransforms} was exceeded");
}
this.ReadTransformation(xSize, ySize, decoder);
numberOfTransformsPresent++;
}
}
// Color cache.
@ -571,54 +584,42 @@ namespace SixLabors.ImageSharp.Formats.WebP
/// Reads the transformations, if any are present.
/// </summary>
/// <param name="decoder">Vp8LDecoder where the transformations will be stored.</param>
private void ReadTransformations(int xSize, int ySize, Vp8LDecoder decoder)
private void ReadTransformation(int xSize, int ySize, Vp8LDecoder decoder)
{
// Next bit indicates, if a transformation is present.
bool transformPresent = this.bitReader.ReadBit();
int numberOfTransformsPresent = 0;
decoder.Transforms = new List<Vp8LTransform>(WebPConstants.MaxNumberOfTransforms);
while (transformPresent)
var transformType = (Vp8LTransformType)this.bitReader.ReadBits(2);
var transform = new Vp8LTransform(transformType, xSize, ySize);
switch (transformType)
{
var transformType = (Vp8LTransformType)this.bitReader.ReadBits(2);
var transform = new Vp8LTransform(transformType, xSize, ySize);
switch (transformType)
{
case Vp8LTransformType.SubtractGreen:
// There is no data associated with this transform.
break;
case Vp8LTransformType.ColorIndexingTransform:
// The transform data contains color table size and the entries in the color table.
// 8 bit value for color table size.
uint numColors = this.bitReader.ReadBits(8) + 1;
int bits = (numColors > 16) ? 0
: (numColors > 4) ? 1
: (numColors > 2) ? 2
: 3;
transform.XSize = LosslessUtils.SubSampleSize(transform.XSize, bits);
break;
case Vp8LTransformType.PredictorTransform:
case Vp8LTransformType.CrossColorTransform:
{
transform.Bits = (int)this.bitReader.ReadBits(3) + 2;
transform.Data = this.DecodeImageStream(
decoder,
LosslessUtils.SubSampleSize(transform.XSize, transform.Bits),
LosslessUtils.SubSampleSize(transform.YSize, transform.Bits),
false);
break;
}
}
decoder.Transforms.Add(transform);
numberOfTransformsPresent++;
case Vp8LTransformType.SubtractGreen:
// There is no data associated with this transform.
break;
case Vp8LTransformType.ColorIndexingTransform:
// The transform data contains color table size and the entries in the color table.
// 8 bit value for color table size.
uint numColors = this.bitReader.ReadBits(8) + 1;
int bits = (numColors > 16) ? 0
: (numColors > 4) ? 1
: (numColors > 2) ? 2
: 3;
transform.XSize = LosslessUtils.SubSampleSize(transform.XSize, bits);
transform.Bits = bits;
transform.Data = this.DecodeImageStream(decoder, (int)numColors, 1, false);
break;
transformPresent = this.bitReader.ReadBit();
if (numberOfTransformsPresent == WebPConstants.MaxNumberOfTransforms && transformPresent)
{
WebPThrowHelper.ThrowImageFormatException($"The maximum number of transforms of {WebPConstants.MaxNumberOfTransforms} was exceeded");
}
case Vp8LTransformType.PredictorTransform:
case Vp8LTransformType.CrossColorTransform:
{
transform.Bits = (int)this.bitReader.ReadBits(3) + 2;
transform.Data = this.DecodeImageStream(
decoder,
LosslessUtils.SubSampleSize(transform.XSize, transform.Bits),
LosslessUtils.SubSampleSize(transform.YSize, transform.Bits),
false);
break;
}
}
decoder.Transforms.Add(transform);
}
/// <summary>

19
tests/ImageSharp.Tests/Formats/WebP/WebPDecoderTests.cs

@ -67,9 +67,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.WebP
[WithFile(Lossless.GreenTransform2, PixelTypes.Rgba32)]
[WithFile(Lossless.GreenTransform3, PixelTypes.Rgba32)]
[WithFile(Lossless.GreenTransform4, PixelTypes.Rgba32)]
// TODO: Figure out whats wrong with those two images
// TODO: Reference decoder throws here MagickCorruptImageErrorException
//[WithFile(Lossless.GreenTransform5, PixelTypes.Rgba32)]
//[WithFile(Lossless.GreenTransform6, PixelTypes.Rgba32)]
public void WebpDecoder_CanDecode_Lossless_WithSubstractGreenTransform<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
@ -86,18 +85,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.WebP
[WithFile(Lossless.ColorIndexTransform3, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform4, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform5, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform6, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform7, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform8, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform9, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform10, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform11, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform12, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform13, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform14, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform15, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform16, PixelTypes.Rgba32)]
[WithFile(Lossless.ColorIndexTransform17, PixelTypes.Rgba32)]
public void WebpDecoder_CanDecode_Lossless_WithColorIndexTransform<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
@ -111,10 +98,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.WebP
[Theory]
[WithFile(Lossless.PredictorTransform1, PixelTypes.Rgba32)]
[WithFile(Lossless.PredictorTransform2, PixelTypes.Rgba32)]
[WithFile(Lossless.PredictorTransform3, PixelTypes.Rgba32)]
[WithFile(Lossless.PredictorTransform4, PixelTypes.Rgba32)]
[WithFile(Lossless.PredictorTransform5, PixelTypes.Rgba32)]
[WithFile(Lossless.PredictorTransform6, PixelTypes.Rgba32)]
public void WebpDecoder_CanDecode_Lossless_WithPredictorTransform<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{

29
tests/ImageSharp.Tests/TestImages.cs

@ -386,33 +386,16 @@ namespace SixLabors.ImageSharp.Tests
public const string GreenTransform2 = "WebP/lossless2.webp";
public const string GreenTransform3 = "WebP/lossless3.webp";
public const string GreenTransform4 = "WebP/lossless_vec_1_4.webp";
public const string GreenTransform5 = "WebP/lossless_vec_1_7.webp";
public const string GreenTransform6 = "WebP/lossless_vec_2_4.webp";
public const string GreenTransform5 = "WebP/lossless_vec_2_4.webp";
public const string CrossColorTransform1 = "WebP/lossless_vec_1_8.webp";
public const string CrossColorTransform2 = "WebP/lossless_vec_2_8.webp";
public const string PredictorTransform1 = "WebP/lossless_vec_1_10.webp";
public const string PredictorTransform2 = "WebP/lossless_vec_1_10.webp";
public const string PredictorTransform3 = "WebP/lossless_vec_1_2.webp";
public const string PredictorTransform4 = "WebP/lossless_vec_2_10.webp";
public const string PredictorTransform5 = "WebP/lossless_vec_2_2.webp";
public const string PredictorTransform6 = "WebP/near_lossless_75.webp";
public const string PredictorTransform1 = "WebP/lossless_vec_1_2.webp";
public const string PredictorTransform2 = "WebP/lossless_vec_2_2.webp";
public const string ColorIndexTransform1 = "WebP/lossless4.webp";
public const string ColorIndexTransform2 = "WebP/lossless_vec_1_1.webp";
public const string ColorIndexTransform3 = "WebP/lossless_vec_1_11.webp";
public const string ColorIndexTransform4 = "WebP/lossless_vec_1_13.webp";
public const string ColorIndexTransform5 = "WebP/lossless_vec_1_15.webp";
public const string ColorIndexTransform6 = "WebP/lossless_vec_1_3.webp";
public const string ColorIndexTransform7 = "WebP/lossless_vec_1_5.webp";
public const string ColorIndexTransform8 = "WebP/lossless_vec_1_7.webp";
public const string ColorIndexTransform9 = "WebP/lossless_vec_1_9.webp";
public const string ColorIndexTransform10 = "WebP/lossless_vec_2_1.webp";
public const string ColorIndexTransform11 = "WebP/lossless_vec_2_11.webp";
public const string ColorIndexTransform12 = "WebP/lossless_vec_2_13.webp";
public const string ColorIndexTransform13 = "WebP/lossless_vec_2_15.webp";
public const string ColorIndexTransform14 = "WebP/lossless_vec_2_3.webp";
public const string ColorIndexTransform15 = "WebP/lossless_vec_2_5.webp";
public const string ColorIndexTransform16 = "WebP/lossless_vec_2_7.webp";
public const string ColorIndexTransform17 = "WebP/lossless_vec_2_9.webp";
public const string ColorIndexTransform3 = "WebP/lossless_vec_1_5.webp";
public const string ColorIndexTransform4 = "WebP/lossless_vec_2_1.webp";
public const string ColorIndexTransform5 = "WebP/lossless_vec_2_5.webp";
}
public static class Lossy

Loading…
Cancel
Save