ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
comic_cbr.c
Go to the documentation of this file.
1
28#include <stddef.h>
29#include <stdint.h>
30
31#include "comic.h"
32#include "comic_internal.h"
33#include "ra8_attributes.h"
34#include "ra8_check.h"
35#include "ra8_decomp_limits.h"
36#include "ra8_rar.h"
37
39static const char* const s_tag_cbr = "comic_cbr";
40
49typedef enum : uint32_t {
51 k_cbr_max_blocks = 100000U,
53
75static ra8_err_t
76internal_add_member(comic_t* c, const ra8_rar_entry_t* ent, const char* name, uint16_t nlen)
77{
78 if (ent->is_file == 0U) {
79 return k_ra8_ok;
80 }
81 if (ent->is_dir != 0U) {
82 return k_ra8_ok;
83 }
84 if (!priv_comic_is_page_name(name, nlen)) {
85 return k_ra8_ok;
86 }
87 /* Decompression-limits guard: a page whose block header declares an
88 * over-cap or bomb-ratio size rejects the whole archive before any
89 * decode (the same policy every decoder enforces). */
91 const ra8_err_t derr = ra8_decomp_check_declared(&lim, ent->pack_size, ent->unp_size);
92 if (derr != k_ra8_ok) {
93 return derr;
94 }
95 const bool is_store = (ent->method == (uint8_t)k_ra8_rar_method_store);
96 const bool is_rar5 = (c->rar.version == k_ra8_rar_ver_5);
97 /* STORE always decodes; a compressed member decodes only on RAR5 (the RAR4
98 * legacy codec is out of scope), so a RAR4-compressed page stays inert. */
99 const uint8_t extractable = (is_store || is_rar5) ? 1U : 0U;
100 return priv_comic_page_add(c,
101 name,
102 nlen,
103 ent->unp_size,
104 extractable,
105 ent->method,
106 0U,
107 ent->data_off,
108 ent->pack_size);
109}
110
112{
113 RA8_CHECK_NULL_PTR(c, s_tag_cbr, "cbr open: null c");
114 if (c->rar.version == k_ra8_rar_ver_none) {
116 }
117 /* Decompression-limits budget for the whole enumeration: every walked
118 * block charges the entry cap, so the many-tiny-blocks bomb dies within
119 * policy long before the static loop cap. Direct field bind (not
120 * ra8_decomp_budget_init) because the default policy cannot fail
121 * validation and the counters start zeroed. */
122 ra8_decomp_budget_t budget = {};
124 uint64_t off = c->rar.first_off;
125 for (uint32_t n = 0U; n < (uint32_t)k_cbr_max_blocks; ++n) {
126 if (off >= c->rar.size) {
127 break;
128 }
129 const ra8_err_t ce = ra8_decomp_budget_charge_entry(&budget);
130 if (ce != k_ra8_ok) {
131 return ce; /* block-flood bomb: reject the archive */
132 }
133 char nb[k_cbr_name_max] = {};
134 ra8_rar_entry_t ent = {};
135 if (ra8_rar_next(&c->rar, off, nb, (uint16_t)sizeof(nb), &ent) != k_ra8_ok) {
136 /* Tolerate trailing junk and let the loop's sole exit handle it. */
137 off = c->rar.size;
138 continue;
139 }
140 const ra8_err_t ae = internal_add_member(c, &ent, nb, ent.name_len);
141 if (ae != k_ra8_ok) {
142 return ae; /* capacity / policy breach -- a real error, propagate */
143 }
144 off = ent.next_off;
145 }
146 return k_ra8_ok;
147}
148
150priv_comic_cbr_extract(comic_t* c, const comic_page_t* p, uint8_t* buf, size_t cap, size_t* got)
151{
152 RA8_CHECK_NULL_PTR(c, s_tag_cbr, "cbr extract: null c");
153 RA8_CHECK_NULL_PTR(p, s_tag_cbr, "cbr extract: null p");
154 RA8_CHECK_NULL_PTR(buf, s_tag_cbr, "cbr extract: null buf");
155 RA8_CHECK_NULL_PTR(got, s_tag_cbr, "cbr extract: null got");
156 *got = 0U;
157 if (c->rar.version == k_ra8_rar_ver_none) {
159 }
160 if (p->extractable == 0U) {
162 }
163 ra8_rar_entry_t ent = {};
164 ent.is_file = 1U;
165 ent.is_dir = 0U;
166 ent.method = p->rar_method;
167 ent.data_off = p->data_off;
168 ent.pack_size = p->pack_size;
169 ent.unp_size = p->raw_size;
170 return ra8_rar_extract(&c->rar, &ent, buf, cap, &c->rar5_state, got);
171}
bool priv_comic_is_page_name(const char *name, uint16_t len)
Whether an archive entry name is a decodable comic page image.
Definition comic.c:152
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.
Definition comic.c:177
Unified demand-paged reader for comic-book archives – CBZ (ZIP) and CBR (RAR).
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).
Definition comic_cbr.c:150
cbr_limits_t
Name scratch size and the hard block-walk bound.
Definition comic_cbr.c:49
@ k_cbr_max_blocks
Static upper bound on blocks walked.
Definition comic_cbr.c:51
@ k_cbr_name_max
Longest member name indexed (bytes, incl.
Definition comic_cbr.c:50
static const char *const s_tag_cbr
Log tag for CBR-backend diagnostics.
Definition comic_cbr.c:39
static ra8_err_t internal_add_member(comic_t *c, const ra8_rar_entry_t *ent, const char *name, uint16_t nlen)
Index one RAR block if it is a decodable page-image file member.
Definition comic_cbr.c:76
ra8_err_t priv_comic_cbr_open(comic_t *c)
Open the CBR (RAR) backend: walk the archive + build the page index.
Definition comic_cbr.c:111
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.
Definition ra8_check.h:243
Unified decompression-limits policy: one bound set for every decoder.
ra8_decomp_limits_t ra8_decomp_limits_default(void)
The owner-approved default decompression policy.
ra8_err_t ra8_decomp_check_declared(const ra8_decomp_limits_t *limits, uint64_t comp_size, uint64_t out_size)
Header-level check of a member's declared sizes against a policy.
ra8_err_t ra8_decomp_budget_charge_entry(ra8_decomp_budget_t *b)
Charge one enumerated archive entry against the entry cap.
@ k_ra8_err_not_supported
Requested feature not compiled in, not wired, or not supported by this MCU variant.
Definition ra8_err.h:180
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Clean-room, read-only RAR archive walker (RAR4 + RAR5 headers, STORE data).
ra8_err_t ra8_rar_next(const ra8_rar_t *rar, uint64_t off, char *name_buf, uint16_t name_cap, ra8_rar_entry_t *out)
Decode the block header at off and advance to the next block.
Definition ra8_rar.c:682
@ k_ra8_rar_ver_none
Not a recognised RAR archive.
Definition ra8_rar.h:98
@ k_ra8_rar_ver_5
RAR 5.0 block format ("RAR5").
Definition ra8_rar.h:100
ra8_err_t ra8_rar_extract(const ra8_rar_t *rar, const ra8_rar_entry_t *ent, uint8_t *buf, size_t cap, ra8_rar5_state_t *st, size_t *got)
Extract any file member – STORE by copy, RAR5-compressed by decode.
Definition ra8_rar.c:840
@ k_ra8_rar_method_store
Uncompressed: data area is the file bytes.
Definition ra8_rar.h:112
One entry in the resident, sorted page index.
Definition comic.h:140
uint64_t raw_size
Encoded image length in bytes (decoder input).
Definition comic.h:148
uint64_t data_off
CBR: absolute offset of the member data area.
Definition comic.h:146
uint64_t pack_size
CBR: packed member size in bytes.
Definition comic.h:147
uint8_t extractable
1 if this reader can decode the page's bytes.
Definition comic.h:143
uint8_t rar_method
CBR: ra8_rar_method_t (0 = store); 0 for CBZ.
Definition comic.h:144
One open comic archive: backing, kind, page index, and backend state.
Definition comic.h:179
ra8_rar_t rar
CBR walker state.
Definition comic.h:190
ra8_rar5_state_t rar5_state
CBR RAR5 decompressor scratch (no heap).
Definition comic.h:191
Running consumption tracker charged by a decoder against its policy.
ra8_decomp_limits_t limits
Policy in force for this budget.
One decompression policy: the five resource bounds decoders enforce.
One decoded RAR block: a file member, a directory, or a skipped block.
Definition ra8_rar.h:169
uint8_t method
ra8_rar_method_t (normalised; 0 = store).
Definition ra8_rar.h:175
uint8_t is_file
1 if this block is a file member header.
Definition ra8_rar.h:176
uint64_t unp_size
Unpacked length, bytes.
Definition ra8_rar.h:172
uint64_t data_off
Absolute offset of the member's data area.
Definition ra8_rar.h:170
uint64_t next_off
Absolute offset of the next block header.
Definition ra8_rar.h:173
uint16_t name_len
Name bytes copied into the caller buffer (clamped).
Definition ra8_rar.h:174
uint8_t is_dir
1 if the file member is a directory entry.
Definition ra8_rar.h:177
uint64_t pack_size
Packed (stored/compressed) data length, bytes.
Definition ra8_rar.h:171
uint64_t size
Container length in bytes.
Definition ra8_rar.h:147
uint64_t first_off
Offset of the first block past the signature.
Definition ra8_rar.h:148
ra8_rar_version_t version
Detected container generation.
Definition ra8_rar.h:149