Browse Source

Use the width and height from the VP8X information, if present

pull/1552/head
Brian Popow 7 years ago
parent
commit
bc80cf1c6b
  1. 39
      src/ImageSharp/Formats/WebP/WebPDecoderCore.cs

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

@ -70,8 +70,6 @@ namespace SixLabors.ImageSharp.Formats.WebP
uint chunkSize = this.ReadImageHeader(); uint chunkSize = this.ReadImageHeader();
WebPImageInfo imageInfo = this.ReadVp8Info(); WebPImageInfo imageInfo = this.ReadVp8Info();
// TODO: there can be optional chunks after that, like EXIF.
var image = new Image<TPixel>(this.configuration, imageInfo.Width, imageInfo.Height, this.metadata); var image = new Image<TPixel>(this.configuration, imageInfo.Width, imageInfo.Height, this.metadata);
Buffer2D<TPixel> pixels = image.GetRootFramePixelBuffer(); Buffer2D<TPixel> pixels = image.GetRootFramePixelBuffer();
if (imageInfo.IsLossLess) if (imageInfo.IsLossLess)
@ -83,6 +81,8 @@ namespace SixLabors.ImageSharp.Formats.WebP
ReadSimpleLossy(pixels, image.Width, image.Height); ReadSimpleLossy(pixels, image.Width, image.Height);
} }
// TODO: there can be optional chunks after the image data, like EXIF, XMP etc.
return image; return image;
} }
@ -121,19 +121,19 @@ namespace SixLabors.ImageSharp.Formats.WebP
return chunkSize; return chunkSize;
} }
private WebPImageInfo ReadVp8Info() private WebPImageInfo ReadVp8Info(int vpxWidth = 0, int vpxHeight = 0)
{ {
// Read VP8 chunk header. // Read VP8 chunk header.
this.currentStream.Read(this.buffer, 0, 4); this.currentStream.Read(this.buffer, 0, 4);
if (this.buffer.AsSpan().SequenceEqual(WebPConstants.Vp8Header)) if (this.buffer.AsSpan().SequenceEqual(WebPConstants.Vp8Header))
{ {
return this.ReadVp8Header(); return this.ReadVp8Header(vpxWidth, vpxHeight);
} }
if (this.buffer.AsSpan().SequenceEqual(WebPConstants.Vp8LHeader)) if (this.buffer.AsSpan().SequenceEqual(WebPConstants.Vp8LHeader))
{ {
return this.ReadVp8LHeader(); return this.ReadVp8LHeader(vpxWidth, vpxHeight);
} }
if (this.buffer.SequenceEqual(WebPConstants.Vp8XHeader)) if (this.buffer.SequenceEqual(WebPConstants.Vp8XHeader))
@ -184,18 +184,13 @@ namespace SixLabors.ImageSharp.Formats.WebP
this.buffer[3] = 0; this.buffer[3] = 0;
int height = BinaryPrimitives.ReadInt32LittleEndian(this.buffer) + 1; int height = BinaryPrimitives.ReadInt32LittleEndian(this.buffer) + 1;
// TODO: optional chunks ICCP and ANIM can follow here. // TODO: optional chunks ICCP and ANIM can follow here. Ignoring them for now.
return new WebPImageInfo() // A VP8 or VP8L chunk will follow here.
{ return this.ReadVp8Info(width, height);
Width = width,
Height = height,
IsLossLess = false, // note: this is maybe incorrect here
DataSize = chunkSize
};
} }
private WebPImageInfo ReadVp8Header() private WebPImageInfo ReadVp8Header(int vpxWidth = 0, int vpxHeight = 0)
{ {
// VP8 data size. // VP8 data size.
this.currentStream.Read(this.buffer, 0, 3); this.currentStream.Read(this.buffer, 0, 3);
@ -227,16 +222,19 @@ namespace SixLabors.ImageSharp.Formats.WebP
int width = BinaryPrimitives.ReadInt16LittleEndian(this.buffer) & 0x3fff; int width = BinaryPrimitives.ReadInt16LittleEndian(this.buffer) & 0x3fff;
int height = BinaryPrimitives.ReadInt16LittleEndian(this.buffer.AsSpan(2)) & 0x3fff; int height = BinaryPrimitives.ReadInt16LittleEndian(this.buffer.AsSpan(2)) & 0x3fff;
// Use the width and height from the VP8X information, if its provided, because its 3 bytes instead of 14 bits.
bool isVpxDimensionsPresent = vpxHeight != 0 || vpxWidth != 0;
return new WebPImageInfo() return new WebPImageInfo()
{ {
Width = width, Width = isVpxDimensionsPresent ? vpxWidth : width,
Height = height, Height = isVpxDimensionsPresent ? vpxHeight : height,
IsLossLess = false, IsLossLess = false,
DataSize = dataSize DataSize = dataSize
}; };
} }
private WebPImageInfo ReadVp8LHeader() private WebPImageInfo ReadVp8LHeader(int vpxWidth = 0, int vpxHeight = 0)
{ {
// VP8 data size. // VP8 data size.
this.currentStream.Read(this.buffer, 0, 4); this.currentStream.Read(this.buffer, 0, 4);
@ -314,10 +312,13 @@ namespace SixLabors.ImageSharp.Formats.WebP
transformPresent = bitReader.ReadBit(); transformPresent = bitReader.ReadBit();
} }
// Use the width and height from the VP8X information, if its provided, because its 3 bytes instead of 14 bits.
bool isVpxDimensionsPresent = vpxHeight != 0 || vpxWidth != 0;
return new WebPImageInfo() return new WebPImageInfo()
{ {
Width = (int)width, Width = isVpxDimensionsPresent ? vpxWidth : (int)width,
Height = (int)height, Height = isVpxDimensionsPresent ? vpxHeight : (int)height,
IsLossLess = true, IsLossLess = true,
DataSize = dataSize DataSize = dataSize
}; };

Loading…
Cancel
Save