ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
mdl_export_jof.c File Reference

JOF tile-atlas exporter: one .jof band atlas per chapter page. More...

#include <stdio.h>
#include <string.h>
#include "jof.h"
#include "jof_produce.h"
#include "mdl_export.h"
#include "mdl_export_internal.h"
#include "ra8_attributes.h"
#include "ra8_err.h"
Include dependency graph for mdl_export_jof.c:

Go to the source code of this file.

Data Structures

struct  jof_pull_ctx_t
 Pull cursor over an in-RAM encoded image. More...

Enumerations

enum  mdl_jof_geom_t : uint16_t { k_jof_band_h = 256 }
 JOF atlas tiling geometry for a long-strip page. More...
enum  mdl_jof_webp_t : uint8_t {
  k_jof_webp_riff_ofs = 0U ,
  k_jof_webp_fourcc_ofs = 8U ,
  k_jof_webp_head_len = 12U ,
  k_jof_webp_tag_len = 4U
}
 WebP container-head offsets for the whole-frame-arena decision. More...
enum  mdl_jof_workspace_t : uint32_t {
  k_jof_source_cap = 16U * 1024U * 1024U ,
  k_jof_work_cap = 16U * 1024U * 1024U ,
  k_jof_webp_work_cap = 64U * 1024U * 1024U
}
 Hard memory ceilings for the non-reentrant transcode workspace. More...

Functions

static bool internal_jof_is_webp (const uint8_t *data, size_t len)
 Test whether a page's bytes carry the WebP RIFF container head.
static ra8_err_t internal_jof_pull (void *ctx, uint8_t *buf, size_t cap, size_t *got)
 Copy the next encoded source span into a producer buffer.
static ra8_err_t internal_jof_sink (void *ctx, const uint8_t *buf, size_t len)
 Append producer output bytes to the active publication transaction.
static ra8_err_t internal_jof_carve_webp (const uint8_t *src, size_t slen, uint16_t w, uint16_t h, uint8_t **out_work, size_t *out_cap, mdl_export_workspace_t *ws)
 Carve the whole-frame WebP work arena for a WebP page (no-op otherwise).
static ra8_err_t internal_jof_produce_page (const uint8_t *src, size_t slen, uint16_t w, uint16_t h, uint16_t tile_h, uint32_t work_cap, mdl_export_output_t *output, mdl_export_workspace_t *ws)
 Produce one page's atlas into an already-open output file.
static ra8_err_t internal_jof_load_source (mdl_storage_t *storage, const char *in_path, mdl_export_workspace_t *ws, uint8_t **out_src, size_t *out_slen)
 Stat, bound-check, arena-claim, and slurp one source image.
static ra8_err_t internal_jof_one (mdl_storage_t *storage, const char *in_path, const char *out_path, mdl_export_workspace_t *ws)
 Transcode one JPEG, PNG, or WebP page to a JOF band atlas.
ra8_err_t priv_mdl_export_jof (mdl_storage_t *storage, const char *dir, const char names[][k_name_max], size_t count, mdl_export_workspace_t *ws)
 Convert every page in a chapter directory to a sibling .jof atlas.

Variables

static const uint8_t s_jof_webp_riff [k_jof_webp_tag_len] = {'R', 'I', 'F', 'F'}
 WebP RIFF container tag (page head bytes 0..3).
static const uint8_t s_jof_webp_webp [k_jof_webp_tag_len] = {'W', 'E', 'B', 'P'}
 WebP form-type fourCC (page head bytes 8..11).

Detailed Description

JOF tile-atlas exporter: one .jof band atlas per chapter page.

The JOF arm of the chapter exporter, split out of mdl_export.c because it is the only format that reaches into the firmware's jof producer – a whole decode (JPEG / PNG / WebP) and encode stack that the ZIP and tar writers have no use for. Producing through the firmware's own code is the point: a container this tool writes is byte-identical to one the board would produce from the same page, so a defect reproduced here is a defect on silicon.

