ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
jof_png_chunk.c File Reference

PNG chunk layer for the streaming decoder: prologue, palette tables, ancillary skipping and the post-IDAT walk (#231). More...

#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "jof_internal.h"
#include "jof_png_internal.h"
#include "ra8_attributes.h"
#include "ra8_err.h"
Include dependency graph for jof_png_chunk.c:

Go to the source code of this file.

Functions

ra8_err_t priv_jof_png_pull_exact (ra8_png_state_t *st, uint8_t *buf, uint32_t len)
 Pull exactly len bytes; EOF mid-read is a protocol error.
ra8_err_t priv_jof_png_skip (ra8_png_state_t *st, uint32_t len)
 Discard exactly len source bytes (unknown / ancillary chunks).
ra8_err_t priv_jof_png_chunk_hdr (ra8_png_state_t *st, uint32_t *out_len, uint32_t *out_type)
 Read one 8-byte chunk header (length + type, both big-endian).
static uint8_t internal_png_src_channels (uint8_t color_type)
 Map an IHDR colour type to its source bytes-per-pixel, or 0.
static ra8_err_t internal_png_check_ihdr (ra8_png_state_t *st, const uint8_t *ihdr, uint16_t max_w, uint16_t max_h)
 Validate the 13 IHDR payload bytes and bind the geometry fields.
static ra8_err_t internal_png_parse_ihdr (ra8_png_state_t *st, uint16_t max_w, uint16_t max_h)
 Read the IHDR chunk (must be first) and validate its payload.
static ra8_err_t internal_png_parse_plte (ra8_png_state_t *st, uint32_t len)
 Parse a PLTE chunk into the palette table (colour type 3).
static ra8_err_t internal_png_parse_trns (ra8_png_state_t *st, uint32_t len)
 Parse a tRNS chunk (palette alpha; colour type 3 only).
ra8_err_t priv_jof_png_prologue (ra8_png_state_t *st, uint16_t max_w, uint16_t max_h)
 Verify the 8-byte signature, then parse + validate the IHDR.
ra8_err_t priv_jof_png_pre_idat (ra8_png_state_t *st, uint32_t len, uint32_t type)
 Dispatch one pre-IDAT chunk (PLTE / tRNS / ancillary / stray IEND).
ra8_err_t priv_jof_png_finish (ra8_png_state_t *st)
 Walk the post-IDAT chunks until IEND (ancillary chunks skipped).

Detailed Description

PNG chunk layer for the streaming decoder: prologue, palette tables, ancillary skipping and the post-IDAT walk (#231).

The byte-source primitives and every chunk-structure concern of the bounded-RAM PNG decoder live here; the pixel layer (inflate + unfilter + translate) drives them from jof_png.c through the prototypes in jof_png_internal.h. All structural anomalies fail closed: this parser feeds on untrusted EPUB content. Spec citations reference the W3C PNG specification (second edition), abbreviated PNG sec N.

[Ring 4 / Domain] {World: NS}

Definition in file jof_png_chunk.c.

Function Documentation

◆ internal_png_check_ihdr()

ra8_err_t internal_png_check_ihdr ( ra8_png_state_t * st,
const uint8_t * ihdr,
uint16_t max_w,
uint16_t max_h )
static

Validate the 13 IHDR payload bytes and bind the geometry fields.

Rejects, fail-closed: zero / over-cap dimensions, non-8-bit depth, unknown colour types, non-zero compression/filter methods and interlacing (Adam7 breaks streaming).

Parameters
[in,out]stDecoder state (geometry fields written).
[in]ihdrThe IHDR payload bytes.
[in]max_wFail-closed width cap.
[in]max_hFail-closed height cap.
Returns
Result code.
Return values
k_ra8_okIHDR accepted.
k_ra8_err_invalid_sizeDimension zero / over the caps.
k_ra8_err_not_supportedDepth / colour / method / interlace.
Precondition
ihdr holds k_ra8_png_ihdr_len bytes.
st is zero-initialised apart from the bound callbacks.
Postcondition
On success w/h/color_type/src_ch are set.
On error the decode aborts.
Note
Not thread-safe.
Since
0.1.0

Definition at line 191 of file jof_png_chunk.c.

References ra8_png_state_t::color_type, ra8_png_state_t::h, internal_png_src_channels(), k_ra8_err_invalid_size, k_ra8_err_not_supported, k_ra8_ok, k_ra8_png_be_sh16, k_ra8_png_be_sh24, k_ra8_png_be_sh8, k_ra8_png_depth_8, k_ra8_png_ihdr_ofs_color, k_ra8_png_ihdr_ofs_compress, k_ra8_png_ihdr_ofs_depth, k_ra8_png_ihdr_ofs_filter, k_ra8_png_ihdr_ofs_interlace, ra8_png_state_t::src_ch, and ra8_png_state_t::w.

Referenced by internal_png_parse_ihdr().

◆ internal_png_parse_ihdr()

ra8_err_t internal_png_parse_ihdr ( ra8_png_state_t * st,
uint16_t max_w,
uint16_t max_h )
static

Read the IHDR chunk (must be first) and validate its payload.

Enforces the IHDR-first rule and the exact 13-byte payload length, then delegates the field checks to internal_png_check_ihdr and skips the trailing CRC.

Parameters
[in,out]stDecoder state (geometry fields written).
[in]max_wFail-closed width cap.
[in]max_hFail-closed height cap.
Returns
Result code.
Return values
k_ra8_okIHDR accepted.
k_ra8_err_protocol_errorStructural mismatch (order, length).
otherPropagated from the field validation.
Precondition
The source sits right after the PNG signature.
st is zero-initialised apart from the bound callbacks.
Postcondition
On success the source sits at the first post-IHDR chunk.
On error the decode aborts.
Note
Not thread-safe.
Since
0.1.0

Definition at line 248 of file jof_png_chunk.c.

References internal_png_check_ihdr(), k_ra8_err_protocol_error, k_ra8_ok, k_ra8_png_crc_bytes, k_ra8_png_ihdr_len, k_ra8_png_type_ihdr, priv_jof_png_chunk_hdr(), priv_jof_png_pull_exact(), and priv_jof_png_skip().

Referenced by priv_jof_png_prologue().

◆ internal_png_parse_plte()

ra8_err_t internal_png_parse_plte ( ra8_png_state_t * st,
uint32_t len )
static

Parse a PLTE chunk into the palette table (colour type 3).

Validates the payload shape, stores the RGB triples, and skips the trailing CRC.

Parameters
[in,out]stDecoder state (palette written).
[in]lenPLTE payload length.
Returns
Result code.
Return values
k_ra8_okPalette stored.
k_ra8_err_validation_failedLength not a multiple of 3 / over cap / duplicate PLTE.
otherPropagated from the pull callback.
Precondition
IHDR has been parsed.
len came from a validated chunk header.
Postcondition
On success plte_count reflects the stored entries.
On error the decode aborts.
Note
Not thread-safe.
Since
0.1.0

Definition at line 289 of file jof_png_chunk.c.

References ra8_png_state_t::has_plte, k_ra8_err_validation_failed, k_ra8_ok, k_ra8_png_ch_3, k_ra8_png_crc_bytes, k_ra8_png_plte_max, ra8_png_state_t::palette, ra8_png_state_t::plte_count, priv_jof_png_pull_exact(), priv_jof_png_skip(), and RA8_INTERNAL.

Referenced by priv_jof_png_pre_idat().

◆ internal_png_parse_trns()

ra8_err_t internal_png_parse_trns ( ra8_png_state_t * st,
uint32_t len )
static

Parse a tRNS chunk (palette alpha; colour type 3 only).

A tRNS on colour types 0/2 (colour-key transparency) is rejected k_ra8_err_not_supported rather than silently flattened – this producer never alters pixels it cannot represent.

Parameters
[in,out]stDecoder state (alpha table written).
[in]lentRNS payload length.
Returns
Result code.
Return values
k_ra8_okAlpha table stored.
k_ra8_err_not_supportedtRNS on a non-palette colour type.
k_ra8_err_validation_failedOversize / missing PLTE / duplicate.
otherPropagated from the pull callback.
Precondition
IHDR has been parsed.
len came from a validated chunk header.
Postcondition
On success trns_count/has_trns reflect the table.
On error the decode aborts.
Note
Not thread-safe.
Since
0.1.0

Definition at line 324 of file jof_png_chunk.c.

References ra8_png_state_t::color_type, ra8_png_state_t::has_plte, ra8_png_state_t::has_trns, k_ra8_err_not_supported, k_ra8_err_validation_failed, k_ra8_ok, k_ra8_png_color_pal, k_ra8_png_crc_bytes, k_ra8_png_trns_max, priv_jof_png_pull_exact(), priv_jof_png_skip(), RA8_INTERNAL, ra8_png_state_t::trns, and ra8_png_state_t::trns_count.

Referenced by priv_jof_png_pre_idat().

◆ internal_png_src_channels()

uint8_t internal_png_src_channels ( uint8_t color_type)
static

Map an IHDR colour type to its source bytes-per-pixel, or 0.

The bit depth is fixed at 8, so bytes per pixel equals the channel count.

Parameters
[in]color_typeIHDR colour-type byte.
Returns
Source channel count for 8-bit depth.
Return values
1-4Legal colour type's bytes per pixel.
0Unsupported / illegal colour type.
Precondition
The bit depth was validated as 8.
None (total over uint8_t).
Postcondition
No state mutated.
Return is 0 or a legal bpp.
Note
Pure; thread-safe.
Since
0.1.0

Definition at line 151 of file jof_png_chunk.c.

References k_ra8_png_ch_1, k_ra8_png_ch_2, k_ra8_png_ch_3, k_ra8_png_ch_4, k_ra8_png_color_ga, k_ra8_png_color_gray, k_ra8_png_color_pal, k_ra8_png_color_rgb, k_ra8_png_color_rgba, and RA8_INTERNAL.

Referenced by internal_png_check_ihdr().

◆ priv_jof_png_chunk_hdr()

ra8_err_t priv_jof_png_chunk_hdr ( ra8_png_state_t * st,
uint32_t * out_len,
uint32_t * out_type )

Read one 8-byte chunk header (length + type, both big-endian).

Assembles the big-endian length and type fields and enforces the spec length cap.

Parameters
[in,out]stDecoder state (source position advances).
[out]out_lenReceives the payload length.
[out]out_typeReceives the chunk type value.
Returns
Result code.
Return values
k_ra8_okHeader read; length within the spec cap.
k_ra8_err_protocol_errorTruncated header or oversize length.
otherPropagated from the pull callback.
Precondition
The source is positioned at a chunk boundary.
Both outputs are writable.
Postcondition
On success the source sits at the chunk payload.
On error the decode aborts.
Note
Not thread-safe.
Since
0.1.0

Definition at line 113 of file jof_png_chunk.c.

References k_ra8_err_protocol_error, k_ra8_ok, k_ra8_png_be_sh16, k_ra8_png_be_sh24, k_ra8_png_be_sh8, k_ra8_png_chunk_hdr, k_ra8_png_max_len, priv_jof_png_pull_exact(), and RA8_PRIV.

Referenced by internal_png_parse_ihdr(), internal_png_refill_input(), internal_png_walk_chunks(), and priv_jof_png_finish().

◆ priv_jof_png_finish()

ra8_err_t priv_jof_png_finish ( ra8_png_state_t * st)

Walk the post-IDAT chunks until IEND (ancillary chunks skipped).

When the zlib stream ended inside the last IDAT (no pending chunk parked by the refill path), that IDAT's trailing CRC is still unread: consume it, then resume the chunk walk.

Parameters
[in,out]stDecoder state (pending chunk consumed first).
Returns
Result code.
Return values
k_ra8_okIEND reached.
k_ra8_err_protocol_errorChunk budget exhausted / truncation / a stray IDAT after the stream ended.
otherPropagated from the pull callback.
Precondition
The inflate phase finished (rows_done == h).
st->idat_rem == 0.
Postcondition
On success the datastream is fully consumed through IEND.
On error the decode aborts.
Note
Not thread-safe.
Since
0.1.0

Definition at line 426 of file jof_png_chunk.c.

References k_ra8_err_protocol_error, k_ra8_ok, k_ra8_png_crc_bytes, k_ra8_png_max_chunks, k_ra8_png_type_idat, k_ra8_png_type_iend, ra8_png_state_t::pending_len, ra8_png_state_t::pending_type, ra8_png_state_t::pending_valid, priv_jof_png_chunk_hdr(), priv_jof_png_skip(), and RA8_PRIV.

Referenced by internal_png_run_idat().

◆ priv_jof_png_pre_idat()

ra8_err_t priv_jof_png_pre_idat ( ra8_png_state_t * st,
uint32_t len,
uint32_t type )

Dispatch one pre-IDAT chunk (PLTE / tRNS / ancillary / stray IEND).

Parameters
[in,out]stDecoder state.
[in]lenChunk payload length.
[in]typeChunk type value.
Returns
Result code.
Return values
k_ra8_okChunk consumed; keep walking.
k_ra8_err_protocol_errorIEND arrived before any IDAT.
otherPropagated from the chunk parsers.
Precondition
The IHDR has been parsed.
len came from a validated chunk header.
Postcondition
On success the source sits at the next chunk boundary.
On error the decode aborts.
Note
Not thread-safe.
Since
0.1.0

Definition at line 394 of file jof_png_chunk.c.

References internal_png_parse_plte(), internal_png_parse_trns(), k_ra8_err_protocol_error, k_ra8_png_crc_bytes, k_ra8_png_type_iend, k_ra8_png_type_plte, k_ra8_png_type_trns, priv_jof_png_skip(), and RA8_PRIV.

Referenced by internal_png_walk_chunks().

◆ priv_jof_png_prologue()

ra8_err_t priv_jof_png_prologue ( ra8_png_state_t * st,
uint16_t max_w,
uint16_t max_h )

Verify the 8-byte signature, then parse + validate the IHDR.

Parameters
[in,out]stDecoder state (geometry fields written).
[in]max_wFail-closed width cap.
[in]max_hFail-closed height cap.
Returns
Result code.
Return values
k_ra8_okPrologue accepted; chunk walk may start.
k_ra8_err_protocol_errorBad signature / IHDR structure.
otherPropagated from the IHDR validation.
Precondition
The source is positioned at byte 0 of the PNG stream.
st holds the bound callbacks.
Postcondition
On success the source sits at the first post-IHDR chunk.
On error the decode aborts.
Note
Not thread-safe.
Since
0.1.0

Definition at line 357 of file jof_png_chunk.c.

References internal_png_parse_ihdr(), k_ra8_err_protocol_error, k_ra8_ok, k_ra8_png_sig_bytes, k_ra8_png_sig_cr, k_ra8_png_sig_high, k_ra8_png_sig_lf, k_ra8_png_sig_sub, memcmp(), priv_jof_png_pull_exact(), and RA8_PRIV.

Referenced by internal_png_walk_chunks().

◆ priv_jof_png_pull_exact()

ra8_err_t priv_jof_png_pull_exact ( ra8_png_state_t * st,
uint8_t * buf,
uint32_t len )

Pull exactly len bytes; EOF mid-read is a protocol error.

Bounded by len (each non-EOF pull delivers >= 1 byte).

Parameters
[in,out]stDecoder state (source position advances).
[out]bufDestination buffer.
[in]lenBytes required.
Returns
Result code.
Return values
k_ra8_okExactly len bytes delivered.
k_ra8_err_protocol_errorThe source ended early.
otherPropagated from the pull callback.
Precondition
buf holds len writable bytes.
st->pull is bound.
Postcondition
On success the source advanced by len bytes.
On error the decode aborts.
Note
Not thread-safe.
Since
0.1.0

Definition at line 47 of file jof_png_chunk.c.

References k_ra8_err_protocol_error, k_ra8_ok, ra8_png_state_t::pull, ra8_png_state_t::pull_ctx, and RA8_PRIV.

Referenced by internal_png_parse_ihdr(), internal_png_parse_plte(), internal_png_parse_trns(), internal_png_refill_input(), priv_jof_png_chunk_hdr(), priv_jof_png_prologue(), and priv_jof_png_skip().

◆ priv_jof_png_skip()

ra8_err_t priv_jof_png_skip ( ra8_png_state_t * st,
uint32_t len )

Discard exactly len source bytes (unknown / ancillary chunks).

Bounded by len over a fixed-size stack scratch.

Parameters
[in,out]stDecoder state (source position advances).
[in]lenBytes to discard.
Returns
Result code.
Return values
k_ra8_okBytes discarded.
k_ra8_err_protocol_errorThe source ended early.
otherPropagated from the pull callback.
Precondition
st->pull is bound.
len came from a validated chunk-length field.
Postcondition
On success the source advanced by len bytes.
On error the decode aborts.
Note
Not thread-safe.
Since
0.1.0

Definition at line 80 of file jof_png_chunk.c.

References k_ra8_ok, k_ra8_png_skip_chunk, priv_jof_png_pull_exact(), and RA8_PRIV.

Referenced by internal_png_parse_ihdr(), internal_png_parse_plte(), internal_png_parse_trns(), internal_png_refill_input(), priv_jof_png_finish(), and priv_jof_png_pre_idat().