diff --git a/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs b/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs index 046e738e76..3d4c8a8c0f 100644 --- a/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs +++ b/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs @@ -328,8 +328,8 @@ namespace SixLabors.ImageSharp.Formats.WebP private void ReadSimpleLossy(Buffer2D pixels, int width, int height, int imageDataSize) where TPixel : struct, IPixel { - // TODO: implement decoding. For simulating the decoding: skipping the chunk size bytes. - this.currentStream.Skip(imageDataSize - 10); // TODO: Not sure why we need to skip 10 bytes less here + var lossyDecoder = new WebPLossyDecoder(this.configuration, this.currentStream); + lossyDecoder.Decode(pixels, width, height, imageDataSize); } private void ReadSimpleLossless(Buffer2D pixels, int width, int height, int imageDataSize) diff --git a/src/ImageSharp/Formats/WebP/WebPLossyDecoder.cs b/src/ImageSharp/Formats/WebP/WebPLossyDecoder.cs new file mode 100644 index 0000000000..294737a885 --- /dev/null +++ b/src/ImageSharp/Formats/WebP/WebPLossyDecoder.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.Memory; + +namespace SixLabors.ImageSharp.Formats.WebP +{ + class WebPLossyDecoder + { + private readonly Configuration configuration; + + private readonly Stream currentStream; + + private MemoryAllocator memoryAllocator; + + public WebPLossyDecoder( + Configuration configuration, + Stream currentStream) + { + this.configuration = configuration; + this.currentStream = currentStream; + this.memoryAllocator = configuration.MemoryAllocator; + } + + public void Decode(Buffer2D pixels, int width, int height, int imageDataSize) + where TPixel : struct, IPixel + { + // TODO: implement decoding. For simulating the decoding: skipping the chunk size bytes. + this.currentStream.Skip(imageDataSize - 10); // TODO: Not sure why we need to skip 10 bytes less here + + // we need buffers for Y U and V in size of the image + // TODO: increase size to enable using all prediction blocks? (see https://tools.ietf.org/html/rfc6386#page-9 ) + Buffer2D yuvBufferCurrentFrame = + this.memoryAllocator + .Allocate2D(width, height); + + // TODO: var predictionBuffer - macro-block-sized with approximation of the portion of the image being reconstructed. + // those prediction values are the base, the values from DCT processing are added to that + + // TODO residue signal from DCT: 4x4 blocks of DCT transforms, 16Y, 4U, 4V + // TODO weiter bei S.11 + + // bit STREAM: See https://tools.ietf.org/html/rfc6386#page-29 ("Frame Header") + Vp8LBitReader bitReader = new Vp8LBitReader(this.currentStream); + bool isInterframe = bitReader.ReadBit(); + if (isInterframe) + { + throw new NotImplementedException("only key frames supported yet"); + } + + byte version = (byte)((bitReader.ReadBit() ? 2 : 0) | (bitReader.ReadBit() ? 1 : 0)); + bool isShowFrame = bitReader.ReadBit(); + + uint firstPartitionSize = (bitReader.Read(16) << 3) | bitReader.Read(3); + } + } + + struct YUVPixel + { + public byte Y { get; } + + public byte U { get; } + + public byte V { get; } + } +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebPDecoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebPDecoderTests.cs index c0636cb191..3db121bada 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebPDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebPDecoderTests.cs @@ -30,5 +30,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.WebP Assert.Equal(expectedBitsPerPixel, imageInfo.PixelType.BitsPerPixel); } } + + [Theory] + [InlineData(Lossy.Alpha.LossyAlpha1, 1000, 307, 24)] + public void DecodeLossyImage_Tmp(string imagePath, int expectedWidth, int expectedHeight, int expectedBitsPerPixel) + { + var testFile = TestFile.Create(imagePath); + using (var stream = new MemoryStream(testFile.Bytes, false)) + { + var image = Image.Load(stream); + Assert.Equal(expectedWidth, image.Width); + Assert.Equal(expectedHeight, image.Height); + } + } } }