ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_fmt_stream_verify.c
Go to the documentation of this file.
1
12
13#include <stddef.h>
14#include <stdint.h>
15#include <string.h>
16
17#include "jof_produce.h"
18#include "ra8_attributes.h"
19#include "ra8_fmt_stream.h"
20
30
32typedef struct {
34 uint64_t offset;
36
62
79{
80 return (source->validate == nullptr) ? k_ra8_ok : source->validate(source->ctx, source->size);
81}
82
104static ra8_err_t internal_pull(void* ctx, uint8_t* bytes, size_t cap, size_t* got)
105{
106 verify_pull_t* pull = (verify_pull_t*)ctx;
107 if ((pull == nullptr) || (got == nullptr) || ((bytes == nullptr) && (cap != 0U))) {
108 return k_ra8_err_null_ptr;
109 }
110 *got = 0U;
111 if ((cap == 0U) || (pull->offset >= pull->source->size)) {
112 return k_ra8_ok;
113 }
114 const uint64_t remain = pull->source->size - pull->offset;
115 if ((uint64_t)cap > remain) {
116 cap = (size_t)remain;
117 }
118 ra8_err_t rc = pull->source->read_at(pull->source->ctx, pull->offset, bytes, cap, got);
119 if ((rc == k_ra8_ok) && (*got <= cap)) {
120 pull->offset += *got;
121 } else if (rc == k_ra8_ok) {
123 }
124 return rc;
125}
126
145static ra8_err_t internal_spool_append(void* ctx, const uint8_t* bytes, size_t len)
146{
147 ra8_fmt_spool_t* spool = (ra8_fmt_spool_t*)ctx;
148 return spool->append(spool->ctx, bytes, len);
149}
150
173 uint16_t tile_h,
175 ra8_fmt_spool_t* spool,
176 jof_info_t* info)
177{
178 verify_pull_t pull = {.source = source, .offset = 0U};
179 const jof_produce_cfg_t cfg = {
180 .pull = internal_pull,
181 .pull_ctx = &pull,
182 .sink = internal_spool_append,
183 .sink_ctx = spool,
184 .tile_w = need->width,
185 .tile_h = tile_h,
186 .codec = (uint8_t)k_jof_codec_deflate,
187 .max_width = need->width,
188 .max_height = need->height,
189 .work = work->work,
190 .work_cap = work->work_cap,
191 .webp_work = work->webp_work,
192 .webp_work_cap = work->webp_work_cap,
193 };
194 ra8_err_t rc = internal_stable(source);
195 if (rc == k_ra8_ok) {
196 rc = jof_produce(&cfg, info);
197 }
198 if (rc == k_ra8_ok) {
199 rc = internal_stable(source);
200 }
201 if (rc == k_ra8_ok) {
202 rc = spool->seal(spool->ctx, info->total_size);
203 }
204 return rc;
205}
206
223static ra8_err_t internal_text(const ra8_fmt_sink_t* sink, const char* text)
224{
225 return sink->write(sink->ctx, (const uint8_t*)text, strlen(text));
226}
227
244static ra8_err_t internal_u64(const ra8_fmt_sink_t* sink, uint64_t value)
245{
246 char reverse[k_verify_decimal_max];
247 size_t count = 0U;
248 do {
249 reverse[count++] = (char)('0' + (char)(value % k_verify_decimal));
250 value /= k_verify_decimal;
251 } while (value != 0U);
252 char text[k_verify_decimal_max];
253 for (size_t i = 0U; i < count; ++i) {
254 text[i] = reverse[count - i - 1U];
255 }
256 return sink->write(sink->ctx, (const uint8_t*)text, count);
257}
258
275static ra8_err_t internal_hex(const ra8_fmt_sink_t* sink, uint8_t value)
276{
277 static const uint8_t digits[] = "0123456789ABCDEF";
278 const uint8_t text[2] = {
279 digits[value / k_verify_hex_radix],
280 digits[value % k_verify_hex_radix],
281 };
282 return sink->write(sink->ctx, text, sizeof(text));
283}
284
300static void
301internal_field(const ra8_fmt_sink_t* sink, uint64_t value, const char* suffix, ra8_err_t* status)
302{
303 if (*status == k_ra8_ok) {
304 *status = internal_u64(sink, value);
305 }
306 if (*status == k_ra8_ok) {
307 *status = internal_text(sink, suffix);
308 }
309}
310
325static void
326internal_geometry(const ra8_fmt_sink_t* report, const jof_info_t* info, const jof_info_t* subject)
327{
328 ra8_err_t rc = internal_text(report, "verify: ");
329 internal_field(report, info->width, "x", &rc);
330 internal_field(report, info->height, " bpp=", &rc);
331 internal_field(report, info->bpp, " | reference 1 tile | banded ", &rc);
332 internal_field(report, subject->tile_count, " tiles of ", &rc);
333 internal_field(report, subject->tile_h, " rows\n", &rc);
334}
335
353 uint64_t x,
354 uint64_t y,
355 uint8_t reference,
356 uint8_t banded)
357{
358 if (state->shown >= k_verify_diffs_max) {
359 return;
360 }
361 ra8_err_t rc = internal_text(state->report, " DIFF at pixel (");
362 internal_field(state->report, x, ", ", &rc);
363 internal_field(state->report, y, "): reference=0x", &rc);
364 if (rc == k_ra8_ok) {
365 rc = internal_hex(state->report, reference);
366 }
367 if (rc == k_ra8_ok) {
368 rc = internal_text(state->report, " banded=0x");
369 }
370 if (rc == k_ra8_ok) {
371 rc = internal_hex(state->report, banded);
372 }
373 if (rc == k_ra8_ok) {
374 (void)internal_text(state->report, "\n");
375 }
376 state->shown++;
377}
378
392{
393 if ((state->dump != nullptr) && (state->dump->ops != nullptr) &&
394 (state->dump->ops->abort != nullptr)) {
395 state->dump->ops->abort(state->dump->ctx);
396 }
397 state->dump_ok = false;
398}
399
414static void internal_dump_bytes(verify_compare_t* state, const uint8_t* bytes, size_t len)
415{
416 if (state->dump_ok && (state->dump != nullptr) &&
417 (state->dump->ops->append(state->dump->ctx, bytes, len) != k_ra8_ok)) {
418 internal_abort_dump(state);
419 }
420}
421
435static void internal_dump_u64(verify_compare_t* state, uint64_t value)
436{
437 char reverse[k_verify_decimal_max];
438 size_t count = 0U;
439 do {
440 reverse[count++] = (char)('0' + (char)(value % k_verify_decimal));
441 value /= k_verify_decimal;
442 } while (value != 0U);
443 char text[k_verify_decimal_max];
444 for (size_t i = 0U; i < count; ++i) {
445 text[i] = reverse[count - i - 1U];
446 }
447 internal_dump_bytes(state, (const uint8_t*)text, count);
448}
449
463{
464 const uint8_t magic[3] = {'P', (state->need->bpp == 1U) ? '5' : '6', '\n'};
465 internal_dump_bytes(state, magic, sizeof(magic));
466 internal_dump_u64(state, state->need->width);
467 internal_dump_bytes(state, (const uint8_t*)" ", 1U);
468 internal_dump_u64(state, state->need->height);
469 internal_dump_bytes(state, (const uint8_t*)"\n255\n", k_verify_ppm_max_text);
470}
471
485static void internal_dump_row(verify_compare_t* state, const uint8_t* row)
486{
487 if ((state->dump == nullptr) || !state->dump_ok) {
488 return;
489 }
490 if (state->need->bpp != 4U) {
491 internal_dump_bytes(state, row, state->need->row_bytes);
492 return;
493 }
494 for (uint32_t x = 0U; x < state->need->width; ++x) {
495 (void)memcpy(&state->work->row[(size_t)x * 3U], &row[(size_t)x * 4U], 3U);
496 }
497 internal_dump_bytes(state, state->work->row, (size_t)state->need->width * 3U);
498}
499
520 const jof_info_t* info,
522 bool reference)
523{
524 uint8_t* const buffer = reference ? work->row : work->band_tile;
525 const uint32_t cap = reference ? work->row_cap : work->band_tile_cap;
526 for (uint16_t y = 0U; y < info->tile_rows; ++y) {
527 uint16_t out_w = 0U;
528 uint16_t out_h = 0U;
529 const ra8_err_t rc = jof_read_tile(spool->read_at,
530 spool->ctx,
531 info,
532 0U,
533 y,
534 work->scratch,
535 work->scratch_cap,
536 buffer,
537 cap,
538 &out_w,
539 &out_h);
540 if ((rc != k_ra8_ok) || (out_w != info->width) || (reference && (out_h != 1U))) {
541 return (rc == k_ra8_ok) ? k_ra8_err_validation_failed : rc;
542 }
543 }
544 return k_ra8_ok;
545}
546
561static void internal_compare_row(verify_compare_t* state, const uint8_t* band_row, uint16_t y)
562{
563 for (uint32_t i = 0U; i < state->need->row_bytes; ++i) {
564 if (state->work->row[i] != band_row[i]) {
565 state->diffs++;
567 (uint64_t)(i / state->need->bpp),
568 y,
569 state->work->row[i],
570 band_row[i]);
571 }
572 }
573 internal_dump_row(state, band_row);
574}
575
593{
594 if (state->dump != nullptr) {
595 state->dump_ok = true;
597 }
598 uint16_t global_y = 0U;
599 for (uint16_t band_y = 0U; band_y < state->ginfo->tile_rows; ++band_y) {
600 uint16_t band_w = 0U;
601 uint16_t band_h = 0U;
602 ra8_err_t rc = jof_read_tile(state->got->read_at,
603 state->got->ctx,
604 state->ginfo,
605 0U,
606 band_y,
607 state->work->scratch,
608 state->work->scratch_cap,
609 state->work->band_tile,
610 state->work->band_tile_cap,
611 &band_w,
612 &band_h);
613 if ((rc != k_ra8_ok) || (band_w != state->need->width)) {
614 return (rc == k_ra8_ok) ? k_ra8_err_validation_failed : rc;
615 }
616 for (uint16_t row = 0U; row < band_h; ++row) {
617 uint16_t ref_w = 0U;
618 uint16_t ref_h = 0U;
619 rc = jof_read_tile(state->ref->read_at,
620 state->ref->ctx,
621 state->rinfo,
622 0U,
623 global_y,
624 state->work->scratch,
625 state->work->scratch_cap,
626 state->work->row,
627 state->work->row_cap,
628 &ref_w,
629 &ref_h);
630 if ((rc != k_ra8_ok) || (ref_w != state->need->width) || (ref_h != 1U)) {
631 return (rc == k_ra8_ok) ? k_ra8_err_validation_failed : rc;
632 }
633 const uint8_t* band_row = &state->work->band_tile[(size_t)row * state->need->row_bytes];
634 internal_compare_row(state, band_row, global_y++);
635 }
636 }
637 return (global_y == state->need->height) ? k_ra8_ok : k_ra8_err_validation_failed;
638}
639
657static bool internal_info(const jof_info_t* info,
659 uint16_t tile_h)
660{
661 const uint16_t rows = (uint16_t)(((uint32_t)need->height + tile_h - 1U) / tile_h);
662 return (info->width == need->width) && (info->height == need->height) &&
663 (info->tile_w == need->width) && (info->tile_h == tile_h) && (info->tile_cols == 1U) &&
664 (info->tile_rows == rows) && (info->tile_count == rows) && (info->bpp == need->bpp) &&
665 (info->codec == (uint8_t)k_jof_codec_deflate);
666}
667
682static void internal_phase_error(const ra8_fmt_sink_t* report, const char* prefix, ra8_err_t status)
683{
684 ra8_err_t rc = internal_text(report, prefix);
685 internal_field(report, status, ")\n", &rc);
686}
687
701static void internal_finish_dump(verify_compare_t* state, const char* dump_name)
702{
703 if (state->dump == nullptr) {
704 return;
705 }
706 if (state->dump_ok && (state->dump->ops->commit(state->dump->ctx) != k_ra8_ok)) {
707 internal_abort_dump(state);
708 }
709 ra8_err_t rc = internal_text(state->report, " wrote reassembled raster to ");
710 if (rc == k_ra8_ok) {
711 rc = internal_text(state->report, dump_name);
712 }
713 if (rc == k_ra8_ok) {
714 (void)internal_text(state->report, state->dump_ok ? " (ok)\n" : " (FAILED)\n");
715 }
716}
717
731static void internal_verdict(const ra8_fmt_sink_t* report, uint64_t diffs)
732{
733 ra8_err_t rc = internal_text(report, "verdict: ");
734 if (rc == k_ra8_ok) {
735 rc = internal_text(report,
736 (diffs == 0U) ? "ROUND-TRIP EXACT -- the produced file is correct"
737 : "MISMATCH");
738 }
739 if (rc == k_ra8_ok) {
740 rc = internal_text(report, " (");
741 }
742 internal_field(report, diffs, " differing bytes)\n", &rc);
743}
744
767static ra8_err_t internal_check(const ra8_fmt_source_t* reference_source,
768 const ra8_fmt_source_t* banded_source,
771 const ra8_fmt_spool_t* ref_spool,
772 const ra8_fmt_spool_t* got_spool,
773 const ra8_fmt_sink_t* report)
774{
775 if ((reference_source == nullptr) || (banded_source == nullptr) ||
776 (reference_source->read_at == nullptr) || (banded_source->read_at == nullptr) ||
777 (reference_source->ctx == banded_source->ctx) || (need == nullptr) || (work == nullptr) ||
778 (ref_spool == nullptr) || (got_spool == nullptr) || (ref_spool->read_at == nullptr) ||
779 (ref_spool->append == nullptr) || (ref_spool->seal == nullptr) ||
780 (got_spool->read_at == nullptr) || (got_spool->append == nullptr) ||
781 (got_spool->seal == nullptr) || (ref_spool->ctx == got_spool->ctx) || (report == nullptr) ||
782 (report->write == nullptr)) {
783 return k_ra8_err_null_ptr;
784 }
785 const uint32_t producer = (need->reference_work_bytes > need->banded_work_bytes)
787 : need->banded_work_bytes;
788 const bool webp_bad =
789 (need->webp_work_bytes != 0U) &&
790 ((work->webp_work == nullptr) || (work->webp_work_cap < need->webp_work_bytes));
791 if ((work->work == nullptr) || (work->work_cap < producer) || webp_bad ||
792 (work->band_tile == nullptr) || (work->band_tile_cap < need->band_tile_bytes) ||
793 (work->scratch == nullptr) || (work->scratch_cap < need->scratch_bytes) ||
794 (work->row == nullptr) || (work->row_cap < need->row_bytes)) {
796 }
797 return k_ra8_ok;
798}
799
805
819{
820 if ((dump != nullptr) && (dump->ops != nullptr) && (dump->ops->abort != nullptr)) {
821 dump->ops->abort(dump->ctx);
822 }
823}
824
848 bool reference,
849 jof_info_t* info)
850{
851 const uint16_t tile_h = reference ? 1U : need->band_height;
852 ra8_err_t rc = jof_parse(spool->read_at, spool->ctx, info->total_size, info);
853 if ((rc == k_ra8_ok) && !internal_info(info, need, tile_h)) {
855 }
856 if (rc == k_ra8_ok) {
857 rc = internal_preflight(spool, info, work, reference);
858 }
859 return rc;
860}
861
884static ra8_err_t internal_prepare(const ra8_fmt_source_t* reference_source,
885 const ra8_fmt_source_t* banded_source,
888 ra8_fmt_spool_t* reference_spool,
889 ra8_fmt_spool_t* banded_spool,
890 const ra8_fmt_sink_t* report,
891 verify_atlases_t* atlases)
892{
893 ra8_err_t rc =
894 internal_produce(reference_source, need, 1U, work, reference_spool, &atlases->reference);
895 if (rc == k_ra8_ok) {
896 rc = internal_accept(reference_spool, need, work, true, &atlases->reference);
897 }
898 if (rc != k_ra8_ok) {
899 internal_phase_error(report, "verify: reference encode failed (rc=", rc);
900 return rc;
901 }
902 rc =
903 internal_produce(banded_source, need, need->band_height, work, banded_spool, &atlases->banded);
904 if (rc == k_ra8_ok) {
905 rc = internal_accept(banded_spool, need, work, false, &atlases->banded);
906 }
907 if (rc != k_ra8_ok) {
908 internal_phase_error(report, "verify: banded encode failed (rc=", rc);
909 }
910 return rc;
911}
912
914 const ra8_fmt_source_t* banded_source,
915 const ra8_fmt_jof_verify_requirements_t* requirements,
917 ra8_fmt_spool_t* reference_spool,
918 ra8_fmt_spool_t* banded_spool,
920 const char* dump_name,
921 const ra8_fmt_sink_t* report)
922{
923 ra8_err_t rc = internal_check(reference_source,
924 banded_source,
925 requirements,
926 workspace,
927 reference_spool,
928 banded_spool,
929 report);
930 const bool dump_bad =
931 (dump != nullptr) &&
932 ((dump->ops == nullptr) || (dump->ops->append == nullptr) || (dump->ops->commit == nullptr) ||
933 (dump->ops->abort == nullptr) || (dump_name == nullptr));
934 if ((rc != k_ra8_ok) || dump_bad) {
935 return (rc == k_ra8_ok) ? k_ra8_err_null_ptr : rc;
936 }
937 verify_atlases_t atlases = {};
938 rc = internal_prepare(reference_source,
939 banded_source,
940 requirements,
941 workspace,
942 reference_spool,
943 banded_spool,
944 report,
945 &atlases);
946 if (rc != k_ra8_ok) {
948 return rc;
949 }
950 internal_geometry(report, &atlases.reference, &atlases.banded);
951 verify_compare_t compare = {
952 .need = requirements,
953 .work = workspace,
954 .ref = reference_spool,
955 .got = banded_spool,
956 .rinfo = &atlases.reference,
957 .ginfo = &atlases.banded,
958 .dump = dump,
959 .report = report,
960 .dump_ok = dump != nullptr,
961 };
962 rc = internal_compare(&compare);
963 if (rc == k_ra8_ok) {
964 rc = internal_stable(reference_source);
965 }
966 if (rc == k_ra8_ok) {
967 rc = internal_stable(banded_source);
968 }
969 if (rc != k_ra8_ok) {
970 internal_abort_dump(&compare);
971 return rc;
972 }
973 internal_finish_dump(&compare, dump_name);
974 internal_verdict(report, compare.diffs);
975 return (compare.diffs == 0U) ? k_ra8_ok : k_ra8_err_validation_failed;
976}
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
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
@ k_jof_codec_deflate
Tile stream is one raw-DEFLATE run.
Definition jof.h:192
Import-time transcode producer: JPEG/PNG/WebP -> JOF band-tile atlas in bounded RAM (#231,...
ra8_err_t jof_produce(const jof_produce_cfg_t *cfg, jof_info_t *out_info)
Transcode one encoded JPEG/PNG/WebP source into a JOF atlas (#231, #290).
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ 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_protocol_error
Protocol-level error (e.g.
Definition ra8_err.h:429
@ 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
Caller-workspace I/O contracts for portable format-tool engines.
static ra8_err_t internal_pull(void *ctx, uint8_t *bytes, size_t cap, size_t *got)
Producer pull adapter over positioned source reads.
static ra8_err_t internal_check(const ra8_fmt_source_t *reference_source, const ra8_fmt_source_t *banded_source, const ra8_fmt_jof_verify_requirements_t *need, const ra8_fmt_jof_verify_workspace_t *work, const ra8_fmt_spool_t *ref_spool, const ra8_fmt_spool_t *got_spool, const ra8_fmt_sink_t *report)
Reject incomplete callbacks, aliased contexts, or undersized arenas.
static ra8_err_t internal_stable(const ra8_fmt_source_t *source)
Validate a source through its optional stability callback.
static void internal_difference(verify_compare_t *state, uint64_t x, uint64_t y, uint8_t reference, uint8_t banded)
Record and optionally report one differing byte.
static void internal_dump_row(verify_compare_t *state, const uint8_t *row)
Stage one subject row in PPM channel order.
verify_const_t
Verification geometry, report, and probe constants.
@ k_verify_decimal_max
Digits in one uint64_t.
@ k_verify_diffs_max
Maximum detailed byte differences.
@ k_verify_ppm_max_text
Bytes in the PPM maximum line.
@ k_verify_decimal
Decimal report radix.
@ k_verify_band_height
Production band height under test.
@ k_verify_hex_radix
Hexadecimal report radix.
static ra8_err_t internal_compare(verify_compare_t *state)
Compare all subject bands against streamed reference rows.
static bool internal_info(const jof_info_t *info, const ra8_fmt_jof_verify_requirements_t *need, uint16_t tile_h)
Check parsed atlas geometry against exact planned policy.
static ra8_err_t internal_text(const ra8_fmt_sink_t *sink, const char *text)
Append one NUL-terminated report fragment.
static void internal_verdict(const ra8_fmt_sink_t *report, uint64_t diffs)
Emit the exact legacy final verdict line.
static void internal_finish_dump(verify_compare_t *state, const char *dump_name)
Commit or abort the optional PPM and emit its legacy status line.
static void internal_phase_error(const ra8_fmt_sink_t *report, const char *prefix, ra8_err_t status)
Report one exact legacy phase-failure line.
static void internal_abort_dump(verify_compare_t *state)
Abort an incomplete optional PPM stage once.
static void internal_compare_row(verify_compare_t *state, const uint8_t *band_row, uint16_t y)
Compare one decoded subject row with its reference row.
static ra8_err_t internal_prepare(const ra8_fmt_source_t *reference_source, const ra8_fmt_source_t *banded_source, const ra8_fmt_jof_verify_requirements_t *need, ra8_fmt_jof_verify_workspace_t *work, ra8_fmt_spool_t *reference_spool, ra8_fmt_spool_t *banded_spool, const ra8_fmt_sink_t *report, verify_atlases_t *atlases)
Produce, seal, parse, and preflight both independent atlases.
static void internal_dump_header(verify_compare_t *state)
Stage the exact P5 or P6 header for subject geometry.
ra8_err_t ra8_fmt_jof_verify_stream(const ra8_fmt_source_t *reference_source, const ra8_fmt_source_t *banded_source, const ra8_fmt_jof_verify_requirements_t *requirements, ra8_fmt_jof_verify_workspace_t *workspace, ra8_fmt_spool_t *reference_spool, ra8_fmt_spool_t *banded_spool, ra8_fmt_transaction_t *dump, const char *dump_name, const ra8_fmt_sink_t *report)
Verify banded JOF pixels against an independently decoded row reference.
static void internal_field(const ra8_fmt_sink_t *sink, uint64_t value, const char *suffix, ra8_err_t *status)
Append one numeric field and suffix while status succeeds.
static ra8_err_t internal_hex(const ra8_fmt_sink_t *sink, uint8_t value)
Append one byte as two uppercase hexadecimal digits.
static ra8_err_t internal_accept(const ra8_fmt_spool_t *spool, const ra8_fmt_jof_verify_requirements_t *need, ra8_fmt_jof_verify_workspace_t *work, bool reference, jof_info_t *info)
Parse, check geometry, and decode every tile of one sealed spool.
static void internal_geometry(const ra8_fmt_sink_t *report, const jof_info_t *info, const jof_info_t *subject)
Emit the exact legacy verifier geometry line.
static ra8_err_t internal_produce(const ra8_fmt_source_t *source, const ra8_fmt_jof_verify_requirements_t *need, uint16_t tile_h, ra8_fmt_jof_verify_workspace_t *work, ra8_fmt_spool_t *spool, jof_info_t *info)
Produce and seal one deflate JOF into an injected spool.
static void internal_dump_bytes(verify_compare_t *state, const uint8_t *bytes, size_t len)
Append optional PPM bytes or mark the dump failed.
static ra8_err_t internal_pull(void *ctx, uint8_t *bytes, size_t cap, size_t *got)
Pull the next bounded source prefix for streamed JOF production.
static ra8_err_t internal_preflight(const ra8_fmt_spool_t *spool, const jof_info_t *info, ra8_fmt_jof_verify_workspace_t *work, bool reference)
Decode every sealed atlas tile before reporting or output staging.
static ra8_err_t internal_u64(const ra8_fmt_sink_t *sink, uint64_t value)
Append one uint64_t as canonical decimal.
static void internal_dump_u64(verify_compare_t *state, uint64_t value)
Append one decimal PPM header field.
static ra8_err_t internal_spool_append(void *ctx, const uint8_t *bytes, size_t len)
Append one produced JOF span to the injected verifier spool.
static void internal_abort_transaction(ra8_fmt_transaction_t *dump)
Abort an optional complete transaction binding.
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.
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
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
Producer configuration: source, sink, tile geometry and work arena.
Exact phase-reused storage requirements for JOF verification.
uint32_t row_bytes
One decoded reference row.
uint8_t bpp
Decoder output bytes per pixel.
uint16_t band_height
Subject tile height under test.
uint32_t reference_work_bytes
One-row reference producer arena.
uint16_t width
Source width in pixels.
uint16_t height
Source height in pixels.
uint32_t band_tile_bytes
Largest decoded subject tile.
uint32_t scratch_bytes
Largest stored-tile staging buffer.
uint32_t webp_work_bytes
Whole-frame WebP arena, or zero.
uint32_t banded_work_bytes
Banded subject producer arena.
Caller-owned phase-overlaid arenas for one bounded JOF verification.
Injected append-only sink.
ra8_fmt_sink_write_fn write
Exact append callback.
void * ctx
Backend-owned context.
Immutable, randomly readable input object.
uint64_t size
Exact object byte length.
void * ctx
Backend-owned context.
ra8_fmt_source_validate_fn validate
Optional stability callback.
jof_pread_fn read_at
Positioned-read callback.
Caller-owned scratch artifact with append, seal, and read seams.
ra8_fmt_sink_write_fn append
Append before seal.
jof_pread_fn read_at
Positioned reader after seal.
ra8_fmt_spool_seal_fn seal
Seal exact produced bytes.
void * ctx
Backend-owned state.
ra8_err_t(* commit)(void *ctx)
Sync and atomically install.
ra8_fmt_sink_write_fn append
Append artifact bytes.
void(* abort)(void *ctx)
Discard owned staging data.
One caller-owned artifact transaction.
void * ctx
Backend-owned state.
const ra8_fmt_transaction_ops_t * ops
Transaction implementation.
Parsed and fully preflighted reference and subject atlases.
jof_info_t banded
Production-band geometry.
jof_info_t reference
One-row reference geometry.
Comparison state shared by bounded tile/row helpers.
const ra8_fmt_spool_t * ref
Sealed reference atlas.
uint32_t shown
Detailed differences emitted.
const jof_info_t * ginfo
Parsed subject geometry.
const ra8_fmt_sink_t * report
Human-readable report sink.
ra8_fmt_transaction_t * dump
Optional unpublished PPM stage.
const jof_info_t * rinfo
Parsed reference geometry.
bool dump_ok
PPM stage remains complete.
const ra8_fmt_jof_verify_requirements_t * need
Exact geometry and capacities.
uint64_t diffs
Differing byte count.
const ra8_fmt_spool_t * got
Sealed banded atlas.
Sequential cursor over one positioned source context.
const ra8_fmt_source_t * source
Immutable positioned source.
uint64_t offset
Next sequential byte offset.