NURLNURL registrynurl-lang.org →

← image

image 0.2.0 API

jpeg.nu

image/jpeg.nu — baseline (sequential DCT, Huffman) JPEG decode.

Supports the baseline JPEGs real encoders emit: 8-bit precision, Huffman coding, 1 component (greyscale) or 3 (YCbCr → RGB), any 4:4:4 / 4:2:2 / 4:2:0 / 4:1:1 subsampling, and restart intervals (DRI/RSTn). Chroma planes are box-upsampled and a separable float IDCT is used, so output matches a reference decoder (libjpeg) to within IDCT/upsampling rounding — JPEG is lossy and the spec permits IDCT variation, so this is not bit-exact.

Not supported (clean None, never an out-of-bounds read): progressive JPEG, arithmetic coding, 12-bit, and 4-component (CMYK/YCCK).

API

: Jpeg

: Jpeg {
    ( Vec u ) buf   i len
    i width  i height  i ncomp
    ( Vec i ) cid  ( Vec i ) chf  ( Vec i ) cvf  ( Vec i ) ctq  ( Vec i ) ctd  ( Vec i ) cta  ( Vec i ) cpred
    i hmax  i vmax  i restart
    ( Vec i ) qt
    ( Vec i ) hmin  ( Vec i ) hmaxc  ( Vec i ) hptr  ( Vec i ) hvals
    ( Vec f ) idct_a  ( Vec i ) zz
    i bpos  i bbuf  i bcnt  i marker
    b ok
}

@ jpeg_decode ( Vec u ) buf → ?Image


image.nu

image — pure-NURL image codecs. One include for the whole package: the Image raster, PPM (P5/P6), PNG decode + encode, and file load/save with format sniffing. (Baseline JPEG decode is planned as a later milestone.)

$ deps/image/src/image.nu ?? ( image_load photo.png ) { T im → { // … use im (width/height/channels/data) … ( image_save_png out.png im ) ( image_free im ) } F → { ( nurleprintln decode failed ) } }

API

@ image_decode ( Vec u ) buf → ?Image

Decode by sniffing the magic bytes: PNG signature → png_decode, JPEG SOI (FF D8) → jpeg_decode, P → PPM.

@ image_load s path → ?Image

Load and decode a file. None on an I/O error or an unrecognised/malformed format.

@ image_save_png s path Image im → b

@ image_save_ppm s path Image im → b


core.nu

image/core.nu — the Image type, byte helpers, and PPM (P5/P6).

An Image is a tightly-packed, row-major, 8-bit-per-channel raster: channels 1 = grayscale, 3 = RGB, 4 = RGBA. data holds widthheightchannels bytes. Every codec in the package decodes into, and encodes from, this one representation.

API

: Image

: Image {
    i width
    i height
    i channels
    ( Vec u ) data
}

@ image_new i w i h i ch → Image

A zero-filled image of the given geometry.

@ image_of i w i h i ch ( Vec u ) data → Image

Adopt an existing byte buffer (moved in; not copied).

@ image_free Image im → v

@ image_width Image im → i

@ image_height Image im → i

@ image_channels Image im → i

@ image_get Image im i x i y i c → i

@ image_set Image im i x i y i c i v → v

@ ppm_decode ( Vec u ) buf → ?Image

@ ppm_encode Image im → ( Vec u )

Encode as binary PPM: 3/4-channel → P6 (alpha dropped), 1-channel → P5.


png.nu

image/png.nu — PNG decode + encode over the stdlib DEFLATE codec.

Decode: 8-bit depth, non-interlaced, colour types 0 (grey), 2 (RGB), 3 (palette → expanded to RGB), 4 (grey+alpha), 6 (RGBA). Reconstructs all five scanline filters. Encode: 8-bit, non-interlaced, filter 0, colour type chosen from the image's channel count. Lossless — a decode→encode→decode round-trip reproduces the pixels exactly.

Not yet: interlaced (Adam7) images, bit depths other than 8, and tRNS transparency on palette/grey images. png_decode returns None on those (and on malformed input); the codec never reads out of bounds.

API

@ png_decode ( Vec u ) buf → ?Image

@ png_encode Image im → ( Vec u )

Encode an image as a non-interlaced, filter-0, 8-bit PNG.