ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_jpeg_sw_encode_emit.c
Go to the documentation of this file.
1
30
31#include <stdint.h>
32
33#include "ra8_attributes.h"
34#include "ra8_err.h"
35#include "ra8_jpeg_sw.h"
38
39/* ------------------------------------------------------------------ */
40/* Annex K.3.3 reference Huffman tables (luma DC/AC, chroma DC/AC) */
41/* ------------------------------------------------------------------ */
42
44static const uint8_t s_hbits_dc_luma[16] = {
45 0,
46 1,
47 5,
48 1,
49 1,
50 1,
51 1,
52 1,
53 1,
54 0,
55 0,
56 0,
57 0,
58 0,
59 0,
60 0,
61};
62
63static const uint8_t s_hval_dc_luma[12] = {
64 0,
65 1,
66 2,
67 3,
68 4,
69 5,
70 6,
71 7,
72 8,
73 9,
74 10,
75 11,
76};
77
79static const uint8_t s_hbits_dc_chroma[16] = {
80 0,
81 3,
82 1,
83 1,
84 1,
85 1,
86 1,
87 1,
88 1,
89 1,
90 1,
91 0,
92 0,
93 0,
94 0,
95 0,
96};
97
98static const uint8_t s_hval_dc_chroma[12] = {
99 0,
100 1,
101 2,
102 3,
103 4,
104 5,
105 6,
106 7,
107 8,
108 9,
109 10,
110 11,
111};
112
114static const uint8_t s_hbits_ac_luma[16] = {
115 0,
116 2,
117 1,
118 3,
119 3,
120 2,
121 4,
122 3,
123 5,
124 5,
125 4,
126 4,
127 0,
128 0,
129 1,
130 0x7d,
131};
132
133static const uint8_t s_hval_ac_luma[162] = {
134 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
135 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52,
136 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25,
137 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
138 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
139 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83,
140 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
141 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
142 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3,
143 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
144 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
145};
146
148static const uint8_t s_hbits_ac_chroma[16] = {
149 0,
150 2,
151 1,
152 2,
153 4,
154 4,
155 3,
156 4,
157 7,
158 5,
159 4,
160 4,
161 0,
162 1,
163 2,
164 0x77,
165};
166
167static const uint8_t s_hval_ac_chroma[162] = {
168 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61,
169 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33,
170 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18,
171 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44,
172 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63,
173 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
174 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
175 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
176 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
177 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
178 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
179};
180
181/* ------------------------------------------------------------------ */
182/* Byte / bit emitters */
183/* ------------------------------------------------------------------ */
184
206{
207 if (e->pos >= e->cap) {
208 e->overflow = true;
209 return;
210 }
211 e->dst[e->pos] = b;
212 e->pos++;
213}
214
221
223RA8_PRIV void priv_jpeg_sw_enc_put_bits(ra8_jpeg_enc_ctx_t* e, uint32_t code, uint8_t n)
224{
225 e->bit_buf = (e->bit_buf << n) | (code & ((1U << n) - 1U));
226 e->bit_cnt = (uint8_t)(e->bit_cnt + n);
227 while (e->bit_cnt >= (uint8_t)k_ra8_jpeg_byte_shift) {
228 uint8_t b = (uint8_t)(e->bit_buf >> (e->bit_cnt - k_ra8_jpeg_byte_shift));
230 if (b == (uint8_t)k_ra8_jpeg_marker_byte) {
232 }
233 e->bit_cnt = (uint8_t)(e->bit_cnt - k_ra8_jpeg_byte_shift);
234 }
235}
236
239{
240 if (e->bit_cnt > 0U) {
241 uint32_t pad = (1U << (k_ra8_jpeg_byte_shift - e->bit_cnt)) - 1U;
243 ((e->bit_buf << (k_ra8_jpeg_byte_shift - e->bit_cnt)) | pad) &
245 (uint8_t)(k_ra8_jpeg_byte_shift - e->bit_cnt));
246 }
247}
248
249/* ------------------------------------------------------------------ */
250/* Canonical Huffman code build (T.81 Annex C) */
251/* ------------------------------------------------------------------ */
252
277RA8_INTERNAL static void internal_enc_build_codes(const uint8_t* bits,
278 const uint8_t* vals,
279 uint16_t* codes,
280 uint8_t* sizes,
281 uint16_t total)
282{
283 uint8_t huffsize[k_ra8_jpeg_huff_max + 1U];
284 uint16_t k = 0U;
285 for (uint8_t i = 0U; i < (uint8_t)k_ra8_jpeg_huff_lengths; i++) {
286 for (uint8_t j = 0U; j < bits[i]; j++) {
287 huffsize[k] = (uint8_t)(i + 1U);
288 k++;
289 }
290 }
291 huffsize[k] = 0U;
292
293 uint16_t huffcode[k_ra8_jpeg_huff_max + 1U];
294 uint16_t code = 0U;
295 uint8_t si = (k > 0U) ? huffsize[0] : 0U;
296 uint16_t kk = 0U;
297 while (huffsize[kk] != 0U) {
298 while (huffsize[kk] == si) {
299 huffcode[kk] = code;
300 code++;
301 kk++;
302 }
303 if (huffsize[kk] == 0U) {
304 break;
305 }
306 do {
307 code = (uint16_t)(code << 1U);
308 si++;
309 } while (huffsize[kk] != si);
310 }
311 for (uint16_t i = 0U; i < total; i++) {
312 codes[vals[i]] = huffcode[i];
313 sizes[vals[i]] = huffsize[i];
314 }
315}
316
319 uint16_t* total_dc_l,
320 uint16_t* total_ac_l,
321 uint16_t* total_dc_c,
322 uint16_t* total_ac_c)
323{
324 *total_dc_l = 0U;
325 *total_ac_l = 0U;
326 *total_dc_c = 0U;
327 *total_ac_c = 0U;
328 for (uint8_t i = 0U; i < (uint8_t)k_ra8_jpeg_huff_lengths; i++) {
329 *total_dc_l = (uint16_t)(*total_dc_l + s_hbits_dc_luma[i]);
330 *total_ac_l = (uint16_t)(*total_ac_l + s_hbits_ac_luma[i]);
331 *total_dc_c = (uint16_t)(*total_dc_c + s_hbits_dc_chroma[i]);
332 *total_ac_c = (uint16_t)(*total_ac_c + s_hbits_ac_chroma[i]);
333 }
336 e->code_dc_l,
337 e->size_dc_l,
338 *total_dc_l);
341 e->code_ac_l,
342 e->size_ac_l,
343 *total_ac_l);
346 e->code_dc_c,
347 e->size_dc_c,
348 *total_dc_c);
351 e->code_ac_c,
352 e->size_ac_c,
353 *total_ac_c);
354}
355
356/* ------------------------------------------------------------------ */
357/* JFIF header segments */
358/* ------------------------------------------------------------------ */
359
378{
380 priv_jpeg_sw_enc_emit_u16(e, (uint16_t)(2U + (2U * (1U + (uint16_t)k_ra8_jpeg_block_size))));
381 internal_enc_emit_u8(e, 0U); /* PqTq=0,0. */
382 for (uint8_t i = 0U; i < (uint8_t)k_ra8_jpeg_block_size; i++) {
384 }
385 internal_enc_emit_u8(e, 1U); /* PqTq=0,1. */
386 for (uint8_t i = 0U; i < (uint8_t)k_ra8_jpeg_block_size; i++) {
388 }
389}
390
412 uint8_t tc_th,
413 const uint8_t* bits,
414 const uint8_t* vals,
415 uint16_t total)
416{
418 priv_jpeg_sw_enc_emit_u16(e, (uint16_t)(2U + 1U + (uint16_t)k_ra8_jpeg_huff_lengths + total));
419 internal_enc_emit_u8(e, tc_th);
420 for (uint8_t i = 0U; i < (uint8_t)k_ra8_jpeg_huff_lengths; i++) {
421 internal_enc_emit_u8(e, bits[i]);
422 }
423 for (uint16_t i = 0U; i < total; i++) {
424 internal_enc_emit_u8(e, vals[i]);
425 }
426}
427
447{
448 /* SOI. */
450
451 /* APP0 JFIF header (16 bytes payload). */
454 internal_enc_emit_u8(e, 'J');
455 internal_enc_emit_u8(e, 'F');
456 internal_enc_emit_u8(e, 'I');
457 internal_enc_emit_u8(e, 'F');
460 internal_enc_emit_u8(e, 1U); /* Version 1.1. */
461 internal_enc_emit_u8(e, 0U); /* No density units. */
463 priv_jpeg_sw_enc_emit_u16(e, 1U); /* Aspect 1:1. */
465 internal_enc_emit_u8(e, 0U); /* No thumbnail. */
466}
467
487RA8_INTERNAL static void internal_enc_emit_sof0(ra8_jpeg_enc_ctx_t* e, uint16_t w, uint16_t h)
488{
495 /* Y: id 1, 2x2 sampling, qtab 0. */
499 /* Cb: id 2, 1x1, qtab 1. */
503 /* Cr: id 3, 1x1, qtab 1. */
507}
508
541
544 uint16_t w,
545 uint16_t h,
546 uint16_t total_dc_l,
547 uint16_t total_ac_l,
548 uint16_t total_dc_c,
549 uint16_t total_ac_c)
550{
553 internal_enc_emit_sof0(e, w, h);
554
562 total_ac_c);
563
565}
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.
Pure-software baseline JPEG (ISO/IEC 10918-1 / ITU-T T.81) codec.
static void internal_enc_emit_dqt(ra8_jpeg_enc_ctx_t *e)
Emit the DQT segment for both luma and chroma tables.
void priv_jpeg_sw_enc_put_bits(ra8_jpeg_enc_ctx_t *e, uint32_t code, uint8_t n)
Implementation of priv_jpeg_sw_enc_put_bits() – T.81 F.1.2.3 stuffing.
void priv_jpeg_sw_enc_headers(ra8_jpeg_enc_ctx_t *e, uint16_t w, uint16_t h, uint16_t total_dc_l, uint16_t total_ac_l, uint16_t total_dc_c, uint16_t total_ac_c)
Implementation of priv_jpeg_sw_enc_headers() – JFIF 1.1 segment order.
static void internal_enc_emit_dht_one(ra8_jpeg_enc_ctx_t *e, uint8_t tc_th, const uint8_t *bits, const uint8_t *vals, uint16_t total)
Emit one DHT segment (T.81 sec B.2.4.2).
static const uint8_t s_hval_dc_chroma[12]
K.3.3 chroma DC HUFFVAL.
static void internal_enc_emit_u8(ra8_jpeg_enc_ctx_t *e, uint8_t b)
Append one byte; sets overflow on capacity exhaustion.
static void internal_enc_emit_app0_jfif(ra8_jpeg_enc_ctx_t *e)
Emit the SOI marker plus the 16-byte APP0 JFIF header.
void priv_jpeg_sw_enc_flush_bits(ra8_jpeg_enc_ctx_t *e)
Implementation of priv_jpeg_sw_enc_flush_bits() – 1-fill pad.
static const uint8_t s_hval_ac_luma[162]
K.3.3 luma AC HUFFVAL (162 symbols).
void priv_jpeg_sw_enc_build_huff(ra8_jpeg_enc_ctx_t *e, uint16_t *total_dc_l, uint16_t *total_ac_l, uint16_t *total_dc_c, uint16_t *total_ac_c)
Implementation of priv_jpeg_sw_enc_build_huff() – four K.3.3 LUT builds.
static const uint8_t s_hval_dc_luma[12]
K.3.3 luma DC HUFFVAL (12 symbols).
static const uint8_t s_hval_ac_chroma[162]
K.3.3 chroma AC HUFFVAL.
static const uint8_t s_hbits_dc_chroma[16]
K.3.3 chroma DC BITS.
void priv_jpeg_sw_enc_emit_u16(ra8_jpeg_enc_ctx_t *e, uint16_t v)
Implementation of priv_jpeg_sw_enc_emit_u16() – big-endian byte pair.
static const uint8_t s_hbits_dc_luma[16]
K.3.3 luma DC BITS (number of codes of each length 1..16).
static const uint8_t s_hbits_ac_chroma[16]
K.3.3 chroma AC BITS.
static void internal_enc_emit_sos(ra8_jpeg_enc_ctx_t *e)
Emit the SOS scan header (T.81 sec B.2.3).
static const uint8_t s_hbits_ac_luma[16]
K.3.3 luma AC BITS.
static void internal_enc_emit_sof0(ra8_jpeg_enc_ctx_t *e, uint16_t w, uint16_t h)
Emit the SOF0 frame header for a 3-component 4:2:0 stream.
static void internal_enc_build_codes(const uint8_t *bits, const uint8_t *vals, uint16_t *codes, uint8_t *sizes, uint16_t total)
Build the canonical-code table from BITS+HUFFVAL.
Module-private declarations shared by the two encoder translation units of the software JPEG codec.
Module-private declarations shared across the software JPEGcodec translation units.
@ k_ra8_jpeg_marker_dht
Define Huffman table.
@ k_ra8_jpeg_marker_sof0
Baseline DCT, Huffman.
@ k_ra8_jpeg_marker_soi
Start of image.
@ k_ra8_jpeg_marker_app0
JFIF APP0.
@ k_ra8_jpeg_marker_dqt
Define quantization table.
@ k_ra8_jpeg_marker_sos
Start of scan.
@ k_ra8_jpeg_byte_shift
RA8 JPEG byte shift.
@ k_ra8_jpeg_huff_lengths
16 BITS-list slots.
@ k_jpeg_sos_seg_len
JPEG sos seg length.
@ k_jpeg_spectral_end
JPEG spectral end.
@ k_jpeg_sof_seg_len
JPEG sof seg length.
@ k_jpeg_byte_mask
JPEG byte mask.
@ k_ra8_jpeg_block_size
Coefficients per block.
@ k_ra8_jpeg_marker_byte
RA8 JPEG marker byte.
@ k_ra8_jpeg_huff_max
Max symbols per Huffman table.
@ k_jpeg_sos_sel_chroma
JPEG sos sel chroma.
@ k_jpeg_dht_ac_chroma
JPEG dht ac chroma.
@ k_jpeg_samp_2x2
JPEG samp 2x2.
@ k_jpeg_samp_1x1
JPEG samp 1x1.
static const uint8_t s_zigzag[64]
Zig-zag de-interleave order (T.81 Figure 5).
Encoder state – buffer cursor, bit accumulator, scaled quant tables, Huffman LUTs and DC predictors.
bool overflow
Set on capacity exhaustion.
uint8_t size_ac_l[k_ra8_jpeg_huff_max]
Luma AC code lengths.
uint16_t code_dc_c[k_ra8_jpeg_huff_max]
Chroma DC Huffman codes.
uint8_t size_dc_l[k_ra8_jpeg_huff_max]
Luma DC code lengths.
uint8_t size_ac_c[k_ra8_jpeg_huff_max]
Chroma AC code lengths.
uint8_t * dst
Destination JPEG byte buffer.
uint32_t pos
Write cursor into dst.
uint32_t bit_buf
MSB-first entropy bit accumulator.
uint16_t code_ac_c[k_ra8_jpeg_huff_max]
Chroma AC Huffman codes.
uint16_t code_dc_l[k_ra8_jpeg_huff_max]
Luma DC Huffman codes.
uint8_t qy[k_ra8_jpeg_block_size]
Scaled luma quant table.
uint16_t code_ac_l[k_ra8_jpeg_huff_max]
Luma AC Huffman codes.
uint8_t bit_cnt
Bits currently valid in bit_buf.
uint8_t size_dc_c[k_ra8_jpeg_huff_max]
Chroma DC code lengths.
uint8_t qc[k_ra8_jpeg_block_size]
Scaled chroma quant table.
uint32_t cap
Capacity of dst in bytes.