ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_rabook_comic.c
Go to the documentation of this file.
1
12
13#include "ra8_rabook_comic.h"
14
15#include <stddef.h>
16#include <stdint.h>
17
18#include "book.h"
19#include "ra8_attributes.h"
20
36RA8_INTERNAL static bool internal_string_is_bounded(const char* text)
37{
38 if (text == nullptr) {
39 return false;
40 }
41 for (uint16_t i = 0U; i < (uint16_t)k_ra8_rabook_comic_string_max; ++i) {
42 if (text[i] == '\0') {
43 return true;
44 }
45 }
46 return false;
47}
48
67internal_intern(ra8_rabook_ctx_t* builder, const char* text, uint32_t* out_off)
68{
69 const uint32_t off = ra8_rabook_intern(builder, text);
70 if (off == (uint32_t)k_book_nil) {
71 return k_ra8_err_no_mem;
72 }
73 *out_off = off;
74 return k_ra8_ok;
75}
76
96 uint32_t page_id_off)
97{
98 uint32_t body_off = 0U;
99 uint32_t img_off = 0U;
100 uint32_t src_off = 0U;
101 ra8_err_t result = internal_intern(&comic->builder, "body", &body_off);
102 if (result == k_ra8_ok) {
103 result = internal_intern(&comic->builder, "img", &img_off);
104 }
105 if (result == k_ra8_ok) {
106 result = internal_intern(&comic->builder, "src", &src_off);
107 }
108 const book_attr_t source = {.name_off = src_off, .value_off = page_id_off};
109 const uint32_t body = (result == k_ra8_ok)
110 ? ra8_rabook_add_element(&comic->builder, body_off, nullptr, 0U)
111 : (uint32_t)k_book_nil;
112 const uint32_t image = (body != (uint32_t)k_book_nil)
113 ? ra8_rabook_add_element(&comic->builder, img_off, &source, 1U)
114 : (uint32_t)k_book_nil;
115 if ((body == (uint32_t)k_book_nil) || (image == (uint32_t)k_book_nil)) {
116 return (result == k_ra8_ok) ? k_ra8_err_no_mem : result;
117 }
118 result = ra8_rabook_link_child(&comic->builder, body, image);
119 if (result != k_ra8_ok) {
120 return result;
121 }
122 if (ra8_rabook_add_chapter(&comic->builder, page_id_off, page_id_off, body) ==
123 (uint32_t)k_book_nil) {
124 return k_ra8_err_no_mem;
125 }
126 return k_ra8_ok;
127}
128
150 uint32_t page_id_off,
151 const ra8_rabook_raster_result_t* raster)
152{
153 const uint32_t offset = comic->builder.image_pool_size;
154 uint32_t written = 0U;
155 ra8_err_t result =
156 comic->image_write(comic->image_ctx, offset, comic->normalized, raster->encoded_size, &written);
157 if (result != k_ra8_ok) {
158 return result;
159 }
160 if (written != raster->encoded_size) {
162 }
163 uint32_t recorded_offset = 0U;
164 const uint32_t image = ra8_rabook_add_image_external(&comic->builder,
165 page_id_off,
166 raster->width,
167 raster->height,
168 (uint8_t)k_book_image_gray4,
169 raster->pixel_format,
170 raster->encoded_size,
171 &recorded_offset);
172 if (image == (uint32_t)k_book_nil) {
173 return k_ra8_err_no_mem;
174 }
175 if (recorded_offset != offset) {
176 comic->builder.failed = true;
178 }
179 return k_ra8_ok;
180}
181
202 const ra8_rabook_comic_metadata_t* metadata)
203{
204 if (metadata == nullptr) {
205 return k_ra8_err_null_ptr;
206 }
207 if (!internal_string_is_bounded(metadata->title) ||
212 }
213 uint32_t fields[] = {0U, 0U, 0U, 0U};
214 const char* const values[] = {metadata->title,
215 metadata->author,
216 metadata->language,
217 metadata->identifier};
218 for (size_t i = 0U; i < (sizeof(values) / sizeof(values[0])); ++i) {
219 const ra8_err_t result = internal_intern(&comic->builder, values[i], &fields[i]);
220 if (result != k_ra8_ok) {
221 return result;
222 }
223 }
224 return ra8_rabook_set_metadata(&comic->builder, fields[0], fields[1], fields[2], fields[3], 0U);
225}
226
228 const ra8_rabook_comic_workspace_t* workspace,
229 ra8_rabook_image_read_fn image_read,
231 void* image_ctx,
232 uint16_t max_image_edge,
233 uint8_t pixel_format)
234{
235 if (comic == nullptr) {
236 return k_ra8_err_null_ptr;
237 }
238 *comic = (ra8_rabook_comic_t){};
239 if ((workspace == nullptr) || (image_read == nullptr) || (image_write == nullptr) ||
240 (image_ctx == nullptr)) {
241 return k_ra8_err_null_ptr;
242 }
243 if ((workspace->normalized == nullptr) || (workspace->stream_scratch == nullptr)) {
244 return k_ra8_err_null_ptr;
245 }
246 if ((workspace->normalized_cap == 0U) || (workspace->stream_scratch_cap == 0U)) {
248 }
249 if ((pixel_format != (uint8_t)k_book_pixfmt_gray4) &&
250 (pixel_format != (uint8_t)k_book_pixfmt_gray8)) {
252 }
253 ra8_err_t result = rabook_compile_init(&comic->builder, &workspace->builder);
254 if (result == k_ra8_ok) {
255 comic->raster = workspace->raster;
256 comic->image_read = image_read;
257 comic->image_write = image_write;
258 comic->image_ctx = image_ctx;
259 comic->normalized = workspace->normalized;
260 comic->normalized_cap = workspace->normalized_cap;
261 comic->stream_scratch = workspace->stream_scratch;
262 comic->stream_scratch_cap = workspace->stream_scratch_cap;
263 comic->max_image_edge = max_image_edge;
264 comic->pixel_format = pixel_format;
265 comic->active = true;
266 }
267 return result;
268}
269
271 const char* page_id,
272 const uint8_t* source,
273 size_t source_size)
274{
275 if (comic == nullptr) {
276 return k_ra8_err_null_ptr;
277 }
278 if (!comic->active) {
280 }
281 if ((page_id == nullptr) || (source == nullptr) || (source_size == 0U)) {
282 comic->active = false;
284 }
285 if (!internal_string_is_bounded(page_id)) {
286 comic->active = false;
288 }
289 ra8_rabook_raster_result_t raster = {};
290 ra8_err_t result = ra8_rabook_raster_encode(source,
291 source_size,
292 comic->max_image_edge,
293 comic->pixel_format,
294 &comic->raster,
295 comic->normalized,
296 comic->normalized_cap,
297 &raster);
298 uint32_t page_id_off = 0U;
299 if (result == k_ra8_ok) {
300 result = internal_intern(&comic->builder, page_id, &page_id_off);
301 }
302 if (result == k_ra8_ok) {
303 result = internal_store_image(comic, page_id_off, &raster);
304 }
305 if (result == k_ra8_ok) {
306 result = internal_append_chapter(comic, page_id_off);
307 }
308 if (result == k_ra8_ok) {
309 comic->page_count++;
310 } else {
311 comic->active = false;
312 }
313 return result;
314}
315
317 const ra8_rabook_comic_metadata_t* metadata,
319 void* write_ctx,
320 uint32_t* out_len)
321{
322 if (comic == nullptr) {
323 return k_ra8_err_null_ptr;
324 }
325 if (!comic->active) {
327 }
328 comic->active = false;
329 if ((write == nullptr) || (write_ctx == nullptr) || (out_len == nullptr)) {
330 return k_ra8_err_null_ptr;
331 }
332 if (comic->page_count == 0U) {
333 return k_ra8_err_empty;
334 }
335 ra8_err_t result = internal_set_metadata(comic, metadata);
336 if (result == k_ra8_ok) {
337 result = ra8_rabook_finalize_stream(&comic->builder,
338 comic->image_read,
339 comic->image_ctx,
340 write,
341 write_ctx,
342 comic->stream_scratch,
343 comic->stream_scratch_cap,
344 out_len);
345 }
346 return result;
347}
Flat, execute-in-place container for a build-time "compiled" e-book.
@ k_book_nil
Absent index / "applies to all chapters".
Definition book.h:129
@ k_book_image_gray4
4bpp gray, 2px/byte; pixel (x,y) is at flat index y*width + x.
Definition book.h:175
@ k_book_pixfmt_gray4
4bpp packed grayscale, 2px/byte (default; every pre-field blob).
Definition book.h:213
@ k_book_pixfmt_gray8
8bpp grayscale, 1px/byte (lossless against any grey panel).
Definition book.h:215
-proof
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
Definition ra8_err.h:142
@ k_ra8_err_empty
Container empty – nothing to retrieve.
Definition ra8_err.h:222
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_err_validation_failed
Validation rule failed (caller-supplied invariant not satisfied).
Definition ra8_err.h:459
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
Definition ra8_err.h:167
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
ra8_err_t ra8_rabook_comic_init(ra8_rabook_comic_t *comic, const ra8_rabook_comic_workspace_t *workspace, ra8_rabook_image_read_fn image_read, ra8_rabook_comic_write_at_fn image_write, void *image_ctx, uint16_t max_image_edge, uint8_t pixel_format)
Initialize one bounded streaming comic builder.
static bool internal_string_is_bounded(const char *text)
Return whether one bounded string has a NUL terminator.
static ra8_err_t internal_append_chapter(ra8_rabook_comic_t *comic, uint32_t page_id_off)
Append the minimal body/img DOM and one chapter row.
ra8_err_t ra8_rabook_comic_add_page(ra8_rabook_comic_t *comic, const char *page_id, const uint8_t *source, size_t source_size)
Normalize and append one source image as one comic chapter.
static ra8_err_t internal_intern(ra8_rabook_ctx_t *builder, const char *text, uint32_t *out_off)
Intern one string or classify the builder failure.
ra8_err_t ra8_rabook_comic_finish(ra8_rabook_comic_t *comic, const ra8_rabook_comic_metadata_t *metadata, ra8_rabook_write_fn write, void *write_ctx, uint32_t *out_len)
Finalize the completed comic as one canonical flat RABOOK1 stream.
static ra8_err_t internal_set_metadata(ra8_rabook_comic_t *comic, const ra8_rabook_comic_metadata_t *metadata)
Validate and intern all final metadata fields.
static ra8_err_t internal_store_image(ra8_rabook_comic_t *comic, uint32_t page_id_off, const ra8_rabook_raster_result_t *raster)
Store one normalized raster and append its image descriptor.
Streaming image-sequence builder for reader-native RABOOK comics.
ra8_err_t(* ra8_rabook_comic_write_at_fn)(void *ctx, uint32_t offset, const uint8_t *source, uint32_t requested, uint32_t *out_written)
Write normalized image bytes at one logical spool offset.
@ k_ra8_rabook_comic_string_max
Bytes including the terminating NUL.
ra8_err_t ra8_rabook_raster_encode(const uint8_t *source, size_t source_size, uint16_t max_edge, uint8_t pixel_format, ra8_rabook_raster_workspace_t *workspace, uint8_t *encoded, size_t encoded_cap, ra8_rabook_raster_result_t *result)
Decode and normalize one encoded raster into a RABOOK image payload.
uint32_t ra8_rabook_add_element(ra8_rabook_ctx_t *ctx, uint32_t name_off, const book_attr_t *attrs, uint16_t attr_count)
Append an element node with its attributes; return its node index.
ra8_err_t ra8_rabook_link_child(ra8_rabook_ctx_t *ctx, uint32_t parent, uint32_t child)
Set parent's first child to child.
uint32_t ra8_rabook_intern(ra8_rabook_ctx_t *ctx, const char *str)
Intern a NUL-terminated UTF-8 string into the pool, de-duplicated.
ra8_err_t(* ra8_rabook_image_read_fn)(void *ctx, uint32_t offset, uint8_t *dst, uint32_t requested, uint32_t *out_read)
Read bytes from an externally stored image pool.
ra8_err_t ra8_rabook_set_metadata(ra8_rabook_ctx_t *ctx, uint32_t title_off, uint32_t author_off, uint32_t language_off, uint32_t identifier_off, uint32_t cover_image_index)
Record the book metadata offsets that land in the blob header.
ra8_err_t(* ra8_rabook_write_fn)(void *ctx, const uint8_t *src, uint32_t requested, uint32_t *out_written)
Append bytes to a streaming RABOOK1 destination.
uint32_t ra8_rabook_add_image_external(ra8_rabook_ctx_t *ctx, uint32_t id_off, uint16_t width, uint16_t height, uint8_t format, uint8_t pixel_format, uint32_t data_size, uint32_t *out_data_off)
Append an image descriptor whose bytes live in a caller-owned spool.
uint32_t ra8_rabook_add_chapter(ra8_rabook_ctx_t *ctx, uint32_t title_off, uint32_t href_off, uint32_t root_node)
Append a spine chapter; return its chapter index.
ra8_err_t rabook_compile_init(ra8_rabook_ctx_t *ctx, const ra8_rabook_buffers_t *buf)
Bind a builder context to its caller-provided arenas.
ra8_err_t ra8_rabook_finalize_stream(const ra8_rabook_ctx_t *ctx, ra8_rabook_image_read_fn image_read, void *image_ctx, ra8_rabook_write_fn write, void *write_ctx, uint8_t *scratch, uint32_t scratch_cap, uint32_t *out_len)
Stream a canonical flat RABOOK1 blob without a full output arena.
One name="value" attribute on an element.
Definition book.h:317
Header metadata interned when the comic is finalized.
const char * title
Human-readable book title.
const char * author
Human-readable author or source.
const char * identifier
Stable book identifier.
const char * language
BCP-47 language spelling.
Mutable state for one image-sequence-to-RABOOK build.
void * image_ctx
Shared image-spool context.
uint8_t * normalized
One normalized page payload.
uint8_t pixel_format
Gray4 or gray8 output depth.
uint16_t max_image_edge
Optional output edge clamp.
uint32_t page_count
Successfully appended pages.
uint8_t * stream_scratch
Finalizer transfer scratch.
uint32_t stream_scratch_cap
Finalizer scratch capacity.
bool active
Build accepts more operations.
size_t normalized_cap
Normalized output capacity.
ra8_rabook_raster_workspace_t raster
Retained raster workspace.
ra8_rabook_ctx_t builder
Canonical table builder.
ra8_rabook_image_read_fn image_read
Repeatable image-spool reader.
ra8_rabook_comic_write_at_fn image_write
Image-spool random writer.
Caller-owned arenas retained for one streaming comic build.
uint8_t * stream_scratch
Finalizer transfer scratch.
size_t normalized_cap
Writable normalized bytes.
uint8_t * normalized
One normalized page payload.
uint32_t stream_scratch_cap
Finalizer scratch bytes.
ra8_rabook_raster_workspace_t raster
Codec and scaling arenas.
ra8_rabook_buffers_t builder
Resident table/string arenas.
Builder state: the arenas plus running counts and a sticky-fail flag.
bool failed
Sticky: an arena overflowed.
uint32_t image_pool_size
Image-pool bytes used.
Geometry and byte count of a normalized RABOOK raster payload.
uint16_t height
Output height in pixels.
uint32_t encoded_size
Bytes written to the encoded destination.
uint8_t pixel_format
book_image_pixfmt_t emitted.
uint16_t width
Output width in pixels.