ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
jof.c
Go to the documentation of this file.
1
18
19#include "jof.h"
20
21#include <stddef.h>
22#include <stdint.h>
23#include <string.h>
24
25#include "ra8_attributes.h"
26#include "ra8_check.h"
27#include "ra8_compress.h"
28#include "ra8_err.h"
29
31static const char* const s_tag = "jof";
32
37typedef enum : uint8_t {
45} jof_le_t;
46
51typedef enum : uint16_t {
55
56/* ---------------------------------------------------------------------------
57 * Small pure helpers.
58 * ---------------------------------------------------------------------------
59 */
60
76RA8_INTERNAL static uint16_t internal_rd_u16(const uint8_t* buf, uint8_t off)
77{
78 return (uint16_t)((uint16_t)buf[off + k_jof_le_b0] |
79 (uint16_t)((uint16_t)buf[off + k_jof_le_b1] << k_jof_le_sh8));
80}
81
97RA8_INTERNAL static uint32_t internal_rd_u32(const uint8_t* buf, uint8_t off)
98{
99 return (uint32_t)buf[off + k_jof_le_b0] | ((uint32_t)buf[off + k_jof_le_b1] << k_jof_le_sh8) |
100 ((uint32_t)buf[off + k_jof_le_b2] << k_jof_le_sh16) |
101 ((uint32_t)buf[off + k_jof_le_b3] << k_jof_le_sh24);
102}
103
119RA8_INTERNAL static uint32_t internal_ceil_div(uint32_t n, uint32_t d)
120{
121 return (n + d - 1U) / d;
122}
123
145internal_pread_exact(jof_pread_fn pread, void* pread_ctx, uint64_t off, uint8_t* buf, size_t len)
146{
147 size_t got = 0U;
148 const ra8_err_t err = pread(pread_ctx, off, buf, len, &got);
149 if (err != k_ra8_ok) {
150 return err;
151 }
152 if (got != len) {
154 }
155 return k_ra8_ok;
156}
157
158/* ---------------------------------------------------------------------------
159 * Memstore sink / pread.
160 * ---------------------------------------------------------------------------
161 */
162
163ra8_err_t jof_memstore_sink(void* ctx, const uint8_t* buf, size_t len)
164{
165 RA8_CHECK_NULL_PTR(ctx, s_tag, "ctx must not be nullptr");
166 RA8_CHECK_NULL_PTR(buf, s_tag, "buf must not be nullptr");
167 jof_memstore_t* store = (jof_memstore_t*)ctx;
168 RA8_CHECK_NULL_PTR(store->buf, s_tag, "store->buf must not be nullptr");
169 if (len > (store->cap - store->len)) {
170 return k_ra8_err_no_mem;
171 }
172 (void)memcpy(&store->buf[store->len], buf, len);
173 store->len += len;
174 return k_ra8_ok;
175}
176
177ra8_err_t jof_memstore_pread(void* ctx, uint64_t offset, uint8_t* buf, size_t len, size_t* got)
178{
179 RA8_CHECK_NULL_PTR(ctx, s_tag, "ctx must not be nullptr");
180 RA8_CHECK_NULL_PTR(buf, s_tag, "buf must not be nullptr");
181 RA8_CHECK_NULL_PTR(got, s_tag, "got must not be nullptr");
182 *got = 0U;
183 jof_memstore_t* store = (jof_memstore_t*)ctx;
184 RA8_CHECK_NULL_PTR(store->buf, s_tag, "store->buf must not be nullptr");
185 if (offset >= (uint64_t)store->len) {
186 return k_ra8_ok; /* at/after end: 0-byte read, mirrors entry pread */
187 }
188 const size_t avail = store->len - (size_t)offset;
189 const size_t take = (len < avail) ? len : avail;
190 (void)memcpy(buf, &store->buf[(size_t)offset], take);
191 *got = take;
192 return k_ra8_ok;
193}
194
195/* ---------------------------------------------------------------------------
196 * Parse + validate.
197 * ---------------------------------------------------------------------------
198 */
199
218{
219 info->width = internal_rd_u16(hdr, (uint8_t)k_jof_ofs_width);
220 info->height = internal_rd_u16(hdr, (uint8_t)k_jof_ofs_height);
221 info->tile_w = internal_rd_u16(hdr, (uint8_t)k_jof_ofs_tile_w);
222 info->tile_h = internal_rd_u16(hdr, (uint8_t)k_jof_ofs_tile_h);
223 info->bpp = hdr[k_jof_ofs_bpp];
224 info->codec = hdr[k_jof_ofs_codec];
225 if (info->width == 0U) {
227 }
228 if ((uint32_t)info->width > (uint32_t)k_jof_max_dim) {
230 }
231 if (info->height == 0U) {
233 }
234 if ((uint32_t)info->height > (uint32_t)k_jof_max_dim) {
236 }
237 if (info->tile_w == 0U) {
239 }
240 if (info->tile_h == 0U) {
242 }
243 /* bpp 1 (gray8), 3 (RGB888) or 4 (RGBA8888); 2 is not a defined layout. */
244 if ((info->bpp == 0U) || (info->bpp == 2U) || ((uint32_t)info->bpp > (uint32_t)k_jof_bpp_max)) {
246 }
247 if (info->codec > (uint8_t)k_jof_codec_deflate) {
249 }
250 return k_ra8_ok;
251}
252
269{
270 for (uint8_t i = (uint8_t)k_jof_ofs_reserved; i < (uint8_t)k_jof_ofs_tile_count; ++i) {
271 if (hdr[i] != 0U) {
273 }
274 }
275 for (uint8_t i = (uint8_t)k_jof_ofs_reserved2; i < (uint8_t)k_jof_hdr_bytes; ++i) {
276 if (hdr[i] != 0U) {
278 }
279 }
280 return k_ra8_ok;
281}
282
303internal_check_cross(jof_info_t* info, uint32_t hdr_count, const uint8_t* ftr, uint64_t total_size)
304{
305 const uint32_t cols = internal_ceil_div(info->width, info->tile_w);
306 const uint32_t rows = internal_ceil_div(info->height, info->tile_h);
307 const uint32_t want = cols * rows;
308 if (want > (uint32_t)k_jof_max_tiles) {
310 }
311 if (hdr_count != want) {
313 }
314 const uint32_t ftr_count = internal_rd_u32(ftr, (uint8_t)k_jof_ftr_tile_count);
315 const uint32_t ftr_total = internal_rd_u32(ftr, (uint8_t)k_jof_ftr_total_size);
316 const uint32_t index_off = internal_rd_u32(ftr, (uint8_t)k_jof_ftr_index_off);
317 if (ftr_count != want) {
319 }
320 if ((uint64_t)ftr_total != total_size) {
322 }
323 if (index_off < (uint32_t)k_jof_hdr_bytes) {
325 }
326 const uint64_t index_end = (uint64_t)index_off + ((uint64_t)want * (uint64_t)k_jof_index_entry) +
327 (uint64_t)k_jof_footer_bytes;
328 if (index_end != total_size) {
330 }
331 info->tile_cols = (uint16_t)cols;
332 info->tile_rows = (uint16_t)rows;
333 info->tile_count = want;
334 info->index_off = index_off;
335 info->total_size = ftr_total;
336 return k_ra8_ok;
337}
338
360 void* pread_ctx,
361 uint8_t* hdr,
362 jof_info_t* out_info)
363{
364 static const uint8_t s_magic_hdr[k_jof_magic_len] = {'J', 'O', 'F', '1'};
365 ra8_err_t err = internal_pread_exact(pread, pread_ctx, 0U, hdr, (size_t)k_jof_hdr_bytes);
366 if (err != k_ra8_ok) {
367 return err;
368 }
369 if (memcmp(&hdr[k_jof_ofs_magic], s_magic_hdr, sizeof(s_magic_hdr)) != 0) {
371 }
372 err = internal_parse_hdr_fields(hdr, out_info);
373 if (err != k_ra8_ok) {
374 return err;
375 }
376 return internal_check_reserved(hdr);
377}
378
379ra8_err_t jof_parse(jof_pread_fn pread, void* pread_ctx, uint64_t total_size, jof_info_t* out_info)
380{
381 static const uint8_t s_magic_ftr[k_jof_magic_len] = {'J', 'O', 'F', 'E'};
382 RA8_CHECK_NULL_PTR(pread, s_tag, "pread must not be nullptr");
383 RA8_CHECK_NULL_PTR(out_info, s_tag, "out_info must not be nullptr");
384 const uint64_t min_size = (uint64_t)k_jof_hdr_bytes + (uint64_t)k_jof_footer_bytes;
385 if ((total_size < min_size) || (total_size > (uint64_t)UINT32_MAX)) {
387 }
388 uint8_t hdr[k_jof_hdr_bytes] = {};
389 ra8_err_t err = internal_parse_header_region(pread, pread_ctx, hdr, out_info);
390 if (err != k_ra8_ok) {
391 return err;
392 }
393 uint8_t ftr[k_jof_footer_bytes] = {};
394 err = internal_pread_exact(pread,
395 pread_ctx,
396 total_size - (uint64_t)k_jof_footer_bytes,
397 ftr,
398 sizeof(ftr));
399 if (err != k_ra8_ok) {
400 return err;
401 }
402 if (memcmp(&ftr[k_jof_ftr_magic], s_magic_ftr, sizeof(s_magic_ftr)) != 0) {
404 }
405 const uint32_t hdr_count = internal_rd_u32(hdr, (uint8_t)k_jof_ofs_tile_count);
406 return internal_check_cross(out_info, hdr_count, ftr, total_size);
407}
408
409/* ---------------------------------------------------------------------------
410 * Tile access.
411 * ---------------------------------------------------------------------------
412 */
413
415 uint16_t tile_x,
416 uint16_t tile_y,
417 uint16_t* out_w,
418 uint16_t* out_h)
419{
420 RA8_CHECK_NULL_PTR(info, s_tag, "info must not be nullptr");
421 RA8_CHECK_NULL_PTR(out_w, s_tag, "out_w must not be nullptr");
422 RA8_CHECK_NULL_PTR(out_h, s_tag, "out_h must not be nullptr");
423 if (tile_x >= info->tile_cols) {
425 }
426 if (tile_y >= info->tile_rows) {
428 }
429 const uint32_t px = (uint32_t)tile_x * (uint32_t)info->tile_w;
430 const uint32_t py = (uint32_t)tile_y * (uint32_t)info->tile_h;
431 const uint32_t rest_w = (uint32_t)info->width - px;
432 const uint32_t rest_h = (uint32_t)info->height - py;
433 *out_w = (uint16_t)((rest_w < (uint32_t)info->tile_w) ? rest_w : (uint32_t)info->tile_w);
434 *out_h = (uint16_t)((rest_h < (uint32_t)info->tile_h) ? rest_h : (uint32_t)info->tile_h);
435 return k_ra8_ok;
436}
437
439uint32_t jof_stored_bound(uint32_t raw_bytes)
440{
441 return raw_bytes + (raw_bytes / (uint32_t)k_jof_bound_div) + (uint32_t)k_jof_bound_add;
442}
443
469 void* pread_ctx,
470 const jof_info_t* info,
471 uint32_t n,
472 uint32_t* out_off,
473 uint32_t* out_len)
474{
475 uint8_t entry[k_jof_index_entry] = {};
476 const uint64_t eoff = (uint64_t)info->index_off + ((uint64_t)n * (uint64_t)k_jof_index_entry);
477 const ra8_err_t err = internal_pread_exact(pread, pread_ctx, eoff, entry, sizeof(entry));
478 if (err != k_ra8_ok) {
479 return err;
480 }
481 const uint32_t toff = internal_rd_u32(entry, (uint8_t)k_jof_idx_ofs_offset);
482 const uint32_t tlen = internal_rd_u32(entry, (uint8_t)k_jof_idx_ofs_length);
483 const uint64_t tend = (uint64_t)toff + (uint64_t)tlen;
484 if ((toff < (uint32_t)k_jof_hdr_bytes) || (tend > (uint64_t)info->index_off)) {
486 }
487 *out_off = toff;
488 *out_len = tlen;
489 return k_ra8_ok;
490}
491
522 void* pread_ctx,
523 const jof_info_t* info,
524 uint32_t toff,
525 uint32_t tlen,
526 uint32_t payload,
527 uint8_t* scratch,
528 uint32_t scratch_cap,
529 uint8_t* out_px)
530{
531 if (info->codec == (uint8_t)k_jof_codec_raw) {
532 if (tlen != payload) {
534 }
535 return internal_pread_exact(pread, pread_ctx, toff, out_px, payload);
536 }
537 RA8_CHECK_NULL_PTR(scratch, s_tag, "scratch must not be nullptr for deflate");
538 if (tlen > scratch_cap) {
540 }
541 const ra8_err_t err = internal_pread_exact(pread, pread_ctx, toff, scratch, tlen);
542 if (err != k_ra8_ok) {
543 return err;
544 }
545 uint32_t got = 0U;
546 if (ra8_decompress(scratch, tlen, out_px, payload, &got) != k_ra8_ok) {
548 }
549 if (got != payload) {
551 }
552 return k_ra8_ok;
553}
554
579 void* pread_ctx,
580 const jof_info_t* info,
581 uint32_t n,
582 uint32_t payload,
583 uint8_t* scratch,
584 uint32_t scratch_cap,
585 uint8_t* out_px)
586{
587 uint32_t toff = 0U;
588 uint32_t tlen = 0U;
589 const ra8_err_t err = internal_index_entry(pread, pread_ctx, info, n, &toff, &tlen);
590 if (err != k_ra8_ok) {
591 return err;
592 }
593 return internal_decode_stream(pread,
594 pread_ctx,
595 info,
596 toff,
597 tlen,
598 payload,
599 scratch,
600 scratch_cap,
601 out_px);
602}
603
624 const jof_info_t* info,
625 const uint8_t* out_px,
626 const uint16_t* out_w,
627 const uint16_t* out_h)
628{
629 RA8_CHECK_NULL_PTR(pread, s_tag, "pread must not be nullptr");
630 RA8_CHECK_NULL_PTR(info, s_tag, "info must not be nullptr");
631 RA8_CHECK_NULL_PTR(out_px, s_tag, "out_px must not be nullptr");
632 RA8_CHECK_NULL_PTR(out_w, s_tag, "out_w must not be nullptr");
633 RA8_CHECK_NULL_PTR(out_h, s_tag, "out_h must not be nullptr");
634 return k_ra8_ok;
635}
636
638 void* pread_ctx,
639 const jof_info_t* info,
640 uint16_t tile_x,
641 uint16_t tile_y,
642 uint8_t* scratch,
643 uint32_t scratch_cap,
644 uint8_t* out_px,
645 uint32_t out_cap,
646 uint16_t* out_w,
647 uint16_t* out_h)
648{
649 const ra8_err_t nz = internal_read_args_ok(pread, info, out_px, out_w, out_h);
650 if (nz != k_ra8_ok) {
651 return nz;
652 }
653 uint16_t tw = 0U;
654 uint16_t th = 0U;
655 ra8_err_t err = jof_tile_dims(info, tile_x, tile_y, &tw, &th);
656 if (err != k_ra8_ok) {
657 return err;
658 }
659 const uint32_t payload = (uint32_t)tw * (uint32_t)th * (uint32_t)info->bpp;
660 if (payload > out_cap) {
662 }
663 const uint32_t n = ((uint32_t)tile_y * (uint32_t)info->tile_cols) + (uint32_t)tile_x;
664 err = internal_fetch_decode(pread, pread_ctx, info, n, payload, scratch, scratch_cap, out_px);
665 if (err != k_ra8_ok) {
666 return err;
667 }
668 *out_w = tw;
669 *out_h = th;
670 return k_ra8_ok;
671}
jof_le_t
Little-endian assembly constants for the header/footer fields.
Definition jof.c:37
@ k_jof_le_sh16
16-bit shift.
Definition jof.c:43
@ k_jof_le_b1
Byte 1 offset.
Definition jof.c:39
@ k_jof_le_b3
Byte 3 (MSB) offset.
Definition jof.c:41
@ k_jof_le_sh24
24-bit shift.
Definition jof.c:44
@ k_jof_le_sh8
8-bit shift.
Definition jof.c:42
@ k_jof_le_b0
Byte 0 (LSB) offset.
Definition jof.c:38
@ k_jof_le_b2
Byte 2 offset.
Definition jof.c:40
ra8_err_t jof_memstore_pread(void *ctx, uint64_t offset, uint8_t *buf, size_t len, size_t *got)
Positioned read from a jof_memstore_t (reader seam).
Definition jof.c:177
static ra8_err_t internal_read_args_ok(jof_pread_fn pread, const jof_info_t *info, const uint8_t *out_px, const uint16_t *out_w, const uint16_t *out_h)
Reject any NULL jof_read_tile pointer argument.
Definition jof.c:623
static uint32_t internal_ceil_div(uint32_t n, uint32_t d)
Ceil-divide n by d (d > 0).
Definition jof.c:119
static ra8_err_t internal_fetch_decode(jof_pread_fn pread, void *pread_ctx, const jof_info_t *info, uint32_t n, uint32_t payload, uint8_t *scratch, uint32_t scratch_cap, uint8_t *out_px)
Fetch tile n's index entry, then read + decode its stream.
Definition jof.c:578
static ra8_err_t internal_pread_exact(jof_pread_fn pread, void *pread_ctx, uint64_t off, uint8_t *buf, size_t len)
Exact positioned read: EOF or a short read is a validation failure.
Definition jof.c:145
ra8_err_t jof_tile_dims(const jof_info_t *info, uint16_t tile_x, uint16_t tile_y, uint16_t *out_w, uint16_t *out_h)
Report the true (edge-clamped) pixel dimensions of one tile.
Definition jof.c:414
static ra8_err_t internal_check_cross(jof_info_t *info, uint32_t hdr_count, const uint8_t *ftr, uint64_t total_size)
Cross-check grid, tile-count, footer and index-window invariants.
Definition jof.c:303
ra8_err_t jof_read_tile(jof_pread_fn pread, void *pread_ctx, const jof_info_t *info, uint16_t tile_x, uint16_t tile_y, uint8_t *scratch, uint32_t scratch_cap, uint8_t *out_px, uint32_t out_cap, uint16_t *out_w, uint16_t *out_h)
Read + decode one tile into caller pixels, in bounded RAM.
Definition jof.c:637
static ra8_err_t internal_parse_header_region(jof_pread_fn pread, void *pread_ctx, uint8_t *hdr, jof_info_t *out_info)
Read + validate the 32-byte header region into out_info.
Definition jof.c:359
ra8_err_t jof_parse(jof_pread_fn pread, void *pread_ctx, uint64_t total_size, jof_info_t *out_info)
Parse + validate a JOF atlas's header, footer and index bounds.
Definition jof.c:379
static uint16_t internal_rd_u16(const uint8_t *buf, uint8_t off)
Read a little-endian uint16 from buf at off.
Definition jof.c:76
uint32_t jof_stored_bound(uint32_t raw_bytes)
Implementation of jof_stored_bound() – raw + raw/8 + 256.
Definition jof.c:439
static ra8_err_t internal_decode_stream(jof_pread_fn pread, void *pread_ctx, const jof_info_t *info, uint32_t toff, uint32_t tlen, uint32_t payload, uint8_t *scratch, uint32_t scratch_cap, uint8_t *out_px)
Decode a validated tile stream into out_px.
Definition jof.c:521
jof_bound_t
Worst-case stored-stream expansion terms (see the header contract).
Definition jof.c:51
@ k_jof_bound_div
Expansion denominator (raw / 8).
Definition jof.c:52
@ k_jof_bound_add
Fixed expansion margin, bytes.
Definition jof.c:53
static ra8_err_t internal_index_entry(jof_pread_fn pread, void *pread_ctx, const jof_info_t *info, uint32_t n, uint32_t *out_off, uint32_t *out_len)
Fetch + window-validate the index entry for tile n.
Definition jof.c:468
static uint32_t internal_rd_u32(const uint8_t *buf, uint8_t off)
Read a little-endian uint32 from buf at off.
Definition jof.c:97
static ra8_err_t internal_check_reserved(const uint8_t *hdr)
Reject any non-zero reserved header byte (strict, fail-closed).
Definition jof.c:268
static ra8_err_t internal_parse_hdr_fields(const uint8_t *hdr, jof_info_t *info)
Validate the header geometry fields into info (fail-closed).
Definition jof.c:217
ra8_err_t jof_memstore_sink(void *ctx, const uint8_t *buf, size_t len)
Append len bytes to a jof_memstore_t (producer sink).
Definition jof.c:163
JOF band-tile atlas: the display-native normalized image format (#231, shared with the longstrip scro...
@ k_jof_ofs_tile_count
Header: u32 tile count.
Definition jof.h:155
@ k_jof_index_entry
Bytes per tile-index entry.
Definition jof.h:145
@ k_jof_ofs_magic
Header: magic "JOF1".
Definition jof.h:147
@ k_jof_ofs_reserved
Header: first reserved byte.
Definition jof.h:154
@ k_jof_magic_len
Magic string length (both ends).
Definition jof.h:146
@ k_jof_footer_bytes
Footer length.
Definition jof.h:144
@ k_jof_ftr_total_size
Footer: u32 total atlas size.
Definition jof.h:159
@ k_jof_hdr_bytes
Header length.
Definition jof.h:143
@ k_jof_ftr_magic
Footer: magic "JOFE".
Definition jof.h:160
@ k_jof_ftr_index_off
Footer: u32 index offset.
Definition jof.h:157
@ k_jof_ofs_reserved2
Header: second reserved run.
Definition jof.h:156
@ k_jof_ofs_tile_h
Header: u16 tile height.
Definition jof.h:151
@ k_jof_ofs_codec
Header: u8 tile codec.
Definition jof.h:153
@ k_jof_idx_ofs_length
Index entry: u32 tile length.
Definition jof.h:162
@ k_jof_ofs_height
Header: u16 image height.
Definition jof.h:149
@ k_jof_ofs_tile_w
Header: u16 tile width.
Definition jof.h:150
@ k_jof_ofs_width
Header: u16 image width.
Definition jof.h:148
@ k_jof_ftr_tile_count
Footer: u32 tile count.
Definition jof.h:158
@ k_jof_ofs_bpp
Header: u8 bytes per pixel.
Definition jof.h:152
@ k_jof_idx_ofs_offset
Index entry: u32 tile offset.
Definition jof.h:161
@ k_jof_bpp_max
Max bytes per pixel.
Definition jof.h:178
@ k_jof_max_dim
Max image width/height, pixels.
Definition jof.h:176
@ k_jof_max_tiles
Max tiles per atlas.
Definition jof.h:177
ra8_err_t(* jof_pread_fn)(void *ctx, uint64_t offset, uint8_t *buf, size_t len, size_t *got)
Positioned-read seam over an atlas backing store (DIP).
Definition jof.h:241
@ k_jof_codec_deflate
Tile stream is one raw-DEFLATE run.
Definition jof.h:192
@ k_jof_codec_raw
Tile stream is the packed pixels.
Definition jof.h:191
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#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
App-domain DEFLATE compress / decompress (zero-heap, firmware-safe).
ra8_err_t ra8_decompress(const uint8_t *src, uint32_t src_len, uint8_t *out, uint32_t out_cap, uint32_t *out_len)
Raw-DEFLATE decompress src into out.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
Definition ra8_err.h:142
@ k_ra8_err_out_of_range
Sensor or peripheral output out of valid range.
Definition ra8_err.h:337
@ 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_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
int memcmp(const void *a, const void *b, size_t n)
Compare bytes in two memory areas.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
Parsed + validated geometry of one JOF atlas.
Definition jof.h:208
uint8_t bpp
Bytes per pixel (1, 3 or 4).
Definition jof.h:215
uint8_t codec
jof_codec_t member.
Definition jof.h:216
uint16_t tile_w
Tile width, pixels.
Definition jof.h:211
uint16_t width
Image width, pixels.
Definition jof.h:209
uint32_t index_off
Absolute byte offset of the tile index.
Definition jof.h:218
uint16_t tile_rows
Ceil(height / tile_h) tile rows.
Definition jof.h:214
uint16_t tile_h
Tile height, pixels.
Definition jof.h:212
uint32_t tile_count
Total tiles (== cols * rows).
Definition jof.h:217
uint16_t height
Image height, pixels.
Definition jof.h:210
uint32_t total_size
Whole atlas byte length (footer included).
Definition jof.h:219
uint16_t tile_cols
Ceil(width / tile_w) tile columns.
Definition jof.h:213
Append-only memory store: the simplest atlas backing (RAM/SDRAM).
Definition jof.h:256
uint8_t * buf
Caller-owned backing bytes.
Definition jof.h:257
size_t cap
Capacity of buf.
Definition jof.h:258
size_t len
Bytes appended so far (see sink).
Definition jof.h:259