52typedef enum : uint32_t {
92[[gnu::section(
".sdram_data"),
105 if ((s ==
nullptr) || (buf ==
nullptr) || (off >= (uint64_t)s->
n)) {
108 const uint64_t avail = (uint64_t)s->
n - off;
109 const size_t k = (len > (size_t)avail) ? (
size_t)avail : len;
110 (void)
memcpy(buf, &s->
d[off], k);
117 const uint8_t* b = (
const uint8_t*)p;
119 for (
size_t i = 0U; i < n; ++i) {
140 g_sh.comic_page = 0U;
141 return g_sh.comic_count > 0U;
153 if ((
g_sh.comic_count == 0U) || (page >=
g_sh.comic_count)) {
165 if (out_w !=
nullptr) {
168 if (out_h !=
nullptr) {
177 if (idx >=
g_sh.book_count) {
212 g_sh.comic_count = 0U;
213 g_sh.comic_page = 0U;
233 const char* dir =
g_sh.comic_rtl ?
"RTL" :
"LTR";
234 for (
const char* s = dir; *s !=
'\0'; ++s) {
245 const char* msg =
"Unable to render this page";
261 }
else if (x >= ((int32_t)
k_sh_fb_w - third)) {
265 return g_sh.comic_rtl ? -base : base;
270 const uint32_t n =
g_sh.comic_count;
274 if ((dir > 0) && ((
g_sh.comic_page + 1U) < n)) {
275 g_sh.comic_page += 1U;
278 if ((dir < 0) && (
g_sh.comic_page > 0U)) {
279 g_sh.comic_page -= 1U;
337 if ((cbz ==
nullptr) || (cbr ==
nullptr) || (rtl_ok ==
nullptr)) {
343 const bool saved =
g_sh.comic_rtl;
344 const int32_t right = (int32_t)
k_sh_fb_w - 1;
345 g_sh.comic_rtl =
false;
348 g_sh.comic_rtl =
true;
351 g_sh.comic_rtl = saved;
352 *rtl_ok = (ltr_right == 1) && (ltr_left == -1) && (rtl_right == -1) && (rtl_left == 1);
365 if ((b ==
nullptr) || (pos ==
nullptr) || (cbz ==
nullptr) || (cbr ==
nullptr)) {
369 const char*
const tag[] = {
" cbz=",
" cbr="};
370 for (uint32_t i = 0U; i < (uint32_t)(
sizeof(set) /
sizeof(set[0])); ++i) {
372 for (
const char* s = tag[i]; *s !=
'\0'; ++s) {
390 const char* rtl = rtl_ok ?
" rtl=OK" :
" rtl=NO";
392 for (
const char* s = rtl; *s !=
'\0'; ++s) {
static uint8_t s_arena[k_c6_cam_arena_bytes]
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.
size_t(* comic_read_fn)(void *ctx, uint64_t offset, void *buf, size_t len)
Seek+read backing over the comic-archive bytes.
ra8_err_t comic_close(comic_t *c)
Release an open comic's backend resources.
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 uint8_t s_blob[(size_t) k_demo_blob_cap]
@ k_ra8_err_out_of_range
Sensor or peripheral output out of valid range.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
size_t strlen(const char *s)
Calculate string length.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
Software 2D graphics primitives layered on top of a caller-ownedframebuffer (DRW / D/AVE 2D / GLCDC r...
@ k_ra8_gfx_format_rgb565
16-bit RGB565, little-endian in memory.
ra8_err_t ra8_gfx_clear(uint32_t color)
Fill the bound framebuffer's clip region with a single colour.
ra8_err_t ra8_gfx_text_out(int32_t x, int32_t y, const char *str, const ra8_gfx_font_t *font, uint32_t fg_color, uint32_t bg_color)
Render a NUL-terminated ASCII string.
ra8_err_t ra8_gfx_init(void *fb, uint16_t width, uint16_t height, ra8_gfx_format_t format)
Bind ra8_gfx to a caller-owned framebuffer.
Bitmap font descriptor + bundled font handles for ra8_gfx.
const ra8_gfx_font_t ra8_gfx_font_8x16
Bundled 8x16 IBM PC VGA bitmap font, ASCII 0x20..0x7E.
Zero-heap raster image decode + scale + blit for reflow (#106).
ra8_err_t ra8_img_decode_blit(ra8_img_arena_t *arena, const uint8_t *bytes, size_t len, int32_t dst_x, int32_t dst_y, int32_t box_w, int32_t box_h, int32_t *out_w, int32_t *out_h)
Decode bytes and blit it, scaled to fit, into the bound framebuffer.
Shared contract for the ereader_shelf multi-screen e-reader.
@ k_sh_screen_shelf
Book grid with cover thumbnails.
bool sh_sd_book_open(const char *name, uint32_t *out_len)
Open SD file name and hold it as the paged book backing.
void sh_titlebar(const char *title, const char *right)
Fill the header bar and draw title left + optional right text.
size_t sh_sd_comic_read(void *ctx, uint64_t offset, void *buf, size_t len)
comic_read_fn over the held-open SD book file (seek + clamped read).
@ k_sh_fb_h
Panel height in pixels.
@ k_sh_glyph_w
Bitmap font cell width.
@ k_sh_bar_h
Header / title-bar height.
@ k_sh_linebuf
Per-line draw buffer bytes.
@ k_sh_fb_w
Panel width in pixels.
@ k_sh_dec_base
Decimal formatting base.
size_t sh_fmt_uint(char *dst, size_t pos, uint32_t v)
Append unsigned v as decimal into dst at pos; returns new pos.
void sh_sd_book_close(void)
Close the held SD book file (idempotent).
sh_state_t g_sh
The single whole-app state instance (defined in main.c).
uint16_t * sh_fb_pixels(void)
The live RGB565 framebuffer ra8_gfx scans (defined in main.c).
@ k_sh_col_sub
Secondary ink (author / hints).
static bool sh_fmt_is_comic(sh_book_fmt_t fmt)
True if fmt is a comic-archive container (CBZ, CBR, or CBT).
bool sh_comic_tap(int32_t x, bool header)
Handle a comic-screen tap: header returns to the shelf, else page-turn.
void sh_comic_render(void)
Render the current comic page full-screen (title bar + fitted image).
static bool sh_comic_bind(comic_read_fn rd, void *ctx, uint64_t size)
Bind comic over rd + set g_sh.comic_count / page; ok on success.
void sh_comic_selfcheck(sh_comic_probe_t *cbz, sh_comic_probe_t *cbr, bool *rtl_ok)
Headless boot self-check: decode the baked CBZ + CBR page 0, verify RTL.
bool sh_comic_turn(int32_t dir)
Turn the comic page by dir in reading order, clamped to the ends.
static comic_t s_comic
The open comic (large: page-index storage + backend scratch).
void sh_comic_close(void)
Close any open comic and release its backing (idempotent).
static size_t sh_comic_blob_read(void *ctx, uint64_t off, void *buf, size_t len)
comic_read_fn over a resident archive buffer (bounds-clamped).
void sh_comic_toggle_rtl(void)
Flip the comic reading direction (LTR <-> RTL); page index unchanged.
int32_t sh_comic_edge_dir(int32_t x)
Map a comic-screen edge tap to a reading-order page delta (RTL-aware).
void sh_comic_append_banner(char *b, size_t *pos, const sh_comic_probe_t *cbz, const sh_comic_probe_t *cbr, bool rtl_ok)
Append " cbz=P:WxH:CRC cbr=P:WxH:CRC rtl=OK" to the boot banner buffer.
static uint32_t sh_comic_fnv(const void *p, size_t n)
FNV-1a-32 over n bytes of p.
static char s_names[k_shc_names_cap]
Caller-owned page-name arena.
static comic_page_t s_pages[k_shc_page_cap]
Caller-owned sorted page index.
static uint16_t s_probe_rgb[(size_t) k_shc_probe_h *(size_t) k_shc_probe_w]
Off-screen RGB565 scratch for the deterministic self-check decode.
static ra8_err_t sh_comic_blit_page(uint32_t page, int32_t x, int32_t y, int32_t w, int32_t h, int32_t *out_w, int32_t *out_h)
Extract page page's encoded bytes and decode+blit into the box.
static int32_t sh_comic_center_x(const char *s)
Centre-align s horizontally for the 8px bitmap font.
static sh_comic_probe_t sh_comic_probe_blob(const uint8_t *blob, uint32_t len)
Open blob, decode its page 0 into the scratch, hash it; then close.
static bool s_from_sd
true when the open comic's backing is a held SD file (close it too).
static uint8_t s_pagebuf[k_shc_pagebuf_cap]
One page's extracted encoded image (the decoder input).
sh_comic_const_t
Comic reader buffer + layout constants.
@ k_shc_probe_bg
Self-check clear colour (matches.
@ k_shc_nib_mask
Low-nibble mask.
@ k_shc_thirds
Edge-tap split (left/centre/right).
@ k_shc_hex_digits
Hex digits in a 32-bit CRC.
@ k_shc_probe_h
Self-check scratch height, pixels.
@ k_shc_nib_bits
Bits per hex nibble.
@ k_shc_probe_w
Self-check scratch width, pixels.
@ k_shc_fnv_prime
FNV-1a-32 prime.
@ k_shc_live_bg
Live comic backdrop (near-black).
@ k_shc_fnv_offset
FNV-1a-32 offset basis.
@ k_shc_arena_cap
stb_image decode bump arena bytes.
@ k_shc_page_cap
Max pages in the sorted index.
@ k_shc_pagebuf_cap
One encoded page image, bytes.
@ k_shc_names_cap
Page-name arena bytes.
bool sh_comic_open(uint16_t idx)
Open shelf entry idx as a comic archive (CBZ / CBR) for page reading.
Baked CBZ + CBR comic fixtures for the ereader_shelf comic self-check.
static const uint32_t k_comic_cbz_len
static const uint8_t k_comic_cbr[]
Baked 401-byte comic fixture.
static const uint8_t k_comic_cbz[]
Baked 576-byte comic fixture.
static const uint32_t k_comic_cbr_len
One entry in the resident, sorted page index.
One open comic archive: backing, kind, page index, and backend state.
Caller-owned bump arena backing a single image decode.
Resident-buffer backing for the comic reader's seek+read seam.
const uint8_t * d
Archive bytes.
One container's headless self-check result (page 0 decode digest).
uint32_t pages
Page count parsed from the archive.
bool ok
true if page 0 opened + decoded successfully.
int32_t w
Blitted (fitted) page width in pixels.
int32_t h
Blitted (fitted) page height in pixels.
uint32_t crc
FNV-1a-32 over the decoded scratch framebuffer.
One shelf book, sourced from MRAM (baked) or the SD card, in either the .rabook or ....
bool from_sd
true: read sd_name from SD; false: use blob.
const uint8_t * blob
Baked RBKC bytes (MRAM), or NULL when SD.
uint32_t blob_len
Baked length, or SD file size in bytes.
char sd_name[k_sh_name_cap]
SD file name, e.g.
sh_book_fmt_t fmt
Container format (rabook / epub).