|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Pure-software baseline JPEG codec: shared entropy/DSP primitives plus the get-dimensions public API. More...
#include "ra8_jpeg_sw.h"#include <stdint.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_jpeg_sw_internal.h"Go to the source code of this file.
Functions | |
| static void | internal_br_fill (ra8_jpeg_bitreader_t *br) |
| Refill acc until at least 16 bits are available. | |
| int32_t | priv_jpeg_sw_br_get_bits (ra8_jpeg_bitreader_t *br, uint8_t n) |
| Pop n bits MSB-first; returns -1 on underflow. | |
| static void | internal_htab_build_lookup (ra8_jpeg_htab_t *h) |
| Build the F.2.2.3 mincode/maxcode/valptr decode tables. | |
| void | priv_jpeg_sw_htab_build (ra8_jpeg_htab_t *h) |
| Build canonical code/size and mincode/maxcode tables. | |
| int32_t | priv_jpeg_sw_htab_decode (ra8_jpeg_bitreader_t *br, const ra8_jpeg_htab_t *h) |
| Decode one Huffman symbol from br using table h. | |
| int32_t | priv_jpeg_sw_huff_extend (int32_t v, uint8_t n) |
| Decode a signed n-bit DCT coefficient (T.81 F.1.2.1.3). | |
| static void | internal_inv_dct_1d_norm (const int32_t *in, int32_t *out) |
| 1-D inverse DCT pass with JPEG normalization folded in. | |
| void | priv_jpeg_sw_idct8x8 (int32_t *block) |
| Full 8x8 inverse DCT, in place. | |
| void | priv_jpeg_sw_ycc_to_rgb (int32_t y, int32_t cb, int32_t cr, uint8_t *out_r, uint8_t *out_g, uint8_t *out_b) |
| Convert a YCbCr triple to RGB (BT.601, fixed-point). | |
| static ra8_err_t | internal_dims_next_marker (const uint8_t *jpeg_buf, uint32_t jpeg_len, uint32_t *i, uint16_t *out_mk) |
| Advance past 0xFF pad bytes and read one marker code. | |
| static ra8_err_t | internal_dims_parse_sof0 (const uint8_t *jpeg_buf, uint32_t i, uint16_t seglen, uint16_t *out_w, uint16_t *out_h) |
| Extract width/height from an SOF0 payload (T.81 sec B.2.2). | |
| static ra8_err_t | internal_dims_step (const uint8_t *jpeg_buf, uint32_t jpeg_len, uint32_t *i, bool *done, uint16_t *out_w, uint16_t *out_h) |
| One step of the dimension walk: read a marker, handle it. | |
| ra8_err_t | ra8_jpeg_sw_get_dimensions (const uint8_t *jpeg_buf, uint32_t jpeg_len, uint16_t *out_w, uint16_t *out_h) |
| Parse the SOF0 marker of a JPEG stream and report its image dimensions without performing entropy decoding. | |
Variables | |
| static const char * | s_tag = "JPEG_SW" |
| Component log tag. | |
Pure-software baseline JPEG codec: shared entropy/DSP primitives plus the get-dimensions public API.
Implements the codec primitives shared by both the decoder and the encoder – the big-endian bit reader, the canonical Huffman tables, the inverse DCT and the BT.601 YCbCr->RGB colour conversion – and the lightweight ra8_jpeg_sw_get_dimensions() public API, which only walks the marker chain to the SOF0 frame header.
The decoder-driver half (marker parser, MCU scan loop and ra8_jpeg_sw_decode()) lives in ra8_jpeg_sw_decode.c; the encoder (forward DCT, quantization, Huffman code emission and ra8_jpeg_sw_encode()) lives in ra8_jpeg_sw_encode.c. Every symbol referenced by more than one of those units – the C23 typed-enum constant blocks, the shared DSP look-up tables, the inline byte helpers, the bit-reader / Huffman-table types and the prototypes for the primitives defined here – lives in ra8_jpeg_sw_internal.h.
The reference codec for the decoder is the C99 reformulation of "TJpgDec" by ChaN; both halves have been re-implemented here from scratch in this project's style and naming conventions; no third-party code is copied.
Spec citations are tagged T.81 sec X.Y "..." and refer to ITU-T Recommendation T.81 (1992) | ISO/IEC 10918-1.
MVE / Helium acceleration:
Definition in file ra8_jpeg_sw.c.
|
static |
Refill acc until at least 16 bits are available.
Pulls bytes from the entropy stream into the 32-bit accumulator, unstuffing 0xFF 0x00 sequences per T.81 F.1.2.3 and stopping when a real marker is reached (rewinds two bytes so the caller can inspect it).
| [in,out] | br | Bit reader (state mutated in place). |
Definition at line 83 of file ra8_jpeg_sw.c.
References ra8_jpeg_bitreader_t::acc, ra8_jpeg_bitreader_t::buf, ra8_jpeg_bitreader_t::had_eoi, k_jpeg_reservoir_lo, k_ra8_jpeg_byte_shift, k_ra8_jpeg_marker_byte, ra8_jpeg_bitreader_t::len, ra8_jpeg_bitreader_t::nbits, ra8_jpeg_bitreader_t::pos, and RA8_INTERNAL.
Referenced by priv_jpeg_sw_br_get_bits(), and priv_jpeg_sw_htab_decode().
|
static |
Advance past 0xFF pad bytes and read one marker code.
Implements the T.81 sec B.1.1.2 "Markers" scan step of the ra8_jpeg_sw_get_dimensions() walk: verifies the cursor sits on a 0xFF prefix, skips any run of 0xFF fill bytes, and returns the 0xFFxx marker code assembled from the byte that follows. The cursor is left one past the marker's low byte.
| [in] | jpeg_buf | JPEG byte stream. |
| [in] | jpeg_len | Total stream length in bytes. |
| [in,out] | i | Parse cursor (advanced past the marker). |
| [out] | out_mk | Receives the 0xFFxx marker code. |
| k_ra8_ok | Marker code stored in *out_mk. |
| k_ra8_err_protocol_error | Cursor not on 0xFF, or the stream ends inside the pad run. |
Definition at line 453 of file ra8_jpeg_sw.c.
References k_jpeg_byte_mask, k_ra8_err_protocol_error, k_ra8_jpeg_byte_shift, k_ra8_jpeg_marker_byte, and k_ra8_ok.
Referenced by internal_dims_step().
|
static |
Extract width/height from an SOF0 payload (T.81 sec B.2.2).
Reads the precision byte and the two big-endian dimension fields of the SOF0 frame header whose length field starts at i, rejecting non-8-bit precision and zero dimensions exactly as the previous monolithic ra8_jpeg_sw_get_dimensions() body did.
| [in] | jpeg_buf | JPEG byte stream. |
| [in] | i | Offset of the SOF0 segment-length field. |
| [in] | seglen | Validated segment length (>= 2, in bounds). |
| [out] | out_w | Receives the image width in pixels. |
| [out] | out_h | Receives the image height in pixels. |
| k_ra8_ok | Dimensions stored. |
| k_ra8_err_protocol_error | Segment too short or zero dimension. |
| k_ra8_err_not_supported | Sample precision is not 8-bit. |
Definition at line 499 of file ra8_jpeg_sw.c.
References internal_read_be16(), k_jpeg_sof_dims_off, k_ra8_err_not_supported, k_ra8_err_protocol_error, k_ra8_ok, and RA8_INTERNAL.
Referenced by internal_dims_step().
|
static |
One step of the dimension walk: read a marker, handle it.
Loop body of ra8_jpeg_sw_get_dimensions(): reads the next marker via internal_dims_next_marker(), skips standalone SOI/EOI codes, validates the segment length, extracts the dimensions on SOF0 (setting *done), rejects unsupported SOFn frames, and otherwise advances the cursor past the segment.
| [in] | jpeg_buf | JPEG byte stream. |
| [in] | jpeg_len | Total stream length in bytes. |
| [in,out] | i | Parse cursor (advances). |
| [out] | done | Set true when SOF0 delivered the dimensions. |
| [out] | out_w | Receives the image width on SOF0. |
| [out] | out_h | Receives the image height on SOF0. |
| k_ra8_ok | Step handled; check *done. |
| k_ra8_err_protocol_error | Malformed marker / length field. |
| k_ra8_err_not_supported | Unsupported SOFn or precision. |
Definition at line 550 of file ra8_jpeg_sw.c.
References internal_dims_next_marker(), internal_dims_parse_sof0(), internal_read_be16(), k_jpeg_marker_jpg, k_jpeg_marker_sof_hi, k_jpeg_marker_sof_lo, k_ra8_err_not_supported, k_ra8_err_protocol_error, k_ra8_jpeg_marker_dht, k_ra8_jpeg_marker_eoi, k_ra8_jpeg_marker_sof0, k_ra8_jpeg_marker_soi, k_ra8_ok, and RA8_INTERNAL.
Referenced by ra8_jpeg_sw_get_dimensions().
|
static |
Build the F.2.2.3 mincode/maxcode/valptr decode tables.
Second phase of priv_jpeg_sw_htab_build(): walks the BITS list and the canonical huffcode array produced by the Annex C phase and derives, per code length, the smallest code (mincode), the largest code (maxcode, -1 for unused lengths) and the index of the first symbol of that length (valptr) exactly as T.81 Annex F.2.2.3 "Decoder tables" specifies.
| [in,out] | h | Huffman table (huffcode/bits in, lookup tables out). |
Definition at line 176 of file ra8_jpeg_sw.c.
References ra8_jpeg_htab_t::bits, ra8_jpeg_htab_t::huffcode, k_ra8_jpeg_huff_lengths, ra8_jpeg_htab_t::maxcode, ra8_jpeg_htab_t::mincode, RA8_INTERNAL, and ra8_jpeg_htab_t::valptr.
Referenced by priv_jpeg_sw_htab_build().
|
static |
1-D inverse DCT pass with JPEG normalization folded in.
Computes y[n] = sum_k sqrt(2/N)*C(k)*Y[k]*cos((2n+1)*k*pi/16). Pre-multiplies each Y[k] by the Q14 weight before the cosine accumulation so the cosine terms stay symmetrical with the forward pass.
| [in] | in | See declaration: const int32_t* in. |
| [out] | out | See declaration: int32_t* out. |
Definition at line 338 of file ra8_jpeg_sw.c.
References k_jpeg_idct_p2_bias_sh, k_jpeg_q14_shift, k_ra8_jpeg_block_dim, RA8_INTERNAL, s_dct_cos_q14, and s_dct_w_q14.
Referenced by priv_jpeg_sw_idct8x8().
| int32_t priv_jpeg_sw_br_get_bits | ( | ra8_jpeg_bitreader_t * | br, |
| uint8_t | n ) |
Pop n bits MSB-first; returns -1 on underflow.
Calls internal_br_fill to top off the accumulator, then drains n MSBs as a non-negative integer.
| [in,out] | br | Bit reader (state mutated in place). |
| [in] | n | Number of bits to consume (0..16). |
| >=0 | n-bit unsigned value drained from the accumulator. |
| -1 | Underflow / EOI before n bits were available. |
Definition at line 134 of file ra8_jpeg_sw.c.
References ra8_jpeg_bitreader_t::acc, internal_br_fill(), ra8_jpeg_bitreader_t::nbits, and RA8_PRIV.
Referenced by internal_dec_block_ac(), priv_jpeg_sw_block(), and priv_jpeg_sw_htab_decode().
| void priv_jpeg_sw_htab_build | ( | ra8_jpeg_htab_t * | h | ) |
Build canonical code/size and mincode/maxcode tables.
Implements T.81 Annex C "Generation of size table" + "Generation of code table" plus the Annex F.2.2.3 mincode/maxcode/valptr tables used by the symbol decoder. Defined in ra8_jpeg_sw.c; the parser unit calls it from dec_parse_dht().
| [in,out] | h | Huffman table (BITS / VALS in, derived tables out). |
Definition at line 192 of file ra8_jpeg_sw.c.
References ra8_jpeg_htab_t::bits, ra8_jpeg_htab_t::huffcode, ra8_jpeg_htab_t::huffsize, internal_htab_build_lookup(), k_ra8_jpeg_huff_lengths, RA8_PRIV, and ra8_jpeg_htab_t::total.
Referenced by internal_dec_parse_dht_one().
| int32_t priv_jpeg_sw_htab_decode | ( | ra8_jpeg_bitreader_t * | br, |
| const ra8_jpeg_htab_t * | h ) |
Decode one Huffman symbol from br using table h.
Single-bit greedy lookup per T.81 F.2.2.3 "Decoder code-length algorithm". Returns -1 on stream underflow or table miss.
| [in,out] | br | Bit reader (state mutated in place). |
| [in] | h | Pre-built canonical Huffman table. |
| >=0 | Symbol value from h->vals. |
| -1 | Stream underflow or table miss. |
Definition at line 250 of file ra8_jpeg_sw.c.
References internal_br_fill(), k_ra8_jpeg_huff_lengths, ra8_jpeg_htab_t::mincode, ra8_jpeg_bitreader_t::nbits, priv_jpeg_sw_br_get_bits(), RA8_PRIV, ra8_jpeg_htab_t::total, ra8_jpeg_htab_t::valptr, and ra8_jpeg_htab_t::vals.
Referenced by internal_dec_block_ac(), and priv_jpeg_sw_block().
| int32_t priv_jpeg_sw_huff_extend | ( | int32_t | v, |
| uint8_t | n ) |
Decode a signed n-bit DCT coefficient (T.81 F.1.2.1.3).
Extends a non-negative n-bit pattern into the signed range documented at T.81 Figure F.12 "EXTEND". A leading-zero pattern is treated as the negative of the symmetric positive value.
| [in] | v | Non-negative bit pattern from the bit reader. |
| [in] | n | Number of significant bits. |
| 0..(1<<n)-1 | v had its high bit set (positive value). |
| -(1<<n)+1..0 | v had its high bit clear (negative value). |
Definition at line 305 of file ra8_jpeg_sw.c.
References RA8_PRIV.
Referenced by internal_dec_block_ac(), and priv_jpeg_sw_block().
| void priv_jpeg_sw_idct8x8 | ( | int32_t * | block | ) |
Full 8x8 inverse DCT, in place.
Two-pass separable IDCT (rows then columns) using the shared Q14 cosine basis. Defined in ra8_jpeg_sw.c; the parser unit calls it from dec_idct_into().
| [in,out] | block | 64-entry row-major coefficient block, IDCTed in place. |
Definition at line 352 of file ra8_jpeg_sw.c.
References internal_inv_dct_1d_norm(), k_ra8_jpeg_block_dim, k_ra8_jpeg_block_size, and RA8_PRIV.
Referenced by priv_jpeg_sw_idct_into().
| void priv_jpeg_sw_ycc_to_rgb | ( | int32_t | y, |
| int32_t | cb, | ||
| int32_t | cr, | ||
| uint8_t * | out_r, | ||
| uint8_t * | out_g, | ||
| uint8_t * | out_b ) |
Convert a YCbCr triple to RGB (BT.601, fixed-point).
MVE-accelerated path is enabled when __ARM_FEATURE_MVE is defined (Cortex-M85 target). Host tests run the scalar path.
| [in,out] | cb | See function signature. |
| [in,out] | cr | See function signature. |
| [in,out] | out_b | See function signature. |
| [in,out] | out_g | See function signature. |
| [in,out] | out_r | See function signature. |
| [in,out] | y | See function signature. |
Definition at line 402 of file ra8_jpeg_sw.c.
References internal_clamp_u8(), k_ra8_jpeg_cb_b, k_ra8_jpeg_cb_g, k_ra8_jpeg_cr_g, k_ra8_jpeg_cr_r, k_ra8_jpeg_level_offset, k_ra8_jpeg_yuv_shift, and RA8_PRIV.
Referenced by internal_dec_emit_mcu_rgb(), and internal_js_emit_mcu().
|
nodiscard |
Parse the SOF0 marker of a JPEG stream and report its image dimensions without performing entropy decoding.
Walks the marker chain looking for T.81 sec B.2.2 "Frame header syntax" (SOF0 = 0xFFC0). On match the 16-bit big-endian Y (height) and X (width) fields are returned. This is the cheap way to size an output buffer before calling ra8_jpeg_sw_decode().
Algorithm:
| [in] | jpeg_buf | Pointer to the JPEG byte stream (not NULL). |
| [in] | jpeg_len | Length of jpeg_buf in bytes (must be >= 4). |
| [out] | out_w | Receives image width in pixels (not NULL). |
| [out] | out_h | Receives image height in pixels (not NULL). |
| k_ra8_ok | Dimensions written to *out_w, *out_h. |
| k_ra8_err_null_ptr | Any pointer argument was NULL. |
| k_ra8_err_invalid_size | jpeg_len smaller than the SOI marker (2 bytes). |
| k_ra8_err_protocol_error | Stream lacks SOI, lacks SOF0, or a marker length field overflows the buffer. |
| k_ra8_err_not_supported | SOF marker is non-baseline (e.g. progressive 0xFFC2, lossless 0xFFC3, arithmetic 0xFFC9+). |
Definition at line 587 of file ra8_jpeg_sw.c.
References internal_dims_step(), internal_read_be16(), k_ra8_err_invalid_size, k_ra8_err_protocol_error, k_ra8_jpeg_marker_soi, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.
Referenced by internal_probe_sniff().
|
static |
Component log tag.
Definition at line 54 of file ra8_jpeg_sw.c.