KiteImageData
One image a document handler produced, ready for a KiteCanvas: the samples plus everything needed to read them (colour space, bit depth, /Decode, masks). PDF fills it from a /XObject /Image resource entry (ISO 32000-1 §8.9.5); EPUB fills it from a decoded PNG, JPEG or GIF.
Treat this image's exposed arrays as immutable while rendering it. A canvas may keep converted pixels across draws. Changed content needs a new image or a new revision identity through withIdentity, so an earlier bitmap cannot be reused.
The decoded byte buffer's interpretation depends on the filter chain:
DCTDecode→ decoded by ImageKodec into a Kind.RAW image. An image without a mask keeps only its encoded data and decodes at the size it draws (toShrunkRgbaBytes). A four-component JPEG gives CMYK samples, which the image's own colour space converts. A JPEG whose headers name a coding ImageKodec does not decode falls back to Kind.JPEG with the file in encodedBytes.FlateDecode/LZWDecode/CCITTFaxDecode/ ASCII / RunLength → pixel samples already decoded into pixelBytes; toRgbaBytes assembles RGBA using resolvedColorSpace, bitsPerComponent, and decode.JBIG2Decode→ decoded in pure Kotlin (Jbig2Decoder, the generic-region arithmetic path) into a 1-bpc DeviceGray RAW image; unsupported JBIG2 flavours fall back to Kind.JBIG2 with the payload in encodedBytes.JPXDecode(JPEG 2000) → decoded in pure Kotlin (JpxDecoder, part 1 baseline) into an 8-bpc RAW image, on demand at the size it draws, as a JPEG is; unsupported flavours fall back to Kind.JPEG2000 with the payload in encodedBytes.
A canvas paints the pixels of a Kind.RAW image and draws a placeholder for every other kind, the same on every platform, so a placeholder marks a decoder gap of KitePDF itself and never a difference between hosts (#184). Stencil masks (/ImageMask true) carry isImageMask and are tinted by maskFill.
Transparency reaches the raster path in three forms: /SMask and a stencil /Mask both arrive as softMaskAlpha, and a colour-key /Mask arrives as colorKeyMask. /SMask wins when an image carries both.
Types
Properties
Colour-key /Mask ranges (ISO 32000-1 §8.9.6): 2 × n integers, a min and a max per colour component, in the image's SOURCE sample values (before /Decode and colour conversion). A pixel whose every component falls inside its range is fully transparent. Null unless the image carries an array-valued /Mask and no /SMask.
/Decode array (per-component min/max remap), or null for the identity map.
Encoded bytes, for the kinds that the shared decoders refused. A PDF's JPEG that is a Kind.RAW image decoding at the size it draws keeps its file here too. Its headers were read when it loaded, not its data, so its first decode can still fail; the image then draws as a placeholder (#475, #184). Every other Kind.RAW image leaves this empty.
The /Interpolate entry of ISO 32000-1, Table 89: the image asks to stay smooth when enlarged (see imageSampling). Images from EPUB, SVG, XPS and CBZ files set it, because browsers smooth an enlarged image by default.
True for /ImageMask stencils: 1-bpc, painted with maskFill.
Fill colour to tint an isImageMask stencil (the graphics-state fill colour).
Pixel bytes, populated for Kind.RAW (already run through the filter chain). A PDF's JPEG or JPEG 2000 image without a mask keeps only its encoded data, and each read of this decodes it at full size. A draw calls toShrunkRgbaBytes instead, which decodes the image at the size it draws (#381). Treat the returned samples as read-only; see the image's identity contract above.
The image's colour space resolved against the document (Indexed palettes, ICCBased component counts, etc.). Null for stencil masks and when it could not be resolved (then toRgbaBytes infers a device space from the data).
Soft-mask alpha (ISO 32000-1 §11.6.5.2), normalised to 8-bit grayscale: one byte per pixel, 0 = transparent, 255 = opaque, row-major over softMaskWidth×softMaskHeight. Null when the image carries neither a /SMask nor a stencil /Mask.
The /Matte colour of the /SMask, converted to RGB. When it is set, the colour samples were preblended with it (ISO 32000-1, 11.6.5.3), and toRgbaBytes undoes that blend. Null when the soft mask has no /Matte.
Functions
The bytes that this image holds in memory: its samples, its encoded data and its soft mask. A PDF's JPEG or JPEG 2000 image without a mask holds only its encoded data (#381).
Assemble a Kind.RAW image's already-decoded samples into a flat RGBA8888 buffer (R,G,B,A per pixel, row-major, no padding) that a platform backend can wrap in a bitmap.
The straight RGBA bitmap a canvas draws with sampling, of KiteImageSampling.rasterWidth by KiteImageSampling.rasterHeight pixels. Power-of-two averaging keeps decoding and colour conversion bounded; a filter widened to cover each destination pixel handles the remaining reduction (#626). ISO 32000-1, 8.9.5.3 leaves the interpolation filter to the reader.
toRgbaBytes, averaged down by shrinkX columns and shrinkY rows as shrinkRgba does. The image converts a band of rows at a time, so a large scan drawn small never becomes one full-size RGBA array, and the pixel limit applies to the smaller output (#381).
A shallow view carrying identity for a platform bitmap cache. Reconstructed images of one immutable resource can share a bitmap without the cache retaining their source samples. This copies no pixel arrays and changes no rendering behaviour (#371).
This image with its colours converting through intent, with or without black point compensation (ISO 32000-1, 8.6.5.8). An image whose colour space does not depend on them returns itself. The image made for an intent is kept, so a cache keyed by the image still finds it the next time.