Class EgamiInput
The data a reader decodes: the caller's stream behind a pooled 64 KB buffer, with exact-read helpers. It also carries the context, limits and cancellation token for the load, and is the only way a reader allocates pixel memory.
public sealed class EgamiInput : IDisposable
- Inheritance
-
EgamiInput
- Implements
- Inherited Members
Examples
/// <summary>A minimal format: "RAW8", width and height as big-endian numbers, then RGBA rows.</summary>
public static class Raw8Format
{
public static FormatInfo Info { get; } = new()
{
Name = "RAW8",
Extensions = ["raw8"],
SignatureLength = 4,
Matches = header => header.StartsWith("RAW8"u8),
Reader = new Reader(),
Writer = new Writer(),
};
private sealed class Reader : IFormatReader
{
public RasterInfo ReadInfo(EgamiInput input, ReaderOptions options)
{
(int width, int height) = Header(input);
return new RasterInfo { Format = Info, Width = width, Height = height, Layout = Rgba8.Layout, FrameCount = 1, EstimatedBytes = 4L * width * height };
}
public Raster<TPixel> Read<TPixel>(EgamiInput input, ReaderOptions options)
where TPixel : unmanaged, IPixelType<TPixel>
{
(int width, int height) = Header(input);
// CreateRaster checks the size against the safety limits before allocating.
Raster<TPixel> raster = input.CreateRaster<TPixel>(width, height);
using IMemoryOwner<byte> row = input.RentScratch(width * 4);
for (int y = 0; y < height; y++)
{
input.ReadExactly(row.Memory.Span[..(width * 4)]);
PixelConvert.Convert<Rgba8, TPixel>(MemoryMarshal.Cast<byte, Rgba8>(row.Memory.Span[..(width * 4)]), raster.Row(y));
}
return raster;
}
public Raster Read(EgamiInput input, ReaderOptions options) => Read<Rgba8>(input, options);
private static (int Width, int Height) Header(EgamiInput input)
{
input.Skip(4);
return ((int)input.ReadUInt32BigEndian(), (int)input.ReadUInt32BigEndian());
}
}
private sealed class Writer : IFormatWriter
{
public void Write<TPixel>(Raster<TPixel> raster, Stream output, WriterOptions options)
where TPixel : unmanaged, IPixelType<TPixel>
{
Span<byte> header = stackalloc byte[12];
"RAW8"u8.CopyTo(header);
BinaryPrimitives.WriteUInt32BigEndian(header[4..], (uint)raster.Width);
BinaryPrimitives.WriteUInt32BigEndian(header[8..], (uint)raster.Height);
output.Write(header);
Rgba8[] row = new Rgba8[raster.Width];
for (int y = 0; y < raster.Height; y++)
{
PixelConvert.Convert<TPixel, Rgba8>(raster.Row(y), row);
output.Write(MemoryMarshal.AsBytes(row.AsSpan()));
}
}
}
}
Remarks
Readers never call the stream directly. Egami never disposes the caller's stream.
Constructors
EgamiInput(Stream, EgamiContext, CancellationToken)
Creates the input of a load a plug-in runs itself, outside Load(Stream, EgamiContext?, ReaderOptions?): a format package that reads a file to convert it, say. Dispose it when the load ends.
public EgamiInput(Stream stream, EgamiContext context, CancellationToken cancellationToken)
Parameters
streamStreamThe data, from its current position. It is left open.
contextEgamiContextThe context of the load: its limits, memory and diagnostics.
cancellationTokenCancellationTokenCancels the load.
Exceptions
- ArgumentNullException
streamorcontextis null.
Properties
CancellationToken
Gets the token that cancels the load. Readers check it between rows.
public CancellationToken CancellationToken { get; }
Property Value
Context
Gets the context of the load.
public EgamiContext Context { get; }
Property Value
Diagnostics
Gets the load's link to Diagnostics, for a reader's Info and Debug events. Warnings go through Warn(Raster, string, string, long?), so they are also listed in Warnings.
public DiagnosticReporter Diagnostics { get; }
Property Value
FormatName
Gets the name of the format being read, used in CorruptDataException messages.
public string FormatName { get; }
Property Value
Limits
Gets the safety limits of the load.
public SafetyLimits Limits { get; }
Property Value
Position
Gets the number of bytes consumed since the start of the image.
public long Position { get; }
Property Value
Methods
AddFrame<TPixel>(Raster<TPixel>, ClearMode)
Appends a new frame the raster's size to a raster this load created with CreateRaster<TPixel>(long, long, ClearMode), for readers of animated
formats. The frame counts against MaxFrames and the load's memory budget. Unless
clear asks for it, its pixels are not cleared.
public Frame<TPixel> AddFrame<TPixel>(Raster<TPixel> raster, ClearMode clear = ClearMode.None) where TPixel : unmanaged, IPixelType<TPixel>
Parameters
Returns
Type Parameters
TPixelThe pixel type.
Exceptions
- LimitExceededException
The frame count or the memory budget would be exceeded.
CheckFrameCount(long)
Checks a frame count against MaxFrames.
public void CheckFrameCount(long frames)
Parameters
frameslongThe frames the file says it has, or will have.
Exceptions
- LimitExceededException
There are too many.
CheckFrameSize(long, long)
Checks a frame size against MaxWidth, MaxHeight and MaxPixels, as CreateRaster<TPixel>(long, long, ClearMode) does, for a reader that allocates its own row buffers before it creates a raster, such as an IRowFormatReader.
public void CheckFrameSize(long width, long height)
Parameters
widthlongThe width the file says the image has.
heightlongThe height the file says the image has.
Exceptions
- LimitExceededException
The size breaks a limit.
CheckMemory(long)
Checks that bytes more would fit the load's memory budget, without allocating.
public void CheckMemory(long bytes)
Parameters
byteslongThe bytes about to be needed.
Exceptions
- LimitExceededException
They would not fit.
CheckMetadataBytes(long)
Checks a metadata size against MaxMetadataBytes.
public void CheckMetadataBytes(long bytes)
Parameters
byteslongThe metadata bytes kept so far, or about to be read.
Exceptions
- LimitExceededException
They are too many.
Corrupt(long, string)
Creates a CorruptDataException for this format.
public CorruptDataException Corrupt(long offset, string problem)
Parameters
offsetlongThe byte offset of the problem, or -1 if unknown.
problemstringWhat is wrong, as a sentence.
Returns
- CorruptDataException
The exception, for the reader to throw.
CreateRaster<TPixel>(long, long, ClearMode)
Creates the raster a reader decodes into, after checking the size against SafetyLimits and the memory budget.
Unless clear asks for it, pixels are not cleared and the reader must write every one.
public Raster<TPixel> CreateRaster<TPixel>(long width, long height, ClearMode clear = ClearMode.None) where TPixel : unmanaged, IPixelType<TPixel>
Parameters
widthlongThe width from the header.
heightlongThe height from the header.
clearClearModeWhether to zero the pixels first. Readers that write every pixel skip it.
Returns
- Raster<TPixel>
A one-frame raster. The reader owns it until it returns it, and must dispose it if decoding fails.
Type Parameters
TPixelThe pixel type.
Exceptions
- LimitExceededException
The size breaks a safety limit.
- CorruptDataException
The width or height is zero or negative.
Dispose()
Returns the buffer to the pool. Leaves the stream open.
public void Dispose()
Peek(int)
Returns up to count upcoming bytes without consuming them. The span is shorter only at the end of the data.
It is valid until the next read.
public ReadOnlySpan<byte> Peek(int count)
Parameters
countintHow many bytes to look at, at most 64 KB.
Returns
- ReadOnlySpan<byte>
The upcoming bytes.
Exceptions
- ArgumentOutOfRangeException
countis negative or above 64 KB.
Read(Span<byte>)
Reads as many bytes as are available, up to the length of destination.
public int Read(Span<byte> destination)
Parameters
Returns
- int
The number of bytes read. Less than requested only at the end of the data.
ReadByte()
Reads one byte.
public byte ReadByte()
Returns
- byte
The byte.
Exceptions
- CorruptDataException
The data has ended.
ReadExactly(Span<byte>)
Reads exactly destination.Length bytes.
public void ReadExactly(Span<byte> destination)
Parameters
Exceptions
- CorruptDataException
The data ends first.
ReadUInt16BigEndian()
Reads a big-endian 16-bit unsigned integer.
public ushort ReadUInt16BigEndian()
Returns
- ushort
The value.
Exceptions
- CorruptDataException
The data ends first.
ReadUInt16LittleEndian()
Reads a little-endian 16-bit unsigned integer.
public ushort ReadUInt16LittleEndian()
Returns
- ushort
The value.
Exceptions
- CorruptDataException
The data ends first.
ReadUInt32BigEndian()
Reads a big-endian 32-bit unsigned integer.
public uint ReadUInt32BigEndian()
Returns
- uint
The value.
Exceptions
- CorruptDataException
The data ends first.
ReadUInt32LittleEndian()
Reads a little-endian 32-bit unsigned integer.
public uint ReadUInt32LittleEndian()
Returns
- uint
The value.
Exceptions
- CorruptDataException
The data ends first.
RentScratch(int, ClearMode)
Rents scratch memory (a canvas row, a previous frame, a decompression buffer) counted against the load's memory budget with the raster. Dispose it when done.
public IMemoryOwner<byte> RentScratch(int byteLength, ClearMode clear = ClearMode.None)
Parameters
Returns
- IMemoryOwner<byte>
The memory.
Exceptions
- LimitExceededException
The memory budget would be exceeded.
Skip(long)
Skips count bytes.
public void Skip(long count)
Parameters
countlongHow many bytes to skip.
Exceptions
- CorruptDataException
The data ends first.
Warn(RasterMetadata, string, string, long?)
Notes a problem a lenient read recovered from in metadata's Warnings, for an
IRowFormatReader's open image, which has its metadata but no raster. The decoder sends the warnings to
Diagnostics as it does for Warn(Raster, string, string, long?).
public void Warn(RasterMetadata metadata, string id, string warning, long? offset = null)
Parameters
metadataRasterMetadataThe open image's Metadata.
idstringA stable id of the form
Source.Name, such as"Pcx.PaletteMissing".warningstringWhat was wrong and what the reader did, as a sentence.
offsetlong?The byte offset in the input the problem is at, if known.
Exceptions
- ArgumentException
idhas no dot, orwarningis empty.
Warn(Raster, string, string, long?)
Notes a problem a lenient read recovered from in the raster's Warnings, which also sends it to Diagnostics when the load ends.
public void Warn(Raster raster, string id, string warning, long? offset = null)
Parameters
rasterRasterThe raster being read.
idstringA stable id of the form
Source.Name, such as"Pcx.PaletteMissing"; Source is the part before the dot. Keep ids the same from version to version so apps can filter on them.warningstringWhat was wrong and what the reader did, as a sentence.
offsetlong?The byte offset in the input the problem is at, if known.
Exceptions
- ArgumentException
idhas no dot, orwarningis empty.