|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Unified demand-paged reader for comic-book archives – CBZ (ZIP) and CBR (RAR). More...
#include <stddef.h>#include <stdint.h>#include "epub_miniz_alloc.h"#include "ra8_err.h"#include "ra8_rar.h"#include "ra8_rar5.h"#include "unarch_gzip.h"#include "unarch_tar.h"#include "unarch_xz.h"Go to the source code of this file.
Data Structures | |
| struct | comic_page_t |
| One entry in the resident, sorted page index. More... | |
| struct | comic_stream_t |
| Stable seek+read descriptor bound to the CBZ backend's miniz reader. More... | |
| struct | comic_t |
| One open comic archive: backing, kind, page index, and backend state. More... | |
Typedefs | |
| typedef size_t(* | comic_read_fn) (void *ctx, uint64_t offset, void *buf, size_t len) |
| Seek+read backing over the comic-archive bytes. | |
Enumerations | |
| enum | comic_kind_t : uint8_t { k_comic_kind_none = 0U , k_comic_kind_cbz = 1U , k_comic_kind_cbr = 2U , k_comic_kind_cbt = 3U } |
| Which container an opened comic is. More... | |
| enum | comic_limits_t : uint16_t { k_comic_magic_len = 8U , k_comic_zip_bytes = 256U } |
| Fixed sizes for magic detection and the inline ZIP-reader storage. More... | |
| enum | comic_wrap_dims_t : uint8_t { k_comic_wrap_align = 8U } |
| Alignment of the unwrap arena a wrapped open consumes. More... | |
Functions | |
| 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. | |
| static uint32_t | comic_page_count (const comic_t *c) |
| Number of pages in an open comic. | |
| static comic_kind_t | comic_kind (const comic_t *c) |
| The detected container kind of an open comic. | |
| ra8_err_t | comic_page_info (const comic_t *c, uint32_t page, char *name_buf, uint16_t name_cap, uint16_t *out_name_len, uint64_t *out_raw_size, uint8_t *out_extractable) |
| Read one page's manifest entry: name, encoded length, decodability. | |
| 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. | |
| ra8_err_t | comic_close (comic_t *c) |
| Release an open comic's backend resources. | |
| ra8_err_t | comic_open_wrapped (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, uint8_t *arena, size_t arena_cap, void *xz_scratch, uint32_t xz_scratch_len) |
| Open a comic that may be gzip- or XZ-wrapped (.cbt.gz, .tar.xz). | |
Unified demand-paged reader for comic-book archives – CBZ (ZIP) and CBR (RAR).
A comic archive is simply a container of page images (JPEG / PNG / GIF / BMP) whose reading order is the sorted entry names. This facade opens either shape – a .cbz (a ZIP of images) or a .cbr (a RAR of images) – behind one interface, so the reader pages through both identically: detect the container, build a sorted page index, then serve each page's encoded image bytes on demand for the image decoder (ra8_img_decode_blit) to rasterise.
The caller supplies all storage: a page-index array, a name arena sized for the archive's page count, and (inside comic_t) one per-object bounded miniz workspace. There is no heap (NASA Rule 3).
Definition in file comic.h.
| typedef size_t(* comic_read_fn) (void *ctx, uint64_t offset, void *buf, size_t len) |
Seek+read backing over the comic-archive bytes.
Identical in shape to the streaming EPUB read seam and ra8_rar_read_fn, so one ra8_fs / ra8_vmem backing drives EPUB, CBZ, and CBR alike. A return shorter than len signals end-of-file.
| [in] | ctx | Opaque backing context (comic_t::ctx). |
| [in] | offset | Absolute byte offset within the archive. |
| [out] | buf | Destination buffer (len writable bytes). |
| [in] | len | Bytes requested. |
| enum comic_kind_t : uint8_t |
Which container an opened comic is.
Set by comic_open from the file magic; selects the backend that comic_page_read dispatches to.
| Enumerator | |
|---|---|
| k_comic_kind_none | Not opened / unrecognised. |
| k_comic_kind_cbz | ZIP of images (.cbz). |
| k_comic_kind_cbr | RAR of images (.cbr). |
| k_comic_kind_cbt | tar of images (.cbt). |
| enum comic_limits_t : uint16_t |
| enum comic_wrap_dims_t : uint8_t |
Alignment of the unwrap arena a wrapped open consumes.
comic_open_wrapped stores its flat-memory descriptor at the arena start, so the caller arena must be at least this aligned (any static or alignas(8) buffer qualifies).
| Enumerator | |
|---|---|
| k_comic_wrap_align | Required unwrap-arena alignment, bytes. |
Release an open comic's backend resources.
Ends the CBZ miniz reader (freeing its central directory through the per-object bounded arena); the CBR backend allocates nothing. Resets c to the unopened state. Idempotent after a failed open.
| [in,out] | c | Comic from comic_open (non-NULL). |
| k_ra8_ok | Resources released; c reset. |
| k_ra8_err_null_ptr | c was NULL. |
c was populated by comic_open or zero-initialised. c out-lives the call. Definition at line 494 of file comic.c.
References k_comic_kind_cbz, k_comic_kind_none, k_ra8_ok, comic_t::kind, unarch_tar_t::live, comic_t::page_count, priv_comic_cbz_close(), RA8_CHECK_NULL_PTR, s_tag_comic, comic_t::tar, and comic_t::zip_active.
Referenced by cm_comic_tiled_selfcheck(), comic_open(), ra8_viewer_close(), ra8_viewer_open(), and sh_comic_close().
|
inlinestatic |
The detected container kind of an open comic.
Reports the kind comic_open set from the file magic, guarding a NULL / unopened reader so a caller can branch before a comic is bound.
| [in] | c | Comic bound by comic_open (may be NULL). |
| k_comic_kind_none | c is NULL or was never opened. |
c was populated by comic_open (or is NULL). c out-lives the call. Definition at line 288 of file comic.h.
References k_comic_kind_none, and comic_t::kind.
|
nodiscard |
Open a comic archive (CBZ or CBR) and build its sorted page index.
Reads the leading magic through read, detects a ZIP (.cbz) or a RAR (.cbr) container, enumerates its image members into pages (filtered to decodable image extensions, names copied into names), and sorts the index by entry name so page 0 is the first page. On success at least one page is present.
| [out] | c | Reader to populate (caller-owned). |
| [in] | read | Byte reader over the archive (non-NULL). |
| [in] | ctx | Context passed to read. |
| [in] | size | Archive length in bytes (> 0). |
| [in] | pages | Caller page-index array (non-NULL). |
| [in] | page_cap | Capacity of pages in entries (> 0). |
| [in] | names | Caller name arena (non-NULL). |
| [in] | names_cap | Capacity of names in bytes (> 0). |
| k_ra8_ok | Comic opened; c bound with >= 1 page. |
| k_ra8_err_null_ptr | A required pointer argument was NULL. |
| k_ra8_err_invalid_size | size / a capacity is 0, a short magic read, or the page index / name arena was too small. |
| k_ra8_err_not_supported | The bytes are neither a ZIP nor a RAR archive. |
| k_ra8_err_not_found | A valid archive with no decodable image pages. |
| k_ra8_err_* | A backend (miniz / RAR) or reader error. |
read serves offsets [0, size) of the archive. pages / names out-live c and every read from it. c is left with kind == k_comic_kind_none.Definition at line 390 of file comic.c.
References comic_close(), comic_t::ctx, internal_open_detect(), internal_open_reject_null(), internal_sort(), k_ra8_err_invalid_size, k_ra8_err_not_found, k_ra8_ok, comic_t::names, comic_t::names_cap, comic_t::page_cap, comic_t::page_count, comic_t::pages, comic_t::read, and comic_t::size.
Referenced by cm_ct_open(), cm_open_comic(), comic_open_wrapped(), internal_open_unwrapped(), priv_viewer_open_comic(), and sh_comic_bind().
|
nodiscard |
Open a comic that may be gzip- or XZ-wrapped (.cbt.gz, .tar.xz).
Probes the leading magic: a bare container (ZIP / RAR / tar) passes straight through to comic_open; a gzip or XZ wrapper is first decoded whole into the caller arena under the default decompression-limits policy, the unwrapped bytes are re-probed (a wrapper inside a wrapper is rejected as a nesting bomb), and the inner container is opened from the arena. The arena therefore must out-live the comic, exactly like the page-index and name buffers.
| [out] | c | Reader to populate (caller-owned). |
| [in] | read | Byte reader over the outer file (non-NULL). |
| [in] | ctx | Context passed to read. |
| [in] | size | Outer file length in bytes (> 0). |
| [in] | pages | Caller page-index array (non-NULL). |
| [in] | page_cap | Capacity of pages in entries (> 0). |
| [in] | names | Caller name arena (non-NULL). |
| [in] | names_cap | Capacity of names in bytes (> 0). |
| [in] | arena | Unwrap arena (non-NULL, 8-aligned; out-lives c). |
| [in] | arena_cap | Capacity of arena in bytes. |
| [in] | xz_scratch | XZ session scratch (8-aligned, > k_unarch_xz_state_reserve bytes; may be NULL when XZ content is not expected – an XZ file is then rejected fail-closed). |
| [in] | xz_scratch_len | Scratch length in bytes. |
| k_ra8_ok | Comic opened; c bound with >= 1 page. |
| k_ra8_err_null_ptr | A required pointer argument was NULL. |
| k_ra8_err_invalid_size | A zero size/capacity, a short magic read, a misaligned or undersized arena, or full index buffers. |
| k_ra8_err_decomp_depth | The unwrapped bytes are another gzip/XZ wrapper (nesting bomb). |
| k_ra8_err_decomp_* | The wrapper breached the policy. |
| k_ra8_err_checksum_mismatch | The gzip integrity check failed. |
| k_ra8_err_not_supported | Not a recognised container or wrapper. |
| k_ra8_err_* | An unwrap or inner-open error. |
read serves offsets [0, size) of the outer file. arena (and every other buffer) out-lives c and every read. c is left with kind == k_comic_kind_none.Log tag for wrapped-open diagnostics.
Definition at line 190 of file comic_wrapped.c.
References comic_open(), internal_arena_valid(), internal_open_unwrapped(), internal_unwrap(), k_comic_magic_len, k_ra8_err_invalid_size, k_ra8_ok, k_wrap_hdr_bytes, RA8_CHECK_NULL_PTR, unarch_gzip_magic(), and unarch_xz_magic().
|
inlinestatic |
Number of pages in an open comic.
Returns the count parsed by comic_open, guarding a NULL/unopened reader so a shelf view can query it safely.
| [in] | c | Comic bound by comic_open (may be NULL). |
| 0 | c is NULL or was never opened. |
c was populated by comic_open (or is NULL). c out-lives the call. Definition at line 263 of file comic.h.
References k_comic_kind_none, comic_t::kind, and comic_t::page_count.
Referenced by cm_ct_open(), cm_open_comic(), internal_open_selected(), and sh_comic_bind().
|
nodiscard |
Read one page's manifest entry: name, encoded length, decodability.
Pure index query – no archive I/O. Copies the page's entry name into name_buf (clamped to name_cap) and reports its encoded byte length and whether this reader can decode it (0 for a compressed CBR member).
| [in] | c | Comic bound by comic_open (non-NULL). |
| [in] | page | Page index (< comic_page_count(c)). |
| [out] | name_buf | Buffer for the entry name (may be NULL if name_cap 0). |
| [in] | name_cap | Capacity of name_buf in bytes. |
| [out] | out_name_len | Receives the copied name length (may be NULL). |
| [out] | out_raw_size | Receives the encoded image length (may be NULL). |
| [out] | out_extractable | Receives 1 if the page is decodable (may be NULL). |
| k_ra8_ok | Outputs populated from the index. |
| k_ra8_err_null_ptr | c was NULL. |
| k_ra8_err_invalid_state | c was never opened. |
| k_ra8_err_out_of_range | page is at or past the page count. |
c was populated by comic_open. name_buf holds name_cap writable bytes when name_cap > 0. page. Definition at line 434 of file comic.c.
References comic_page_t::extractable, k_comic_kind_none, k_ra8_err_invalid_state, k_ra8_err_out_of_range, k_ra8_ok, comic_t::kind, memcpy(), comic_page_t::name_len, comic_page_t::name_off, comic_t::names, comic_t::page_count, comic_t::pages, RA8_CHECK_NULL_PTR, comic_page_t::raw_size, and s_tag_comic.
Referenced by internal_read_page().
|
nodiscard |
Extract one page's encoded image bytes for the decoder.
Streams the page's encoded image (JPEG / PNG / GIF / BMP) into buf: for a CBZ, miniz inflates the ZIP entry (STORE or DEFLATE) through the streaming reader; for a CBR, a STORE member is copied and a RAR5-compressed member is inflated by the clean-room decompressor, both via the RAR walker. The result is ready to hand to ra8_img_decode_blit. One call is one page's worth of I/O – the demand-paged model.
| [in] | c | Comic bound by comic_open (non-NULL). |
| [in] | page | Page index (< comic_page_count(c)). |
| [out] | buf | Destination for the encoded image (non-NULL). |
| [in] | cap | Capacity of buf in bytes; must be >= the page raw_size. |
| [out] | got | Receives the bytes written (non-NULL). |
| k_ra8_ok | Page bytes written; *got == raw_size. |
| k_ra8_err_null_ptr | A required pointer argument was NULL. |
| k_ra8_err_invalid_state | c was never opened. |
| k_ra8_err_out_of_range | page is at or past the page count. |
| k_ra8_err_not_supported | A CBR page packed with a RAR compressor. |
| k_ra8_err_no_mem | cap is smaller than the page raw_size. |
| k_ra8_err_* | A backend extract / reader error. |
c was populated by comic_open. buf holds at least cap writable bytes. buf contents are unspecified and *got == 0.Definition at line 472 of file comic.c.
References k_comic_kind_cbt, k_comic_kind_cbz, k_comic_kind_none, k_ra8_err_invalid_state, k_ra8_err_out_of_range, comic_t::kind, comic_t::page_count, comic_t::pages, priv_comic_cbr_extract(), priv_comic_cbt_extract(), priv_comic_cbz_extract(), RA8_CHECK_NULL_PTR, and s_tag_comic.
Referenced by cm_ct_open(), cm_draw_page(), internal_read_page(), and sh_comic_blit_page().