///|
/// Adapters to the ecosystem image codecs in `mizchi/image`.
///
/// PixelForge keeps its own `Image` type and codec APIs stable; these helpers
/// bridge RGBA bytes to the external package for formats that are too large to
/// maintain safely in this repository. JPEG decoding/encoding works on all
/// supported targets. WebP encoding is lossless and available on all targets.
/// AVIF encoding requires a JS host with Canvas AVIF encoding or local ffmpeg
/// in Node.js, and accepts opaque pixels only. Unsupported targets or encoding
/// failures abort. PixelForge's own WebP Lossless decoder is separate.
fn image_to_bytes(image : Image) -> Bytes {
  let bytes : Array[Byte] = []
  for byte in image.data {
    bytes.push(byte)
  }
  Bytes::from_array(bytes)
}

///|
fn external_to_image(data : @image.ImageData) -> Image {
  Image::from_bytes(data.width, data.height, data.data.to_fixedarray())
}

///|
/// Decodes a baseline JPEG into RGBA8 pixels.
pub fn jpeg_decode(data : Array[Byte]) -> Image? {
  Some(external_to_image(@image.decode_jpeg(Bytes::from_array(data)))) catch {
    _ => None
  }
}

///|
/// Encodes an RGBA8 image as JPEG. `quality` is clamped by the external codec.
pub fn jpeg_encode(image : Image, quality : Int) -> Array[Byte] {
  let encoded = @image.encode_jpeg(
    { width: image.width, height: image.height, data: image_to_bytes(image), },
    quality~,
  ) catch {
    _ => abort("jpeg_encode: external codec rejected the image")
  }
  Bytes::to_array(encoded)
}

///|
/// Encodes an RGBA8 image as lossless WebP.
pub fn webp_encode(image : Image) -> Array[Byte] {
  let encoded = @image.encode_webp({
    width: image.width,
    height: image.height,
    data: image_to_bytes(image),
  }) catch {
    _ => abort("webp_encode: external codec rejected the image")
  }
  Bytes::to_array(encoded)
}