mirror of https://github.com/SixLabors/ImageSharp
2 changed files with 98 additions and 6 deletions
@ -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 |
|||
{ |
|||
/// <summary>
|
|||
/// A bit reader for VP8 streams.
|
|||
/// </summary>
|
|||
public class Vp8LBitreader |
|||
{ |
|||
private readonly Stream stream; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Vp8LBitreader"/> class.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream to read from.</param>
|
|||
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; } |
|||
|
|||
/// <summary>
|
|||
/// Check if the offset is inside the stream length.
|
|||
/// </summary>
|
|||
private bool ValidPosition |
|||
{ |
|||
get |
|||
{ |
|||
return this.Offset < this.stream.Length; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Reads a unsigned short value from the stream. The bits of each byte are read in least-significant-bit-first order.
|
|||
/// </summary>
|
|||
/// <param name="count">The number of bits to read (should not exceed 16).</param>
|
|||
/// <returns>A ushort value.</returns>
|
|||
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; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Reads one bit.
|
|||
/// </summary>
|
|||
/// <returns>True, if the bit is one, otherwise false.</returns>
|
|||
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; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Advances the stream by one Bit.
|
|||
/// </summary>
|
|||
public void AdvanceBit() |
|||
{ |
|||
this.Bit = (this.Bit + 1) % 8; |
|||
if (this.Bit == 0) |
|||
{ |
|||
this.Offset++; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue