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

Pure-software baseline JPEG encoder: pixel pipeline and public API. More...

#include <stdint.h>
#include <string.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_jpeg_sw.h"
#include "ra8_jpeg_sw_encode_internal.h"
#include "ra8_jpeg_sw_internal.h"
#include "ra8_log.h"
Include dependency graph for ra8_jpeg_sw_encode.c:

Go to the source code of this file.

Functions

static void internal_fwd_dct_1d_norm (const int32_t *in, int32_t *out)
 1-D forward DCT pass with JPEG normalization folded in.
static void internal_fdct8x8 (int32_t *block)
 2-D forward DCT of one 8x8 block, in place.
static uint16_t internal_enc_quality_scale (uint8_t q)
 Compute the IJG quality-scale factor.
static void internal_enc_scale_qtab (const uint8_t *base, uint8_t *dst, uint16_t scale)
 Scale a base quantization table by scale/100, clamped to 1..255.
static uint8_t internal_enc_bits_needed (int32_t v)
 Compute the number of significant-magnitude bits of v.
static int32_t internal_enc_quantize (int32_t v, uint8_t qv)
 Quantize one DCT coefficient with symmetric rounding.
static void internal_enc_block_ac (ra8_jpeg_enc_ctx_t *e, const int32_t *z, const uint16_t *ac_codes, const uint8_t *ac_sizes)
 Emit the 63 AC coefficients of one quantized block.
static void internal_enc_block (ra8_jpeg_enc_ctx_t *e, const int32_t *spatial, const uint8_t *qtab, uint8_t comp_idx, const uint16_t *dc_codes, const uint8_t *dc_sizes, const uint16_t *ac_codes, const uint8_t *ac_sizes)
 Encode one 8x8 block of source samples.
static void internal_enc_rgb_to_ycc_row (const uint8_t *rgb, uint16_t n, int32_t *y, int32_t *cb, int32_t *cr)
 Convert one row of RGB into Y, Cb, Cr samples (BT.601 Q16).
static void internal_enc_sample_y_block (const int32_t *yplane, uint16_t plane_w, uint16_t plane_h, uint16_t x0, uint16_t y0, int32_t *out)
 Sample one 8x8 luma block from the Y plane (clamp-to-edge).
static int32_t internal_enc_avg_2x2 (const int32_t *cplane, uint16_t plane_w, uint16_t plane_h, uint16_t sx, uint16_t sy)
 Average the 2x2 chroma neighbourhood at (sx, sy), clamped.
static void internal_enc_sample_c_block_420 (const int32_t *cplane, uint16_t plane_w, uint16_t plane_h, uint16_t x0, uint16_t y0, int32_t *out)
 Build one 8x8 chroma block by 2x2 averaging from a 16x16 region.
static void internal_enc_convert_strip_to_ycc (const uint8_t *rgb, uint16_t w, uint16_t h, uint16_t pad_w, uint16_t mby, int32_t *y_strip, int32_t *cb_strip, int32_t *cr_strip, uint8_t *tmp_rgb)
 Convert 16 source RGB rows into Y / Cb / Cr 16-row strips.
static void internal_enc_encode_mcu_row (ra8_jpeg_enc_ctx_t *e, uint16_t pad_w, const int32_t *y_strip, const int32_t *cb_strip, const int32_t *cr_strip)
 Encode every 16x16 MCU in a 16-row YCbCr strip.
static ra8_err_t internal_enc_run (ra8_jpeg_enc_ctx_t *e, const uint8_t *rgb, uint16_t w, uint16_t h, uint8_t quality)
 Top-level encode driver – emits the full JFIF byte stream.
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.

Variables

static const char * s_tag = "JPEG_SW"
 Component log tag.
static const uint8_t s_quant_luma [64]
 T.81 Annex K.1 luma quantization table.
static const uint8_t s_quant_chroma [64]
 T.81 Annex K.1 chroma quantization table.

Detailed Description

Pure-software baseline JPEG encoder: pixel pipeline and public API.

Tag
[Ring 4 / Domain] {World: NS}

Implements ra8_jpeg_sw_encode() for baseline (8-bit, sequential, Huffman) JPEG output in the YCbCr 4:2:0 layout. The reference codec is the write_JPEG_file() example shipped with the IJG libjpeg sources and the matching pseudo-code in ITU-T T.81 Annex K; it has been re-implemented here from scratch in this project's style and naming conventions, with no third-party code copied.

This unit owns the pixel pipeline: RGB->YCbCr strip conversion, luma/chroma block sampling, the forward DCT, quantization and the per-block Huffman emission driver. The byte/bit emitters, the Annex K.3.3 reference tables and the JFIF header writers live in ra8_jpeg_sw_encode_emit.c; the symbols shared between the two units are declared in ra8_jpeg_sw_encode_internal.h. The decoder half and the shared entropy/DSP primitives live in ra8_jpeg_sw.c, with cross-unit symbols in ra8_jpeg_sw_internal.h.

Spec citations are tagged T.81 sec X.Y "..." and refer to ITU-T Recommendation T.81 (1992) | ISO/IEC 10918-1.

Since
0.1.0

Definition in file ra8_jpeg_sw_encode.c.

Function Documentation

◆ internal_enc_avg_2x2()

int32_t internal_enc_avg_2x2 ( const int32_t * cplane,
uint16_t plane_w,
uint16_t plane_h,
uint16_t sx,
uint16_t sy )
static

Average the 2x2 chroma neighbourhood at (sx, sy), clamped.

Sums the four plane samples of the 2x2 window whose top-left corner is (sx, sy), clamping each coordinate to the plane edge, and returns the integer mean – the 4:2:0 sub-sampling kernel of internal_enc_sample_c_block_420().

Parameters
[in]cplaneChroma plane (plane_w samples per row).
[in]plane_wPlane width in samples.
[in]plane_hPlane height in rows.
[in]sxWindow left edge.
[in]syWindow top edge.
Returns
Integer mean of the four (edge-clamped) samples.
Return values
0..255For chroma planes in the nominal range.
Precondition
cplane covers plane_w * plane_h samples.
plane_w >= 1 and plane_h >= 1.
Postcondition
No global state is touched.
The divisor is exactly 4 (the window never shrinks).
Note
Internal helper; not thread-safe.
Since
0.1.0

Definition at line 508 of file ra8_jpeg_sw_encode.c.

References RA8_INTERNAL.

Referenced by internal_enc_sample_c_block_420().

◆ internal_enc_bits_needed()

uint8_t internal_enc_bits_needed ( int32_t v)
static

Compute the number of significant-magnitude bits of v.

T.81 Table F.1 SSSS category: bit length of |v|, with 0 mapping to category 0.

Parameters
[in]vCoefficient difference or value.
Returns
Magnitude category (bit count of |v|).
Return values
0v is zero.
1..31Bit length of |v| otherwise.
Precondition
v > INT32_MIN (JPEG coefficients are far smaller).
Caller uses the result as a Huffman symbol or SSSS nibble.
Postcondition
Return value is the exact bit length of |v|.
No state is mutated.
Note
Pure helper; safe from any context.
Since
0.1.0

Definition at line 229 of file ra8_jpeg_sw_encode.c.

References RA8_INTERNAL.

Referenced by internal_enc_block(), and internal_enc_block_ac().

◆ internal_enc_block()

void internal_enc_block ( ra8_jpeg_enc_ctx_t * e,
const int32_t * spatial,
const uint8_t * qtab,
uint8_t comp_idx,
const uint16_t * dc_codes,
const uint8_t * dc_sizes,
const uint16_t * ac_codes,
const uint8_t * ac_sizes )
static

Encode one 8x8 block of source samples.

Forward-DCTs the spatial block, quantizes it in zig-zag order, emits the DC difference (T.81 sec F.1.2.1) and hands the AC coefficients to internal_enc_block_ac().

Parameters
[in,out]eEncoder context (DC predictor + bits mutate).
[in]spatial64-entry level-shifted sample block.
[in]qtabScaled quant table for this component.
[in]comp_idxComponent index (0 luma, 1 Cb, 2 Cr).
[in]dc_codesDC Huffman code LUT.
[in]dc_sizesDC Huffman code-length LUT.
[in]ac_codesAC Huffman code LUT.
[in]ac_sizesAC Huffman code-length LUT.
Precondition
All LUTs were built by priv_jpeg_sw_enc_build_huff().
spatial holds 64 valid samples.
Postcondition
The block's entropy bits are in the output stream.
e->dc_pred[comp_idx] reflects this block's DC value.
Note
Internal helper; not thread-safe.
Since
0.1.0

Definition at line 355 of file ra8_jpeg_sw_encode.c.

References ra8_jpeg_enc_ctx_t::dc_pred, internal_enc_bits_needed(), internal_enc_block_ac(), internal_enc_quantize(), internal_fdct8x8(), k_ra8_jpeg_block_size, priv_jpeg_sw_enc_put_bits(), RA8_INTERNAL, and s_zigzag.

Referenced by internal_enc_encode_mcu_row().

◆ internal_enc_block_ac()

void internal_enc_block_ac ( ra8_jpeg_enc_ctx_t * e,
const int32_t * z,
const uint16_t * ac_codes,
const uint8_t * ac_sizes )
static

Emit the 63 AC coefficients of one quantized block.

T.81 sec F.1.2.2 run-length coding: zero runs of 16 emit ZRL (0xF0), each non-zero coefficient emits its (RRRR,SSSS) symbol followed by the magnitude bits, and a trailing zero run emits EOB.

Parameters
[in,out]eEncoder context (bit buffer mutates).
[in]z64-entry zig-zag-ordered quantized block.
[in]ac_codesAC Huffman code LUT for this component.
[in]ac_sizesAC Huffman code-length LUT.
Precondition
z was produced by the caller's quantize loop.
The AC LUTs were built by priv_jpeg_sw_enc_build_huff().
Postcondition
All non-zero AC coefficients are in the entropy stream.
An EOB symbol terminates the block when it ends in zeros.
Note
Internal helper; not thread-safe.
Since
0.1.0

Definition at line 300 of file ra8_jpeg_sw_encode.c.

References internal_enc_bits_needed(), k_jpeg_zrl_symbol, k_ra8_jpeg_block_size, k_ra8_jpeg_nibble_shift, priv_jpeg_sw_enc_put_bits(), and RA8_INTERNAL.

Referenced by internal_enc_block().

◆ internal_enc_convert_strip_to_ycc()

void internal_enc_convert_strip_to_ycc ( const uint8_t * rgb,
uint16_t w,
uint16_t h,
uint16_t pad_w,
uint16_t mby,
int32_t * y_strip,
int32_t * cb_strip,
int32_t * cr_strip,
uint8_t * tmp_rgb )
static

Convert 16 source RGB rows into Y / Cb / Cr 16-row strips.

For each of 16 output rows, replicates the right-edge / bottom-edge source pixels (clamp-to-edge) so that the YCbCr strips cover the full pad_w width and the requested vertical strip starting at mby. Uses the caller-provided scratch RGB buffer for one row at a time, so the chroma sub-sampling later in internal_enc_sample_c_block_420() sees fully-populated planes.

Parameters
[in]rgbSource RGB888 image of size w*h.
[in]wSource image width in pixels.
[in]hSource image height in pixels.
[in]pad_wPadded (16-aligned) strip width.
[in]mbyStrip start row in the padded image.
[out]y_stripOutput Y plane of pad_w * 16 samples.
[out]cb_stripOutput Cb plane of pad_w * 16 samples.
[out]cr_stripOutput Cr plane of pad_w * 16 samples.
[out]tmp_rgbScratch RGB row buffer of pad_w*3 bytes.
Precondition
rgb, y_strip, cb_strip, cr_strip, tmp_rgb non-NULL.
w > 0, h > 0, pad_w >= w, pad_w is a multiple of 16.
Postcondition
YCbCr strips populated for all 16 rows of the slice.
tmp_rgb contents undefined after return (scratch only).
Note
Not thread-safe; relies on caller-provided scratch buffers.
Since
0.1.0

Definition at line 601 of file ra8_jpeg_sw_encode.c.

References internal_enc_rgb_to_ycc_row(), k_ra8_jpeg_rgb_components, and RA8_INTERNAL.

Referenced by internal_enc_run().

◆ internal_enc_encode_mcu_row()

void internal_enc_encode_mcu_row ( ra8_jpeg_enc_ctx_t * e,
uint16_t pad_w,
const int32_t * y_strip,
const int32_t * cb_strip,
const int32_t * cr_strip )
static

Encode every 16x16 MCU in a 16-row YCbCr strip.

For each MCU column inside pad_w, samples four 8x8 luma blocks at (0,0)(8,0)(0,8)(8,8), then two sub-sampled 8x8 chroma blocks (Cb,Cr). Each block is fed through internal_enc_block() with the matching quant table and Huffman LUTs, which emits the entropy-coded bits into the encoder context.

Parameters
[in,out]eEncoder context (bit-buffer mutates).
[in]pad_wPadded strip width (multiple of 16).
[in]y_stripLuma plane samples for this strip.
[in]cb_stripCb plane samples for this strip.
[in]cr_stripCr plane samples for this strip.
Precondition
e is initialized with valid Huffman LUTs.
pad_w > 0 and a multiple of 16.
Postcondition
e->pos/bit buffer advanced by the entropy bytes of every MCU in the strip.
Block sample order is byte-identical to the pre-split encoder.
Note
Not thread-safe; caller serializes via encoder context.
Since
0.1.0

Definition at line 660 of file ra8_jpeg_sw_encode.c.

References ra8_jpeg_enc_ctx_t::code_ac_c, ra8_jpeg_enc_ctx_t::code_ac_l, ra8_jpeg_enc_ctx_t::code_dc_c, ra8_jpeg_enc_ctx_t::code_dc_l, internal_enc_block(), internal_enc_sample_c_block_420(), internal_enc_sample_y_block(), k_ra8_jpeg_block_size, ra8_jpeg_enc_ctx_t::qc, ra8_jpeg_enc_ctx_t::qy, RA8_INTERNAL, ra8_jpeg_enc_ctx_t::size_ac_c, ra8_jpeg_enc_ctx_t::size_ac_l, ra8_jpeg_enc_ctx_t::size_dc_c, and ra8_jpeg_enc_ctx_t::size_dc_l.

Referenced by internal_enc_run().

◆ internal_enc_quality_scale()

uint16_t internal_enc_quality_scale ( uint8_t q)
static

Compute the IJG quality-scale factor.

Maps the user quality 1..100 onto the IJG percentage scale: 5000/q below the pivot (50), 200 - 2q at or above it.

Parameters
[in]qQuality setting (1..100, caller-validated).
Returns
Scale percentage applied to the Annex K.1 base tables.
Return values
5000..100For q in 1..49.
100..0For q in 50..100.
Precondition
q >= 1 (public API validated the range).
q <= 100.
Postcondition
Return value matches the IJG jpeg_quality_scaling() curve.
No state is mutated.
Note
Pure helper; safe from any context.
Since
0.1.0

Definition at line 170 of file ra8_jpeg_sw_encode.c.

References k_jpeg_q_scale_high, k_jpeg_q_scale_low, k_ra8_jpeg_quality_pivot, and RA8_INTERNAL.

Referenced by internal_enc_run().

◆ internal_enc_quantize()

int32_t internal_enc_quantize ( int32_t v,
uint8_t qv )
static

Quantize one DCT coefficient with symmetric rounding.

Divides by the quant-table entry with round-half-away-from- zero semantics; a zero table entry is clamped to 1 as a divide-by-zero guard.

Parameters
[in]vRaw DCT coefficient.
[in]qvQuant-table divisor entry.
Returns
Quantized coefficient.
Return values
0|v| below half the divisor.
non-zeroRounded quotient otherwise.
Precondition
qv >= 1 in practice (internal_enc_scale_qtab() clamps to 1).
v is a valid 2-D DCT output value.
Postcondition
Sign of the result matches the sign of v.
No state is mutated.
Note
Pure helper; safe from any context.
Since
0.1.0

Definition at line 262 of file ra8_jpeg_sw_encode.c.

References RA8_INTERNAL.

Referenced by internal_enc_block().

◆ internal_enc_rgb_to_ycc_row()

void internal_enc_rgb_to_ycc_row ( const uint8_t * rgb,
uint16_t n,
int32_t * y,
int32_t * cb,
int32_t * cr )
static

Convert one row of RGB into Y, Cb, Cr samples (BT.601 Q16).

Fixed-point BT.601 forward transform using the same Q16 coefficients as IJG jccolor.c; chroma outputs carry the +128 level offset.

Parameters
[in]rgbPacked RGB888 row (n pixels).
[in]nPixel count.
[out]yLuma output row.
[out]cbCb output row (level-offset applied).
[out]crCr output row (level-offset applied).
Precondition
All five pointers are non-NULL (module-internal call chain).
Output rows hold at least n int32 slots each.
Postcondition
Every output sample is in the nominal 0..255 range.
No global state is touched.
Note
Internal helper; not thread-safe.
Since
0.1.0

Definition at line 416 of file ra8_jpeg_sw_encode.c.

References k_ra8_jpeg_cbb, k_ra8_jpeg_cbg, k_ra8_jpeg_cbr, k_ra8_jpeg_crb, k_ra8_jpeg_crg, k_ra8_jpeg_crr, k_ra8_jpeg_level_offset, k_ra8_jpeg_rgb_components, k_ra8_jpeg_yb, k_ra8_jpeg_yg, k_ra8_jpeg_yr, and k_ra8_jpeg_yuv_shift.

Referenced by internal_enc_convert_strip_to_ycc().

◆ internal_enc_run()

ra8_err_t internal_enc_run ( ra8_jpeg_enc_ctx_t * e,
const uint8_t * rgb,
uint16_t w,
uint16_t h,
uint8_t quality )
static

Top-level encode driver – emits the full JFIF byte stream.

Builds the quant tables and Huffman LUTs, emits the header segments, streams the image through 16-row YCbCr strips (bounded working set), then flushes the entropy bits and closes the stream with EOI.

Parameters
[in,out]eZeroed encoder context bound to the output buffer.
[in]rgbSource RGB888 image.
[in]wImage width in pixels.
[in]hImage height in pixels.
[in]qualityIJG quality setting (1..100).
Returns
ra8_err_t Error code.
Return values
k_ra8_okStream complete in e->dst[0..e->pos).
k_ra8_err_invalid_argPadded width exceeds the encoder cap.
k_ra8_err_invalid_sizeOutput buffer overflowed.
Precondition
e, rgb are non-NULL (public API validated them).
w, h, quality were range-checked by the public API.
Postcondition
On success e->pos is the total stream length.
On overflow e->overflow is latched and an error returned.
Note
Internal helper; not thread-safe.
Since
0.1.0

Definition at line 726 of file ra8_jpeg_sw_encode.c.

References internal_enc_convert_strip_to_ycc(), internal_enc_encode_mcu_row(), internal_enc_quality_scale(), internal_enc_scale_qtab(), k_jpeg_mcu_align, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_jpeg_enc_max_w, k_ra8_jpeg_marker_eoi, k_ra8_ok, ra8_jpeg_enc_ctx_t::overflow, priv_jpeg_sw_enc_build_huff(), priv_jpeg_sw_enc_emit_u16(), priv_jpeg_sw_enc_flush_bits(), priv_jpeg_sw_enc_headers(), ra8_jpeg_enc_ctx_t::qc, ra8_jpeg_enc_ctx_t::qy, s_quant_chroma, and s_quant_luma.

Referenced by ra8_jpeg_sw_encode().

◆ internal_enc_sample_c_block_420()

void internal_enc_sample_c_block_420 ( const int32_t * cplane,
uint16_t plane_w,
uint16_t plane_h,
uint16_t x0,
uint16_t y0,
int32_t * out )
static

Build one 8x8 chroma block by 2x2 averaging from a 16x16 region.

Each destination sample is the internal_enc_avg_2x2() mean of the matching 2x2 source window, level-shifted by -128 for the DCT – the 4:2:0 chroma sub-sampling step.

Parameters
[in]cplaneChroma plane (plane_w samples per row).
[in]plane_wPlane width in samples.
[in]plane_hPlane height in rows.
[in]x0Source region left edge.
[in]y0Source region top edge.
[out]out64-entry destination block.
Precondition
cplane covers plane_w * plane_h samples.
plane_w >= 1 and plane_h >= 1.
Postcondition
out holds 64 level-shifted sub-sampled chroma values.
No global state is touched.
Note
Internal helper; not thread-safe.
Since
0.1.0

