// image.mbt 鈥?Image struct + decoder adapter over
// `riantr/moonbit_image@0.3.4` (v0.14.0).
//
// This module bridges between the upstream decoder API
// (`@moonbit_image.decode` returning an `Image` with private
// `.data` field, accessed via `get_pixel`) and the snn_mbt
// project's Float32 4D NCHW tensor convention.
//
// Conventions:
// - `Image { data, n, c, h, w }` is a 4D NCHW Float32 image.
// `data.length() == n * c * h * w`.
// - Pixel values are normalised to [0.0, 1.0] Float32.
// - Decode supports all upstream formats (BMP/QOI/TGA/PNG/GIF/
// JPEG/ICO/TIFF, auto-detected).
//
// **Note on encode**: encoding via `@moonbit_image.encode` requires
// constructing an upstream `Image` with `Image::new(w, h, fmt, ...)`,
// but the `PixelFormat` enum variants are not publicly constructable
// from outside the upstream package. Encoding is therefore not part
// of this adapter. If you need to write an image file, write the
// raw bytes from `image_from_bytes` output and call upstream directly
// via a thin shim.
///|
/// 4D NCHW Float32 image tensor.
pub struct Image {
data : Array[Float]
n : Int
c : Int
h : Int
w : Int
}
///|
/// Build an empty NCHW image filled with zeros.
pub fn Image::zeros(n : Int, c : Int, h : Int, w : Int) -> Image {
{ data: Array::make(n * c * h * w, 0.0F), n, c, h, w }
}
///|
/// Total element count.
pub fn Image::numel(self : Image) -> Int {
self.data.length()
}
///|
/// Image dimensions as (n, c, h, w).
pub fn Image::shape(self : Image) -> (Int, Int, Int, Int) {
(self.n, self.c, self.h, self.w)
}
///|
/// Normalise 8-bit channel value to Float32 in [0, 1].
fn norm8(b : Int) -> Float {
Float::from_int(b) / 255.0F
}
///|
/// Wrap an upstream `Image` as our 4D NCHW Float Image (3 channels,
/// RGB). Alpha is dropped. To preserve alpha, use
/// `image_from_moonbit_image_rgba` instead.
pub fn image_from_moonbit_image(img : @moonbit_image.Image) -> Image {
let h = img.height
let w = img.width
let data : Array[Float] = Array::make(3 * h * w, 0.0F)
for y in 0.. Image {
let h = img.height
let w = img.width
let data : Array[Float] = Array::make(4 * h * w, 0.0F)
for y in 0.. Image raise @moonbit_image.DecodeError {
let upstream = @moonbit_image.decode(bytes)
image_from_moonbit_image(upstream)
}