From 821250729f24f9bf76f91e9a0c30fdf5481efc8c Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 19 Jan 2020 07:45:49 +0100 Subject: [PATCH] Add VP8 bitreader to image info, remove image data size (not used except inside the bitreader) --- .../Formats/WebP/WebPDecoderCore.cs | 23 +++++++++++-------- src/ImageSharp/Formats/WebP/WebPImageInfo.cs | 12 +++++----- .../Formats/WebP/WebPLossyDecoder.cs | 14 ++++------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs b/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs index bdc73a939b..1816e56ae0 100644 --- a/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs +++ b/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs @@ -89,13 +89,13 @@ namespace SixLabors.ImageSharp.Formats.WebP Buffer2D pixels = image.GetRootFramePixelBuffer(); if (imageInfo.IsLossLess) { - var losslessDecoder = new WebPLosslessDecoder(imageInfo.Vp9LBitReader, this.memoryAllocator); + var losslessDecoder = new WebPLosslessDecoder(imageInfo.Vp8LBitReader, this.memoryAllocator); losslessDecoder.Decode(pixels, image.Width, image.Height); } else { - var lossyDecoder = new WebPLossyDecoder(this.configuration, this.currentStream); - lossyDecoder.Decode(pixels, image.Width, image.Height, imageInfo.ImageDataSize, imageInfo.Vp8Profile); + var lossyDecoder = new WebPLossyDecoder(imageInfo.Vp8BitReader, this.memoryAllocator); + lossyDecoder.Decode(pixels, image.Width, image.Height, imageInfo.Vp8Profile); } // There can be optional chunks after the image data, like EXIF and XMP. @@ -335,15 +335,17 @@ namespace SixLabors.ImageSharp.Formats.WebP WebPThrowHelper.ThrowImageFormatException("width or height can not be zero"); } + var bitReader = new Vp8BitReader(this.currentStream, dataSize - 10, this.memoryAllocator); + return new WebPImageInfo() { Width = width, Height = height, BitsPerPixel = features?.Alpha is true ? WebPBitsPerPixel.Pixel32 : WebPBitsPerPixel.Pixel24, IsLossLess = false, - ImageDataSize = dataSize - 10, // 10 bytes are read here in the header already. Features = features, - Vp8Profile = (sbyte)version + Vp8Profile = (sbyte)version, + Vp8BitReader = bitReader }; } @@ -377,12 +379,16 @@ namespace SixLabors.ImageSharp.Formats.WebP } // The alphaIsUsed flag should be set to 0 when all alpha values are 255 in the picture, and 1 otherwise. + // TODO: this flag value is not used yet bool alphaIsUsed = bitReader.ReadBit(); - // The next 3 bits are the version. The version_number is a 3 bit code that must be set to 0. + // The next 3 bits are the version. The version number is a 3 bit code that must be set to 0. // Any other value should be treated as an error. - // TODO: should we throw here when version number is != 0? uint version = bitReader.ReadValue(WebPConstants.Vp8LVersionBits); + if (version != 0) + { + WebPThrowHelper.ThrowNotSupportedException($"Unexpected version number {version} found in VP8L header"); + } return new WebPImageInfo() { @@ -390,9 +396,8 @@ namespace SixLabors.ImageSharp.Formats.WebP Height = (int)height, BitsPerPixel = WebPBitsPerPixel.Pixel32, IsLossLess = true, - ImageDataSize = imageDataSize, Features = features, - Vp9LBitReader = bitReader + Vp8LBitReader = bitReader }; } diff --git a/src/ImageSharp/Formats/WebP/WebPImageInfo.cs b/src/ImageSharp/Formats/WebP/WebPImageInfo.cs index 5b602cce8c..08bfe2314c 100644 --- a/src/ImageSharp/Formats/WebP/WebPImageInfo.cs +++ b/src/ImageSharp/Formats/WebP/WebPImageInfo.cs @@ -31,18 +31,18 @@ namespace SixLabors.ImageSharp.Formats.WebP public WebPFeatures Features { get; set; } /// - /// Gets or sets the bytes of the image payload. + /// Gets or sets the VP8 profile / version. Valid values are between 0 and 3. Default value will be the invalid value -1. /// - public uint ImageDataSize { get; set; } + public int Vp8Profile { get; set; } = -1; /// - /// Gets or sets the VP8 profile / version. Valid values are between 0 and 3. Default value will be the invalid value -1. + /// Gets or sets the Vp8L bitreader. Will be null, if its not lossless image. /// - public int Vp8Profile { get; set; } = -1; + public Vp8LBitReader Vp8LBitReader { get; set; } = null; /// - /// Gets or sets Vp8L bitreader. Will be null if its not lossless image. + /// Gets or sets the VP8 bitreader. Will be null, if its not a lossy image. /// - public Vp8LBitReader Vp9LBitReader { get; set; } = null; + public Vp8BitReader Vp8BitReader { get; set; } = null; } } diff --git a/src/ImageSharp/Formats/WebP/WebPLossyDecoder.cs b/src/ImageSharp/Formats/WebP/WebPLossyDecoder.cs index 9a1862981b..b41e5b1e32 100644 --- a/src/ImageSharp/Formats/WebP/WebPLossyDecoder.cs +++ b/src/ImageSharp/Formats/WebP/WebPLossyDecoder.cs @@ -11,20 +11,17 @@ namespace SixLabors.ImageSharp.Formats.WebP { internal sealed class WebPLossyDecoder : WebPDecoderBase { - private readonly Configuration configuration; - - private readonly Stream currentStream; + private readonly Vp8BitReader bitReader; private readonly MemoryAllocator memoryAllocator; - public WebPLossyDecoder(Configuration configuration, Stream currentStream) + public WebPLossyDecoder(Vp8BitReader bitReader, MemoryAllocator memoryAllocator) { - this.configuration = configuration; - this.currentStream = currentStream; - this.memoryAllocator = configuration.MemoryAllocator; + this.memoryAllocator = memoryAllocator; + this.bitReader = bitReader; } - public void Decode(Buffer2D pixels, int width, int height, uint imageDataSize, int vp8Version) + public void Decode(Buffer2D pixels, int width, int height, int vp8Version) where TPixel : struct, IPixel { // we need buffers for Y U and V in size of the image @@ -35,7 +32,6 @@ namespace SixLabors.ImageSharp.Formats.WebP // 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 - var bitReader = new Vp8BitReader(this.currentStream, imageDataSize, this.memoryAllocator); Vp8Profile vp8Profile = this.DecodeProfile(vp8Version); }