43typedef enum : uint16_t {
58typedef enum : uint8_t {
107 if (ext[i] ==
'\0') {
110 elen = (size_t)i + 1U;
112 if ((
size_t)len < elen) {
115 const char* tail = &name[(size_t)len - elen];
116 for (
size_t i = 0U; i < elen; ++i) {
142 static const char*
const k_exts[] = {
".jpg",
".jpeg",
".png",
".gif",
".bmp"};
143 for (uint8_t i = 0U; i < (uint8_t)(
sizeof(k_exts) /
sizeof(k_exts[0]));
154 if (name ==
nullptr) {
161 for (
size_t i = 0U; i < (size_t)len; ++i) {
162 if (name[i] ==
'/') {
165 if (name[i] ==
'\\') {
169 if (base < (
size_t)len) {
170 if (name[base] ==
'.') {
233 const uint16_t m = (alen < blen) ? alen : blen;
235 for (uint16_t i = 0U; (i < m) && (c == 0); ++i) {
236 c = (int)(uint8_t)a[i] - (int)(uint8_t)b[i];
239 return (c < 0) ? -1 : 1;
265 for (uint32_t i = 1U; i < c->
page_count; ++i) {
364 const size_t got = c->
read(c->
ctx, 0U, sig,
sizeof(sig));
407 if (page_cap == 0U) {
410 if (names_cap == 0U) {
438 uint16_t* out_name_len,
439 uint64_t* out_raw_size,
440 uint8_t* out_extractable)
450 if (name_buf !=
nullptr) {
455 if (out_name_len !=
nullptr) {
456 *out_name_len = want;
458 }
else if (out_name_len !=
nullptr) {
463 if (out_raw_size !=
nullptr) {
466 if (out_extractable !=
nullptr) {
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.
static const char *const s_tag_comic
Log tag for comic-facade diagnostics.
ra8_err_t comic_close(comic_t *c)
Release an open comic's backend resources.
comic_magic_t
ZIP magic bytes and the minimum magic-read length.
@ k_comic_sig_min
Bytes required to test the ZIP magic.
@ k_zip_eocd_b2
Empty-archive EOCD 3rd byte.
@ k_zip_eocd_b3
Empty-archive EOCD 4th byte.
@ k_zip_lfh_b2
Local-file-header 3rd byte.
@ k_zip_lfh_b3
Local-file-header 4th byte.
static ra8_err_t internal_open_reject_null(const comic_t *c, comic_read_fn read, const comic_page_t *pages, const char *names)
Reject any NULL required argument to comic_open.
bool priv_comic_is_page_name(const char *name, uint16_t len)
Whether an archive entry name is a decodable comic page image.
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 int32_t internal_name_cmp(const char *a, uint16_t alen, const char *b, uint16_t blen)
Lexicographic compare of two entry names (byte order, length tiebreak).
static void internal_sort(comic_t *c)
Insertion-sort the page index by entry name (reading order).
ra8_err_t priv_comic_page_add(comic_t *c, const char *name, uint16_t name_len, uint64_t raw_size, uint8_t extractable, uint8_t method, uint32_t zip_index, uint64_t data_off, uint64_t pack_size)
Append one image member to the resident page index.
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.
static bool internal_ends_with_ci(const char *name, uint16_t len, const char *ext)
Case-insensitive test that name ends with ext.
comic_ascii_t
Constants for branchless ASCII case folding.
@ k_ascii_alpha_n
Letters in the alphabet.
@ k_comic_ext_max
Longest extension the filter compares.
@ k_ascii_case_sh
0x20 == 1 << 5 (upper->lower bit).
static bool internal_is_image_ext(const char *name, uint16_t len)
Whether name ends in a decodable image extension.
static uint8_t internal_lower(uint8_t c)
ASCII-lowercase one byte, branchlessly (letters only).
static bool internal_is_zip(const uint8_t *s)
Whether the leading bytes are a ZIP local-file-header or empty EOCD.
static ra8_err_t internal_open_detect(comic_t *c)
Detect the container and run its backend enumeration.
Unified demand-paged reader for comic-book archives – CBZ (ZIP) and CBR (RAR).
size_t(* comic_read_fn)(void *ctx, uint64_t offset, void *buf, size_t len)
Seek+read backing over the comic-archive bytes.
@ k_comic_kind_cbz
ZIP of images (.cbz).
@ k_comic_kind_cbt
tar of images (.cbt).
@ k_comic_kind_cbr
RAR of images (.cbr).
@ k_comic_kind_none
Not opened / unrecognised.
@ k_comic_magic_len
Bytes read to detect the container magic.
ra8_err_t priv_comic_cbr_extract(comic_t *c, const comic_page_t *p, uint8_t *buf, size_t cap, size_t *got)
Extract one CBR page's encoded image (STORE copy or RAR5 decode).
ra8_err_t priv_comic_cbr_open(comic_t *c)
Open the CBR (RAR) backend: walk the archive + build the page index.
ra8_err_t priv_comic_cbt_open(comic_t *c)
Open the CBT (tar) backend: walk the archive + build the page index.
ra8_err_t priv_comic_cbt_extract(comic_t *c, const comic_page_t *p, uint8_t *buf, size_t cap, size_t *got)
Extract one CBT page's encoded image (verbatim tar member copy).
ra8_err_t priv_comic_cbz_extract(comic_t *c, const comic_page_t *p, uint8_t *buf, size_t cap, size_t *got)
Extract one CBZ page's encoded image through the streaming ZIP reader.
ra8_err_t priv_comic_cbz_close(comic_t *c)
Tear down the CBZ backend's miniz reader.
ra8_err_t priv_comic_cbz_open(comic_t *c)
Open the CBZ (ZIP) backend: init the streaming miniz reader + page index.
Cross-TU seams between the comic facade and its CBZ / CBR backends.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_PRIV
Module-private helper: shared across TUs but only inside one library.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
@ k_ra8_err_not_supported
Requested feature not compiled in, not wired, or not supported by this MCU variant.
@ k_ra8_err_out_of_range
Sensor or peripheral output out of valid range.
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_not_found
Requested item not found (lookup / search missed).
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
ra8_err_t ra8_rar_open(ra8_rar_t *rar, ra8_rar_read_fn read, void *ctx, uint64_t size)
Detect a RAR archive's generation and locate its first block.
One entry in the resident, sorted page index.
uint64_t raw_size
Encoded image length in bytes (decoder input).
uint64_t data_off
CBR: absolute offset of the member data area.
uint64_t pack_size
CBR: packed member size in bytes.
uint8_t extractable
1 if this reader can decode the page's bytes.
uint32_t zip_index
CBZ: miniz central-directory index.
uint16_t name_len
Page name length in bytes.
uint32_t name_off
Offset of the page name in the name arena.
uint8_t rar_method
CBR: ra8_rar_method_t (0 = store); 0 for CBZ.
uint64_t size
Archive length in bytes.
void * ctx
Backing context.
comic_read_fn read
Backing reader (mirrors comic_t::read).
One open comic archive: backing, kind, page index, and backend state.
unarch_tar_t tar
CBT tar walker state.
uint32_t page_count
Populated page count.
uint8_t zip_active
1 = miniz reader is initialised (CBZ).
uint32_t names_len
Bytes used in names.
comic_read_fn read
Byte reader over the archive.
void * ctx
Context for read.
comic_kind_t kind
Detected container kind.
comic_stream_t stream
CBZ miniz I/O descriptor (stable addr).
char * names
Caller name arena.
ra8_rar_t rar
CBR walker state.
uint32_t page_cap
Capacity of pages in entries.
uint64_t size
Archive length in bytes.
comic_page_t * pages
Caller page-index array.
uint32_t names_cap
Capacity of names in bytes.
bool live
Open succeeded and not superseded.
ra8_err_t unarch_tar_open(unarch_tar_t *t, unarch_read_fn read, void *ctx, uint64_t size, const ra8_decomp_limits_t *limits)
Bind a walker to an archive and validate its first header block.