ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
jof_produce_webp.c
Go to the documentation of this file.
1
27
28#include <stddef.h>
29#include <stdint.h>
30
31#include "jof_internal.h"
32#include "jof_produce.h"
33#include "ra8_attributes.h"
34#include "ra8_err.h"
35#include "ra8_webp.h"
36#include "ra8_webp_arena.h"
37
48typedef enum : uint32_t {
51 k_jof_webp_scratch_slack = 1U * 1024U * 1024U,
53
54uint32_t jof_webp_work_bytes(uint16_t max_width, uint16_t max_height, uint32_t max_src_bytes)
55{
56 if ((max_width == 0U) || ((uint32_t)max_width > (uint32_t)k_ra8_webp_max_dim) ||
57 (max_height == 0U) || ((uint32_t)max_height > (uint32_t)k_ra8_webp_max_dim) ||
58 (max_src_bytes == 0U)) {
59 return 0U;
60 }
61 const uint64_t frame = (uint64_t)max_width * (uint64_t)max_height * (uint64_t)k_jof_webp_bpp;
62 const uint64_t scratch =
63 ((uint64_t)k_jof_webp_scratch_mult * frame) + (uint64_t)k_jof_webp_scratch_slack;
64 const uint64_t total = (uint64_t)max_src_bytes + frame + scratch + (uint64_t)k_jof_carve_slack;
65 if (total > (uint64_t)UINT32_MAX) {
66 return 0U;
67 }
68 return (uint32_t)total;
69}
70
94internal_webp_pull_all(jof_prefix_pull_t* pfx, uint8_t* dst, size_t cap, size_t* out_len)
95{
96 size_t len = 0U;
97 while (len < cap) {
98 size_t got = 0U;
99 const ra8_err_t err = priv_jof_prefix_pull(pfx, &dst[len], cap - len, &got);
100 if (err != k_ra8_ok) {
101 return err;
102 }
103 if (got == 0U) {
104 *out_len = len;
105 return k_ra8_ok;
106 }
107 len += got;
108 }
109 /* The arena filled without hitting end of stream: the source is at least as
110 * large as the whole arena, so there is no room for the frame + scratch. */
112}
113
137internal_webp_feed(jof_prod_state_t* st, const uint8_t* frame, uint16_t w, uint16_t h)
138{
139 const uint32_t stride = (uint32_t)w * (uint32_t)k_jof_webp_bpp;
140 const uint32_t th = (uint32_t)st->cfg->tile_h;
141 uint32_t y = 0U;
142 while (y < (uint32_t)h) {
143 const uint32_t nrows = (((uint32_t)h - y) < th) ? ((uint32_t)h - y) : th;
144 const ra8_err_t err = priv_jof_on_rows(st,
145 &frame[(size_t)y * (size_t)stride],
146 w,
147 (uint16_t)y,
148 (uint16_t)nrows,
149 (uint8_t)k_jof_webp_bpp);
150 if (err != k_ra8_ok) {
151 return err;
152 }
153 y += nrows;
154 }
155 return k_ra8_ok;
156}
157
159{
160 uint8_t* const arena = st->cfg->webp_work;
161 if (arena == nullptr) {
162 return k_ra8_err_not_supported; /* WebP source but no whole-frame arena */
163 }
164 const size_t acap = st->cfg->webp_work_cap;
165 size_t src_len = 0U;
166 ra8_err_t err = internal_webp_pull_all(pfx, arena, acap, &src_len);
167 if (err != k_ra8_ok) {
168 return err;
169 }
170 uint32_t w = 0U;
171 uint32_t h = 0U;
172 err = ra8_webp_get_info(arena, src_len, &w, &h);
173 if (err != k_ra8_ok) {
174 return err;
175 }
176 err = priv_jof_on_geom(st, (uint16_t)w, (uint16_t)h, (uint8_t)k_jof_webp_bpp);
177 if (err != k_ra8_ok) {
178 return err;
179 }
180 const size_t mask = (size_t)k_jof_bump_align - 1U;
181 const size_t used = (src_len + mask) & ~mask;
182 const uint64_t frame64 = (uint64_t)w * (uint64_t)h * (uint64_t)k_jof_webp_bpp;
183 if ((used >= acap) || (frame64 >= ((uint64_t)acap - (uint64_t)used))) {
184 return k_ra8_err_invalid_size; /* no room for frame + at least some scratch */
185 }
186 const size_t frame_n = (size_t)frame64;
187 uint8_t* const frame = &arena[used];
188 const size_t scr_off = used + frame_n;
189 ra8_webp_arena_t wa = {.base = &arena[scr_off], .cap = acap - scr_off, .offset = 0U, .live = 0U};
190 err = ra8_webp_decode_rgba(arena,
191 src_len,
192 &wa,
193 frame,
194 (size_t)w * (size_t)k_jof_webp_bpp,
195 frame_n,
196 nullptr,
197 nullptr);
198 if (err != k_ra8_ok) {
199 return err;
200 }
201 return internal_webp_feed(st, frame, (uint16_t)w, (uint16_t)h);
202}
Module-private seams shared by the producer translation units.
ra8_err_t priv_jof_on_geom(void *ctx, uint16_t width, uint16_t height, uint8_t channels)
Bind the source geometry: validate caps, carve buffers, emit header.
@ k_jof_bump_align
Every carve is 8-byte aligned.
@ k_jof_carve_slack
Alignment slack folded into every arena sizing.
ra8_err_t priv_jof_on_rows(void *ctx, const uint8_t *px, uint16_t width, uint16_t y0, uint16_t nrows, uint8_t channels)
Row sink shared by every decoder arm: accumulate, flush full bands.
ra8_err_t priv_jof_prefix_pull(void *ctx, uint8_t *buf, size_t cap, size_t *got)
Pull adapter: replay the sniffed head, then delegate to the source.
Import-time transcode producer: JPEG/PNG/WebP -> JOF band-tile atlas in bounded RAM (#231,...
static ra8_err_t internal_webp_feed(jof_prod_state_t *st, const uint8_t *frame, uint16_t w, uint16_t h)
Band a decoded RGBA frame through the shared tile path.
static ra8_err_t internal_webp_pull_all(jof_prefix_pull_t *pfx, uint8_t *dst, size_t cap, size_t *out_len)
Pull the whole compressed WebP source into the webp_work arena.
uint32_t jof_webp_work_bytes(uint16_t max_width, uint16_t max_height, uint32_t max_src_bytes)
Compute the whole-frame webp_work arena a WebP source needs (#290).
jof_webp_const_t
WebP whole-frame arena sizing constants (webp_work layout).
@ k_jof_webp_scratch_mult
Scratch >= this * frame bytes.
@ k_jof_webp_bpp
WebP decodes to RGBA8888.
@ k_jof_webp_scratch_slack
Fixed scratch slack (bytes).
ra8_err_t priv_jof_webp_transcode(jof_prod_state_t *st, jof_prefix_pull_t *pfx)
Transcode a WebP source into the JOF tile path (whole-frame, #290).
Annotation-attribute framework macros for ra8-firmware.
#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).
Error Code Definitions for ra8-firmware.
@ 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_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
Zero-heap WebP (VP8 / VP8L) decode facade over the vendored libwebp.
ra8_err_t ra8_webp_decode_rgba(const uint8_t *data, size_t size, ra8_webp_arena_t *arena, uint8_t *out_rgba, size_t out_stride, size_t out_capacity, uint32_t *out_w, uint32_t *out_h)
Decode a WebP into a caller-owned RGBA8888 buffer, heap-free.
Definition ra8_webp.c:187
@ k_ra8_webp_max_dim
Max accepted width/height, pixels/axis.
Definition ra8_webp.h:58
ra8_err_t ra8_webp_get_info(const uint8_t *data, size_t size, uint32_t *out_w, uint32_t *out_h)
Read a WebP header's pixel dimensions without decoding the body.
Definition ra8_webp.c:33
Heap-free scratch allocator hooks for the vendored libwebp decoder.
Pull adapter that replays the sniffed head bytes, then delegates.
Whole transcode state (module-static instance in the producer TU).
const jof_produce_cfg_t * cfg
Caller configuration.
size_t webp_work_cap
WebP arena size; see webp_work_bytes().
uint8_t * webp_work
Whole-frame arena for WebP; NULL disables it.
uint16_t tile_h
Tile height, pixels (>= 1).
Caller-owned bump arena backing a single WebP decode.