ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
media_download_image.c
Go to the documentation of this file.
1
13
14#include <stddef.h>
15#include <stdint.h>
16
17#include "book.h"
18#include "mdl_format.h"
21#include "ra8_compress.h"
22#include "ra8_img_arena.h"
23#include "ra8_mdl_storage_ram.h"
24#include "ra8_webp_arena.h"
25
42
44typedef struct {
46 alignas(max_align_t) uint8_t bytes[k_ra8_compress_scratch_bytes];
48
67static uint8_t s_dummy_image[1];
69static uint8_t s_dummy_output[1];
70
72[[gnu::section(".sdram_data"), gnu::aligned(16)]] static uint8_t s_source[k_image_source_bytes];
74[[gnu::section(".sdram_data"),
75 gnu::aligned(16)]] static uint8_t s_stb_arena[k_image_stb_arena_bytes];
77[[gnu::section(".sdram_data"),
78 gnu::aligned(16)]] static uint8_t s_webp_arena[k_image_webp_arena_bytes];
80[[gnu::section(".sdram_data"), gnu::aligned(16)]] static uint8_t s_rgba[k_image_rgba_bytes];
82[[gnu::section(".sdram_data"), gnu::aligned(16)]] static uint8_t s_gray[k_image_gray_bytes];
84[[gnu::section(".sdram_data"),
85 gnu::aligned(16)]] static uint8_t s_normalized[k_image_normalized_bytes];
87[[gnu::section(".sdram_data"), gnu::aligned(16)]] static uint8_t s_image[k_image_normalized_bytes];
89[[gnu::section(".sdram_data"), gnu::aligned(16)]] static uint8_t s_flat[k_image_flat_bytes];
91[[gnu::section(".sdram_data"), gnu::aligned(16)]] static uint8_t s_packed[k_image_packed_bytes];
93[[gnu::section(".sdram_data"),
94 gnu::aligned(16)]] static uint8_t s_container_input[k_image_chunk_bytes];
96[[gnu::section(".sdram_data"),
97 gnu::aligned(16)]] static uint8_t s_container_compressed[k_image_compressed_bytes];
99[[gnu::section(".sdram_data"),
100 gnu::aligned(16)]] static uint64_t s_container_offsets[k_image_offset_entries];
102[[gnu::section(".sdram_data"), gnu::aligned(16)]] static image_compressor_t s_compressor;
103
118{
119 return (ra8_rabook_buffers_t){.chapters = s_chapters,
120 .nodes = s_nodes,
121 .attrs = s_attrs,
122 .stylesheets = s_styles,
123 .images = s_images,
124 .string_pool = s_strings,
125 .image_pool = s_dummy_image,
126 .out = s_dummy_output,
127 .chapter_cap = 1U,
128 .node_cap = 2U,
129 .attr_cap = 1U,
130 .stylesheet_cap = 1U,
131 .image_cap = 1U,
132 .string_cap = sizeof s_strings,
133 .image_pool_cap = sizeof s_dummy_image,
134 .out_cap = sizeof s_dummy_output};
135}
136
153 ra8_webp_arena_t* webp)
154{
155 *stb = (ra8_img_arena_t){.base = s_stb_arena, .cap = sizeof s_stb_arena};
156 *webp = (ra8_webp_arena_t){.base = s_webp_arena, .cap = sizeof s_webp_arena};
157 const ra8_rabook_comic_workspace_t comic = {
158 .builder = internal_builder(),
159 .raster = {.stb_arena = stb,
160 .webp_arena = webp,
161 .rgba = s_rgba,
162 .rgba_cap = sizeof s_rgba,
163 .gray = s_gray,
164 .gray_cap = sizeof s_gray},
165 .normalized = s_normalized,
166 .normalized_cap = sizeof s_normalized,
167 .stream_scratch = s_container_input,
168 .stream_scratch_cap = sizeof s_container_input,
169 };
170 const ra8_rabook_container_workspace_t container = {
171 .input = s_container_input,
172 .compressed = s_container_compressed,
173 .compressor = s_compressor.bytes,
174 .offsets = s_container_offsets,
175 .input_cap = sizeof s_container_input,
176 .compressed_cap = sizeof s_container_compressed,
177 .compressor_cap = sizeof s_compressor.bytes,
178 .offset_cap = k_image_offset_entries,
179 };
180 return (media_download_format_workspace_t){.comic = comic,
181 .container = container,
182 .image = s_image,
183 .flat = s_flat,
184 .packed = s_packed,
185 .image_cap = sizeof s_image,
186 .flat_cap = sizeof s_flat,
187 .packed_cap = sizeof s_packed};
188}
189
205RA8_INTERNAL static ra8_err_t internal_format(uint64_t* packed_size)
206{
209 }
210 const uint8_t* source = nullptr;
211 size_t source_size = 0U;
212 ra8_err_t err = ra8_mdl_storage_ram_view(&s_source_storage, &source, &source_size);
213 if (err != k_ra8_ok) {
214 return err;
215 }
216 ra8_img_arena_t stb = {};
217 ra8_webp_arena_t webp = {};
219 const media_download_format_config_t config = {
220 .page_id = "source-image",
221 .metadata = {.title = "Downloaded image",
222 .author = "C6 HTTPS source",
223 .language = "und",
224 .identifier = "urn:ra8:media-download:image"},
225 .chunk_bytes = k_image_chunk_bytes,
226 .max_image_edge = (uint16_t)k_image_edge,
227 .pixel_format = (uint8_t)k_book_pixfmt_gray4,
228 };
229 return priv_media_download_format_rabook(source, source_size, &config, &workspace, packed_size);
230}
231
250 uint64_t offset,
251 uint16_t length)
252{
253 uint16_t written = 0U;
254 ra8_err_t err =
255 transfer->storage.write(transfer->storage.ctx, &s_packed[(size_t)offset], length, &written);
256 if ((err == k_ra8_ok) && (written != length)) {
258 }
259 if (err == k_ra8_ok) {
260 err = transfer->sha256.update(transfer->sha256.ctx, &s_packed[(size_t)offset], length);
261 }
262 return err;
263}
264
283 uint64_t packed_size,
284 const char* destination)
285{
286 if ((packed_size == 0U) || (packed_size > sizeof s_packed) || (transfer->chunk_bytes == 0U)) {
288 }
289 ra8_err_t err = transfer->storage.begin(transfer->storage.ctx, destination);
290 bool active = err == k_ra8_ok;
291 if (err == k_ra8_ok) {
292 err = transfer->sha256.init(transfer->sha256.ctx);
293 }
294 uint64_t offset = 0U;
295 while ((err == k_ra8_ok) && (offset < packed_size)) {
296 uint64_t remaining = packed_size - offset;
297 uint16_t chunk = transfer->chunk_bytes;
298 if (remaining < (uint64_t)chunk) {
299 chunk = (uint16_t)remaining;
300 }
301 err = internal_publish_fragment(transfer, offset, chunk);
302 offset += (err == k_ra8_ok) ? chunk : 0U;
303 }
304 uint8_t digest[k_ra8_mdl_sha256_bytes] = {};
305 if (err == k_ra8_ok) {
306 err = transfer->sha256.final(transfer->sha256.ctx, digest);
307 }
308 if (err == k_ra8_ok) {
309 err = transfer->storage.validate(transfer->storage.ctx, packed_size, digest);
310 }
311 if (err == k_ra8_ok) {
312 err = transfer->storage.commit(transfer->storage.ctx);
313 if (err == k_ra8_ok) {
314 active = false;
315 }
316 }
317 if ((err != k_ra8_ok) && active) {
318 (void)transfer->storage.abort(transfer->storage.ctx);
319 }
320 return err;
321}
322
339{
340 if (transfer == nullptr) {
341 return k_ra8_err_null_ptr;
342 }
343 if ((transfer->storage.begin == nullptr) || (transfer->storage.write == nullptr) ||
344 (transfer->storage.validate == nullptr) || (transfer->storage.commit == nullptr) ||
345 (transfer->storage.abort == nullptr) || (transfer->storage.ctx == nullptr) ||
346 (transfer->sha256.init == nullptr) || (transfer->sha256.update == nullptr) ||
347 (transfer->sha256.final == nullptr) || (transfer->sha256.ctx == nullptr)) {
348 return k_ra8_err_null_ptr;
349 }
350 return k_ra8_ok;
351}
352
354 const char* url,
355 const char* destination,
356 const ra8_mdl_transfer_config_t* transfer)
357{
358 if ((link == nullptr) || (url == nullptr) || (destination == nullptr)) {
359 return k_ra8_err_null_ptr;
360 }
361 ra8_err_t err = internal_check_transfer(transfer);
362 ra8_mdl_transfer_config_t source_transfer = {};
363 if (err == k_ra8_ok) {
364 source_transfer = *transfer;
365 source_transfer.format = k_mdl_format_loose;
367 &source_transfer.storage,
368 s_source,
369 sizeof s_source);
370 }
371 if (err == k_ra8_ok) {
372 ra8_mdl_transfer_result_t result = {};
373 err = ra8_c6link_mdl_transfer(link, url, "source-image", &source_transfer, &result);
374 }
375 uint64_t packed_size = 0U;
376 if (err == k_ra8_ok) {
377 err = internal_format(&packed_size);
378 }
379 if (err == k_ra8_ok) {
380 err = internal_publish(transfer, packed_size, destination);
381 }
382 return err;
383}
Flat, execute-in-place container for a build-time "compiled" e-book.
@ k_book_pixfmt_gray4
4bpp packed grayscale, 2px/byte (default; every pre-field blob).
Definition book.h:213
static uint8_t s_packed[k_ez_packed_bytes]
Composite scratch: the dithered strip packed to 4 bpp (SRAM).
Definition main.c:211
static book_node_t s_nodes[k_arena_nodes]
Definition cpu1_main.c:110
static book_stylesheet_t s_styles[k_arena_styles]
Definition cpu1_main.c:112
static book_image_t s_images[k_arena_images]
Definition cpu1_main.c:113
static book_chapter_t s_chapters[k_arena_chapters]
Definition cpu1_main.c:109
static book_attr_t s_attrs[k_arena_attrs]
Definition cpu1_main.c:111
Shared media artifact format contract for download and export paths.
mdl_format_t
Artifact format selected by a media-download composition root.
Definition mdl_format.h:35
@ k_mdl_format_loose
Leave loose page images.
Definition mdl_format.h:36
@ k_mdl_format_rabook
Chunked reader-native book (.rabook).
Definition mdl_format.h:44
Private source-image to RBKC formatter for the media app.
ra8_err_t priv_media_download_format_rabook(const uint8_t *source, size_t source_size, const media_download_format_config_t *config, media_download_format_workspace_t *workspace, uint64_t *packed_size)
Format one encoded source image as a reader-native .rabook.
static char s_strings[k_image_string_bytes]
Metadata and DOM string pool.
static ra8_mdl_storage_ram_t s_source_storage
Private transaction for the encoded source bytes.
static uint8_t s_dummy_image[1]
External-image mode sentinel arena.
RA8_PRIV ra8_err_t priv_media_download_image_run(ra8_c6link_t *link, const char *url, const char *destination, const ra8_mdl_transfer_config_t *transfer)
Download one encoded image and publish it as a strict .rabook.
static image_compressor_t s_compressor
RBKC compressor state.
static RA8_INTERNAL ra8_err_t internal_publish(const ra8_mdl_transfer_config_t *transfer, uint64_t packed_size, const char *destination)
Strictly publish one complete locally generated RBKC artifact.
static uint8_t s_rgba[k_image_rgba_bytes]
Full-resolution WebP RGBA frame storage.
static RA8_INTERNAL media_download_format_workspace_t internal_workspace(ra8_img_arena_t *stb, ra8_webp_arena_t *webp)
Bind all fixed source-image formatter workspaces.
static uint8_t s_dummy_output[1]
Streaming-output mode sentinel arena.
static RA8_INTERNAL ra8_err_t internal_publish_fragment(const ra8_mdl_transfer_config_t *transfer, uint64_t offset, uint16_t length)
Append and hash one generated artifact fragment.
static uint8_t s_stb_arena[k_image_stb_arena_bytes]
Caller arena for stb JPEG/PNG/GIF/BMP decoding.
static RA8_INTERNAL ra8_rabook_buffers_t internal_builder(void)
Construct the fixed one-page builder arena descriptor.
static uint8_t s_webp_arena[k_image_webp_arena_bytes]
Caller arena for WebP decoder transient storage.
static RA8_INTERNAL ra8_err_t internal_check_transfer(const ra8_mdl_transfer_config_t *transfer)
Prove every injected callback required by image mode is present.
static uint8_t s_flat[k_image_flat_bytes]
Complete private flat RABOOK1 spool.
static uint8_t s_source[k_image_source_bytes]
Complete fetched encoded image.
static uint8_t s_normalized[k_image_normalized_bytes]
One normalized gray4 payload.
static const mdl_format_t s_output_format
Real application output selection, independent of the C6 transport.
static RA8_INTERNAL ra8_err_t internal_format(uint64_t *packed_size)
Convert the committed encoded source into private RBKC bytes.
static uint8_t s_gray[k_image_gray_bytes]
Downscaled grayscale frame storage.
static uint8_t s_container_input[k_image_chunk_bytes]
One uncompressed container chunk.
image_limit_t
Fixed one-page source and conversion capacities.
@ k_image_string_bytes
Builder string-pool bytes.
@ k_image_webp_arena_bytes
WebP decoder scratch arena.
@ k_image_flat_bytes
Flat RABOOK1 capacity.
@ k_image_offset_entries
Flat chunks plus terminator.
@ k_image_compressed_bytes
One zlib stream capacity.
@ k_image_stb_arena_bytes
stb decoder allocation arena.
@ k_image_chunk_bytes
RBKC inflated chunk geometry.
@ k_image_gray_bytes
1600x1600 grayscale frame.
@ k_image_normalized_bytes
Gray4 normalized page bytes.
@ k_image_source_bytes
Maximum fetched encoded image.
@ k_image_rgba_bytes
Maximum decoded RGBA frame.
@ k_image_packed_bytes
Final RBKC capacity.
@ k_image_edge
Longest normalized page edge.
static uint64_t s_container_offsets[k_image_offset_entries]
Complete RBKC offset table for the bounded flat spool.
static uint8_t s_container_compressed[k_image_compressed_bytes]
One compressed container stream.
static uint8_t s_image[k_image_normalized_bytes]
External normalized-image spool.
Private encoded-image download and RABOOK publication composition.
#define RA8_PRIV
Module-private helper: shared across TUs but only inside one library.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
App-domain DEFLATE compress / decompress (zero-heap, firmware-safe).
@ k_ra8_compress_scratch_bytes
Minimum compress scratch size (one miniz tdefl_compressor).
@ k_ra8_err_not_supported
Requested feature not compiled in, not wired, or not supported by this MCU variant.
Definition ra8_err.h:180
@ 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
Heap-free scratch allocator hooks for the stb_image single-TU build.
@ k_ra8_mdl_sha256_bytes
SHA-256 digest size in bytes.
Caller-buffer transaction adapter for verified C6 media sources.
ra8_err_t ra8_mdl_storage_ram_view(const ra8_mdl_storage_ram_t *storage, const uint8_t **data, size_t *length)
Expose the complete committed source as an immutable byte view.
ra8_err_t ra8_mdl_storage_ram_init(ra8_mdl_storage_ram_t *storage, ra8_mdl_storage_iface_t *output, uint8_t *data, size_t capacity)
Bind a caller buffer as one transactional media destination.
Heap-free scratch allocator hooks for the vendored libwebp decoder.
One name="value" attribute on an element.
Definition book.h:317
One spine document (a renderable chapter) plus its TOC label.
Definition book.h:280
Descriptor for one transcoded image in the image pool.
Definition book.h:354
One DOM node.
Definition book.h:299
A preserved CSS stylesheet and the chapter it scopes to.
Definition book.h:332
Aligned caller-owned miniz compressor storage.
uint8_t bytes[k_ra8_compress_scratch_bytes]
Compressor state bytes.
Immutable policy for one fetched-image conversion.
Complete caller-owned storage for image-to-RBKC conversion.
Caller-owned bump arena backing a single image decode.
ra8_err_t(* update)(void *ctx, const uint8_t *data, uint16_t len)
Feed one ordered byte span to the running hash.
ra8_err_t(* init)(void *ctx)
Reset the caller-owned context for a SHA-256 operation.
void * ctx
Hash context passed to every function.
ra8_err_t(* final)(void *ctx, uint8_t out[k_ra8_mdl_sha256_bytes])
Finalise the hash into the caller-provided digest.
ra8_err_t(* write)(void *ctx, const uint8_t *data, uint16_t len, uint16_t *written)
Append len bytes and report the exact number persisted.
ra8_err_t(* commit)(void *ctx)
Atomically publish the complete temporary object.
void * ctx
Backend context passed to every function.
ra8_err_t(* begin)(void *ctx, const char *destination)
Create private temporary state for destination.
ra8_err_t(* validate)(void *ctx, uint64_t total_bytes, const uint8_t sha256[k_ra8_mdl_sha256_bytes])
Validate artifact identity and structure before publication.
ra8_err_t(* abort)(void *ctx)
Destroy temporary state; valid after every successful begin.
Mutable transaction over one caller-owned destination span.
ra8_mdl_sha256_iface_t sha256
Independent running digest.
mdl_format_t format
Requested and validated artifact.
uint16_t chunk_bytes
Maximum bytes requested per pull.
ra8_mdl_storage_iface_t storage
Transactional RA8-local destination.
Caller-owned, fixed-capacity arenas the builder appends into (no heap).
Caller-owned arenas retained for one streaming comic build.
Caller-owned transient storage for one RBKC write.
Caller-owned bump arena backing a single WebP decode.