Pure-MoonBit image decoder/encoder covering BMP / QOI / TGA / PNG / GIF / JPEG / ICO / TIFF / FIM with zero external runtime dependencies. Decoders raise a structured `DecodeError` sub-error type so callers can branch on cause (UnsupportedFormat / TruncatedData / InvalidHeader / InvalidValue / EncodeNotImplemented). 0.3.7 re-licensed under MIT only (was `MIT OR Apache-2.0`); see LICENSE-MIT for the full text.
| Field | Supported |
|---|---|
| Byte order | II (little-endian); MM raises InvalidHeader |
| Compression | 1 (none); LZW / Deflate / JPEG-in-TIFF rejected |
| Photometric | 0 (WhiteIsZero), 1 (BlackIsZero), 2 (RGB), 3 (Palette) |
| BitsPerSample | 1 / 2 / 4 / 8 / 16 (uniform across samples) |
| SamplesPerPixel | 1 (greyscale / palette) or 3 (RGB) |
| PlanarConfiguration | 1 (chunky); planar rejected |
| Layout | single strip only |
| Sample format | UINT |
| Variant | When it fires |
|---|---|
| DecodeError::UnsupportedFormat(String) | magic bytes do not match any known format signature |
| DecodeError::TruncatedData(String) | a frame / chunk / scanline ended in the middle of a read |
| DecodeError::InvalidHeader(String) | a header field is out of range or has an unsupported value |
| DecodeError::InvalidValue(String) | a header / pixel-data value was readable but rejected downstream |
| DecodeError::EncodeNotImplemented(String) | encode() was called with a decode-only format |
match fmt {
ImageFormat::BMP => ...
f if f.is_decodable() => ...
}// one-shot auto-detect decoder; raises DecodeError
pub fn decode(data : Bytes) -> Image raise DecodeError
// header-only dimension read (no pixel decode)
pub fn image_dimensions(data : Bytes) -> (Int, Int, ImageFormat) raise DecodeError
// per-format decoders (still raise the lower-level Failure)
pub fn decode_bmp(data : Bytes) -> Image raise Failure
pub fn decode_qoi(data : Bytes) -> Image raise Failure
pub fn decode_tga(data : Bytes) -> Image raise Failure
pub fn decode_png(data : Bytes) -> Image raise Failure
pub fn decode_gif(data : Bytes) -> Image raise Failure
pub fn decode_jpeg(data : Bytes) -> Image raise Failure
pub fn decode_fim(data : Bytes) -> Image raise Failure // dual-energy side-by-side, Gray8
pub fn decode_fim_raw(data : Bytes) -> Image raise Failure // raw 16-bit detector, GrayA8
pub fn fim_dimensions(data : Bytes) -> (Int, Int) raise Failure // raw detector (width, height)
// FIM geometry helpers (GrayA8 in, GrayA8 out)
pub fn fim_side_by_side(left : Image, right : Image) -> Image raise Failure
pub fn fim_split_rows(img : Image) -> (Image, Image) raise Failure
pub fn fim_split_cols(img : Image) -> (Image, Image) raise Failure
pub fn fim_apply_y_roll(img : Image, shift_px : Int) -> Image raise Failure
pub fn fim_find_bright_strip(img : Image, air_threshold? : Double = 50000.0) -> (Int, Int) raise Failure
pub fn fim_find_auto_y_roll(img : Image) -> Int raise Failure
// FIM renderers
pub fn fim_to_grayscale8(img : Image, invert? : Bool = true, degamma? : Bool = false,
percentile_low? : Double? = Some(1.0),
percentile_high? : Double? = Some(99.0)) -> Image raise Failure
pub fn fim_ratio_grayscale(low : Image, high : Image) -> Image raise Failure
pub fn fim_ratio_pseudo_color(low : Image, high : Image) -> Image raise Failure
pub fn fim_ratio_pseudo_color_hsb(low : Image, high : Image) -> Image raise Failure
// writers (QOI + BMP only); encode() raises DecodeError::EncodeNotImplemented
// for everything else (including FIM)
pub fn encode(image : Image, format : ImageFormat) -> Bytes raise DecodeError
pub fn encode_qoi(image : Image) -> Bytes raise Failure
pub fn encode_bmp(image : Image) -> Bytes raise Failure// decode a JPEG -> Image, resize, re-encode as QOI
let img = @moonbit_image.decode(jpeg_bytes) catch {
err => {
@log.warn("decode failed: \{err}")
abort("give up")
}
}
let half = img.resize_nearest(img.width / 2, img.height / 2)
let qoi = @moonbit_image.encode(half, ImageFormat::QOI)pub suberror DecodeError {
UnsupportedFormat(String)
TruncatedData(String)
InvalidHeader(String)
InvalidValue(String)
EncodeNotImplemented(String)
}fn AnimatedImage::new(frames : Array[Image], delays : Array[Int], width : Int, height : Int, loop_count : Int) -> AnimatedImagepub struct Color {
r : Int
g : Int
b : Int
a : Int
}pub enum ImageFormat {
BMP
QOI
TGA
PNG
GIF
JPEG
ICO
TIFF
FIM
}pub enum PixelFormat {
Gray8
GrayA8
RGB8
RGBA8
}Install
Download zipPure-MoonBit image decoder/encoder covering BMP / QOI / TGA / PNG / GIF / JPEG / ICO / TIFF / FIM with zero external runtime dependencies. Decoders raise a structured `DecodeError` sub-error type so callers can branch on cause (UnsupportedFormat / TruncatedData / InvalidHeader / InvalidValue / EncodeNotImplemented). 0.3.7 re-licensed under MIT only (was `MIT OR Apache-2.0`); see LICENSE-MIT for the full text.