Definition at line 555 of file ra8_jpeg_sw_encode.c.

References internal_enc_avg_2x2(), k_ra8_jpeg_block_dim, k_ra8_jpeg_level_offset, and RA8_INTERNAL.

Referenced by internal_enc_encode_mcu_row().

◆ internal_enc_sample_y_block()

void internal_enc_sample_y_block ( const int32_t * yplane,
uint16_t plane_w,
uint16_t plane_h,
uint16_t x0,
uint16_t y0,
int32_t * out )
static

Sample one 8x8 luma block from the Y plane (clamp-to-edge).

Reads an 8x8 window at (x0, y0), clamping out-of-range coordinates to the plane edge, and level-shifts each sample by -128 for the DCT.

Parameters
[in]yplaneLuma plane (plane_w samples per row).
[in]plane_wPlane width in samples.
[in]plane_hPlane height in rows.
[in]x0Window left edge.
[in]y0Window top edge.
[out]out64-entry destination block.
Precondition
yplane covers plane_w * plane_h samples.
plane_w >= 1 and plane_h >= 1.
Postcondition
out holds 64 level-shifted samples.
No global state is touched.
Note
Internal helper; not thread-safe.
Since
0.1.0

Definition at line 459 of file ra8_jpeg_sw_encode.c.

References k_ra8_jpeg_block_dim, k_ra8_jpeg_level_offset, and RA8_INTERNAL.

Referenced by internal_enc_encode_mcu_row().

◆ internal_enc_scale_qtab()

void internal_enc_scale_qtab ( const uint8_t * base,
uint8_t * dst,
uint16_t scale )
static

Scale a base quantization table by scale/100, clamped to 1..255.

Applies the IJG rounding form (base*scale + 50) / 100 per entry and clamps into the legal 8-bit DQT range.

Parameters
[in]base64-entry Annex K.1 base table.
[out]dst64-entry destination table.
[in]scalePercentage from internal_enc_quality_scale().
Precondition
base and dst hold 64 valid/writable bytes each.
scale <= 5000 (bounded by the quality curve).
Postcondition
Every dst entry is in 1..255.
No global state is touched.
Note
Internal helper; not thread-safe.
Since
0.1.0

Definition at line 196 of file ra8_jpeg_sw_encode.c.

References k_jpeg_q_percent, k_jpeg_q_round_bias, k_ra8_jpeg_block_size, k_ra8_jpeg_pixel_max, and RA8_INTERNAL.

Referenced by internal_enc_run().

◆ internal_fdct8x8()

void internal_fdct8x8 ( int32_t * block)
static

2-D forward DCT of one 8x8 block, in place.

Separable two-pass transform: internal_fwd_dct_1d_norm() over the rows, then over the columns of the intermediate result.

Parameters
[in,out]block64-entry row-major sample block, DCTed in place.
Precondition
block holds 64 level-shifted spatial samples.
block is non-NULL (module-internal call chain).
Postcondition
block holds the 2-D DCT coefficients.
No global state is touched.
Note
Internal helper; not thread-safe.
Since
0.1.0

Definition at line 120 of file ra8_jpeg_sw_encode.c.

References internal_fwd_dct_1d_norm(), k_ra8_jpeg_block_dim, k_ra8_jpeg_block_size, and RA8_INTERNAL.

Referenced by internal_enc_block().

◆ internal_fwd_dct_1d_norm()

void internal_fwd_dct_1d_norm ( const int32_t * in,
int32_t * out )
static

1-D forward DCT pass with JPEG normalization folded in.

Computes Y[k] = sqrt(2/N)*C(k) * sum_n y[n]*cos((2n+1)*k*pi/16) over the shared Q14 cosine basis, so the encoder and decoder use a numerically identical transform pair.

Parameters
[in]in8-entry spatial sample row/column.
[out]out8-entry frequency coefficient row/column.
Precondition
in and out hold 8 valid/writable int32 slots each.
Input samples are level-shifted to be centred on zero.
Postcondition
out holds the normalized 1-D DCT of in.
No global state is touched.
Note
Internal helper; not thread-safe.
Since
0.1.0

