You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
2.6 KiB
81 lines
2.6 KiB
using System; |
|
using System.Diagnostics; |
|
using System.IO; |
|
using System.Runtime.CompilerServices; |
|
|
|
namespace Avalonia.Gif.Extensions |
|
{ |
|
[DebuggerStepThrough] |
|
internal static class StreamExtensions |
|
{ |
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
public static ushort SpanToShort(Span<byte> b) => (ushort)(b[0] | (b[1] << 8)); |
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
public static void Skip(this Stream stream, long count) |
|
{ |
|
stream.Position += count; |
|
} |
|
|
|
/// <summary> |
|
/// Read a Gif block from stream while advancing the position. |
|
/// </summary> |
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
public static int ReadBlock(this Stream stream, byte[] tempBuf) |
|
{ |
|
stream.Read(tempBuf, 0, 1); |
|
|
|
var blockLength = (int)tempBuf[0]; |
|
|
|
if (blockLength > 0) |
|
stream.Read(tempBuf, 0, blockLength); |
|
|
|
// Guard against infinite loop. |
|
if (stream.Position >= stream.Length) |
|
throw new InvalidGifStreamException("Reach the end of the filestream without trailer block."); |
|
|
|
return blockLength; |
|
} |
|
|
|
/// <summary> |
|
/// Skips GIF blocks until it encounters an empty block. |
|
/// </summary> |
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
public static void SkipBlocks(this Stream stream, byte[] tempBuf) |
|
{ |
|
int blockLength; |
|
do |
|
{ |
|
stream.Read(tempBuf, 0, 1); |
|
|
|
blockLength = tempBuf[0]; |
|
stream.Position += blockLength; |
|
|
|
// Guard against infinite loop. |
|
if (stream.Position >= stream.Length) |
|
throw new InvalidGifStreamException("Reach the end of the filestream without trailer block."); |
|
} while (blockLength > 0); |
|
} |
|
|
|
/// <summary> |
|
/// Read a <see cref="ushort"/> from stream by providing a temporary buffer. |
|
/// </summary> |
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
public static ushort ReadUShortS(this Stream stream, byte[] tempBuf) |
|
{ |
|
stream.Read(tempBuf, 0, 2); |
|
return SpanToShort(tempBuf); |
|
} |
|
|
|
/// <summary> |
|
/// Read a <see cref="ushort"/> from stream by providing a temporary buffer. |
|
/// </summary> |
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
public static byte ReadByteS(this Stream stream, byte[] tempBuf) |
|
{ |
|
stream.Read(tempBuf, 0, 1); |
|
var finalVal = tempBuf[0]; |
|
return finalVal; |
|
} |
|
} |
|
}
|
|
|