Browse Source

Add all found chunk types to the metadata

Note: this does not seem to work in all cases at the moment
pull/1552/head
Brian Popow 7 years ago
parent
commit
4cd0ce4e74
  1. 5
      src/ImageSharp/Formats/WebP/Vp8LBitReader.cs
  2. 2
      src/ImageSharp/Formats/WebP/WebPChunkType.cs
  3. 26
      src/ImageSharp/Formats/WebP/WebPDecoderCore.cs
  4. 8
      src/ImageSharp/Formats/WebP/WebPMetadata.cs
  5. 2
      tests/ImageSharp.Tests/Formats/WebP/WebPDecoderTests.cs

5
src/ImageSharp/Formats/WebP/Vp8LBitReader.cs

@ -18,10 +18,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
/// <param name="inputStream">The input stream to read from.</param> /// <param name="inputStream">The input stream to read from.</param>
public Vp8LBitReader(Stream inputStream) public Vp8LBitReader(Stream inputStream)
{ {
this.stream = new MemoryStream(); this.stream = inputStream;
long inputStreamPos = inputStream.Position;
inputStream.CopyTo(this.stream);
inputStream.Position = inputStreamPos;
this.Offset = 0; this.Offset = 0;
this.Bit = 0; this.Bit = 0;
} }

2
src/ImageSharp/Formats/WebP/WebPChunkType.cs

@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
/// <summary> /// <summary>
/// Contains a list of different webp chunk types. /// Contains a list of different webp chunk types.
/// </summary> /// </summary>
internal enum WebPChunkType : uint public enum WebPChunkType : uint
{ {
/// <summary> /// <summary>
/// Header signaling the use of VP8 video format. /// Header signaling the use of VP8 video format.

26
src/ImageSharp/Formats/WebP/WebPDecoderCore.cs

@ -67,8 +67,6 @@ namespace SixLabors.ImageSharp.Formats.WebP
public Image<TPixel> Decode<TPixel>(Stream stream) public Image<TPixel> Decode<TPixel>(Stream stream)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
var metadata = new ImageMetadata();
WebPMetadata webpMetadata = metadata.GetFormatMetadata(WebPFormat.Instance);
this.currentStream = stream; this.currentStream = stream;
uint fileSize = this.ReadImageHeader(); uint fileSize = this.ReadImageHeader();
@ -298,11 +296,8 @@ namespace SixLabors.ImageSharp.Formats.WebP
// The next 3 bytes are the version. The version_number is a 3 bit code that must be set to 0. // The next 3 bytes 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. // Any other value should be treated as an error.
// TODO: should we throw here when version number is != 0?
uint version = bitReader.Read(3); uint version = bitReader.Read(3);
if (version != 0)
{
WebPThrowHelper.ThrowImageFormatException($"Unexpected webp version number: {version}");
}
// Next bit indicates, if a transformation is present. // Next bit indicates, if a transformation is present.
bool transformPresent = bitReader.ReadBit(); bool transformPresent = bitReader.ReadBit();
@ -365,15 +360,15 @@ namespace SixLabors.ImageSharp.Formats.WebP
private void ReadSimpleLossy<TPixel>(Buffer2D<TPixel> pixels, int width, int height, int imageDataSize) private void ReadSimpleLossy<TPixel>(Buffer2D<TPixel> pixels, int width, int height, int imageDataSize)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
// TODO: implement decoding, for simulating the decoding, skipping the chunk size bytes. // TODO: implement decoding. For simulating the decoding: skipping the chunk size bytes.
this.currentStream.Skip(imageDataSize - 10); // 10 bytes because of VP8X header. this.currentStream.Skip(imageDataSize); // TODO: this does not seem to work in all cases
} }
private void ReadSimpleLossless<TPixel>(Buffer2D<TPixel> pixels, int width, int height, int imageDataSize) private void ReadSimpleLossless<TPixel>(Buffer2D<TPixel> pixels, int width, int height, int imageDataSize)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
// TODO: implement decoding, for simulating the decoding, skipping the chunk size bytes. // TODO: implement decoding. For simulating the decoding: skipping the chunk size bytes.
this.currentStream.Skip(imageDataSize - 10); // 10 bytes because of VP8X header. this.currentStream.Skip(imageDataSize); // TODO: this does not seem to work in all cases
} }
private void ReadExtended<TPixel>(Buffer2D<TPixel> pixels, int width, int height) private void ReadExtended<TPixel>(Buffer2D<TPixel> pixels, int width, int height)
@ -403,9 +398,14 @@ namespace SixLabors.ImageSharp.Formats.WebP
/// </exception> /// </exception>
private WebPChunkType ReadChunkType() private WebPChunkType ReadChunkType()
{ {
return this.currentStream.Read(this.buffer, 0, 4) == 4 if (this.currentStream.Read(this.buffer, 0, 4) == 4)
? (WebPChunkType)BinaryPrimitives.ReadUInt32BigEndian(this.buffer) {
: throw new ImageFormatException("Invalid WebP data."); var chunkType = (WebPChunkType)BinaryPrimitives.ReadUInt32BigEndian(this.buffer);
this.webpMetadata.ChunkTypes.Enqueue(chunkType);
return chunkType;
}
throw new ImageFormatException("Invalid WebP data.");
} }
/// <summary> /// <summary>

8
src/ImageSharp/Formats/WebP/WebPMetadata.cs

@ -1,6 +1,9 @@
// Copyright (c) Six Labors and contributors. // Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System.Collections;
using System.Collections.Generic;
namespace SixLabors.ImageSharp.Formats.WebP namespace SixLabors.ImageSharp.Formats.WebP
{ {
/// <summary> /// <summary>
@ -33,6 +36,11 @@ namespace SixLabors.ImageSharp.Formats.WebP
/// </summary> /// </summary>
public WebPFormatType Format { get; set; } public WebPFormatType Format { get; set; }
/// <summary>
/// All found chunk types ordered by appearance.
/// </summary>
public Queue<WebPChunkType> ChunkTypes { get; set; } = new Queue<WebPChunkType>();
/// <summary> /// <summary>
/// Indicates, if the webp file contains a animation. /// Indicates, if the webp file contains a animation.
/// </summary> /// </summary>

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

@ -17,7 +17,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.WebP
[InlineData(Lossless.Lossless2, 1000, 307, 24)] [InlineData(Lossless.Lossless2, 1000, 307, 24)]
[InlineData(Lossy.Alpha.LossyAlpha1, 1000, 307, 24)] [InlineData(Lossy.Alpha.LossyAlpha1, 1000, 307, 24)]
[InlineData(Lossy.Alpha.LossyAlpha2, 1000, 307, 24)] [InlineData(Lossy.Alpha.LossyAlpha2, 1000, 307, 24)]
//[InlineData(Animated.Animated1, 400, 400, 24)] [InlineData(Animated.Animated1, 400, 400, 24)]
public void Identify_DetectsCorrectDimensions(string imagePath, int expectedWidth, int expectedHeight, int expectedBitsPerPixel) public void Identify_DetectsCorrectDimensions(string imagePath, int expectedWidth, int expectedHeight, int expectedBitsPerPixel)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);

Loading…
Cancel
Save