Each page becomes a full-width-column atlas – tile_w is the whole image width, so every tile is one horizontal band – which is the shape the longstrip engine scrolls a viewport at a time.

WebP is the one format that cannot stream: its arm needs a single arena holding the compressed source, the decoded RGBA frame and libwebp's scratch at once. That arena is carved only for pages that really are WebP, so JPEG and PNG pages do not pay a whole-frame cost for a format they do not use.

[Ring 4 / Domain] {World: NS}

Since
0.1.0

Definition in file mdl_export_jof.c.

Enumeration Type Documentation

◆ mdl_jof_geom_t

enum mdl_jof_geom_t : uint16_t

JOF atlas tiling geometry for a long-strip page.

tile_w is set to the full image width, so each tile is one full-width horizontal band – the shape the longstrip engine scrolls a viewport at a time.

Since
0.1.0
Enumerator
k_jof_band_h 

Tile-band height in pixels.

Definition at line 49 of file mdl_export_jof.c.

◆ mdl_jof_webp_t

enum mdl_jof_webp_t : uint8_t

WebP container-head offsets for the whole-frame-arena decision.

The exporter must know whether a page is WebP before producing, to decide whether to carve the whole-frame arena the WebP arm needs.

See also
internal_jof_is_webp()
Since
0.1.0
Enumerator
k_jof_webp_riff_ofs 

Offset of the "RIFF" fourCC.

k_jof_webp_fourcc_ofs 

Offset of the "WEBP" fourCC.

k_jof_webp_head_len 

Bytes needed to sniff both fourCCs.

k_jof_webp_tag_len 

Length of one fourCC tag.

Definition at line 61 of file mdl_export_jof.c.

◆ mdl_jof_workspace_t

enum mdl_jof_workspace_t : uint32_t

Hard memory ceilings for the non-reentrant transcode workspace.

Enumerator
k_jof_source_cap 

Maximum encoded source bytes.

k_jof_work_cap 

Maximum streaming work bytes.

k_jof_webp_work_cap 

Maximum WebP frame workspace.

Definition at line 68 of file mdl_export_jof.c.

Function Documentation

◆ internal_jof_carve_webp()

ra8_err_t internal_jof_carve_webp ( const uint8_t * src,
size_t slen,
uint16_t w,
uint16_t h,
uint8_t ** out_work,
size_t * out_cap,
mdl_export_workspace_t * ws )
static

Carve the whole-frame WebP work arena for a WebP page (no-op otherwise).

WebP cannot stream, so its producer arm needs one arena holding the compressed source, the decoded RGBA frame and libwebp's scratch at once. JPEG and PNG stream, so they would pay that whole-frame cost for nothing; the arena is carved only when the page really is a WebP. Reporting success with a NULL arena is the producer's fail-closed "reject WebP" signal, correct for the other codecs.

Parameters
[in]srcPage bytes to sniff.
[in]slenLength of src in bytes.
[in]wDecoded page width in pixels.
[in]hDecoded page height in pixels.
[out]out_workReceives the arena, or nullptr for a non-WebP page.
[out]out_capReceives the arena size in bytes, or 0.
[in,out]wsCaller-owned arena from which WebP storage is carved.
Returns
Result code.
Return values
k_ra8_okNon-WebP page, or arena carved successfully.
k_ra8_err_invalid_sizeThe geometry does not admit a WebP arena.
k_ra8_err_invalid_sizeThe caller workspace cannot satisfy the arena.
Precondition
src holds slen readable bytes.
out_work and out_cap are writable.
ws owns writable storage and is exclusive to this conversion.
Postcondition
On success *out_work is nullptr (non-WebP) or a workspace slice.
On failure *out_work is nullptr and the arena remains caller-owned.
Note
Not thread-safe; the slice remains owned by ws.
See also
jof_webp_work_bytes()
Since
0.1.0

Definition at line 198 of file mdl_export_jof.c.

References internal_jof_is_webp(), jof_webp_work_bytes(), k_jof_webp_work_cap, k_ra8_err_invalid_size, k_ra8_ok, mdl_export_workspace_take(), and RA8_INTERNAL.

Referenced by internal_jof_produce_page().

◆ internal_jof_is_webp()

bool internal_jof_is_webp ( const uint8_t * data,
size_t len )
static

Test whether a page's bytes carry the WebP RIFF container head.

Mirrors the producer's own dispatch sniff: both fourCCs must match, so a non-WebP RIFF (WAVE, AVI) is not mistaken for a WebP page and charged the whole-frame arena.

Parameters
[in]dataPage bytes (non-NULL).
[in]lenReadable byte count at data.
Returns
Whether data begins with a WebP container head.
Return values
trueBoth the "RIFF" and "WEBP" fourCCs are present.
falseToo short, or either fourCC differs.
Precondition
data holds len readable bytes.
The page has been slurped whole (the sniff reads the head only).
Postcondition
No state is mutated.
A false result means the streaming JPEG / PNG arms handle the page.
Note
Pure; thread-safe.
See also
internal_jof_one()
Since
0.1.0

Definition at line 98 of file mdl_export_jof.c.

References k_jof_webp_fourcc_ofs, k_jof_webp_head_len, k_jof_webp_riff_ofs, memcmp(), RA8_INTERNAL, s_jof_webp_riff, and s_jof_webp_webp.

Referenced by internal_jof_carve_webp().

◆ internal_jof_load_source()

ra8_err_t internal_jof_load_source ( mdl_storage_t * storage,
const char * in_path,
mdl_export_workspace_t * ws,
uint8_t ** out_src,
size_t * out_slen )
static

Stat, bound-check, arena-claim, and slurp one source image.

Requires a non-empty regular file within k_jof_source_cap, claims exactly that many bytes from ws, and reads the complete source into the claimed span.

Parameters
[in,out]storageInjected portable storage and transaction provider.
[in]in_pathNUL-terminated verified source image path.
[in,out]wsExclusive caller-owned export workspace to claim from.
[out]out_srcClaimed and filled source buffer on success.
[out]out_slenExact byte length read into out_src on success.
Returns
Stat-claim-slurp status.
Return values
k_ra8_okout_src holds out_slen valid source bytes.
k_ra8_err_not_foundin_path does not exist.
k_ra8_err_invalid_argin_path is not a regular non-empty file.
k_ra8_err_invalid_sizeThe source or arena bound was exceeded.
otherThe stat or slurp call failed.
Precondition
storage, in_path, ws, out_src, and out_slen are non-NULL.
ws is initialized and exclusive to this page.
Postcondition
On failure ws retains whatever partial claim it already made.
On success out_src points inside ws and stays valid until the caller rewinds that workspace.
Note
Not thread-safe for a shared workspace.
Since
Version 0.1.0

Definition at line 323 of file mdl_export_jof.c.

References fw_fs_stat_t::exists, mdl_storage_t::fs, fw_fs_stat(), k_fw_fs_node_file, k_jof_source_cap, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_err_not_found, k_ra8_ok, mdl_export_workspace_take(), fw_fs_t::names, priv_mdl_export_source_slurp(), RA8_INTERNAL, fw_fs_stat_t::size_bytes, and fw_fs_stat_t::type.

Referenced by internal_jof_one().

◆ internal_jof_one()

ra8_err_t internal_jof_one ( mdl_storage_t * storage,
const char * in_path,
const char * out_path,
mdl_export_workspace_t * ws )
static

Transcode one JPEG, PNG, or WebP page to a JOF band atlas.

Bounds the source and producer arenas, probes dimensions through the firmware producer, validates the borrowed staged file with the canonical JOF verifier, and publishes the completed sibling.

