diff --git a/src/ImageSharp/Formats/WebP/Vp8LBitReader.cs b/src/ImageSharp/Formats/WebP/Vp8LBitReader.cs
new file mode 100644
index 000000000..bcde6e74c
--- /dev/null
+++ b/src/ImageSharp/Formats/WebP/Vp8LBitReader.cs
@@ -0,0 +1,93 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System.IO;
+
+namespace SixLabors.ImageSharp.Formats.WebP
+{
+ ///
+ /// A bit reader for VP8 streams.
+ ///
+ public class Vp8LBitreader
+ {
+ private readonly Stream stream;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The stream to read from.
+ public Vp8LBitreader(Stream stream)
+ {
+ this.stream = new MemoryStream();
+ stream.CopyTo(this.stream);
+ this.Offset = 0;
+ this.Bit = 0;
+ }
+
+ private long Offset { get; set; }
+
+ private int Bit { get; set; }
+
+ ///
+ /// Check if the offset is inside the stream length.
+ ///
+ private bool ValidPosition
+ {
+ get
+ {
+ return this.Offset < this.stream.Length;
+ }
+ }
+
+ ///
+ /// Reads a unsigned short value from the stream. The bits of each byte are read in least-significant-bit-first order.
+ ///
+ /// The number of bits to read (should not exceed 16).
+ /// A ushort value.
+ public uint Read(int count)
+ {
+ uint readValue = 0;
+ for (int bitPos = 0; bitPos < count; bitPos++)
+ {
+ bool bitRead = this.ReadBit();
+ if (bitRead)
+ {
+ readValue = (uint)(readValue | (1 << bitPos));
+ }
+ }
+
+ return readValue;
+ }
+
+ ///
+ /// Reads one bit.
+ ///
+ /// True, if the bit is one, otherwise false.
+ public bool ReadBit()
+ {
+ if (!ValidPosition)
+ {
+ WebPThrowHelper.ThrowImageFormatException("The image stream does not contain enough data");
+ }
+
+ this.stream.Seek(this.Offset, SeekOrigin.Begin);
+ byte value = (byte)((this.stream.ReadByte() >> this.Bit) & 1);
+ this.AdvanceBit();
+ this.stream.Seek(this.Offset, SeekOrigin.Begin);
+
+ return value == 1;
+ }
+
+ ///
+ /// Advances the stream by one Bit.
+ ///
+ public void AdvanceBit()
+ {
+ this.Bit = (this.Bit + 1) % 8;
+ if (this.Bit == 0)
+ {
+ this.Offset++;
+ }
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs b/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs
index 49871d005..769c1a1ca 100644
--- a/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs
+++ b/src/ImageSharp/Formats/WebP/WebPDecoderCore.cs
@@ -230,15 +230,14 @@ namespace SixLabors.ImageSharp.Formats.WebP
}
// The first 28 bits of the bitstream specify the width and height of the image.
- this.currentStream.Read(this.buffer, 0, 4);
- // TODO: A bitreader should be used from here on which reads least-significant-bit-first
- int height = 0;
- int width = 0;
+ var bitReader = new Vp8LBitreader(this.currentStream);
+ uint height = bitReader.Read(WebPConstants.Vp8LImageSizeBits) + 1;
+ uint width = bitReader.Read(WebPConstants.Vp8LImageSizeBits) + 1;
return new WebPImageInfo()
{
- Width = width,
- Height = height,
+ Width = (int)width,
+ Height = (int)height,
IsLossLess = true,
DataSize = dataSize
};