|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
JOF atlas reader: parse/validate + bounded per-tile decode (#231). More...
#include "jof.h"#include <stddef.h>#include <stdint.h>#include <string.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_compress.h"#include "ra8_err.h"Go to the source code of this file.
Enumerations | |
| enum | jof_le_t : uint8_t { k_jof_le_b0 = 0U , k_jof_le_b1 = 1U , k_jof_le_b2 = 2U , k_jof_le_b3 = 3U , k_jof_le_sh8 = 8U , k_jof_le_sh16 = 16U , k_jof_le_sh24 = 24U } |
| Little-endian assembly constants for the header/footer fields. More... | |
| enum | jof_bound_t : uint16_t { k_jof_bound_div = 8U , k_jof_bound_add = 256U } |
| Worst-case stored-stream expansion terms (see the header contract). More... | |
Functions | |
| static uint16_t | internal_rd_u16 (const uint8_t *buf, uint8_t off) |
Read a little-endian uint16 from buf at off. | |
| static uint32_t | internal_rd_u32 (const uint8_t *buf, uint8_t off) |
Read a little-endian uint32 from buf at off. | |
| static uint32_t | internal_ceil_div (uint32_t n, uint32_t d) |
Ceil-divide n by d (d > 0). | |
| static ra8_err_t | internal_pread_exact (jof_pread_fn pread, void *pread_ctx, uint64_t off, uint8_t *buf, size_t len) |
| Exact positioned read: EOF or a short read is a validation failure. | |
| ra8_err_t | jof_memstore_sink (void *ctx, const uint8_t *buf, size_t len) |
| Append len bytes to a jof_memstore_t (producer sink). | |
| ra8_err_t | jof_memstore_pread (void *ctx, uint64_t offset, uint8_t *buf, size_t len, size_t *got) |
| Positioned read from a jof_memstore_t (reader seam). | |
| static ra8_err_t | internal_parse_hdr_fields (const uint8_t *hdr, jof_info_t *info) |
Validate the header geometry fields into info (fail-closed). | |
| static ra8_err_t | internal_check_reserved (const uint8_t *hdr) |
| Reject any non-zero reserved header byte (strict, fail-closed). | |
| static ra8_err_t | internal_check_cross (jof_info_t *info, uint32_t hdr_count, const uint8_t *ftr, uint64_t total_size) |
| Cross-check grid, tile-count, footer and index-window invariants. | |
| static ra8_err_t | internal_parse_header_region (jof_pread_fn pread, void *pread_ctx, uint8_t *hdr, jof_info_t *out_info) |
Read + validate the 32-byte header region into out_info. | |
| ra8_err_t | jof_parse (jof_pread_fn pread, void *pread_ctx, uint64_t total_size, jof_info_t *out_info) |
| Parse + validate a JOF atlas's header, footer and index bounds. | |
| ra8_err_t | jof_tile_dims (const jof_info_t *info, uint16_t tile_x, uint16_t tile_y, uint16_t *out_w, uint16_t *out_h) |
| Report the true (edge-clamped) pixel dimensions of one tile. | |
| uint32_t | jof_stored_bound (uint32_t raw_bytes) |
| Implementation of jof_stored_bound() – raw + raw/8 + 256. | |
| static ra8_err_t | internal_index_entry (jof_pread_fn pread, void *pread_ctx, const jof_info_t *info, uint32_t n, uint32_t *out_off, uint32_t *out_len) |
Fetch + window-validate the index entry for tile n. | |
| static ra8_err_t | internal_decode_stream (jof_pread_fn pread, void *pread_ctx, const jof_info_t *info, uint32_t toff, uint32_t tlen, uint32_t payload, uint8_t *scratch, uint32_t scratch_cap, uint8_t *out_px) |
Decode a validated tile stream into out_px. | |
| static ra8_err_t | internal_fetch_decode (jof_pread_fn pread, void *pread_ctx, const jof_info_t *info, uint32_t n, uint32_t payload, uint8_t *scratch, uint32_t scratch_cap, uint8_t *out_px) |
Fetch tile n's index entry, then read + decode its stream. | |
| static ra8_err_t | internal_read_args_ok (jof_pread_fn pread, const jof_info_t *info, const uint8_t *out_px, const uint16_t *out_w, const uint16_t *out_h) |
| Reject any NULL jof_read_tile pointer argument. | |
| ra8_err_t | jof_read_tile (jof_pread_fn pread, void *pread_ctx, const jof_info_t *info, uint16_t tile_x, uint16_t tile_y, uint8_t *scratch, uint32_t scratch_cap, uint8_t *out_px, uint32_t out_cap, uint16_t *out_w, uint16_t *out_h) |
| Read + decode one tile into caller pixels, in bounded RAM. | |
Variables | |
| static const char *const | s_tag = "jof" |
| Module log tag. | |
JOF atlas reader: parse/validate + bounded per-tile decode (#231).
Implements the fail-closed structural validation (jof_parse) and the bounded decode-one-tile primitive (jof_read_tile) documented in jof.h. Deflate tiles inflate through the zero-heap ra8_decompress(); raw tiles are a single positioned read. The memstore helpers give tests and apps a RAM-backed sink/pread pair.
[Ring 4 / Domain] {World: NS}
Definition in file jof.c.
| enum jof_bound_t : uint16_t |
| enum jof_le_t : uint8_t |
|
static |
Ceil-divide n by d (d > 0).
Integer ceiling division for tile-grid geometry.
| [in] | n | Numerator. |
| [in] | d | Denominator (> 0). |
| 0-UINT32_MAX | The ceiling of the division. |
d is non-zero. d is >= n. Definition at line 119 of file jof.c.
References RA8_INTERNAL.
Referenced by internal_check_cross().
|
static |
Cross-check grid, tile-count, footer and index-window invariants.
The compound decisions here carry MC/DC vectors in test_jof.c (hostile-atlas suite).
| [in,out] | info | Geometry (grid fields written here). |
| [in] | hdr_count | Header tile-count field. |
| [in] | ftr | The 16 footer bytes. |
| [in] | total_size | Caller-supplied backing size. |
| k_ra8_ok | All invariants hold; info completed. |
| k_ra8_err_validation_failed | A cross-check failed. |
info holds validated header geometry fields. ftr holds k_jof_footer_bytes bytes. info must not be used. Definition at line 303 of file jof.c.
References jof_info_t::height, jof_info_t::index_off, internal_ceil_div(), internal_rd_u32(), k_jof_footer_bytes, k_jof_ftr_index_off, k_jof_ftr_tile_count, k_jof_ftr_total_size, k_jof_hdr_bytes, k_jof_index_entry, k_jof_max_tiles, k_ra8_err_validation_failed, k_ra8_ok, jof_info_t::tile_cols, jof_info_t::tile_count, jof_info_t::tile_h, jof_info_t::tile_rows, jof_info_t::tile_w, jof_info_t::total_size, and jof_info_t::width.
Referenced by jof_parse().
|
static |
Reject any non-zero reserved header byte (strict, fail-closed).
Walks both reserved header runs; any non-zero byte rejects the atlas.
| [in] | hdr | The 32 header bytes. |
| k_ra8_ok | All reserved bytes are zero. |
| k_ra8_err_validation_failed | A reserved byte is non-zero. |
hdr holds k_jof_hdr_bytes bytes. Definition at line 268 of file jof.c.
References k_jof_hdr_bytes, k_jof_ofs_reserved, k_jof_ofs_reserved2, k_jof_ofs_tile_count, k_ra8_err_validation_failed, k_ra8_ok, and RA8_INTERNAL.
Referenced by internal_parse_header_region().
|
static |
Decode a validated tile stream into out_px.
Raw streams must match the payload size exactly and are pread straight into the destination; deflate streams stage in scratch and inflate through ra8_decompress(), then the inflated size is checked against the payload size.
| [in] | pread | Backing read seam. |
| [in] | pread_ctx | Context for pread. |
| [in] | info | Parsed atlas geometry (codec source). |
| [in] | toff | Tile stream offset (window-validated). |
| [in] | tlen | Tile stream length (window-validated). |
| [in] | payload | Exact decoded payload size for this tile. |
| [out] | scratch | Deflate staging buffer (unused for raw). |
| [in] | scratch_cap | Capacity of scratch. |
| [out] | out_px | Destination pixels. |
| k_ra8_ok | Tile decoded; exactly payload bytes. |
| k_ra8_err_invalid_size | scratch_cap too small (deflate). |
| k_ra8_err_null_ptr | scratch NULL for a deflate atlas. |
| k_ra8_err_validation_failed | Size mismatch or corrupt stream. |
| other | Propagated from pread. |
out_px holds at least payload writable bytes. out_px holds the packed tile pixels. out_px content is unspecified. Definition at line 521 of file jof.c.
References jof_info_t::codec, internal_pread_exact(), k_jof_codec_raw, k_ra8_err_invalid_size, k_ra8_err_validation_failed, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_decompress(), RA8_INTERNAL, and s_tag.
Referenced by internal_fetch_decode().
|
static |
Fetch tile n's index entry, then read + decode its stream.
Combines the two bounded backing operations of a tile read so the public entry stays within the statement budget.
| [in] | pread | Backing read seam. |
| [in] | pread_ctx | Context for pread. |
| [in] | info | Parsed atlas geometry. |
| [in] | n | Linear tile number. |
| [in] | payload | Exact decoded payload size for this tile. |
| [out] | scratch | Deflate staging buffer (unused for raw). |
| [in] | scratch_cap | Capacity of scratch. |
| [out] | out_px | Destination pixels. |
| k_ra8_ok | Tile decoded; exactly payload bytes valid. |
| other | Propagated from the index fetch / stream decode. |
n is < info->tile_count (caller-bounded). out_px holds at least payload writable bytes. out_px holds the packed tile pixels. out_px content is unspecified. Definition at line 578 of file jof.c.
References internal_decode_stream(), internal_index_entry(), k_ra8_ok, and RA8_INTERNAL.
Referenced by jof_read_tile().
|
static |
Fetch + window-validate the index entry for tile n.
The tile-stream window must lie fully inside [header end, index start) – a hostile index cannot alias the header, the index, or the footer. The compound decision carries MC/DC vectors in test_jof.c.
| [in] | pread | Backing read seam. |
| [in] | pread_ctx | Context for pread. |
| [in] | info | Parsed atlas geometry. |
| [in] | n | Linear tile number. |
| [out] | out_off | Receives the tile stream's absolute offset. |
| [out] | out_len | Receives the tile stream's byte length. |
| k_ra8_ok | Entry read and window-validated. |
| k_ra8_err_validation_failed | Short read or window out of bounds. |
| other | Propagated from pread. |
n is < info->tile_count (caller-bounded). out_off and out_len are writable. Definition at line 468 of file jof.c.
References jof_info_t::index_off, internal_pread_exact(), internal_rd_u32(), k_jof_hdr_bytes, k_jof_idx_ofs_length, k_jof_idx_ofs_offset, k_jof_index_entry, k_ra8_err_validation_failed, k_ra8_ok, and RA8_INTERNAL.
Referenced by internal_fetch_decode().
|
static |
Validate the header geometry fields into info (fail-closed).
Single-condition guards so each rejection is independently testable; the compound cross-checks live in the caller.
| [in] | hdr | The 32 header bytes. |
| [in,out] | info | Geometry output (fields filled before checks). |
| k_ra8_ok | Geometry fields legal. |
| k_ra8_err_validation_failed | A field is zero, over-cap, or illegal. |
hdr holds k_jof_hdr_bytes bytes. info is writable. info is partially written and must not be used. Definition at line 217 of file jof.c.
References jof_info_t::bpp, jof_info_t::codec, jof_info_t::height, internal_rd_u16(), k_jof_bpp_max, k_jof_codec_deflate, k_jof_max_dim, k_jof_ofs_bpp, k_jof_ofs_codec, k_jof_ofs_height, k_jof_ofs_tile_h, k_jof_ofs_tile_w, k_jof_ofs_width, k_ra8_err_validation_failed, k_ra8_ok, RA8_INTERNAL, jof_info_t::tile_h, jof_info_t::tile_w, and jof_info_t::width.
Referenced by internal_parse_header_region().
|
static |
Read + validate the 32-byte header region into out_info.
Magic, geometry fields and reserved runs; grid cross-checks stay with the footer phase.
| [in] | pread | Backing read seam. |
| [in] | pread_ctx | Context for pread. |
| [out] | hdr | Receives the raw header bytes (for the count field). |
| [out] | out_info | Geometry fields filled on success. |
| k_ra8_ok | Header structurally valid. |
| k_ra8_err_validation_failed | Magic / geometry / reserved rejection. |
| other | Propagated from pread. |
hdr covers k_jof_hdr_bytes bytes. out_info must not be used. Definition at line 359 of file jof.c.
References internal_check_reserved(), internal_parse_hdr_fields(), internal_pread_exact(), k_jof_hdr_bytes, k_jof_magic_len, k_jof_ofs_magic, k_ra8_err_validation_failed, k_ra8_ok, memcmp(), and RA8_INTERNAL.
Referenced by jof_parse().
|
static |
Exact positioned read: EOF or a short read is a validation failure.
Wraps the pread seam so structural reads treat any short read as corruption.
| [in] | pread | Backing read seam. |
| [in] | pread_ctx | Context for pread. |
| [in] | off | Byte offset to read at. |
| [out] | buf | Destination buffer. |
| [in] | len | Bytes required. |
| k_ra8_ok | Exactly len bytes were read. |
| k_ra8_err_validation_failed | The backing came up short. |
| other | Propagated from pread. |
pread is non-NULL (caller-validated). buf holds len writable bytes. buf holds len backing bytes from off. buf content is unspecified. Definition at line 145 of file jof.c.
References k_ra8_err_validation_failed, and k_ra8_ok.
Referenced by internal_decode_stream(), internal_index_entry(), internal_parse_header_region(), and jof_parse().
|
static |
Read a little-endian uint16 from buf at off.
Assembles the two little-endian bytes at off.
| [in] | buf | Source bytes. |
| [in] | off | Field offset. |
| 0-65535 | Little-endian uint16 from the two bytes at off. |
buf holds at least off + 2 readable bytes. off is a header/footer field offset. Definition at line 76 of file jof.c.
References k_jof_le_b0, k_jof_le_b1, k_jof_le_sh8, and RA8_INTERNAL.
Referenced by internal_parse_hdr_fields().
|
static |
Read a little-endian uint32 from buf at off.
Assembles the four little-endian bytes at off.
| [in] | buf | Source bytes. |
| [in] | off | Field offset. |
| 0-UINT32_MAX | Little-endian uint32 from the four bytes at off. |
buf holds at least off + 4 readable bytes. off is a header/footer/index field offset. Definition at line 97 of file jof.c.
References k_jof_le_b0, k_jof_le_b1, k_jof_le_b2, k_jof_le_b3, k_jof_le_sh16, k_jof_le_sh24, k_jof_le_sh8, and RA8_INTERNAL.
Referenced by internal_check_cross(), internal_index_entry(), and jof_parse().
|
static |
Reject any NULL jof_read_tile pointer argument.
Split out so the public entry stays under the statement budget.
| [in] | pread | Backing read seam to validate. |
| [in] | info | Atlas geometry pointer to validate. |
| [in] | out_px | Destination pixels pointer to validate. |
| [in] | out_w | Width output pointer to validate. |
| [in] | out_h | Height output pointer to validate. |
| k_ra8_ok | Every required pointer is non-NULL. |
| k_ra8_err_null_ptr | Some pointer is NULL. |
Definition at line 623 of file jof.c.
References k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_INTERNAL, and s_tag.
Referenced by jof_read_tile().
|
nodiscard |
Positioned read from a jof_memstore_t (reader seam).
Matching jof_pread_fn: bind with ctx = &store. Reads clamp at store->len; a read at/after the end reports *got == 0 without error, mirroring epub_entry_pread.
| [in] | ctx | Store to read from (a jof_memstore_t*). |
| [in] | offset | Byte offset into the stored atlas. |
| [out] | buf | Destination buffer. |
| [in] | len | Bytes requested. |
| [out] | got | Bytes actually copied (possibly short at the tail). |
| k_ra8_ok | Window read (short reads included). |
| k_ra8_err_null_ptr | ctx, store->buf, buf, or got is NULL. |
ctx points at a store previously filled through the sink. buf holds len writable bytes. buf. Definition at line 177 of file jof.c.
References jof_memstore_t::buf, k_ra8_ok, jof_memstore_t::len, memcpy(), RA8_CHECK_NULL_PTR, and s_tag.
Referenced by ls_open_strip(), mg_build_atlas(), and mg_setup_cache().
|
nodiscard |
Append len bytes to a jof_memstore_t (producer sink).
Matching jof_sink_fn shape (see the producer header): bind with ctx = &store. Fails closed when the store is full so a hostile source can never write past cap.
| [in] | ctx | Store to append to (a jof_memstore_t*). |
| [in] | buf | Bytes to append. |
| [in] | len | Byte count (0 is a no-op). |
| k_ra8_ok | Bytes appended; store->len advanced. |
| k_ra8_err_null_ptr | ctx, store->buf, or buf is NULL. |
| k_ra8_err_no_mem | The append would exceed store->cap. |
ctx points at an initialised store (buf/cap set). buf holds len readable bytes. len bytes were copied at the old len. Definition at line 163 of file jof.c.
References jof_memstore_t::buf, jof_memstore_t::cap, k_ra8_err_no_mem, k_ra8_ok, jof_memstore_t::len, memcpy(), RA8_CHECK_NULL_PTR, and s_tag.
Referenced by mg_build_atlas().
|
nodiscard |
Parse + validate a JOF atlas's header, footer and index bounds.
Reads the 32-byte header at offset 0 and the 16-byte footer at total_size - 16, then cross-checks every field fail-closed: both magics, non-zero geometry within jof_limits_t, legal bpp/codec, zeroed reserved bytes, tile_count == cols * rows in both header and footer, the footer's total_size against the caller-supplied backing size, and the index window [index_off, index_off + 8 * tile_count + 16] == total_size. Per-tile offset/length windows are validated later, per read, by jof_read_tile() (the index itself may be larger than any bounded parse buffer).
| [in] | pread | Backing read seam (non-NULL). |
| [in] | pread_ctx | Context for pread. |
| [in] | total_size | Backing size in bytes (entry/file/store length). |
| [out] | out_info | Receives the validated geometry. |
| k_ra8_ok | Atlas structurally valid; info filled. |
| k_ra8_err_null_ptr | pread or out_info is NULL. |
| k_ra8_err_invalid_size | total_size cannot hold header+footer or exceeds the u32 format cap. |
| k_ra8_err_validation_failed | A magic/geometry/cross-check failed. |
| other | Propagated from pread. |
pread serves the atlas bytes for [0, total_size). out_info is writable. Definition at line 379 of file jof.c.
References internal_check_cross(), internal_parse_header_region(), internal_pread_exact(), internal_rd_u32(), k_jof_footer_bytes, k_jof_ftr_magic, k_jof_hdr_bytes, k_jof_magic_len, k_jof_ofs_tile_count, k_ra8_err_invalid_size, k_ra8_err_validation_failed, k_ra8_ok, memcmp(), RA8_CHECK_NULL_PTR, and s_tag.
Referenced by internal_accept(), internal_require_jof(), internal_verify_jof(), jof_audit(), jof_audit_requirements(), longstrip_open(), mg_build_atlas(), and priv_viewer_open_jof().
|
nodiscard |
Read + decode one tile into caller pixels, in bounded RAM.
Fetches the tile's index entry (one 8-byte pread), validates its window against the tile-stream region, reads the stored stream, and decodes it: raw tiles are pread directly into out_px; deflate tiles are pread into scratch and inflated with ra8_decompress() (zero heap). The decoded byte count must equal the tile's exact payload size or the read fails closed. Resident cost is scratch_cap + out_cap, independent of the image size – the property #231 needs for decode-on-demand paging.
| [in] | pread | Backing read seam (non-NULL). |
| [in] | pread_ctx | Context for pread. |
| [in] | info | Parsed atlas geometry. |
| [in] | tile_x | Tile column, [0, tile_cols). |
| [in] | tile_y | Tile row, [0, tile_rows). |
| [out] | scratch | Stored-stream staging (deflate codec only; may be NULL for raw atlases). |
| [in] | scratch_cap | Capacity of scratch; must cover jof_stored_bound() of the tile payload for deflate atlases. |
| [out] | out_px | Destination pixel buffer. |
| [in] | out_cap | Capacity of out_px; must cover the payload. |
| [out] | out_w | Receives the tile's clamped width, pixels. |
| [out] | out_h | Receives the tile's clamped height, pixels. |
| k_ra8_ok | Tile decoded into out_px. |
| k_ra8_err_null_ptr | A required pointer is NULL. |
| k_ra8_err_out_of_range | tile_x / tile_y outside the grid. |
| k_ra8_err_invalid_size | out_cap (or scratch_cap) too small for this tile. |
| k_ra8_err_validation_failed | Index/stream window corrupt, short read, or decoded size mismatch. |
| other | Propagated from pread. |
info came from a successful jof_parse() over the same backing. out_px holds out_cap writable bytes. out_px content is unspecified. Definition at line 637 of file jof.c.
References jof_info_t::bpp, internal_fetch_decode(), internal_read_args_ok(), jof_tile_dims(), k_ra8_err_invalid_size, k_ra8_ok, and jof_info_t::tile_cols.
Referenced by internal_audit_tile(), internal_compare(), internal_preflight(), longstrip_tile_decode(), and mg_tile_decode().
|
nodiscard |
Implementation of jof_stored_bound() – raw + raw/8 + 256.
Worst-case stored-tile byte bound for scratch/cell sizing.
Definition at line 439 of file jof.c.
References k_jof_bound_add, and k_jof_bound_div.
Referenced by internal_carve_pixel_path(), internal_require_jof(), jof_audit_requirements(), jof_work_bytes(), priv_viewer_open_jof(), and ra8_fmt_jof_verify_requirements().
|
nodiscard |
Report the true (edge-clamped) pixel dimensions of one tile.
| [in] | info | Parsed atlas geometry. |
| [in] | tile_x | Tile column, [0, tile_cols). |
| [in] | tile_y | Tile row, [0, tile_rows). |
| [out] | out_w | Receives the tile's width, pixels. |
| [out] | out_h | Receives the tile's height, pixels. |
| k_ra8_ok | Dimensions reported. |
| k_ra8_err_null_ptr | info, out_w, or out_h is NULL. |
| k_ra8_err_out_of_range | tile_x / tile_y outside the grid. |
info came from a successful jof_parse(). out_w and out_h are writable. Definition at line 414 of file jof.c.
References jof_info_t::height, k_ra8_err_out_of_range, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, jof_info_t::tile_cols, jof_info_t::tile_h, jof_info_t::tile_rows, jof_info_t::tile_w, and jof_info_t::width.
Referenced by internal_audit_tile(), and jof_read_tile().