Parameters
[in,out]storageInjected portable storage and transaction provider.
[in]in_pathNUL-terminated verified source image path.
[in]out_pathNUL-terminated destination JOF path.
[in,out]wsExclusive caller-owned export workspace.
Returns
Transcode status.
Return values
k_ra8_okA complete independently validated JOF was published.
k_ra8_err_invalid_sizeA source or workspace bound was exceeded.
k_ra8_err_not_supportedThe producer cannot decode the image.
k_ra8_failStorage, validation, or publication operations failed.
Precondition
Paths are non-NULL, NUL-terminated, and stable for the call.
storage is initialized and exclusive to this operation.
ws owns writable storage and is exclusive to this page.
Postcondition
Success leaves one complete reader-consumable JOF.
Failure before publication aborts the stage and preserves the prior sibling.
Note
Not thread-safe for a shared workspace or destination.
Since
0.1.0

Definition at line 377 of file mdl_export_jof.c.

References fw_fs_transaction_t::active, internal_jof_load_source(), internal_jof_produce_page(), jof_probe_dims(), jof_work_bytes(), k_jof_band_h, k_mdl_format_jof, k_ra8_err_invalid_size, k_ra8_err_not_supported, k_ra8_ok, priv_mdl_export_output_abort(), priv_mdl_export_output_begin(), priv_mdl_export_output_commit(), RA8_INTERNAL, mdl_storage_txn_t::transaction, and mdl_export_output_t::writer.

Referenced by priv_mdl_export_jof().

◆ internal_jof_produce_page()

ra8_err_t internal_jof_produce_page ( const uint8_t * src,
size_t slen,
uint16_t w,
uint16_t h,
uint16_t tile_h,
uint32_t work_cap,
mdl_export_output_t * output,
mdl_export_workspace_t * ws )
static

Produce one page's atlas into an already-open output file.

Carves the producer's two scratch arenas – the streaming work arena, and the whole-frame arena only a WebP page needs – runs the producer, and releases both when the caller restores its workspace mark. Splitting this out of internal_jof_one() keeps producer configuration separate from source and publication ownership.

Parameters
[in]srcEncoded page bytes.
[in]slenLength of src in bytes.
[in]wDecoded page width in pixels.
[in]hDecoded page height in pixels.
[in]tile_hBand height for this page.
[in]work_capWork-arena size, from jof_work_bytes.
[in,out]outputActive staged output the atlas is written to.
[in,out]wsCaller-owned producer workspace.
Returns
Producer result.
Return values
k_ra8_okThe atlas was written to out.
k_ra8_err_no_memAn arena could not be allocated.
k_ra8_err_invalid_sizeThe geometry admits no WebP arena.
Precondition
src holds slen readable bytes and output is active.
work_cap is non-zero.
ws is exclusive and has not been reset during this page.
Postcondition
Both scratch arenas are released, on success and on every failure.
Nothing is written to output beyond what the producer emitted.
Note
Not thread-safe.
See also
internal_jof_carve_webp()
Since
0.1.0

Definition at line 258 of file mdl_export_jof.c.

References internal_jof_carve_webp(), internal_jof_pull(), internal_jof_sink(), jof_produce(), k_jof_codec_deflate, k_jof_work_cap, k_ra8_err_invalid_size, k_ra8_ok, mdl_export_workspace_take(), and RA8_INTERNAL.

Referenced by internal_jof_one().

◆ internal_jof_pull()

ra8_err_t internal_jof_pull ( void * ctx,
uint8_t * buf,
size_t cap,
size_t * got )
static

Copy the next encoded source span into a producer buffer.

Advances a bounded in-memory cursor by at most cap bytes and reports zero bytes at end of input.

Parameters
[in,out]ctxPull cursor describing the encoded page.
[out]bufDestination passed by the producer.
[in]capWritable capacity of buf.
[out]gotNumber of bytes copied.
Returns
Pull status.
Return values
k_ra8_okA bounded span, possibly empty at EOF, was returned.
Precondition
All pointers are non-NULL and cursor position does not exceed length.
buf addresses cap writable bytes.
Postcondition
Cursor position advances by exactly *got.
*got never exceeds cap or remaining input.
Note
Not thread-safe when a cursor is shared.
Since
0.1.0

Definition at line 131 of file mdl_export_jof.c.

