Table of Contents

Interface IPixelType<TSelf>

Namespace
Egami.Pixels
Assembly
Egami.dll

A pixel type: an unmanaged struct holding one pixel. The conversions (ToScaled, FromScaled, ToRgba8, FromRgba8) always use sRGB-encoded values with straight (not premultiplied) alpha; Layout says how the pixel is stored, so Egami can take faster paths for layouts it knows. Types from outside Egami may use any layout, with Other for ones Egami does not know.

public interface IPixelType<TSelf> : IEquatable<TSelf> where TSelf : unmanaged, IPixelType<TSelf>

Type Parameters

TSelf

The pixel type itself.

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()));
            }
        }
    }
}

Properties

Layout

Gets the memory layout of this pixel type.

public static abstract PixelLayoutInfo Layout { get; }

Property Value

PixelLayoutInfo

Methods

FromRgba16(Rgba16)

Creates a pixel from a 16-bit color. Conversions between two integer types wider than 8 bits go through this, so they are exact wherever the type can hold the color. The default goes through FromScaled(Vector4); types with integer channels may override it with exact integer code.

public static TSelf FromRgba16(Rgba16 value)

Parameters

value Rgba16

The color.

Returns

TSelf

The pixel.

FromRgba8(Rgba8)

Creates a pixel from an 8-bit color. The conversion is exact wherever the type can hold the color. Gray types take the Rec. 709 luma, weighted in linear light. Types without alpha drop it.

public static abstract TSelf FromRgba8(Rgba8 value)

Parameters

value Rgba8

The color.

Returns

TSelf

The pixel.

FromScaled(Vector4)

Creates a pixel from red, green, blue and alpha scaled to 0..1, with straight alpha. Values outside 0..1 are clamped and NaN becomes 0. Gray types take the Rec. 709 luma of the color, weighted in linear light. Types without alpha drop it.

public static abstract TSelf FromScaled(Vector4 rgba)

Parameters

rgba Vector4

The color, with each channel scaled to 0..1.

Returns

TSelf

The nearest pixel of this type.

ToRgba16()

Returns the pixel as a 16-bit color. The default goes through ToScaled(); types with integer channels may override it with exact integer code.

Rgba16 ToRgba16()

Returns

Rgba16

The 16-bit color.

ToRgba8()

Returns the pixel as an 8-bit color. 16-bit channels are rounded to the nearest 8-bit value, and gray is copied to red, green and blue.

Rgba8 ToRgba8()

Returns

Rgba8

The 8-bit color.

ToScaled()

Returns red, green, blue and alpha scaled to 0..1. Types without alpha return an alpha of 1.

Vector4 ToScaled()

Returns

Vector4

The scaled color.