33typedef enum : uint32_t {
45typedef enum : uint8_t {
50static const char*
const s_tag =
"ra8_rabook_gray4";
90 RA8_ASSERT(src !=
nullptr,
"Source pointer must not be null");
91 RA8_ASSERT(src_w > 0U,
"Source width must be positive");
92 RA8_ASSERT(src_h > 0U,
"Source height must be positive");
94 uint16_t sx0 = (uint16_t)(sx_fp >>
k_fp_shift);
95 uint16_t sy0 = (uint16_t)(sy_fp >>
k_fp_shift);
97 (uint16_t)((((uint32_t)sx0 + 1U) < (uint32_t)src_w) ? ((uint32_t)sx0 + 1U) : (src_w - 1U));
99 (uint16_t)((((uint32_t)sy0 + 1U) < (uint32_t)src_h) ? ((uint32_t)sy0 + 1U) : (src_h - 1U));
100 uint64_t fx = sx_fp & (uint64_t)
k_fp_mask;
101 uint64_t fy = sy_fp & (uint64_t)
k_fp_mask;
105 uint64_t p00 = src[((uint32_t)sy0 * src_w) + sx0];
106 uint64_t p10 = src[((uint32_t)sy0 * src_w) + sx1];
107 uint64_t p01 = src[((uint32_t)sy1 * src_w) + sx0];
108 uint64_t p11 = src[((uint32_t)sy1 * src_w) + sx1];
110 uint64_t val = (p00 * ifx * ify) + (p10 * fx * ify) + (p01 * ifx * fy) + (p11 * fx * fy);
139 for (uint32_t i = 0U; i < n_pixels; i++) {
150 out[byte_idx] |= nib;
165 if ((out_w ==
nullptr) || (out_h ==
nullptr)) {
169 if ((src_w == 0U) || (src_h == 0U) || (max_edge == 0U)) {
175 uint16_t longer = (src_w >= src_h) ? src_w : src_h;
176 if (longer <= max_edge) {
182 uint32_t half_longer = (uint32_t)longer / 2U;
183 *out_w = (uint16_t)((((uint32_t)src_w * max_edge) + half_longer) / longer);
184 *out_h = (uint16_t)((((uint32_t)src_h * max_edge) + half_longer) / longer);
204 if ((dst_w == 0U) || (dst_h == 0U)) {
209 if ((src_w == 0U) || (src_h == 0U)) {
210 (void)
memset(dst, 0, (
size_t)dst_w * (
size_t)dst_h);
214 uint64_t x_step = ((uint64_t)src_w <<
k_fp_shift) / dst_w;
215 uint64_t y_step = ((uint64_t)src_h <<
k_fp_shift) / dst_h;
217 for (uint16_t dy = 0U; dy < dst_h; dy++) {
218 uint64_t sy_fp = (uint64_t)dy * y_step;
220 for (uint16_t dx = 0U; dx < dst_w; dx++) {
221 uint64_t sx_fp = (uint64_t)dx * x_step;
240 uint32_t n_pixels = (uint32_t)w * h;
243 if (n_pixels == 0U) {
248 if (out_cap < n_bytes) {
253 (void)
memset(out, 0, n_bytes);
271 uint32_t n_bytes = (uint32_t)w * h;
278 if (out_cap < n_bytes) {
283 (void)
memcpy(out, gray_pixels, n_bytes);
static const char * s_tag
Logging / check tag.
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_ASSERT(condition, message)
Runtime invariant check.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_error(tag, message)
RA8 log error.
ra8_err_t ra8_rabook_gray4_encode(const uint8_t *gray_pixels, uint16_t w, uint16_t h, uint8_t *out, uint32_t out_cap, uint32_t *out_size)
Quantise a grayscale buffer to 16 levels and pack as 4-bpp nibbles.
ra8_err_t ra8_rabook_gray4_downscale(const uint8_t *src, uint16_t src_w, uint16_t src_h, uint8_t *dst, uint16_t dst_w, uint16_t dst_h)
Bilinear-interpolate a grayscale image from (src_w x src_h) to (dst_w x dst_h).
static uint8_t internal_bilinear_sample(const uint8_t *src, uint16_t src_w, uint16_t src_h, uint64_t sx_fp, uint64_t sy_fp)
Sample one bilinear-interpolated pixel at fixed-point source (sx_fp, sy_fp).
ra8_gray4_fp_t
Q16.16 fixed-point constants for the bilinear downscale kernel.
@ k_fp_norm_shift
Right-shift to normalise 64-bit product.
@ k_fp_shift
Integer part starts at bit 16.
@ k_fp_mask
Fractional-bits mask (low 16 bits).
@ k_fp_unit
1.0 in Q16.16 (65536).
ra8_err_t ra8_rabook_gray8_encode(const uint8_t *gray_pixels, uint16_t w, uint16_t h, uint8_t *out, uint32_t out_cap, uint32_t *out_size)
Copy a grayscale buffer out verbatim as 8-bpp (one byte per pixel).
static void internal_pack_nibbles(const uint8_t *gray_pixels, uint32_t n_pixels, uint8_t *out)
Quantise n_pixels grayscale bytes to 4-bpp nibbles packed into out.
ra8_gray4_nib_t
Nibble packing constants.
@ k_nib_shift
Shift even pixel into the high nibble of a byte.
@ k_nib_lo_msk
Bit 0: whether pixel index is odd (low nibble).
void ra8_rabook_gray4_output_dims(uint16_t src_w, uint16_t src_h, uint16_t max_edge, uint16_t *out_w, uint16_t *out_h)
Compute scaled output dimensions keeping the longer edge within max_edge.
Grayscale image transcode stage (4-bpp / 8-bpp) for the on-device EPUB compiler (#149).
@ k_ra8_rabook_gray4_quant_div
Palette step: 255 / 15 rounds to 17.
@ k_ra8_rabook_gray4_nib_per_byte
Pixels packed per output byte.
@ k_ra8_rabook_gray4_nib_max
Maximum nibble value (4 bits unsigned).
@ k_ra8_rabook_gray4_round_half
Added before quant divide to round-to-nearest.