Definition at line 90 of file ra8_jpeg_sw_encode.c.

References k_jpeg_idct_p1_bias_sh, k_jpeg_idct_p1_sh, k_ra8_jpeg_block_dim, RA8_INTERNAL, s_dct_cos_q14, and s_dct_w_q14.

Referenced by internal_fdct8x8().

◆ ra8_jpeg_sw_encode()

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 )
nodiscard

Encode a packed RGB888 frame as a baseline JPEG.

Emits an SOI / APP0(JFIF 1.01) / DQT / SOF0 / DHT / SOS / compressed-data / EOI byte stream. Quantization tables are the T.81 Annex K.1 "Quantization table examples" luma and chroma tables, scaled by the IJG quality formula (scale = 5000/q for q < 50, 200 - 2q for q >= 50). Huffman tables are the T.81 Annex K.3.3 "Typical Huffman tables for 8-bit precision luminance and chrominance" reference tables, included verbatim via DHT segments rather than being optimized per image.

Colour space: input is interpreted as sRGB and converted to YCbCr per ITU-R BT.601, then chroma is averaged 4:1 to produce 4:2:0 subsampling. Width and height are padded to a multiple of 16 internally; the SOF0 marker still records the requested unpadded dimensions so decoders crop correctly.

Parameters
[in]rgb_bufSource pixels, 3 bytes per pixel (R, G, B), width * height * 3 total.
[in]widthImage width in pixels (1..0xFFFF).
[in]heightImage height in pixels (1..0xFFFF).
[in]qualityQuality factor in [k_ra8_jpeg_sw_quality_min, k_ra8_jpeg_sw_quality_max].
[out]out_bufDestination buffer for the JPEG bytes.
[in]out_buf_lenCapacity of out_buf.
[out]out_lenReceives the encoded byte count.
Returns
ra8_err_t error code.
Return values
k_ra8_okEncoded; *out_len <= out_buf_len.
k_ra8_err_null_ptrAny pointer argument was NULL.
k_ra8_err_invalid_argquality out of range, or width == 0, or height == 0.
k_ra8_err_invalid_sizeout_buf_len too small to hold the encoded stream (worst case is roughly width * height * 3).
Precondition
rgb_buf, out_buf and out_len are non-NULL.
out_buf capacity is at least width * height bytes for well-compressing inputs (caller should over-provision).
Postcondition
On success the bytes at out_buf[0..*out_len) form a valid JFIF 1.01 JPEG file.
On any error *out_len is set to 0.
Note
Thread-safe.
Example:
uint32_t produced;
ra8_err_t e = ra8_jpeg_sw_encode(rgb, 640, 480,
jpeg, sizeof jpeg, &produced);
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
@ k_ra8_jpeg_sw_quality_default
IJG cjpeg default.
Definition ra8_jpeg_sw.h:76
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.
See also
ra8_jpeg_sw_decode Inverse operation.
Since
0.1.0

Definition at line 778 of file ra8_jpeg_sw_encode.c.

References ra8_jpeg_enc_ctx_t::cap, ra8_jpeg_enc_ctx_t::dst, internal_enc_run(), k_ra8_err_invalid_arg, k_ra8_jpeg_sw_quality_max, k_ra8_jpeg_sw_quality_min, k_ra8_ok, memset(), ra8_jpeg_enc_ctx_t::pos, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by internal_jpeg_sw_encode().

Variable Documentation

◆ s_quant_chroma

const uint8_t s_quant_chroma[64]
static
Initial value:
= {
17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99,
99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
}

T.81 Annex K.1 chroma quantization table.

Definition at line 61 of file ra8_jpeg_sw_encode.c.

Referenced by internal_enc_run().

◆ s_quant_luma

const uint8_t s_quant_luma[64]
static
Initial value:
= {
16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57,
69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64,
81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99,
}

T.81 Annex K.1 luma quantization table.

Definition at line 54 of file ra8_jpeg_sw_encode.c.

Referenced by internal_enc_run().

◆ s_tag

const char* s_tag = "JPEG_SW"
static

Component log tag.

Definition at line 47 of file ra8_jpeg_sw_encode.c.