The picture itself: layouts, conversion, geometry, scaling, animation frames, metadata, limits and the one error type.
struct
pub(all) struct Animation
A sequence of frames over one canvas.
- widthInt32 The canvas width every frame is placed on.
- heightInt32 The canvas height every frame is placed on.
- loopsInt32 How many times the animation plays. 0 means forever, which is what an
animation without a repeat count means in all three formats.
- framesArray[Frame] The frames, in order.
- metadataMetadata Metadata that belongs to the animation as a whole.
pub 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.
pub fn Animation::new(width : Int32, height : Int32, frames : Array[Frame], loops? : Int32, metadata? : Metadata) -> Animation
An animation over a canvas, with no frames yet unless given some.
enum
pub(all) enum Blend
How a frame's pixels meet what is already on the canvas.
- Source Replace, alpha and all.
- Over Composite, the usual
over.
struct
pub(all) struct Chromaticities
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.
- white_xDouble
- white_yDouble
- red_xDouble
- red_yDouble
- green_xDouble
- green_yDouble
- blue_xDouble
- blue_yDouble
pub fn Chromaticities::srgb() -> Chromaticities
The primaries of sRGB, which is what almost every file means when it says nothing.
enum
pub(all) enum Dispose
What to do with the frame's rectangle once the frame has been shown.
- Keep Leave it: the next frame draws over it.
- Background Clear it to transparent black.
- Previous Put back whatever was under it before it was drawn.
enum
pub(all) enum Format
The formats this library reads and writes.
- Png PNG, with APNG for animation.
- Qoi Quite OK Image.
- Bmp Windows bitmap.
- Tga Truevision TGA.
- Jpeg JPEG, baseline and progressive.
- Gif GIF, with animation.
- Webp WebP, lossless, lossy and animated.
- pub
pub fn Format::extension(self : Format) -> String
The extension a file of this format usually has, without the dot.
pub fn Format::mime(self : Format) -> String
The media type a server would send for this format.
pub 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.
pub fn Format::to_string(Self) -> String
struct
pub(all) struct Frame
One frame: a picture, where it goes, and how long it stays.
- imageImage The pixels of this frame, already in a pixel format.
- xInt32 Where the frame's top-left corner sits on the canvas.
- yInt32 Where the frame's top-left corner sits on the canvas.
- delayInt32 How long the frame is shown, in milliseconds.
- disposeDispose What to do with the rectangle afterwards.
- blendBlend How to lay the frame over what is there.
pub fn Frame::new(image : Image, x? : Int32, y? : Int32, delay? : Int32, dispose? : Dispose, blend? : Blend) -> Frame
A frame that covers the canvas, shown for a tenth of a second, drawn over what is there.
struct
pub(all) struct Icc
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.
struct
pub(all) struct Image
An image: its shape, its layout, and the bytes.
- widthInt32 How many pixels across.
- heightInt32 How many pixels down.
- formatPixelFormat How each pixel is laid out.
- strideInt32 How many bytes from the start of one row to the start of the next.
- pixelsBytes The samples, row after row,
height * stride bytes or a little less when
the last row is tight.
- premultipliedBool Whether the colour channels have already been multiplied by alpha.
- metadataMetadata What the file said about itself.
pub 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.
pub fn Image::crop(self : Image, x : Int32, y : Int32, width : Int32, height : Int32) -> 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.
pub fn Image::flip_horizontal(self : Image) -> Image
The image reflected left to right.
pub fn Image::flip_vertical(self : Image) -> Image
The image reflected top to bottom.
pub fn Image::new(width : Int32, height : Int32, format : PixelFormat, stride? : Int32, 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.
pub fn Image::of(width : Int32, height : Int32, format : PixelFormat, pixels : Bytes, stride? : Int32, 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.
pub fn Image::pixel(self : Image, x : Int32, y : Int32) -> 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.
pub fn Image::rotate(self : Image, quarters? : Int32) -> 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.
pub fn Image::row(self : Image, y : Int32) -> BytesView raise Refused
One row, without its padding.
pub fn Image::scale(self : Image, width : Int32, height : Int32, 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.
pub 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.
pub 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.
enum
pub(all) enum Intent
What a column of pixels was meant to be seen in.
- Perceptual For a picture.
- Relative For a colour that should come out as it went in.
- Saturation For a diagram, where saturation matters more than hue.
- Absolute For comparing against a proof.
pub fn Intent::code(self : Intent) -> Int32
The number a file writes for this intent, which is how PNG's sRGB chunk numbers them.
pub fn Intent::of(code : Int32) -> Intent?
The intent a number stands for, or None if it is not one of the four.
struct
pub(all) struct Limits
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.
- widthInt32 The widest image accepted, in pixels.
- heightInt32 The tallest image accepted, in pixels.
- pixelsInt32 The most pixels accepted, whatever the shape: this is the one that stops a
long thin image from slipping past the two above.
- bytesInt32 The most bytes a decoder may produce while unpacking: a compressed stream
can expand without limit, so the expansion is capped separately.
pub fn Limits::allows(self : Limits, width : Int32, height : Int32) -> Bool
Whether an image of this shape is inside the limits.
pub fn Limits::check(self : Limits, width : Int32, height : Int32) -> 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.
pub fn Limits::check_bytes(self : Limits, bytes : Int32) -> Unit raise Refused
Refuse a buffer of this many bytes unless the limits allow it.
pub fn Limits::default() -> Limits
The desktop defaults: a million pixels a side, 256 megapixels in all, and a gigabyte of expansion.
pub fn Limits::strict() -> Limits
What a viewer of untrusted uploads would choose: 8192 square, 64 megapixels, 256 MiB of expansion.
struct
pub(all) struct Metadata
Everything the file said about itself besides its pixels.
- gammaDouble? The file gamma: the exponent the samples were encoded with, so that 0.45455
means what sRGB means.
- chromaticitiesChromaticities? The primaries the image was authored for.
- intentIntent? The rendering intent, which only means anything next to an sRGB or ICC tag.
- iccIcc? The embedded profile, if there was one.
- textsArray[Text] The text notes, in the order the file had them.
pub fn Metadata::default() -> Metadata
No metadata at all, which is what an image built in memory has.
pub fn Metadata::is_empty(self : Metadata) -> Bool
Whether there is nothing to write.
struct
pub(all) struct Pixel
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.
- rDouble
- gDouble
- bDouble
- aDouble
pub fn Pixel::of_rgba8(r : Int32, g : Int32, b : Int32, a? : Int32) -> Pixel
A pixel from the eight-bit values an editor shows.
pub fn Pixel::rgba16(self : Pixel) -> (Int32, Int32, Int32, Int32)
The pixel as sixteen-bit samples, which is what a PNG stores when its bit depth is sixteen.
pub fn Pixel::rgba8(self : Pixel) -> (Int32, Int32, Int32, Int32)
The pixel as bytes an editor shows: rounded, clamped, alpha last.
enum
pub(all) enum PixelFormat
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.
- Gray8 One sample, 8 bits.
- GrayAlpha8 Grey and alpha, 8 bits each.
- Rgb8 Three samples, 8 bits each, red first.
- Rgba8 Four samples, 8 bits each, red first, alpha last.
- Gray16 One sample, 16 bits, big-endian.
- GrayAlpha16 Grey and alpha, 16 bits each.
- Rgb16 Three samples, 16 bits each, big-endian.
- Rgba16 Four samples, 16 bits each, big-endian.
- RgbaF32 Four samples as
Float, 0–1, little-endian.
- pub
pub fn PixelFormat::bits(self : PixelFormat) -> Int32
How many bits one sample takes. For RgbaF32 this is 32, which says how wide the sample is, not that it is an integer.
pub fn PixelFormat::bytes(self : PixelFormat) -> Int32
How many bytes a pixel of this format takes.
pub fn PixelFormat::channels(self : PixelFormat) -> Int32
How many samples a pixel of this format has.
pub fn PixelFormat::has_alpha(self : PixelFormat) -> Bool
Whether the image carries alpha.
pub fn PixelFormat::is_float(self : PixelFormat) -> Bool
Whether the samples are floats rather than integers.
pub fn PixelFormat::is_gray(self : PixelFormat) -> Bool
Whether the image carries colour at all.
pub fn PixelFormat::to_string(Self) -> String
error
pub(all) suberror Refused
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.
- Unexpected(at~ : Int32, got~ : String, want~ : String) The bytes at
at are not allowed here; want says what is.
- Unknown(at~ : Int32, got~ : String) Nothing at
at is an image this library reads.
- Unsupported(at~ : Int32, got~ : String) A part of the format this library does not read.
- Truncated(at~ : Int32, want~ : Int32) The bytes end
want short of where the format needs them.
- OverLimit(limit~ : Int32, got~ : Int32) A size or a length past what the caller's
Limits allow.
- Checksum(at~ : Int32, got~ : String, want~ : String) A checksum that does not match the bytes it covers.
- pub
pub fn Refused::to_string(Self) -> String
enum
pub(all) enum Sampling
How a scaler decides what an unknown pixel is worth.
- Nearest The nearest pixel, and nothing else: no new colours.
- Bilinear A weighted average of the four nearest, weights linear in distance.
- Lanczos A weighted average of the six nearest per axis, weights from the Lanczos
window with a = 3.
enum
pub(all) enum Text
A text note, in the flavour of the chunk it came from, so that writing the image back produces the same kind of chunk.
- Latin(keyword~ : String, text~ : String)
tEXt: Latin-1, one keyword and one line.
- Compressed(keyword~ : String, text~ : String)
zTXt: the same, deflated.
- International(keyword~ : String, language~ : String, translated~ : String, text~ : String)
iTXt: UTF-8, with a language tag and a translated keyword.
pub fn Text::keyword(self : Text) -> String
The keyword a note is filed under.
pub fn Text::text(self : Text) -> String
function
pub fn hex(bytes : BytesView, at : Int32, count : Int32) -> String
A few bytes as hexadecimal, for the got field of a refusal.