ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
cm_tiled_check.c
Go to the documentation of this file.
1
22
23#include "cm_tiled_check.h"
24
25#include <stddef.h>
26#include <stdint.h>
27#include <string.h>
28
29#include "comic.h"
30#include "comic_large_fixture.h"
31#include "comic_tiles.h"
32#include "jof.h"
33#include "jof_produce.h"
34#include "ra8_err.h"
35#include "ra8_tile_cache.h"
36
46typedef enum : uint32_t {
47 k_ct_tile = 256U,
52 k_ct_budget = 2U * 1024U * 1024U,
53 k_ct_pagebuf = 64U * 1024U,
54 k_ct_work = 2U * 1024U * 1024U,
55 k_ct_atlas = 2U * 1024U * 1024U,
56 k_ct_scratch = 96U * 1024U,
59 k_ct_fnv_offset = 2166136261U,
60 k_ct_fnv_prime = 16777619U,
62
70typedef struct {
71 const uint8_t* d;
72 size_t n;
74
76[[gnu::section(".sdram_data")]] static uint8_t s_ct_pagebuf[k_ct_pagebuf];
78[[gnu::section(".sdram_data")]] static uint8_t s_ct_work[k_ct_work];
80[[gnu::section(".sdram_data")]] static uint8_t s_ct_atlas[k_ct_atlas];
82[[gnu::section(
83 ".sdram_data")]] static uint8_t s_ct_cells[(size_t)k_ct_cells * (size_t)k_ct_cell_bytes];
85[[gnu::section(".sdram_data")]] static uint8_t s_ct_scratch[k_ct_scratch];
87[[gnu::section(".sdram_data")]] static comic_page_t s_ct_pages[k_ct_page_cap];
89[[gnu::section(".sdram_data")]] static char s_ct_names[k_ct_name_cap];
91[[gnu::section(".sdram_data")]] static comic_t s_ct_comic;
93[[gnu::section(".sdram_data")]] static comic_tile_reader_t s_ct_reader;
104
106// cppcheck-suppress constParameterCallback -- ctx is pinned by the comic_read_fn vtable signature
107static size_t cm_ct_read(void* ctx, uint64_t off, void* buf, size_t len)
108{
109 const cm_ct_blob_t* s = (const cm_ct_blob_t*)ctx;
110 if ((s == nullptr) || (buf == nullptr) || (off >= (uint64_t)s->n)) {
111 return 0U;
112 }
113 const uint64_t avail = (uint64_t)s->n - off;
114 const size_t k = (len > (size_t)avail) ? (size_t)avail : len;
115 (void)memcpy(buf, &s->d[off], k);
116 return k;
117}
118
120static uint32_t cm_ct_fnv(uint32_t h, const uint8_t* p, size_t n)
121{
122 for (size_t i = 0U; i < n; ++i) {
123 h = (h ^ (uint32_t)p[i]) * (uint32_t)k_ct_fnv_prime;
124 }
125 return h;
126}
127
141static bool cm_ct_open(size_t* out_got)
142{
147 &s_ct_blob,
148 (uint64_t)k_comic_large_cbz_len,
150 (uint32_t)k_ct_page_cap,
152 (uint32_t)k_ct_name_cap) != k_ra8_ok) {
153 return false;
154 }
155 if (comic_page_count(&s_ct_comic) == 0U) {
156 return false;
157 }
158 *out_got = 0U;
159 return comic_page_read(&s_ct_comic, 0U, s_ct_pagebuf, sizeof s_ct_pagebuf, out_got) == k_ra8_ok;
160}
161
176static bool cm_ct_hash_tiles(const jof_info_t* info, uint32_t* out_crc)
177{
178 uint32_t crc = (uint32_t)k_ct_fnv_offset;
179 for (uint16_t ty = 0U; ty < info->tile_rows; ++ty) {
180 for (uint16_t tx = 0U; tx < info->tile_cols; ++tx) {
181 ra8_tile_t tile = {};
182 if (comic_tiles_tile(&s_ct_reader, tx, ty, &tile) != k_ra8_ok) {
183 return false;
184 }
185 const size_t n = (size_t)tile.width * (size_t)tile.height * (size_t)info->bpp;
186 crc = cm_ct_fnv(crc, tile.pixels, n);
188 return false;
189 }
190 }
191 }
192 *out_crc = crc;
193 return true;
194}
195
198{
199 return (ra8_tile_cache_cfg_t){
200 .cell_mem = s_ct_cells,
201 .cell_bytes = (uint32_t)k_ct_cell_bytes,
202 .cell_count = (uint32_t)k_ct_cells,
203 .meta = s_ct_meta,
204 .keys = s_ct_keys,
205 .dims = s_ct_dims,
206 .buckets = s_ct_buckets,
207 .bucket_count = (uint32_t)k_ct_buckets,
208 .decode = nullptr,
209 .decode_ctx = nullptr,
210 };
211}
212
214{
215 cm_tiled_result_t r = {};
216 size_t got = 0U;
217 if (!cm_ct_open(&got)) {
218 return r;
219 }
220 uint16_t w = 0U;
221 uint16_t h = 0U;
222 uint64_t dec = 0U;
223 if (comic_tiles_footprint(s_ct_pagebuf, got, &w, &h, &dec) != k_ra8_ok) {
224 (void)comic_close(&s_ct_comic);
225 return r;
226 }
227 if (!comic_tiles_over_budget(dec, (uint64_t)k_ct_budget)) {
228 (void)comic_close(&s_ct_comic);
229 return r; /* fixture must be oversized; a fit page is not the case under test */
230 }
232 if (comic_tiles_init(&s_ct_reader, &storage, s_ct_scratch, (uint32_t)k_ct_scratch) != k_ra8_ok) {
233 (void)comic_close(&s_ct_comic);
234 return r;
235 }
236 const comic_tiles_import_cfg_t cfg = {
237 .tile_w = (uint16_t)k_ct_tile,
238 .tile_h = (uint16_t)k_ct_tile,
239 .codec = (uint8_t)k_jof_codec_deflate,
240 .max_width = (uint16_t)k_comic_large_w,
241 .max_height = (uint16_t)k_comic_large_h,
242 .work = s_ct_work,
243 .work_cap = sizeof s_ct_work,
244 .webp_work = nullptr,
245 .webp_work_cap = 0U,
246 .atlas = s_ct_atlas,
247 .atlas_cap = sizeof s_ct_atlas,
248 };
250 (void)comic_close(&s_ct_comic);
251 return r;
252 }
253 jof_info_t info = {};
254 if (comic_tiles_info(&s_ct_reader, &info) != k_ra8_ok) {
255 (void)comic_close(&s_ct_comic);
256 return r;
257 }
258 uint32_t crc = 0U;
259 r.ok = cm_ct_hash_tiles(&info, &crc);
260 r.w = (uint32_t)info.width;
261 r.h = (uint32_t)info.height;
262 r.tiles = info.tile_count;
263 r.crc = r.ok ? crc : 0U;
264 (void)comic_close(&s_ct_comic);
265 return r;
266}
static comic_t s_ct_comic
SDRAM: the open comic reader.
cm_tiled_result_t cm_comic_tiled_selfcheck(void)
Open the baked oversized page through the tile path and digest it.
static comic_page_t s_ct_pages[k_ct_page_cap]
SDRAM: comic page-index storage.
static uint8_t s_ct_pagebuf[k_ct_pagebuf]
SDRAM: encoded page scratch (the tile producer's input).
static char s_ct_names[k_ct_name_cap]
SDRAM: comic name arena.
static int32_t s_ct_buckets[k_ct_buckets]
Tile-cache hash buckets.
static cm_ct_blob_t s_ct_blob
Blob backing bound into the read seam.
static comic_tile_reader_t s_ct_reader
SDRAM: the comic tile reader.
static ra8_keycache_cell_t s_ct_meta[k_ct_cells]
Tile-cache link metadata.
static bool cm_ct_open(size_t *out_got)
Open the baked oversized CBZ and read page 0's encoded bytes.
static uint8_t s_ct_atlas[k_ct_atlas]
SDRAM: produced JOF atlas backing store.
static uint8_t s_ct_scratch[k_ct_scratch]
SDRAM: stored-tile staging for deflate tiles.
static uint32_t cm_ct_fnv(uint32_t h, const uint8_t *p, size_t n)
FNV-1a-32 folding n bytes of p into the running hash h.
cm_tiled_cfg_t
Tile geometry, cache budget, and hashing constants for the self-check.
@ k_ct_buckets
Tile-cache hash buckets.
@ k_ct_name_cap
Comic name-arena bytes.
@ k_ct_cell_bytes
Bytes per cache cell.
@ k_ct_work
Producer work arena, bytes.
@ k_ct_page_cap
Comic page-index capacity.
@ k_ct_fnv_offset
FNV-1a-32 offset basis.
@ k_ct_bpp_gray
Grayscale atlas bytes per pixel.
@ k_ct_cells
Tile-cache cell budget.
@ k_ct_atlas
Atlas memstore backing, bytes.
@ k_ct_budget
Whole-decode budget (threshold).
@ k_ct_tile
Square tile edge, pixels.
@ k_ct_pagebuf
Encoded page scratch, bytes.
@ k_ct_fnv_prime
FNV-1a-32 prime.
@ k_ct_scratch
Stored-tile staging, bytes.
static bool cm_ct_hash_tiles(const jof_info_t *info, uint32_t *out_crc)
Decode every tile of the bound atlas, FNV-hashing the pixels.
static ra8_tile_key_t s_ct_keys[k_ct_cells]
Tile-cache key storage.
static uint8_t s_ct_cells[(size_t) k_ct_cells *(size_t) k_ct_cell_bytes]
SDRAM: tile-cache cell storage.
static ra8_tile_cache_cfg_t cm_ct_cache_cfg(void)
Tile-cache storage config over the file-static cache buffers.
static uint8_t s_ct_work[k_ct_work]
SDRAM: producer streaming work arena.
static ra8_tile_dims_t s_ct_dims[k_ct_cells]
Tile-cache dimension descriptors.
static size_t cm_ct_read(void *ctx, uint64_t off, void *buf, size_t len)
comic_read_fn over the resident CBZ blob (bounds-clamped).
Boot-time self-check that opens an oversized comic page via the JOF tile path and reports a determini...
Unified demand-paged reader for comic-book archives – CBZ (ZIP) and CBR (RAR).
ra8_err_t comic_page_read(comic_t *c, uint32_t page, uint8_t *buf, size_t cap, size_t *got)
Extract one page's encoded image bytes for the decoder.
Definition comic.c:472
ra8_err_t comic_close(comic_t *c)
Release an open comic's backend resources.
Definition comic.c:494
ra8_err_t comic_open(comic_t *c, comic_read_fn read, void *ctx, uint64_t size, comic_page_t *pages, uint32_t page_cap, char *names, uint32_t names_cap)
Open a comic archive (CBZ or CBR) and build its sorted page index.
Definition comic.c:390
static uint32_t comic_page_count(const comic_t *c)
Number of pages in an open comic.
Definition comic.h:263
Baked oversized single-page CBZ for the ereader_comic tile self-check (#344; generated by scripts/gen...
@ k_comic_large_h
Decoded height in pixels.
@ k_comic_large_w
Decoded width in pixels.
static const uint8_t k_comic_large_cbz[]
Baked 423-byte single-page oversized CBZ.
static const uint32_t k_comic_large_cbz_len
Length of k_comic_large_cbz in bytes.
Tile an oversized comic page through the JOF atlas + ra8_tile_cache so a CBZ/CBR page larger than the...
ra8_err_t comic_tiles_tile(comic_tile_reader_t *r, uint16_t tile_x, uint16_t tile_y, ra8_tile_t *out_tile)
Get (and pin) one decoded tile of the bound page (#344).
ra8_err_t comic_tiles_import(comic_tile_reader_t *r, const uint8_t *enc, size_t enc_len, const comic_tiles_import_cfg_t *cfg)
Transcode one encoded comic page to a JOF atlas and bind it for tiling.
ra8_err_t comic_tiles_info(const comic_tile_reader_t *r, jof_info_t *out_info)
Report the bound page's parsed atlas geometry (#344).
ra8_err_t comic_tiles_footprint(const uint8_t *enc, size_t len, uint16_t *out_w, uint16_t *out_h, uint64_t *out_decoded_bytes)
Read a comic page's decoded footprint from its encoded header (#344).
bool comic_tiles_over_budget(uint64_t decoded_bytes, uint64_t budget_bytes)
Decide whether a page's decoded footprint exceeds the resident budget.
ra8_err_t comic_tiles_init(comic_tile_reader_t *r, const ra8_tile_cache_cfg_t *storage, uint8_t *scratch, uint32_t scratch_cap)
Initialise a comic tile reader over caller-supplied tile-cache storage.
ra8_err_t comic_tiles_release(comic_tile_reader_t *r, const uint8_t *pixels)
Release one pin taken by comic_tiles_tile (#344).
JOF band-tile atlas: the display-native normalized image format (#231, shared with the longstrip scro...
@ k_jof_codec_deflate
Tile stream is one raw-DEFLATE run.
Definition jof.h:192
Import-time transcode producer: JPEG/PNG/WebP -> JOF band-tile atlas in bounded RAM (#231,...
Error Code Definitions for ra8-firmware.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
Fixed-RAM-budget image-tile cache with LRU eviction (Layer 3b, #147).
Resident-buffer backing for the comic reader's seek+read seam.
size_t n
Archive length.
const uint8_t * d
Archive bytes.
Outcome of the oversized-page tile self-check.
uint32_t w
Decoded page width, pixels.
uint32_t h
Decoded page height, pixels.
bool ok
True when the oversized page tiled cleanly.
uint32_t tiles
Tile count in the produced JOF atlas.
uint32_t crc
FNV-1a-32 over the concatenated tile bytes.
One entry in the resident, sorted page index.
Definition comic.h:140
One open comic archive: backing, kind, page index, and backend state.
Definition comic.h:179
One comic tile reader: owned tile cache, atlas store, bound page.
Import-time transcode knobs, work arena, and destination atlas store.
Parsed + validated geometry of one JOF atlas.
Definition jof.h:208
uint8_t bpp
Bytes per pixel (1, 3 or 4).
Definition jof.h:215
uint16_t width
Image width, pixels.
Definition jof.h:209
uint16_t tile_rows
Ceil(height / tile_h) tile rows.
Definition jof.h:214
uint32_t tile_count
Total tiles (== cols * rows).
Definition jof.h:217
uint16_t height
Image height, pixels.
Definition jof.h:210
uint16_t tile_cols
Ceil(width / tile_w) tile columns.
Definition jof.h:213
Per-cell link metadata (one caller-owned array entry per cell).
Caller-supplied storage + decoder for ra8_tile_cache_init.
Per-cell user descriptor: the decoded tile dimensions.
Identifies one decoded image tile.
A pinned view of a cached tile returned by ra8_tile_cache_get.
const uint8_t * pixels
Decoded tile pixels (cell payload).
uint16_t height
Decoded tile height in pixels.
uint16_t width
Decoded tile width in pixels.