ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_camera_codec_jpeg_sw.c
Go to the documentation of this file.
1
17
19
20#include <stddef.h>
21#include <stdint.h>
22
23#include "ra8_attributes.h"
24#include "ra8_camera_internal.h"
25#include "ra8_err.h"
26#include "ra8_jpeg_sw.h"
27
41
57RA8_INTERNAL static uint8_t internal_jpeg_sw_clamp(int32_t component)
58{
59 if (component < 0) {
60 return 0U;
61 }
62 if (component > (int32_t)k_camera_jpeg_u8_max) {
63 return (uint8_t)k_camera_jpeg_u8_max;
64 }
65 return (uint8_t)component;
66}
67
83RA8_INTERNAL static void
84internal_jpeg_sw_ycbcr_to_rgb(uint8_t y, uint8_t cb, uint8_t cr, uint8_t* output)
85{
86 int32_t luma = (int32_t)y - (int32_t)k_camera_jpeg_luma_black;
87 if (luma < 0) {
88 luma = 0;
89 }
90 const int32_t blue_delta = (int32_t)cb - (int32_t)k_camera_jpeg_chroma_mid;
91 const int32_t red_delta = (int32_t)cr - (int32_t)k_camera_jpeg_chroma_mid;
92 output[0] = internal_jpeg_sw_clamp(((int32_t)k_camera_jpeg_luma_scale * luma +
93 (int32_t)k_camera_jpeg_red_cr * red_delta +
94 (int32_t)k_camera_jpeg_rounding) >>
95 (int32_t)k_camera_jpeg_shift);
96 output[1] = internal_jpeg_sw_clamp(
97 ((int32_t)k_camera_jpeg_luma_scale * luma - (int32_t)k_camera_jpeg_green_cb * blue_delta -
98 (int32_t)k_camera_jpeg_green_cr * red_delta + (int32_t)k_camera_jpeg_rounding) >>
99 (int32_t)k_camera_jpeg_shift);
100 output[2] = internal_jpeg_sw_clamp(((int32_t)k_camera_jpeg_luma_scale * luma +
101 (int32_t)k_camera_jpeg_blue_cb * blue_delta +
102 (int32_t)k_camera_jpeg_rounding) >>
103 (int32_t)k_camera_jpeg_shift);
104}
105
122RA8_INTERNAL static void
123internal_jpeg_sw_read_rgb(const ra8_camera_frame_t* input, uint32_t x, uint32_t y, uint8_t* output)
124{
125 const uint32_t row = y * input->stride_bytes;
126 if (input->format == k_ra8_camera_format_rgb888) {
127 const uint32_t offset = row + (x * 3U);
128 output[0] = input->data[offset];
129 output[1] = input->data[offset + 1U];
130 output[2] = input->data[offset + 2U];
131 return;
132 }
133 const uint32_t pair = row + ((x & ~1U) * 2U);
134 const uint32_t yoff = ((x & 1U) == 0U) ? 1U : 3U;
135 internal_jpeg_sw_ycbcr_to_rgb(input->data[pair + yoff],
136 input->data[pair],
137 input->data[pair + 2U],
138 output);
139}
140
156 const ra8_camera_frame_t* input)
157{
158 const uint32_t out_width = (uint32_t)state->cfg.output_width;
159 const uint32_t out_height = (uint32_t)state->cfg.output_height;
160 for (uint32_t y = 0U; y < out_height; y += 1U) {
161 const uint32_t source_y = (y * (uint32_t)input->height) / out_height;
162 for (uint32_t x = 0U; x < out_width; x += 1U) {
163 const uint32_t source_x = (x * (uint32_t)input->width) / out_width;
165 source_x,
166 source_y,
167 &state->cfg.rgb_workspace[(((size_t)y * out_width) + x) * 3U]);
168 }
169 }
170}
171
194 const ra8_camera_frame_t* input,
195 const ra8_camera_buffer_t* output_buffer,
196 ra8_camera_frame_t* out_frame)
197{
198 if (ctx == nullptr) {
199 return k_ra8_err_null_ptr;
200 }
201 if (input == nullptr) {
202 return k_ra8_err_null_ptr;
203 }
204 if (output_buffer == nullptr) {
205 return k_ra8_err_null_ptr;
206 }
207 if (out_frame == nullptr) {
208 return k_ra8_err_null_ptr;
209 }
210 if (output_buffer->data == nullptr) {
211 return k_ra8_err_null_ptr;
212 }
213 if (output_buffer->capacity == 0U) {
214 return k_ra8_err_null_ptr;
215 }
216 if (input->format != k_ra8_camera_format_rgb888) {
217 if (input->format != k_ra8_camera_format_uyvy422) {
219 }
220 }
222 internal_jpeg_sw_prepare_rgb(state, input);
223 uint32_t produced = 0U;
224 const ra8_err_t encoded = ra8_jpeg_sw_encode(state->cfg.rgb_workspace,
225 state->cfg.output_width,
226 state->cfg.output_height,
227 state->cfg.quality,
228 output_buffer->data,
229 output_buffer->capacity,
230 &produced);
231 if (encoded != k_ra8_ok) {
232 return encoded;
233 }
234 *out_frame = (ra8_camera_frame_t){
235 .data = output_buffer->data,
236 .bytes = produced,
237 .stride_bytes = 0U,
238 .width = state->cfg.output_width,
239 .height = state->cfg.output_height,
240 .format = k_ra8_camera_format_jpeg,
241 };
242 return k_ra8_ok;
243}
244
249
253{
254 if (codec == nullptr) {
255 return k_ra8_err_null_ptr;
256 }
257 if (state == nullptr) {
258 return k_ra8_err_null_ptr;
259 }
260 if (cfg == nullptr) {
261 return k_ra8_err_null_ptr;
262 }
263 if (cfg->rgb_workspace == nullptr) {
264 return k_ra8_err_null_ptr;
265 }
266 if (cfg->quality < (uint8_t)k_ra8_jpeg_sw_quality_min) {
268 }
269 if (cfg->quality > (uint8_t)k_ra8_jpeg_sw_quality_max) {
271 }
272 if (cfg->output_width == 0U) {
274 }
275 if (cfg->output_height == 0U) {
277 }
278 const uint32_t row_bytes = (uint32_t)cfg->output_width * 3U;
279 if ((uint32_t)cfg->output_height > (UINT32_MAX / row_bytes)) {
281 }
282 if (cfg->rgb_workspace_capacity < (row_bytes * (uint32_t)cfg->output_height)) {
284 }
285 state->cfg = *cfg;
287 codec->ctx = state;
288 return k_ra8_ok;
289}
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
struct ra8_camera_codec_iface ra8_camera_codec_iface_t
Opaque codec vtable; concrete codec backends define its rows.
Definition ra8_camera.h:51
@ k_ra8_camera_format_rgb888
Packed R, G, B bytes per pixel.
Definition ra8_camera.h:64
@ k_ra8_camera_format_uyvy422
Packed Cb, Y0, Cr, Y1 pixel pairs.
Definition ra8_camera.h:65
@ k_ra8_camera_format_jpeg
Complete encoded JPEG byte stream.
Definition ra8_camera.h:66
camera_jpeg_color_t
BT.601 limited-range fixed-point conversion constants.
@ k_camera_jpeg_luma_scale
Fixed-point luma scale.
@ k_camera_jpeg_blue_cb
Cb contribution to blue.
@ k_camera_jpeg_shift
Fixed-point fractional-bit count.
@ k_camera_jpeg_u8_max
Maximum packed RGB channel value.
@ k_camera_jpeg_chroma_mid
Neutral chroma level.
@ k_camera_jpeg_luma_black
Limited-range black level.
@ k_camera_jpeg_red_cr
Cr contribution to red.
@ k_camera_jpeg_green_cb
Cb subtraction from green.
@ k_camera_jpeg_rounding
Fixed-point rounding bias.
@ k_camera_jpeg_green_cr
Cr subtraction from green.
static ra8_err_t internal_jpeg_sw_encode(void *ctx, const ra8_camera_frame_t *input, const ra8_camera_buffer_t *output_buffer, ra8_camera_frame_t *out_frame)
Convert and encode one raw frame with ra8_jpeg_sw.
ra8_err_t ra8_camera_codec_jpeg_sw_init(ra8_camera_codec_t *codec, ra8_camera_codec_jpeg_sw_state_t *state, const ra8_camera_codec_jpeg_sw_cfg_t *cfg)
Bind the software baseline-JPEG encoder backend.
static uint8_t internal_jpeg_sw_clamp(int32_t component)
Clamp a signed RGB component to one byte.
static void internal_jpeg_sw_ycbcr_to_rgb(uint8_t y, uint8_t cb, uint8_t cr, uint8_t *output)
Convert one limited-range YCbCr pixel to packed RGB888.
static void internal_jpeg_sw_prepare_rgb(const ra8_camera_codec_jpeg_sw_state_t *state, const ra8_camera_frame_t *input)
Nearest-neighbour sample input into the configured RGB workspace.
static void internal_jpeg_sw_read_rgb(const ra8_camera_frame_t *input, uint32_t x, uint32_t y, uint8_t *output)
Read one source pixel as RGB888.
static const ra8_camera_codec_iface_t s_jpeg_sw_codec_iface
Software JPEG codec vtable.
RGB888-to-JPEG software codec backend for ra8_camera.
Private source and codec vtables for ra8_camera backends.
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_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ 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
Pure-software baseline JPEG (ISO/IEC 10918-1 / ITU-T T.81) codec.
@ k_ra8_jpeg_sw_quality_min
Lowest legal quality.
Definition ra8_jpeg_sw.h:74
@ k_ra8_jpeg_sw_quality_max
Largest legal quality.
Definition ra8_jpeg_sw.h:78
ra8_err_t ra8_jpeg_sw_encode(const uint8_t *rgb_buf, uint16_t width, uint16_t height, uint8_t quality, uint8_t *out_buf, uint32_t out_buf_len, uint32_t *out_len)
Encode a packed RGB888 frame as a baseline JPEG.
Caller-owned writable byte-buffer description.
Definition ra8_camera.h:80
uint32_t capacity
Writable byte capacity.
Definition ra8_camera.h:82
uint8_t * data
First writable byte, or NULL when capacity is zero.
Definition ra8_camera.h:81
Configuration and caller-owned RGB workspace for software JPEG.
uint16_t output_width
Encoded image width.
uint32_t rgb_workspace_capacity
Writable workspace bytes.
uint8_t quality
JPEG quality passed to the encoder.
uint16_t output_height
Encoded image height.
uint8_t * rgb_workspace
Caller-owned packed RGB workspace.
Caller-owned private state for the software JPEG backend.
ra8_camera_codec_jpeg_sw_cfg_t cfg
Validated configuration (private).
Caller-owned handle binding one image codec and its context.
Definition ra8_camera.h:145
void * ctx
Caller-owned backend context.
Definition ra8_camera.h:147
const ra8_camera_codec_iface_t * iface
Bound codec vtable (private).
Definition ra8_camera.h:146
Immutable view of one captured or encoded image.
Definition ra8_camera.h:96
ra8_camera_format_t format
Pixel or compressed-image layout.
Definition ra8_camera.h:102
const uint8_t * data
Borrowed immutable image bytes.
Definition ra8_camera.h:97
uint16_t height
Image height in pixels.
Definition ra8_camera.h:101
uint16_t width
Image width in pixels.
Definition ra8_camera.h:100
uint32_t stride_bytes
Bytes between uncompressed rows.
Definition ra8_camera.h:99