References jof_pull_ctx_t::data, k_ra8_ok, jof_pull_ctx_t::len, memcpy(), jof_pull_ctx_t::pos, and RA8_INTERNAL.

Referenced by internal_jof_produce_page().

◆ internal_jof_sink()

ra8_err_t internal_jof_sink ( void * ctx,
const uint8_t * buf,
size_t len )
static

Append producer output bytes to the active publication transaction.

Converts the bounded transaction writer result into the producer error contract without exposing a host stream.

Parameters
[in,out]ctxExport output transaction owned by the caller.
[in]bufAtlas bytes to append.
[in]lenNumber of readable bytes at buf.
Returns
Sink status.
Return values
k_ra8_okEvery byte was written.
k_ra8_err_invalid_sizelen exceeds the transaction count type.
k_ra8_failThe transaction sink rejected the write.
Precondition
ctx is an active mdl_export_output_t.
buf holds len readable bytes.
Postcondition
Success advances the staged output by len bytes.
Failure remains visible to the producer.
Note
Not thread-safe for a shared output transaction.
Since
0.1.0

Definition at line 162 of file mdl_export_jof.c.

References k_ra8_err_invalid_size, priv_mdl_export_output_write(), and RA8_INTERNAL.

Referenced by internal_jof_produce_page().

◆ priv_mdl_export_jof()

ra8_err_t priv_mdl_export_jof ( mdl_storage_t * storage,
const char * dir,
const char names[][k_name_max],
size_t count,
mdl_export_workspace_t * ws )

Convert every page in a chapter directory to a sibling .jof atlas.

Transcodes each listed page in place: page.jpg becomes page.jof beside it, leaving the source file untouched. Each page is produced through the firmware's own jof producer, so a container this tool writes is byte-identical to one the board would produce from the same source, and the full-width band geometry is the shape longstrip scrolls.

Stops at the first page that fails and reports that page's error, so a partially converted directory is always explained by a non-ok return rather than discovered later; pages already written before the failure remain.

Parameters
[in,out]storageInjected portable storage and transaction provider.
[in]dirChapter directory holding the page files.
[in]namesPage file names, count entries of at most k_name_max bytes each, in the order they should be converted.
[in]countNumber of valid entries in names.
[in,out]wsExclusive caller-owned exporter workspace.
Returns
Result code.
Return values
k_ra8_okEvery page was transcoded.
k_ra8_err_not_supportedA page is in no format the producer decodes.
k_ra8_err_invalid_sizeA page's geometry admits no work arena.
k_ra8_failA page could not be read, or its output could not be opened or written.
Precondition
storage is initialized and exclusive to this export.
dir names an existing, readable directory.
names holds count readable entries.
Postcondition
On k_ra8_ok a .jof sibling exists for every entry in names.
On failure, earlier committed pages remain visible; the failed page and every later page preserve their prior destinations.
Note
Not thread-safe for a shared workspace or destination directory.
See also
mdl_export_chapter_ws()
Since
0.1.0

Definition at line 415 of file mdl_export_jof.c.

References internal_jof_one(), k_fw_fs_path_cap, k_name_max, k_ra8_err_invalid_size, k_ra8_ok, memcpy(), priv_mdl_export_path_join(), priv_mdl_export_snprintf_fit(), RA8_PRIV, strrchr(), and mdl_export_workspace::used.

Referenced by mdl_export_chapter_meta_ws().

Variable Documentation

◆ s_jof_webp_riff

const uint8_t s_jof_webp_riff[k_jof_webp_tag_len] = {'R', 'I', 'F', 'F'}
static

WebP RIFF container tag (page head bytes 0..3).

Definition at line 75 of file mdl_export_jof.c.

Referenced by internal_jof_is_webp().

◆ s_jof_webp_webp

const uint8_t s_jof_webp_webp[k_jof_webp_tag_len] = {'W', 'E', 'B', 'P'}
static

WebP form-type fourCC (page head bytes 8..11).

Definition at line 78 of file mdl_export_jof.c.

Referenced by internal_jof_is_webp().