diff --git a/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs b/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs index 022ded8aa..f705b44e9 100644 --- a/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs +++ b/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs @@ -299,55 +299,6 @@ namespace SixLabors.ImageSharp.Formats.WebP // TODO: should we throw here when version number is != 0? uint version = bitReader.Read(3); - // Next bit indicates, if a transformation is present. - bool transformPresent = bitReader.ReadBit(); - int numberOfTransformsPresent = 0; - while (transformPresent) - { - var transformType = (WebPTransformType)bitReader.Read(2); - switch (transformType) - { - case WebPTransformType.SubtractGreen: - // There is no data associated with this transform. - break; - case WebPTransformType.ColorIndexingTransform: - // The transform data contains color table size and the entries in the color table. - // 8 bit value for color table size. - uint colorTableSize = bitReader.Read(8) + 1; - // TODO: color table should follow here? - break; - - case WebPTransformType.PredictorTransform: - { - // The first 3 bits of prediction data define the block width and height in number of bits. - // The number of block columns, block_xsize, is used in indexing two-dimensionally. - uint sizeBits = bitReader.Read(3) + 2; - int blockWidth = 1 << (int)sizeBits; - int blockHeight = 1 << (int)sizeBits; - - break; - } - - case WebPTransformType.ColorTransform: - { - // The first 3 bits of the color transform data contain the width and height of the image block in number of bits, - // just like the predictor transform: - uint sizeBits = bitReader.Read(3) + 2; - int blockWidth = 1 << (int)sizeBits; - int blockHeight = 1 << (int)sizeBits; - break; - } - } - - numberOfTransformsPresent++; - if (numberOfTransformsPresent == 4) - { - break; - } - - transformPresent = bitReader.ReadBit(); - } - return new WebPImageInfo() { Width = (int)width, @@ -361,12 +312,15 @@ namespace SixLabors.ImageSharp.Formats.WebP where TPixel : struct, IPixel { // TODO: implement decoding. For simulating the decoding: skipping the chunk size bytes. - this.currentStream.Skip(imageDataSize); // TODO: this does not seem to work in all cases + this.currentStream.Skip(imageDataSize - 10); } private void ReadSimpleLossless(Buffer2D pixels, int width, int height, int imageDataSize) where TPixel : struct, IPixel { + var losslessDecoder = new WebPLosslessDecoder(this.currentStream); + losslessDecoder.Decode(pixels, width, height, imageDataSize); + // TODO: implement decoding. For simulating the decoding: skipping the chunk size bytes. this.currentStream.Skip(imageDataSize); // TODO: this does not seem to work in all cases } diff --git a/src/ImageSharp/Formats/WebP/WebPLosslessDecoder.cs b/src/ImageSharp/Formats/WebP/WebPLosslessDecoder.cs new file mode 100644 index 000000000..4545e5855 --- /dev/null +++ b/src/ImageSharp/Formats/WebP/WebPLosslessDecoder.cs @@ -0,0 +1,84 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; + +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Formats.WebP +{ + /// + /// Decoder for lossless webp images. + /// + internal sealed class WebPLosslessDecoder + { + private Vp8LBitReader bitReader; + + public WebPLosslessDecoder(Stream stream) + { + this.bitReader = new Vp8LBitReader(stream); + } + + public void Decode(Buffer2D pixels, int width, int height, int imageDataSize) + where TPixel : struct, IPixel + { + //ReadTransformations(); + } + + private void ReadTransformations() + { + // Next bit indicates, if a transformation is present. + bool transformPresent = bitReader.ReadBit(); + int numberOfTransformsPresent = 0; + while (transformPresent) + { + var transformType = (WebPTransformType)bitReader.Read(2); + switch (transformType) + { + case WebPTransformType.SubtractGreen: + // There is no data associated with this transform. + break; + case WebPTransformType.ColorIndexingTransform: + // The transform data contains color table size and the entries in the color table. + // 8 bit value for color table size. + uint colorTableSize = bitReader.Read(8) + 1; + + // TODO: color table should follow here? + break; + + case WebPTransformType.PredictorTransform: + { + // The first 3 bits of prediction data define the block width and height in number of bits. + // The number of block columns, block_xsize, is used in indexing two-dimensionally. + uint sizeBits = bitReader.Read(3) + 2; + int blockWidth = 1 << (int)sizeBits; + int blockHeight = 1 << (int)sizeBits; + + break; + } + + case WebPTransformType.ColorTransform: + { + // The first 3 bits of the color transform data contain the width and height of the image block in number of bits, + // just like the predictor transform: + uint sizeBits = bitReader.Read(3) + 2; + int blockWidth = 1 << (int)sizeBits; + int blockHeight = 1 << (int)sizeBits; + break; + } + } + + numberOfTransformsPresent++; + if (numberOfTransformsPresent == 4) + { + break; + } + + transformPresent = bitReader.ReadBit(); + } + + // TODO: return transformation in an appropriate form. + } + } +}