moonbitstack/moonimage/raster does not have a README file

    Refused

    pub(all) suberror Refused {
    Unexpected(at~ : Int, got~ : String, want~ : String)
    Unknown(at~ : Int, got~ : String)
    Unsupported(at~ : Int, got~ : String)
    Truncated(at~ : Int, want~ : Int)
    OverLimit(limit~ : Int, got~ : Int)
    Checksum(at~ : Int, got~ : String, want~ : String)
    } derive(Eq,
    Debug
    )

    A refusal to read bytes as an image, or to write an image as bytes.

    The variants separate the three questions a caller asks: is this the wrong kind of file (Unknown), is the file damaged (Unexpected, Truncated, Checksum), or is the caller asking for more than it allowed (OverLimit). Unsupported is the fourth: a part of a format this library does not read.
    impl Show for Refused

    Refused::equal

    fn Refused::equal(Refused, Refused) -> Bool

    Refused::not_equal

    fn Refused::not_equal(x : Refused, y : Refused) -> Bool

    Refused::output

    fn Refused::output(self : Refused, logger : &Logger) -> Unit

    Refused::to_repr

    Refused::to_string

    fn Refused::to_string(self : Refused) -> String

    Animation

    pub(all) struct Animation {
    width : Int
    height : Int
    loops : Int
    frames : Array[Frame]
    metadata : Metadata
    }

    A sequence of frames over one canvas.

    Animation::compose

    fn Animation::compose(self : Animation) -> Array[Image]

    Every frame as a full canvas, in order, with each rule applied as it goes.

    The result is what a viewer shows: the same length as frames, each one the whole canvas. This is the expensive way to watch an animation and the only way to see it out of context, which is what a test does.

    The canvas is sixteen-bit, so that an eight-bit animation and a sixteen-bit one come out of the same code without either losing its precision.

    Animation::new

    fn Animation::new(width : Int, height : Int, frames : Array[Frame], loops? : Int, metadata? : Metadata) -> Animation

    An animation over a canvas, with no frames yet unless given some.

    Blend

    pub(all) enum Blend {
    Source
    Over
    } derive(Eq,
    Debug
    )

    How a frame's pixels meet what is already on the canvas.

    Blend::equal

    fn Blend::equal(Blend, Blend) -> Bool

    Blend::not_equal

    fn Blend::not_equal(x : Blend, y : Blend) -> Bool

    Blend::to_repr

    Chromaticities

    pub(all) struct Chromaticities {
    white_x : Double
    white_y : Double
    red_x : Double
    red_y : Double
    green_x : Double
    green_y : Double
    blue_x : Double
    blue_y : Double
    } derive(Eq,
    Debug
    )

    The white point and the three primaries, as chromaticity coordinates.

    Eight numbers rather than a matrix: this is what a file writes, and a matrix would be a conversion, which this library does not do.

    Chromaticities::equal

    Chromaticities::not_equal

    fn Chromaticities::not_equal(x : Chromaticities, y : Chromaticities) -> Bool

    Chromaticities::srgb

    The primaries of sRGB, which is what almost every file means when it says nothing.

    Dispose

    pub(all) enum Dispose {
    Keep
    Background
    Previous
    } derive(Eq,
    Debug
    )

    What to do with the frame's rectangle once the frame has been shown.

    Dispose::equal

    fn Dispose::equal(Dispose, Dispose) -> Bool

    Dispose::not_equal

    fn Dispose::not_equal(x : Dispose, y : Dispose) -> Bool

    Dispose::to_repr

    Format

    pub(all) enum Format {
    Png
    Qoi
    Bmp
    Tga
    Jpeg
    Gif
    Webp
    } derive(Eq,
    Debug
    )

    The formats this library reads and writes.
    impl Show for Format

    Format::equal

    fn Format::equal(Format, Format) -> Bool

    Format::extension

    fn Format::extension(self : Format) -> String

    The extension a file of this format usually has, without the dot.

    Format::mime

    fn Format::mime(self : Format) -> String

    The media type a server would send for this format.

    Format::not_equal

    fn Format::not_equal(x : Format, y : Format) -> Bool

    Format::of

    fn Format::of(bytes : BytesView) -> Format raise Refused

    Which format these bytes are, by signature.

    Raises Unknown when nothing matches and Truncated when there are too few bytes to tell: two bytes of a PNG are not a PNG, and saying so is better than guessing.

    Format::output

    fn Format::output(self : Format, logger : &Logger) -> Unit

    Format::to_repr

    Format::to_string

    fn Format::to_string(self : Format) -> String

    Frame

    pub(all) struct Frame {
    image : Image
    x : Int
    y : Int
    delay : Int
    dispose : Dispose
    blend : Blend
    }

    One frame: a picture, where it goes, and how long it stays.

    Frame::new

    fn Frame::new(image : Image, x? : Int, y? : Int, delay? : Int, dispose? : Dispose, blend? : Blend) -> Frame

    A frame that covers the canvas, shown for a tenth of a second, drawn over what is there.

    Icc

    pub(all) struct Icc {
    name : String
    profile : Bytes
    } derive(Eq,
    Debug
    )

    An embedded ICC profile, kept by name and bytes. Not applied: a caller that wants colour management hands these bytes to something that does it.

    Icc::equal

    fn Icc::equal(Icc, Icc) -> Bool

    Icc::not_equal

    fn Icc::not_equal(x : Icc, y : Icc) -> Bool

    Icc::to_repr

    Image

    pub(all) struct Image {
    width : Int
    height : Int
    format : PixelFormat
    stride : Int
    pixels : Bytes
    premultiplied : Bool
    metadata : Metadata
    }

    An image: its shape, its layout, and the bytes.

    Image::convert

    fn Image::convert(self : Image, format : PixelFormat) -> Image

    The same image, in another sample format.

    Colour is preserved as far as the target can hold it: a grey image becomes grey, an image without alpha becomes opaque, and narrowing rounds to nearest.

    Image::crop

    fn Image::crop(self : Image, x : Int, y : Int, width : Int, height : Int) -> Image raise Refused

    The rectangle at (x, y) of the given size, as an image of its own.

    Raises when the rectangle does not fit: a crop is a claim about the image, and a crop that reaches outside it is a bug in the caller.

    Image::flip_horizontal

    fn Image::flip_horizontal(self : Image) -> Image

    The image reflected left to right.

    Image::flip_vertical

    fn Image::flip_vertical(self : Image) -> Image

    The image reflected top to bottom.

    Image::new

    fn Image::new(width : Int, height : Int, format : PixelFormat, stride? : Int, premultiplied? : Bool, metadata? : Metadata) -> Image

    A black image of this shape, with tight rows.

    stride is only needed when the rows must be padded; leave it out and the rows are as wide as the pixels.

    Image::of

    fn Image::of(width : Int, height : Int, format : PixelFormat, pixels : Bytes, stride? : Int, premultiplied? : Bool, metadata? : Metadata) -> Image raise Refused

    An image over bytes that already exist.

    Raises when the bytes cannot hold the shape: a stride narrower than a row, or fewer bytes than the last row needs.

    Image::pixel

    fn Image::pixel(self : Image, x : Int, y : Int) -> Pixel raise Refused

    The pixel at a coordinate, in the units every operation works in.

    Straight alpha, as stored: an image that says it is premultiplied returns premultiplied samples, because pretending otherwise would be a conversion the caller did not ask for.

    Image::rotate

    fn Image::rotate(self : Image, quarters? : Int) -> Image

    The image turned a quarter turn clockwise, quarters times.

    Negative counts turn anticlockwise, and anything beyond four wraps: this is a total function because a rotation is.

    Image::row

    fn Image::row(self : Image, y : Int) -> BytesView raise Refused

    One row, without its padding.

    Image::scale

    fn Image::scale(self : Image, width : Int, height : Int, sampling? : Sampling) -> Image raise Refused

    The image at a new size.

    Raises when either dimension is not positive, and when the result would be larger than Limits::default() — a scaler is easy to point at a huge size by accident.

    Image::to_premultiplied

    fn Image::to_premultiplied(self : Image) -> Image

    The same image with colour multiplied by alpha.

    Idempotent: an image that already says it is premultiplied comes back unchanged, so a caller can ask without checking first.

    Image::to_straight

    fn Image::to_straight(self : Image) -> Image

    The same image with alpha divided back out.

    The inverse of to_premultiplied up to rounding, which is why a round trip is only exact for images whose colour is already premultiplied.

    Intent

    pub(all) enum Intent {
    Perceptual
    Relative
    Saturation
    Absolute
    } derive(Eq,
    Debug
    )

    What a column of pixels was meant to be seen in.

    Intent::code

    fn Intent::code(self : Intent) -> Int

    The number a file writes for this intent, which is how PNG's sRGB chunk numbers them.

    Intent::equal

    fn Intent::equal(Intent, Intent) -> Bool

    Intent::not_equal

    fn Intent::not_equal(x : Intent, y : Intent) -> Bool

    Intent::of

    fn Intent::of(code : Int) -> Intent?

    The intent a number stands for, or None if it is not one of the four.

    Intent::to_repr

    Limits

    pub(all) struct Limits {
    width : Int
    height : Int
    pixels : Int
    bytes : Int
    }

    The ceilings a decoder works under.

    The defaults are the ones a desktop application can live with: a texture no larger than a modern GPU takes, and a megabyte of pixels at the very most. A caller reading files from the network should set them lower; a caller reading its own assets can leave them alone.

    Limits::allows

    fn Limits::allows(self : Limits, width : Int, height : Int) -> Bool

    Whether an image of this shape is inside the limits.

    Limits::check

    fn Limits::check(self : Limits, width : Int, height : Int) -> Unit raise Refused

    Refuse an image of this shape unless the limits allow it.

    The pixel count is multiplied in 64 bits so that a declaration of 65535 × 65535 cannot wrap into a small number and pass.

    Limits::check_bytes

    fn Limits::check_bytes(self : Limits, bytes : Int) -> Unit raise Refused

    Refuse a buffer of this many bytes unless the limits allow it.

    Limits::default

    fn Limits::default() -> Limits

    The desktop defaults: a million pixels a side, 256 megapixels in all, and a gigabyte of expansion.

    Limits::strict

    fn Limits::strict() -> Limits

    What a viewer of untrusted uploads would choose: 8192 square, 64 megapixels, 256 MiB of expansion.

    Metadata

    pub(all) struct Metadata {
    gamma : Double?
    chromaticities : Chromaticities?
    intent : Intent?
    icc : Icc?
    texts : Array[Text]
    } derive(Eq,
    Debug
    )

    Everything the file said about itself besides its pixels.

    Metadata::default

    fn Metadata::default() -> Metadata

    No metadata at all, which is what an image built in memory has.

    Metadata::equal

    fn Metadata::equal(Metadata, Metadata) -> Bool

    Metadata::is_empty

    fn Metadata::is_empty(self : Metadata) -> Bool

    Whether there is nothing to write.

    Metadata::not_equal

    fn Metadata::not_equal(x : Metadata, y : Metadata) -> Bool

    Metadata::to_repr

    Pixel

    pub(all) struct Pixel {
    r : Double
    g : Double
    b : Double
    a : Double
    } derive(Eq,
    Debug
    )

    One pixel, in the units every operation in the library works in: four samples from 0 to 1, alpha straight.

    A grey pixel has r, g and b equal, which is why there is no grey variant: a reader that has to branch on whether a pixel is grey is a reader that will forget to inflate one of the three channels.

    Pixel::equal

    fn Pixel::equal(Pixel, Pixel) -> Bool

    Pixel::not_equal

    fn Pixel::not_equal(x : Pixel, y : Pixel) -> Bool

    Pixel::of_rgba8

    fn Pixel::of_rgba8(r : Int, g : Int, b : Int, a? : Int) -> Pixel

    A pixel from the eight-bit values an editor shows.

    Pixel::rgba16

    fn Pixel::rgba16(self : Pixel) -> (Int, Int, Int, Int)

    The pixel as sixteen-bit samples, which is what a PNG stores when its bit depth is sixteen.

    Pixel::rgba8

    fn Pixel::rgba8(self : Pixel) -> (Int, Int, Int, Int)

    The pixel as bytes an editor shows: rounded, clamped, alpha last.

    Pixel::to_repr

    PixelFormat

    pub(all) enum PixelFormat {
    Gray8
    GrayAlpha8
    Rgb8
    Rgba8
    Gray16
    GrayAlpha16
    Rgb16
    Rgba16
    RgbaF32
    } derive(Eq,
    Debug
    )

    How the samples of an image are laid out.

    The names are the usual ones: Gray8 is one byte per pixel, Rgba8 four, Rgba16 eight with each channel big-endian, RgbaF32 four floats.
    impl Show for PixelFormat

    PixelFormat::bits

    fn PixelFormat::bits(self : PixelFormat) -> Int

    How many bits one sample takes. For RgbaF32 this is 32, which says how wide the sample is, not that it is an integer.

    PixelFormat::bytes

    fn PixelFormat::bytes(self : PixelFormat) -> Int

    How many bytes a pixel of this format takes.

    PixelFormat::channels

    fn PixelFormat::channels(self : PixelFormat) -> Int

    How many samples a pixel of this format has.

    PixelFormat::equal

    fn PixelFormat::equal(PixelFormat, PixelFormat) -> Bool

    PixelFormat::has_alpha

    fn PixelFormat::has_alpha(self : PixelFormat) -> Bool

    Whether the image carries alpha.

    PixelFormat::is_float

    fn PixelFormat::is_float(self : PixelFormat) -> Bool

    Whether the samples are floats rather than integers.

    PixelFormat::is_gray

    fn PixelFormat::is_gray(self : PixelFormat) -> Bool

    Whether the image carries colour at all.

    PixelFormat::not_equal

    fn PixelFormat::not_equal(x : PixelFormat, y : PixelFormat) -> Bool

    PixelFormat::output

    fn PixelFormat::output(self : PixelFormat, logger : &Logger) -> Unit

    PixelFormat::to_string

    fn PixelFormat::to_string(self : PixelFormat) -> String

    Sampling

    pub(all) enum Sampling {
    Nearest
    Bilinear
    Lanczos
    } derive(Eq,
    Debug
    )

    How a scaler decides what an unknown pixel is worth.

    Sampling::equal

    fn Sampling::equal(Sampling, Sampling) -> Bool

    Sampling::not_equal

    fn Sampling::not_equal(x : Sampling, y : Sampling) -> Bool

    Sampling::to_repr

    Text

    pub(all) enum Text {
    Latin(keyword~ : String, text~ : String)
    Compressed(keyword~ : String, text~ : String)
    International(keyword~ : String, language~ : String, translated~ : String, text~ : String)
    } derive(Eq,
    Debug
    )

    A text note, in the flavour of the chunk it came from, so that writing the image back produces the same kind of chunk.

    Text::equal

    fn Text::equal(Text, Text) -> Bool

    Text::keyword

    fn Text::keyword(self : Text) -> String

    The keyword a note is filed under.

    Text::not_equal

    fn Text::not_equal(x : Text, y : Text) -> Bool

    Text::text

    fn Text::text(self : Text) -> String

    What the note says.

    Text::to_repr

    hex

    fn hex(bytes : BytesView, at : Int, count : Int) -> String

    A few bytes as hexadecimal, for the got field of a refusal.

    Powered by MoonBit

    Site sourceReport issueModulesSkillsBuild queueStatistics

    © 2026 mooncakes.io