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.
82 lines
2.6 KiB
82 lines
2.6 KiB
11 months ago
|
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;
|
||
|
}
|
||
|
}
|
||
|
}
|