FastLED 3.9.15
Loading...
Searching...
No Matches
tjpgd.cpp.hpp
Go to the documentation of this file.
1/*----------------------------------------------------------------------------/
2/ TJpgDec - Tiny JPEG Decompressor R0.03 (C)ChaN, 2021
3/-----------------------------------------------------------------------------/
4/ The TJpgDec is a generic JPEG decompressor module for tiny embedded systems.
5/ This is a free software that opened for education, research and commercial
6/ developments under license policy of following terms.
7/
8/ Copyright (C) 2021, ChaN, all right reserved.
9/
10/ * The TJpgDec module is a free software and there is NO WARRANTY.
11/ * No restriction on use. You can use, modify and redistribute it for
12/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
13/ * Redistributions of source code must retain the above copyright notice.
14/
15/-----------------------------------------------------------------------------/
16/ Oct 04, 2011 R0.01 First release.
17/ Feb 19, 2012 R0.01a Fixed decompression fails when scan starts with an escape seq.
18/ Sep 03, 2012 R0.01b Added JD_TBLCLIP option.
19/ Mar 16, 2019 R0.01c Supprted stdint.h.
20/ Jul 01, 2020 R0.01d Fixed wrong integer type usage.
21/ May 08, 2021 R0.02 Supprted grayscale image. Separated configuration options.
22/ Jun 11, 2021 R0.02a Some performance improvement.
23/ Jul 01, 2021 R0.03 Added JD_FASTDECODE option.
24/ Some performance improvement.
25/----------------------------------------------------------------------------*/
26
27// Include standard library headers outside namespace to avoid conflicts
28#include "fl/stl/cstdlib.h"
29#include "fl/stl/string.h"
30#include "fl/stl/cstring.h" // for fl::memset() and fl::memcpy()
31#include "fl/stl/noexcept.h"
32
33#include "tjpgd.h"
34
35namespace fl {
36namespace third_party {
37
38
39#if JD_FASTDECODE == 2
40#define HUFF_BIT 10 /* Bit length to apply fast huffman decode */
41#define HUFF_LEN (1 << HUFF_BIT)
42#define HUFF_MASK (HUFF_LEN - 1)
43#endif
44
45
46/*-----------------------------------------------*/
47/* Zigzag-order to raster-order conversion table */
48/*-----------------------------------------------*/
49
50static const uint8_t Zig[64] = { /* Zigzag-order to raster-order conversion table */
51 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
52 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
53 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
54 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
55};
56
57
58
59/*-------------------------------------------------*/
60/* Input scale factor of Arai algorithm */
61/* (scaled up 16 bits for fixed point operations) */
62/*-------------------------------------------------*/
63
64static const uint16_t Ipsf[64] = { /* See also aa_idct.png */
65 (uint16_t)(1.00000*8192), (uint16_t)(1.38704*8192), (uint16_t)(1.30656*8192), (uint16_t)(1.17588*8192), (uint16_t)(1.00000*8192), (uint16_t)(0.78570*8192), (uint16_t)(0.54120*8192), (uint16_t)(0.27590*8192),
66 (uint16_t)(1.38704*8192), (uint16_t)(1.92388*8192), (uint16_t)(1.81226*8192), (uint16_t)(1.63099*8192), (uint16_t)(1.38704*8192), (uint16_t)(1.08979*8192), (uint16_t)(0.75066*8192), (uint16_t)(0.38268*8192),
67 (uint16_t)(1.30656*8192), (uint16_t)(1.81226*8192), (uint16_t)(1.70711*8192), (uint16_t)(1.53636*8192), (uint16_t)(1.30656*8192), (uint16_t)(1.02656*8192), (uint16_t)(0.70711*8192), (uint16_t)(0.36048*8192),
68 (uint16_t)(1.17588*8192), (uint16_t)(1.63099*8192), (uint16_t)(1.53636*8192), (uint16_t)(1.38268*8192), (uint16_t)(1.17588*8192), (uint16_t)(0.92388*8192), (uint16_t)(0.63638*8192), (uint16_t)(0.32442*8192),
69 (uint16_t)(1.00000*8192), (uint16_t)(1.38704*8192), (uint16_t)(1.30656*8192), (uint16_t)(1.17588*8192), (uint16_t)(1.00000*8192), (uint16_t)(0.78570*8192), (uint16_t)(0.54120*8192), (uint16_t)(0.27590*8192),
70 (uint16_t)(0.78570*8192), (uint16_t)(1.08979*8192), (uint16_t)(1.02656*8192), (uint16_t)(0.92388*8192), (uint16_t)(0.78570*8192), (uint16_t)(0.61732*8192), (uint16_t)(0.42522*8192), (uint16_t)(0.21677*8192),
71 (uint16_t)(0.54120*8192), (uint16_t)(0.75066*8192), (uint16_t)(0.70711*8192), (uint16_t)(0.63638*8192), (uint16_t)(0.54120*8192), (uint16_t)(0.42522*8192), (uint16_t)(0.29290*8192), (uint16_t)(0.14932*8192),
72 (uint16_t)(0.27590*8192), (uint16_t)(0.38268*8192), (uint16_t)(0.36048*8192), (uint16_t)(0.32442*8192), (uint16_t)(0.27590*8192), (uint16_t)(0.21678*8192), (uint16_t)(0.14932*8192), (uint16_t)(0.07612*8192)
73};
74
75
76
77/*---------------------------------------------*/
78/* Conversion table for fast clipping process */
79/*---------------------------------------------*/
80
81#if JD_TBLCLIP
82
83#define BYTECLIP(v) Clip8[(unsigned int)(v) & 0x3FF]
84
85static const uint8_t Clip8[1024] = {
86 /* 0..255 */
87 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
88 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
89 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
90 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
91 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
92 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
93 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
94 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
95 /* 256..511 */
96 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
97 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
98 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
99 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
100 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
101 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
102 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
103 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
104 /* -512..-257 */
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
113 /* -256..-1 */
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
118 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
121 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
122};
123
124#else /* JD_TBLCLIP */
125
127{
128 if (val < 0) return 0;
129 else if (val > 255) return 255;
130 return (uint8_t)val;
131}
132
133#endif
134
135
136
137/*-----------------------------------------------------------------------*/
138/* Allocate a memory block from memory pool */
139/*-----------------------------------------------------------------------*/
140
141static void* alloc_pool ( /* Pointer to allocated memory block (NULL:no memory available) */
142 JDEC* jd, /* Pointer to the decompressor object */
143 size_t ndata /* Number of bytes to allocate */
145{
146 char *rp = 0;
147
148
149 ndata = (ndata + 3) & ~3; /* Align block size to the word boundary */
150
151 if (jd->sz_pool >= ndata) {
152 jd->sz_pool -= ndata;
153 rp = (char*)jd->pool; /* Get start of available memory pool */
154 jd->pool = (void*)(rp + ndata); /* Allocate requierd bytes */
155 }
156
157 return (void*)rp; /* Return allocated memory block (NULL:no memory to allocate) */
158}
159
160
161
162
163/*-----------------------------------------------------------------------*/
164/* Create de-quantization and prescaling tables with a DQT segment */
165/*-----------------------------------------------------------------------*/
166
167static JRESULT create_qt_tbl ( /* 0:OK, !0:Failed */
168 JDEC* jd, /* Pointer to the decompressor object */
169 const uint8_t* data, /* Pointer to the quantizer tables */
170 size_t ndata /* Size of input data */
172{
173 unsigned int i, zi;
174 uint8_t d;
175 int32_t *pb;
176
177
178 while (ndata) { /* Process all tables in the segment */
179 if (ndata < 65) return JDR_FMT1; /* Err: table size is unaligned */
180 ndata -= 65;
181 d = *data++; /* Get table property */
182 if (d & 0xF0) return JDR_FMT1; /* Err: not 8-bit resolution */
183 i = d & 3; /* Get table ID */
184 pb = (int32_t*)alloc_pool(jd, 64 * sizeof (int32_t));/* Allocate a memory block for the table */
185 if (!pb) return JDR_MEM1; /* Err: not enough memory */
186 jd->qttbl[i] = pb; /* Register the table */
187 for (i = 0; i < 64; i++) { /* Load the table */
188 zi = Zig[i]; /* Zigzag-order to raster-order conversion */
189 pb[zi] = (int32_t)((uint32_t)*data++ * Ipsf[zi]); /* Apply scale factor of Arai algorithm to the de-quantizers */
190 }
191 }
192
193 return JDR_OK;
194}
195
196
197
198
199/*-----------------------------------------------------------------------*/
200/* Create huffman code tables with a DHT segment */
201/*-----------------------------------------------------------------------*/
202
203static JRESULT create_huffman_tbl ( /* 0:OK, !0:Failed */
204 JDEC* jd, /* Pointer to the decompressor object */
205 const uint8_t* data, /* Pointer to the packed huffman tables */
206 size_t ndata /* Size of input data */
208{
209 unsigned int i, j, b, cls, num;
210 size_t np;
211 uint8_t d, *pb, *pd;
212 uint16_t hc, *ph;
213
214
215 while (ndata) { /* Process all tables in the segment */
216 if (ndata < 17) return JDR_FMT1; /* Err: wrong data size */
217 ndata -= 17;
218 d = *data++; /* Get table number and class */
219 if (d & 0xEE) return JDR_FMT1; /* Err: invalid class/number */
220 cls = d >> 4; num = d & 0x0F; /* class = dc(0)/ac(1), table number = 0/1 */
221 pb = (uint8_t*)alloc_pool(jd, 16); /* Allocate a memory block for the bit distribution table */
222 if (!pb) return JDR_MEM1; /* Err: not enough memory */
223 jd->huffbits[num][cls] = pb;
224 for (np = i = 0; i < 16; i++) { /* Load number of patterns for 1 to 16-bit code */
225 np += (pb[i] = *data++); /* Get sum of code words for each code */
226 }
227 ph = (uint16_t*)alloc_pool(jd, np * sizeof (uint16_t));/* Allocate a memory block for the code word table */
228 if (!ph) return JDR_MEM1; /* Err: not enough memory */
229 jd->huffcode[num][cls] = ph;
230 hc = 0;
231 for (j = i = 0; i < 16; i++) { /* Re-build huffman code word table */
232 b = pb[i];
233 while (b--) ph[j++] = hc++;
234 hc <<= 1;
235 }
236
237 if (ndata < np) return JDR_FMT1; /* Err: wrong data size */
238 ndata -= np;
239 pd = (uint8_t*)alloc_pool(jd, np); /* Allocate a memory block for the decoded data */
240 if (!pd) return JDR_MEM1; /* Err: not enough memory */
241 jd->huffdata[num][cls] = pd;
242 for (i = 0; i < np; i++) { /* Load decoded data corresponds to each code word */
243 d = *data++;
244 if (!cls && d > 11) return JDR_FMT1;
245 pd[i] = d;
246 }
247#if JD_FASTDECODE == 2
248 { /* Create fast huffman decode table */
249 unsigned int span, td, ti;
250 uint16_t *tbl_ac = 0;
251 uint8_t *tbl_dc = 0;
252
253 if (cls) {
254 tbl_ac = (uint16_t*)alloc_pool(jd, HUFF_LEN * sizeof (uint16_t)); /* LUT for AC elements */
255 if (!tbl_ac) return JDR_MEM1; /* Err: not enough memory */
256 jd->hufflut_ac[num] = tbl_ac;
257 fl::memset(tbl_ac, 0xFF, HUFF_LEN * sizeof (uint16_t)); /* Default value (0xFFFF: may be long code) */
258 } else {
259 tbl_dc = (uint8_t*)alloc_pool(jd, HUFF_LEN * sizeof (uint8_t)); /* LUT for AC elements */
260 if (!tbl_dc) return JDR_MEM1; /* Err: not enough memory */
261 jd->hufflut_dc[num] = tbl_dc;
262 fl::memset(tbl_dc, 0xFF, HUFF_LEN * sizeof (uint8_t)); /* Default value (0xFF: may be long code) */
263 }
264 for (i = b = 0; b < HUFF_BIT; b++) { /* Create LUT */
265 for (j = pb[b]; j; j--) {
266 ti = ph[i] << (HUFF_BIT - 1 - b) & HUFF_MASK; /* Index of input pattern for the code */
267 if (cls) {
268 td = pd[i++] | ((b + 1) << 8); /* b15..b8: code length, b7..b0: zero run and data length */
269 for (span = 1 << (HUFF_BIT - 1 - b); span; span--, tbl_ac[ti++] = (uint16_t)td) ;
270 } else {
271 td = pd[i++] | ((b + 1) << 4); /* b7..b4: code length, b3..b0: data length */
272 for (span = 1 << (HUFF_BIT - 1 - b); span; span--, tbl_dc[ti++] = (uint8_t)td) ;
273 }
274 }
275 }
276 jd->longofs[num][cls] = i; /* Code table offset for long code */
277 }
278#endif
279 }
280
281 return JDR_OK;
282}
283
284
285
286
287/*-----------------------------------------------------------------------*/
288/* Extract a huffman decoded data from input stream */
289/*-----------------------------------------------------------------------*/
290
291static int huffext ( /* >=0: decoded data, <0: error code */
292 JDEC* jd, /* Pointer to the decompressor object */
293 unsigned int id, /* Table ID (0:Y, 1:C) */
294 unsigned int cls /* Table class (0:DC, 1:AC) */
296{
297 size_t dc = jd->dctr;
298 uint8_t *dp = jd->dptr;
299 unsigned int d, flg = 0;
300
301#if JD_FASTDECODE == 0
302 uint8_t bm, nd, bl;
303 const uint8_t *hb = jd->huffbits[id][cls]; /* Bit distribution table */
304 const uint16_t *hc = jd->huffcode[id][cls]; /* Code word table */
305 const uint8_t *hd = jd->huffdata[id][cls]; /* Data table */
306
307
308 bm = jd->dbit; /* Bit mask to extract */
309 d = 0; bl = 16; /* Max code length */
310 do {
311 if (!bm) { /* Next byte? */
312 if (!dc) { /* No input data is available, re-fill input buffer */
313 dp = jd->inbuf; /* Top of input buffer */
314 dc = jd->infunc(jd, dp, JD_SZBUF);
315 if (!dc) return 0 - (int)JDR_INP; /* Err: read error or wrong stream termination */
316 } else {
317 dp++; /* Next data ptr */
318 }
319 dc--; /* Decrement number of available bytes */
320 if (flg) { /* In flag sequence? */
321 flg = 0; /* Exit flag sequence */
322 if (*dp != 0) return 0 - (int)JDR_FMT1; /* Err: unexpected flag is detected (may be collapted data) */
323 *dp = 0xFF; /* The flag is a data 0xFF */
324 } else {
325 if (*dp == 0xFF) { /* Is start of flag sequence? */
326 flg = 1; continue; /* Enter flag sequence, get trailing byte */
327 }
328 }
329 bm = 0x80; /* Read from MSB */
330 }
331 d <<= 1; /* Get a bit */
332 if (*dp & bm) d++;
333 bm >>= 1;
334
335 for (nd = *hb++; nd; nd--) { /* Search the code word in this bit length */
336 if (d == *hc++) { /* Matched? */
337 jd->dbit = bm; jd->dctr = dc; jd->dptr = dp;
338 return *hd; /* Return the decoded data */
339 }
340 hd++;
341 }
342 bl--;
343 } while (bl);
344
345#else
346 const uint8_t *hb, *hd;
347 const uint16_t *hc;
348 unsigned int nc, bl, wbit = jd->dbit % 32;
349 uint32_t w = jd->wreg & ((1UL << wbit) - 1);
350
351
352 while (wbit < 16) { /* Prepare 16 bits into the working register */
353 if (jd->marker) {
354 d = 0xFF; /* Input stream has stalled for a marker. Generate stuff bits */
355 } else {
356 if (!dc) { /* Buffer empty, re-fill input buffer */
357 dp = jd->inbuf; /* Top of input buffer */
358 dc = jd->infunc(jd, dp, JD_SZBUF);
359 if (!dc) return 0 - (int)JDR_INP; /* Err: read error or wrong stream termination */
360 }
361 d = *dp++; dc--;
362 if (flg) { /* In flag sequence? */
363 flg = 0; /* Exit flag sequence */
364 if (d != 0) jd->marker = d; /* Not an escape of 0xFF but a marker */
365 d = 0xFF;
366 } else {
367 if (d == 0xFF) { /* Is start of flag sequence? */
368 flg = 1; continue; /* Enter flag sequence, get trailing byte */
369 }
370 }
371 }
372 w = w << 8 | d; /* Shift 8 bits in the working register */
373 wbit += 8;
374 }
375 jd->dctr = dc; jd->dptr = dp;
376 jd->wreg = w;
377
378#if JD_FASTDECODE == 2
379 /* Table serch for the short codes */
380 d = (unsigned int)(w >> (wbit - HUFF_BIT)); /* Short code as table index */
381 if (cls) { /* AC element */
382 d = jd->hufflut_ac[id][d]; /* Table decode */
383 if (d != 0xFFFF) { /* It is done if hit in short code */
384 jd->dbit = wbit - (d >> 8); /* Snip the code length */
385 return d & 0xFF; /* b7..0: zero run and following data bits */
386 }
387 } else { /* DC element */
388 d = jd->hufflut_dc[id][d]; /* Table decode */
389 if (d != 0xFF) { /* It is done if hit in short code */
390 jd->dbit = wbit - (d >> 4); /* Snip the code length */
391 return d & 0xF; /* b3..0: following data bits */
392 }
393 }
394
395 /* Incremental serch for the codes longer than HUFF_BIT */
396 hb = jd->huffbits[id][cls] + HUFF_BIT; /* Bit distribution table */
397 hc = jd->huffcode[id][cls] + jd->longofs[id][cls]; /* Code word table */
398 hd = jd->huffdata[id][cls] + jd->longofs[id][cls]; /* Data table */
399 bl = HUFF_BIT + 1;
400#else
401 /* Incremental serch for all codes */
402 hb = jd->huffbits[id][cls]; /* Bit distribution table */
403 hc = jd->huffcode[id][cls]; /* Code word table */
404 hd = jd->huffdata[id][cls]; /* Data table */
405 bl = 1;
406#endif
407 for ( ; bl <= 16; bl++) { /* Incremental search */
408 nc = *hb++;
409 if (nc) {
410 d = w >> (wbit - bl);
411 do { /* Search the code word in this bit length */
412 if (d == *hc++) { /* Matched? */
413 jd->dbit = wbit - bl; /* Snip the huffman code */
414 return *hd; /* Return the decoded data */
415 }
416 hd++;
417 } while (--nc);
418 }
419 }
420#endif
421
422 return 0 - (int)JDR_FMT1; /* Err: code not found (may be collapted data) */
423}
424
425
426
427
428/*-----------------------------------------------------------------------*/
429/* Extract N bits from input stream */
430/*-----------------------------------------------------------------------*/
431
432static int bitext ( /* >=0: extracted data, <0: error code */
433 JDEC* jd, /* Pointer to the decompressor object */
434 unsigned int nbit /* Number of bits to extract (1 to 16) */
436{
437 size_t dc = jd->dctr;
438 uint8_t *dp = jd->dptr;
439 unsigned int d, flg = 0;
440
441#if JD_FASTDECODE == 0
442 uint8_t mbit = jd->dbit;
443
444 d = 0;
445 do {
446 if (!mbit) { /* Next byte? */
447 if (!dc) { /* No input data is available, re-fill input buffer */
448 dp = jd->inbuf; /* Top of input buffer */
449 dc = jd->infunc(jd, dp, JD_SZBUF);
450 if (!dc) return 0 - (int)JDR_INP; /* Err: read error or wrong stream termination */
451 } else {
452 dp++; /* Next data ptr */
453 }
454 dc--; /* Decrement number of available bytes */
455 if (flg) { /* In flag sequence? */
456 flg = 0; /* Exit flag sequence */
457 if (*dp != 0) return 0 - (int)JDR_FMT1; /* Err: unexpected flag is detected (may be collapted data) */
458 *dp = 0xFF; /* The flag is a data 0xFF */
459 } else {
460 if (*dp == 0xFF) { /* Is start of flag sequence? */
461 flg = 1; continue; /* Enter flag sequence */
462 }
463 }
464 mbit = 0x80; /* Read from MSB */
465 }
466 d <<= 1; /* Get a bit */
467 if (*dp & mbit) d |= 1;
468 mbit >>= 1;
469 nbit--;
470 } while (nbit);
471
472 jd->dbit = mbit; jd->dctr = dc; jd->dptr = dp;
473 return (int)d;
474
475#else
476 unsigned int wbit = jd->dbit % 32;
477 uint32_t w = jd->wreg & ((1UL << wbit) - 1);
478
479
480 while (wbit < nbit) { /* Prepare nbit bits into the working register */
481 if (jd->marker) {
482 d = 0xFF; /* Input stream stalled, generate stuff bits */
483 } else {
484 if (!dc) { /* Buffer empty, re-fill input buffer */
485 dp = jd->inbuf; /* Top of input buffer */
486 dc = jd->infunc(jd, dp, JD_SZBUF);
487 if (!dc) return 0 - (int)JDR_INP; /* Err: read error or wrong stream termination */
488 }
489 d = *dp++; dc--;
490 if (flg) { /* In flag sequence? */
491 flg = 0; /* Exit flag sequence */
492 if (d != 0) jd->marker = d; /* Not an escape of 0xFF but a marker */
493 d = 0xFF;
494 } else {
495 if (d == 0xFF) { /* Is start of flag sequence? */
496 flg = 1; continue; /* Enter flag sequence, get trailing byte */
497 }
498 }
499 }
500 w = w << 8 | d; /* Get 8 bits into the working register */
501 wbit += 8;
502 }
503 jd->wreg = w; jd->dbit = wbit - nbit;
504 jd->dctr = dc; jd->dptr = dp;
505
506 return (int)(w >> ((wbit - nbit) % 32));
507#endif
508}
509
510
511
512
513/*-----------------------------------------------------------------------*/
514/* Process restart interval */
515/*-----------------------------------------------------------------------*/
516
518 JDEC* jd, /* Pointer to the decompressor object */
519 uint16_t rstn /* Expected restert sequense number */
521{
522 unsigned int i;
523 uint8_t *dp = jd->dptr;
524 size_t dc = jd->dctr;
525
526#if JD_FASTDECODE == 0
527 uint16_t d = 0;
528
529 /* Get two bytes from the input stream */
530 for (i = 0; i < 2; i++) {
531 if (!dc) { /* No input data is available, re-fill input buffer */
532 dp = jd->inbuf;
533 dc = jd->infunc(jd, dp, JD_SZBUF);
534 if (!dc) return JDR_INP;
535 } else {
536 dp++;
537 }
538 dc--;
539 d = d << 8 | *dp; /* Get a byte */
540 }
541 jd->dptr = dp; jd->dctr = dc; jd->dbit = 0;
542
543 /* Check the marker */
544 if ((d & 0xFFD8) != 0xFFD0 || (d & 7) != (rstn & 7)) {
545 return JDR_FMT1; /* Err: expected RSTn marker is not detected (may be collapted data) */
546 }
547
548#else
549 uint16_t marker;
550
551
552 if (jd->marker) { /* Generate a maker if it has been detected */
553 marker = 0xFF00 | jd->marker;
554 jd->marker = 0;
555 } else {
556 marker = 0;
557 for (i = 0; i < 2; i++) { /* Get a restart marker */
558 if (!dc) { /* No input data is available, re-fill input buffer */
559 dp = jd->inbuf;
560 dc = jd->infunc(jd, dp, JD_SZBUF);
561 if (!dc) return JDR_INP;
562 }
563 marker = (marker << 8) | *dp++; /* Get a byte */
564 dc--;
565 }
566 jd->dptr = dp; jd->dctr = dc;
567 }
568
569 /* Check the marker */
570 if ((marker & 0xFFD8) != 0xFFD0 || (marker & 7) != (rstn & 7)) {
571 return JDR_FMT1; /* Err: expected RSTn marker was not detected (may be collapted data) */
572 }
573
574 jd->dbit = 0; /* Discard stuff bits */
575#endif
576
577 jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0; /* Reset DC offset */
578 return JDR_OK;
579}
580
581
582
583
584/*-----------------------------------------------------------------------*/
585/* Apply Inverse-DCT in Arai Algorithm (see also aa_idct.png) */
586/*-----------------------------------------------------------------------*/
587
588static void block_idct (
589 int32_t* src, /* Input block data (de-quantized and pre-scaled for Arai Algorithm) */
590 jd_yuv_t* dst /* Pointer to the destination to store the block as byte array */
592{
593 const int32_t M13 = (int32_t)(1.41421*4096), M2 = (int32_t)(1.08239*4096), M4 = (int32_t)(2.61313*4096), M5 = (int32_t)(1.84776*4096);
594 int32_t v0, v1, v2, v3, v4, v5, v6, v7;
595 int32_t t10, t11, t12, t13;
596 int i;
597
598 /* Process columns */
599 for (i = 0; i < 8; i++) {
600 v0 = src[8 * 0]; /* Get even elements */
601 v1 = src[8 * 2];
602 v2 = src[8 * 4];
603 v3 = src[8 * 6];
604
605 t10 = v0 + v2; /* Process the even elements */
606 t12 = v0 - v2;
607 t11 = (v1 - v3) * M13 >> 12;
608 v3 += v1;
609 t11 -= v3;
610 v0 = t10 + v3;
611 v3 = t10 - v3;
612 v1 = t11 + t12;
613 v2 = t12 - t11;
614
615 v4 = src[8 * 7]; /* Get odd elements */
616 v5 = src[8 * 1];
617 v6 = src[8 * 5];
618 v7 = src[8 * 3];
619
620 t10 = v5 - v4; /* Process the odd elements */
621 t11 = v5 + v4;
622 t12 = v6 - v7;
623 v7 += v6;
624 v5 = (t11 - v7) * M13 >> 12;
625 v7 += t11;
626 t13 = (t10 + t12) * M5 >> 12;
627 v4 = t13 - (t10 * M2 >> 12);
628 v6 = t13 - (t12 * M4 >> 12) - v7;
629 v5 -= v6;
630 v4 -= v5;
631
632 src[8 * 0] = v0 + v7; /* Write-back transformed values */
633 src[8 * 7] = v0 - v7;
634 src[8 * 1] = v1 + v6;
635 src[8 * 6] = v1 - v6;
636 src[8 * 2] = v2 + v5;
637 src[8 * 5] = v2 - v5;
638 src[8 * 3] = v3 + v4;
639 src[8 * 4] = v3 - v4;
640
641 src++; /* Next column */
642 }
643
644 /* Process rows */
645 src -= 8;
646 for (i = 0; i < 8; i++) {
647 v0 = src[0] + (128L << 8); /* Get even elements (remove DC offset (-128) here) */
648 v1 = src[2];
649 v2 = src[4];
650 v3 = src[6];
651
652 t10 = v0 + v2; /* Process the even elements */
653 t12 = v0 - v2;
654 t11 = (v1 - v3) * M13 >> 12;
655 v3 += v1;
656 t11 -= v3;
657 v0 = t10 + v3;
658 v3 = t10 - v3;
659 v1 = t11 + t12;
660 v2 = t12 - t11;
661
662 v4 = src[7]; /* Get odd elements */
663 v5 = src[1];
664 v6 = src[5];
665 v7 = src[3];
666
667 t10 = v5 - v4; /* Process the odd elements */
668 t11 = v5 + v4;
669 t12 = v6 - v7;
670 v7 += v6;
671 v5 = (t11 - v7) * M13 >> 12;
672 v7 += t11;
673 t13 = (t10 + t12) * M5 >> 12;
674 v4 = t13 - (t10 * M2 >> 12);
675 v6 = t13 - (t12 * M4 >> 12) - v7;
676 v5 -= v6;
677 v4 -= v5;
678
679 /* Descale the transformed values 8 bits and output a row */
680#if JD_FASTDECODE >= 1
681 dst[0] = (int16_t)((v0 + v7) >> 8);
682 dst[7] = (int16_t)((v0 - v7) >> 8);
683 dst[1] = (int16_t)((v1 + v6) >> 8);
684 dst[6] = (int16_t)((v1 - v6) >> 8);
685 dst[2] = (int16_t)((v2 + v5) >> 8);
686 dst[5] = (int16_t)((v2 - v5) >> 8);
687 dst[3] = (int16_t)((v3 + v4) >> 8);
688 dst[4] = (int16_t)((v3 - v4) >> 8);
689#else
690 dst[0] = BYTECLIP((v0 + v7) >> 8);
691 dst[7] = BYTECLIP((v0 - v7) >> 8);
692 dst[1] = BYTECLIP((v1 + v6) >> 8);
693 dst[6] = BYTECLIP((v1 - v6) >> 8);
694 dst[2] = BYTECLIP((v2 + v5) >> 8);
695 dst[5] = BYTECLIP((v2 - v5) >> 8);
696 dst[3] = BYTECLIP((v3 + v4) >> 8);
697 dst[4] = BYTECLIP((v3 - v4) >> 8);
698#endif
699
700 dst += 8; src += 8; /* Next row */
701 }
702}
703
704
705
706
707/*-----------------------------------------------------------------------*/
708/* Load all blocks in an MCU into working buffer */
709/*-----------------------------------------------------------------------*/
710
712 JDEC* jd /* Pointer to the decompressor object */
714{
715 int32_t *tmp = (int32_t*)jd->workbuf; /* Block working buffer for de-quantize and IDCT */
716 int d, e;
717 unsigned int blk, nby, i, bc, z, id, cmp;
718 jd_yuv_t *bp;
719 const int32_t *dqf;
720
721
722 nby = jd->msx * jd->msy; /* Number of Y blocks (1, 2 or 4) */
723 bp = jd->mcubuf; /* Pointer to the first block of MCU */
724
725 for (blk = 0; blk < nby + 2; blk++) { /* Get nby Y blocks and two C blocks */
726 cmp = (blk < nby) ? 0 : blk - nby + 1; /* Component number 0:Y, 1:Cb, 2:Cr */
727
728 if (cmp && jd->ncomp != 3) { /* Clear C blocks if not exist (monochrome image) */
729 for (i = 0; i < 64; bp[i++] = 128) ;
730
731 } else { /* Load Y/C blocks from input stream */
732 id = cmp ? 1 : 0; /* Huffman table ID of this component */
733
734 /* Extract a DC element from input stream */
735 d = huffext(jd, id, 0); /* Extract a huffman coded data (bit length) */
736 if (d < 0) return (JRESULT)(0 - d); /* Err: invalid code or input */
737 bc = (unsigned int)d;
738 d = jd->dcv[cmp]; /* DC value of previous block */
739 if (bc) { /* If there is any difference from previous block */
740 e = bitext(jd, bc); /* Extract data bits */
741 if (e < 0) return (JRESULT)(0 - e); /* Err: input */
742 bc = 1 << (bc - 1); /* MSB position */
743 if (!(e & bc)) e -= (bc << 1) - 1; /* Restore negative value if needed */
744 d += e; /* Get current value */
745 jd->dcv[cmp] = (int16_t)d; /* Save current DC value for next block */
746 }
747 dqf = jd->qttbl[jd->qtid[cmp]]; /* De-quantizer table ID for this component */
748 tmp[0] = d * dqf[0] >> 8; /* De-quantize, apply scale factor of Arai algorithm and descale 8 bits */
749
750 /* Extract following 63 AC elements from input stream */
751 fl::memset(&tmp[1], 0, 63 * sizeof (int32_t)); /* Initialize all AC elements */
752 z = 1; /* Top of the AC elements (in zigzag-order) */
753 do {
754 d = huffext(jd, id, 1); /* Extract a huffman coded value (zero runs and bit length) */
755 if (d == 0) break; /* EOB? */
756 if (d < 0) return (JRESULT)(0 - d); /* Err: invalid code or input error */
757 bc = (unsigned int)d;
758 z += bc >> 4; /* Skip leading zero run */
759 if (z >= 64) return JDR_FMT1; /* Too long zero run */
760 if (bc &= 0x0F) { /* Bit length? */
761 d = bitext(jd, bc); /* Extract data bits */
762 if (d < 0) return (JRESULT)(0 - d); /* Err: input device */
763 bc = 1 << (bc - 1); /* MSB position */
764 if (!(d & bc)) d -= (bc << 1) - 1; /* Restore negative value if needed */
765 i = Zig[z]; /* Get raster-order index */
766 tmp[i] = d * dqf[i] >> 8; /* De-quantize, apply scale factor of Arai algorithm and descale 8 bits */
767 }
768 } while (++z < 64); /* Next AC element */
769
770 if (JD_FORMAT != 2 || !cmp) { /* C components may not be processed if in grayscale output */
771 if (z == 1 || (JD_USE_SCALE && jd->scale == 3)) { /* If no AC element or scale ratio is 1/8, IDCT can be ommited and the block is filled with DC value */
772 d = (jd_yuv_t)((*tmp / 256) + 128);
773 if (JD_FASTDECODE >= 1) {
774 for (i = 0; i < 64; bp[i++] = d) ;
775 } else {
776 fl::memset(bp, d, 64);
777 }
778 } else {
779 block_idct(tmp, bp); /* Apply IDCT and store the block to the MCU buffer */
780 }
781 }
782 }
783
784 bp += 64; /* Next block */
785 }
786
787 return JDR_OK; /* All blocks have been loaded successfully */
788}
789
790
791
792
793/*-----------------------------------------------------------------------*/
794/* Output an MCU: Convert YCrCb to RGB and output it in RGB form */
795/*-----------------------------------------------------------------------*/
796
798 JDEC* jd, /* Pointer to the decompressor object */
799 int (*outfunc)(JDEC*, void*, JRECT*), /* RGB output function */
800 unsigned int x, /* MCU location in the image */
801 unsigned int y /* MCU location in the image */
803{
804 const int CVACC = (sizeof (int) > 2) ? 1024 : 128; /* Adaptive accuracy for both 16-/32-bit systems */
805 unsigned int ix, iy, mx, my, rx, ry;
806 int yy, cb, cr;
807 jd_yuv_t *py, *pc;
808 uint8_t *pix;
809 JRECT rect;
810
811
812 mx = jd->msx * 8; my = jd->msy * 8; /* MCU size (pixel) */
813 rx = (x + mx <= jd->width) ? mx : jd->width - x; /* Output rectangular size (it may be clipped at right/bottom end of image) */
814 ry = (y + my <= jd->height) ? my : jd->height - y;
815 if (JD_USE_SCALE) {
816 rx >>= jd->scale; ry >>= jd->scale;
817 if (!rx || !ry) return JDR_OK; /* Skip this MCU if all pixel is to be rounded off */
818 x >>= jd->scale; y >>= jd->scale;
819 }
820 rect.left = x; rect.right = x + rx - 1; /* Rectangular area in the frame buffer */
821 rect.top = y; rect.bottom = y + ry - 1;
822
823
824 if (!JD_USE_SCALE || jd->scale != 3) { /* Not for 1/8 scaling */
825 pix = (uint8_t*)jd->workbuf;
826
827 if (JD_FORMAT != 2) { /* RGB output (build an RGB MCU from Y/C component) */
828 for (iy = 0; iy < my; iy++) {
829 pc = py = jd->mcubuf;
830 if (my == 16) { /* Double block height? */
831 pc += 64 * 4 + (iy >> 1) * 8;
832 if (iy >= 8) py += 64;
833 } else { /* Single block height */
834 pc += mx * 8 + iy * 8;
835 }
836 py += iy * 8;
837 for (ix = 0; ix < mx; ix++) {
838 cb = pc[0] - 128; /* Get Cb/Cr component and remove offset */
839 cr = pc[64] - 128;
840 if (mx == 16) { /* Double block width? */
841 if (ix == 8) py += 64 - 8; /* Jump to next block if double block heigt */
842 pc += ix & 1; /* Step forward chroma pointer every two pixels */
843 } else { /* Single block width */
844 pc++; /* Step forward chroma pointer every pixel */
845 }
846 yy = *py++; /* Get Y component */
847 *pix++ = /*R*/ BYTECLIP(yy + ((int)(1.402 * CVACC) * cr) / CVACC);
848 *pix++ = /*G*/ BYTECLIP(yy - ((int)(0.344 * CVACC) * cb + (int)(0.714 * CVACC) * cr) / CVACC);
849 *pix++ = /*B*/ BYTECLIP(yy + ((int)(1.772 * CVACC) * cb) / CVACC);
850 }
851 }
852 } else { /* Monochrome output (build a grayscale MCU from Y comopnent) */
853 for (iy = 0; iy < my; iy++) {
854 py = jd->mcubuf + iy * 8;
855 if (my == 16) { /* Double block height? */
856 if (iy >= 8) py += 64;
857 }
858 for (ix = 0; ix < mx; ix++) {
859 if (mx == 16) { /* Double block width? */
860 if (ix == 8) py += 64 - 8; /* Jump to next block if double block height */
861 }
862 if (JD_FASTDECODE >= 1) {
863 *pix++ = BYTECLIP(*py++); /* Get and store a Y value as grayscale */
864 } else {
865 *pix++ = *py++; /* Get and store a Y value as grayscale */
866 }
867 }
868 }
869 }
870
871 /* Descale the MCU rectangular if needed */
872 if (JD_USE_SCALE && jd->scale) {
873 unsigned int x, y, r, g, b, s, w, a;
874 uint8_t *op;
875
876 /* Get averaged RGB value of each square correcponds to a pixel */
877 s = jd->scale * 2; /* Number of shifts for averaging */
878 w = 1 << jd->scale; /* Width of square */
879 a = (mx - w) * (JD_FORMAT != 2 ? 3 : 1); /* Bytes to skip for next line in the square */
880 op = (uint8_t*)jd->workbuf;
881 for (iy = 0; iy < my; iy += w) {
882 for (ix = 0; ix < mx; ix += w) {
883 pix = (uint8_t*)jd->workbuf + (iy * mx + ix) * (JD_FORMAT != 2 ? 3 : 1);
884 r = g = b = 0;
885 for (y = 0; y < w; y++) { /* Accumulate RGB value in the square */
886 for (x = 0; x < w; x++) {
887 r += *pix++; /* Accumulate R or Y (monochrome output) */
888 if (JD_FORMAT != 2) { /* RGB output? */
889 g += *pix++; /* Accumulate G */
890 b += *pix++; /* Accumulate B */
891 }
892 }
893 pix += a;
894 } /* Put the averaged pixel value */
895 *op++ = (uint8_t)(r >> s); /* Put R or Y (monochrome output) */
896 if (JD_FORMAT != 2) { /* RGB output? */
897 *op++ = (uint8_t)(g >> s); /* Put G */
898 *op++ = (uint8_t)(b >> s); /* Put B */
899 }
900 }
901 }
902 }
903
904 } else { /* For only 1/8 scaling (left-top pixel in each block are the DC value of the block) */
905
906 /* Build a 1/8 descaled RGB MCU from discrete comopnents */
907 pix = (uint8_t*)jd->workbuf;
908 pc = jd->mcubuf + mx * my;
909 cb = pc[0] - 128; /* Get Cb/Cr component and restore right level */
910 cr = pc[64] - 128;
911 for (iy = 0; iy < my; iy += 8) {
912 py = jd->mcubuf;
913 if (iy == 8) py += 64 * 2;
914 for (ix = 0; ix < mx; ix += 8) {
915 yy = *py; /* Get Y component */
916 py += 64;
917 if (JD_FORMAT != 2) {
918 *pix++ = /*R*/ BYTECLIP(yy + ((int)(1.402 * CVACC) * cr / CVACC));
919 *pix++ = /*G*/ BYTECLIP(yy - ((int)(0.344 * CVACC) * cb + (int)(0.714 * CVACC) * cr) / CVACC);
920 *pix++ = /*B*/ BYTECLIP(yy + ((int)(1.772 * CVACC) * cb / CVACC));
921 } else {
922 *pix++ = yy;
923 }
924 }
925 }
926 }
927
928 /* Squeeze up pixel table if a part of MCU is to be truncated */
929 mx >>= jd->scale;
930 if (rx < mx) { /* Is the MCU spans rigit edge? */
931 uint8_t *s, *d;
932 unsigned int x, y;
933
934 s = d = (uint8_t*)jd->workbuf;
935 for (y = 0; y < ry; y++) {
936 for (x = 0; x < rx; x++) { /* Copy effective pixels */
937 *d++ = *s++;
938 if (JD_FORMAT != 2) {
939 *d++ = *s++;
940 *d++ = *s++;
941 }
942 }
943 s += (mx - rx) * (JD_FORMAT != 2 ? 3 : 1); /* Skip truncated pixels */
944 }
945 }
946
947 /* Convert RGB888 to RGB565 if needed */
948 if (JD_FORMAT == 1) {
949 uint8_t *s = (uint8_t*)jd->workbuf;
950 uint16_t w, *d = (uint16_t*)s;
951 unsigned int n = rx * ry;
952
953 if (jd->swap)
954 {
955 do {
956 w = (*s++ & 0xF8) << 8; // RRRRR-----------
957 w |= (*s++ & 0xFC) << 3; // -----GGGGGG-----
958 w |= *s++ >> 3; // -----------BBBBB
959 *d++ = (w << 8) | (w >> 8); // Swap bytes
960 } while (--n);
961 }
962 else
963 {
964 do {
965 w = ( *s++ & 0xF8) << 8; // RRRRR-----------
966 w |= (*s++ & 0xFC) << 3; // -----GGGGGG-----
967 w |= *s++ >> 3; // -----------BBBBB
968 *d++ = w;
969 } while (--n);
970 }
971 }
972
973 /* Output the rectangular */
974 return outfunc(jd, jd->workbuf, &rect) ? JDR_OK : JDR_INTR;
975}
976
977
978
979
980/*-----------------------------------------------------------------------*/
981/* Analyze the JPEG image and Initialize decompressor object */
982/*-----------------------------------------------------------------------*/
983
984#define LDB_WORD(ptr) (uint16_t)(((uint16_t)*((uint8_t*)(ptr))<<8)|(uint16_t)*(uint8_t*)((ptr)+1))
985
986
988 JDEC* jd, /* Blank decompressor object */
989 size_t (*infunc)(JDEC*, uint8_t*, size_t), /* JPEG strem input function */
990 void* pool, /* Working buffer for the decompression session */
991 size_t sz_pool, /* Size of working buffer */
992 void* dev /* I/O device identifier for the session */
994{
995 uint8_t *seg, b;
996 uint16_t marker;
997 unsigned int n, i, ofs;
998 size_t len;
999 JRESULT rc;
1000
1001 uint8_t tmp = jd->swap; // Copy the swap flag
1002 fl::memset(jd, 0, sizeof (JDEC)); /* Clear decompression object (this might be a problem if machine's null pointer is not all bits zero) */
1003 jd->pool = pool; /* Work memroy */
1004 jd->sz_pool = sz_pool; /* Size of given work memory */
1005 jd->infunc = infunc; /* Stream input function */
1006 jd->device = dev; /* I/O device identifier */
1007 jd->swap = tmp; // Restore the swap flag
1008
1009 jd->inbuf = seg = (uint8_t*)alloc_pool(jd, JD_SZBUF); /* Allocate stream input buffer */
1010 if (!seg) return JDR_MEM1;
1011
1012 ofs = marker = 0; /* Find SOI marker */
1013 do {
1014 if (jd->infunc(jd, seg, 1) != 1) return JDR_INP; /* Err: SOI was not detected */
1015 ofs++;
1016 marker = marker << 8 | seg[0];
1017 } while (marker != 0xFFD8);
1018
1019 for (;;) { /* Parse JPEG segments */
1020 /* Get a JPEG marker */
1021 if (jd->infunc(jd, seg, 4) != 4) return JDR_INP;
1022 marker = LDB_WORD(seg); /* Marker */
1023 len = LDB_WORD(seg + 2); /* Length field */
1024 if (len <= 2 || (marker >> 8) != 0xFF) return JDR_FMT1;
1025 len -= 2; /* Segent content size */
1026 ofs += 4 + len; /* Number of bytes loaded */
1027
1028 switch (marker & 0xFF) {
1029 case 0xC0: /* SOF0 (baseline JPEG) */
1030 if (len > JD_SZBUF) return JDR_MEM2;
1031 if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */
1032
1033 jd->width = LDB_WORD(&seg[3]); /* Image width in unit of pixel */
1034 jd->height = LDB_WORD(&seg[1]); /* Image height in unit of pixel */
1035 jd->ncomp = seg[5]; /* Number of color components */
1036 if (jd->ncomp != 3 && jd->ncomp != 1) return JDR_FMT3; /* Err: Supports only Grayscale and Y/Cb/Cr */
1037
1038 /* Check each image component */
1039 for (i = 0; i < jd->ncomp; i++) {
1040 b = seg[7 + 3 * i]; /* Get sampling factor */
1041 if (i == 0) { /* Y component */
1042 if (b != 0x11 && b != 0x22 && b != 0x21) { /* Check sampling factor */
1043 return JDR_FMT3; /* Err: Supports only 4:4:4, 4:2:0 or 4:2:2 */
1044 }
1045 jd->msx = b >> 4; jd->msy = b & 15; /* Size of MCU [blocks] */
1046 } else { /* Cb/Cr component */
1047 if (b != 0x11) return JDR_FMT3; /* Err: Sampling factor of Cb/Cr must be 1 */
1048 }
1049 jd->qtid[i] = seg[8 + 3 * i]; /* Get dequantizer table ID for this component */
1050 if (jd->qtid[i] > 3) return JDR_FMT3; /* Err: Invalid ID */
1051 }
1052 break;
1053
1054 case 0xDD: /* DRI - Define Restart Interval */
1055 if (len > JD_SZBUF) return JDR_MEM2;
1056 if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */
1057
1058 jd->nrst = LDB_WORD(seg); /* Get restart interval (MCUs) */
1059 break;
1060
1061 case 0xC4: /* DHT - Define Huffman Tables */
1062 if (len > JD_SZBUF) return JDR_MEM2;
1063 if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */
1064
1065 rc = create_huffman_tbl(jd, seg, len); /* Create huffman tables */
1066 if (rc) return rc;
1067 break;
1068
1069 case 0xDB: /* DQT - Define Quaitizer Tables */
1070 if (len > JD_SZBUF) return JDR_MEM2;
1071 if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */
1072
1073 rc = create_qt_tbl(jd, seg, len); /* Create de-quantizer tables */
1074 if (rc) return rc;
1075 break;
1076
1077 case 0xDA: /* SOS - Start of Scan */
1078 if (len > JD_SZBUF) return JDR_MEM2;
1079 if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */
1080
1081 if (!jd->width || !jd->height) return JDR_FMT1; /* Err: Invalid image size */
1082 if (seg[0] != jd->ncomp) return JDR_FMT3; /* Err: Wrong color components */
1083
1084 /* Check if all tables corresponding to each components have been loaded */
1085 for (i = 0; i < jd->ncomp; i++) {
1086 b = seg[2 + 2 * i]; /* Get huffman table ID */
1087 if (b != 0x00 && b != 0x11) return JDR_FMT3; /* Err: Different table number for DC/AC element */
1088 n = i ? 1 : 0; /* Component class */
1089 if (!jd->huffbits[n][0] || !jd->huffbits[n][1]) { /* Check huffman table for this component */
1090 return JDR_FMT1; /* Err: Nnot loaded */
1091 }
1092 if (!jd->qttbl[jd->qtid[i]]) { /* Check dequantizer table for this component */
1093 return JDR_FMT1; /* Err: Not loaded */
1094 }
1095 }
1096
1097 /* Allocate working buffer for MCU and pixel output */
1098 n = jd->msy * jd->msx; /* Number of Y blocks in the MCU */
1099 if (!n) return JDR_FMT1; /* Err: SOF0 has not been loaded */
1100 len = n * 64 * 2 + 64; /* Allocate buffer for IDCT and RGB output */
1101 if (len < 256) len = 256; /* but at least 256 byte is required for IDCT */
1102 jd->workbuf = alloc_pool(jd, len); /* and it may occupy a part of following MCU working buffer for RGB output */
1103 if (!jd->workbuf) return JDR_MEM1; /* Err: not enough memory */
1104 jd->mcubuf = (jd_yuv_t*)alloc_pool(jd, (n + 2) * 64 * sizeof (jd_yuv_t)); /* Allocate MCU working buffer */
1105 if (!jd->mcubuf) return JDR_MEM1; /* Err: not enough memory */
1106
1107 /* Align stream read offset to JD_SZBUF */
1108 if (ofs %= JD_SZBUF) {
1109 jd->dctr = jd->infunc(jd, seg + ofs, (size_t)(JD_SZBUF - ofs));
1110 }
1111 jd->dptr = seg + ofs - (JD_FASTDECODE ? 0 : 1);
1112
1113 return JDR_OK; /* Initialization succeeded. Ready to decompress the JPEG image. */
1114
1115 case 0xC1: /* SOF1 */
1116 case 0xC2: /* SOF2 */
1117 case 0xC3: /* SOF3 */
1118 case 0xC5: /* SOF5 */
1119 case 0xC6: /* SOF6 */
1120 case 0xC7: /* SOF7 */
1121 case 0xC9: /* SOF9 */
1122 case 0xCA: /* SOF10 */
1123 case 0xCB: /* SOF11 */
1124 case 0xCD: /* SOF13 */
1125 case 0xCE: /* SOF14 */
1126 case 0xCF: /* SOF15 */
1127 case 0xD9: /* EOI */
1128 return JDR_FMT3; /* Unsuppoted JPEG standard (may be progressive JPEG) */
1129
1130 default: /* Unknown segment (comment, exif or etc..) */
1131 /* Skip segment data (null pointer specifies to remove data from the stream) */
1132 if (jd->infunc(jd, 0, len) != len) return JDR_INP;
1133 }
1134 }
1135}
1136
1137
1138
1139
1140/*-----------------------------------------------------------------------*/
1141/* Start to decompress the JPEG picture */
1142/*-----------------------------------------------------------------------*/
1143
1145 JDEC* jd, /* Initialized decompression object */
1146 int (*outfunc)(JDEC*, void*, JRECT*), /* RGB output function */
1147 uint8_t scale /* Output de-scaling factor (0 to 3) */
1149{
1150 unsigned int x, y, mx, my;
1151 uint16_t rst, rsc;
1152 JRESULT rc;
1153
1154
1155 if (scale > (JD_USE_SCALE ? 3 : 0)) return JDR_PAR;
1156 jd->scale = scale;
1157
1158 mx = jd->msx * 8; my = jd->msy * 8; /* Size of the MCU (pixel) */
1159
1160 jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0; /* Initialize DC values */
1161 rst = rsc = 0;
1162
1163 rc = JDR_OK;
1164 for (y = 0; y < jd->height; y += my) { /* Vertical loop of MCUs */
1165 for (x = 0; x < jd->width; x += mx) { /* Horizontal loop of MCUs */
1166 if (jd->nrst && rst++ == jd->nrst) { /* Process restart interval if enabled */
1167 rc = restart(jd, rsc++);
1168 if (rc != JDR_OK) return rc;
1169 rst = 1;
1170 }
1171 rc = mcu_load(jd); /* Load an MCU (decompress huffman coded stream, dequantize and apply IDCT) */
1172 if (rc != JDR_OK) return rc;
1173 rc = mcu_output(jd, outfunc, x, y); /* Output the MCU (YCbCr to RGB, scaling and output) */
1174 if (rc != JDR_OK) return rc;
1175 }
1176 }
1177
1178 return rc;
1179}
1180
1181
1182/*-----------------------------------------------------------------------*/
1183/* Progressive decompression with 4ms yield points */
1184/*-----------------------------------------------------------------------*/
1185
1187 JDEC_Progressive* jpd, /* Progressive decoder state */
1188 int (*outfunc)(JDEC*, void*, JRECT*), /* Output callback */
1189 uint8_t scale, /* Scaling factor */
1190 uint16_t max_mcus_per_call, /* MCU processing limit per call */
1191 uint8_t* more_data_needed, /* Output: needs more input data */
1192 uint8_t* processing_complete /* Output: decode finished */
1194{
1195 JDEC* jd = &jpd->base;
1196 unsigned int mx, my;
1197 uint16_t rst, rsc;
1198 JRESULT rc;
1199 uint16_t mcus_processed_this_call = 0;
1200
1201 // Initialize output flags
1202 if (more_data_needed) *more_data_needed = 0;
1203 if (processing_complete) *processing_complete = 0;
1204
1205 if (scale > (JD_USE_SCALE ? 3 : 0)) return JDR_PAR;
1206 jd->scale = scale;
1207
1208 mx = jd->msx * 8; my = jd->msy * 8; /* Size of the MCU (pixel) */
1209
1210 // Initialize progressive state if first call
1211 if (!jpd->workspace_initialized) {
1212 jpd->current_mcu_x = 0;
1213 jpd->current_mcu_y = 0;
1214 jpd->mcus_processed = 0;
1215 jpd->total_mcus = ((jd->width + mx - 1) / mx) * ((jd->height + my - 1) / my);
1216 jpd->is_suspended = 0;
1217 jpd->workspace_initialized = 1;
1218
1219 // Initialize DC values and restart state
1220 jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0;
1221 rst = rsc = 0;
1222 }
1223
1224 rc = JDR_OK;
1225
1226 // Resume from where we left off
1227 unsigned int x = jpd->current_mcu_x * mx;
1228 unsigned int y = jpd->current_mcu_y * my;
1229 rst = jpd->mcus_processed % (jd->nrst ? jd->nrst : 1);
1230 rsc = jpd->mcus_processed / (jd->nrst ? jd->nrst : 1);
1231
1232 // Process MCUs with yield support
1233 while (y < jd->height) {
1234 while (x < jd->width) {
1235 // Process restart interval if enabled
1236 if (jd->nrst && rst++ == jd->nrst) {
1237 rc = restart(jd, rsc++);
1238 if (rc != JDR_OK) return rc;
1239 rst = 1;
1240 }
1241
1242 // Load and output single MCU
1243 rc = mcu_load(jd);
1244 if (rc != JDR_OK) return rc;
1245
1246 rc = mcu_output(jd, outfunc, x, y);
1247 if (rc != JDR_OK) return rc;
1248
1249 // Update progressive state
1250 jpd->mcus_processed++;
1251 mcus_processed_this_call++;
1252 x += mx;
1253 jpd->current_mcu_x++;
1254
1255 // Check if we should yield
1256 if (mcus_processed_this_call >= max_mcus_per_call) {
1257 jpd->is_suspended = 1;
1258 jpd->suspend_reason = 1; // Time/MCU limit reached
1259
1260 // Save current position
1261 if (x >= jd->width) {
1262 jpd->current_mcu_x = 0;
1263 jpd->current_mcu_y++;
1264 } else {
1265 jpd->current_mcu_x = x / mx;
1266 }
1267
1268 return (JRESULT)JDR_SUSPEND;
1269 }
1270 }
1271
1272 // Move to next row
1273 x = 0;
1274 y += my;
1275 jpd->current_mcu_x = 0;
1276 jpd->current_mcu_y++;
1277 }
1278
1279 // Processing complete
1280 if (processing_complete) *processing_complete = 1;
1281 return rc;
1282}
1283
1284
1285} // namespace third_party
1286} // namespace fl
uint32_t z[NUM_LAYERS]
Definition Fire2023.h:93
fl::UISlider scale("Scale", 4,.1, 4,.1)
static uint8_t BYTECLIP(int val) FL_NOEXCEPT
fl::u32 uint32_t
Definition coder.h:219
JRESULT jd_decomp(JDEC *jd, int(*outfunc)(JDEC *, void *, JRECT *), uint8_t scale) FL_NOEXCEPT
static void block_idct(int32_t *src, jd_yuv_t *dst) FL_NOEXCEPT
static JRESULT create_huffman_tbl(JDEC *jd, const uint8_t *data, size_t ndata) FL_NOEXCEPT
static JRESULT create_qt_tbl(JDEC *jd, const uint8_t *data, size_t ndata) FL_NOEXCEPT
static int bitext(JDEC *jd, unsigned int nbit) FL_NOEXCEPT
fl::u16 uint16_t
Definition coder.h:214
JRESULT jd_prepare(JDEC *jd, size_t(*infunc)(JDEC *, uint8_t *, size_t), void *pool, size_t sz_pool, void *dev) FL_NOEXCEPT
static const uint8_t Zig[64]
Definition tjpgd.cpp.hpp:50
static void * alloc_pool(JDEC *jd, size_t ndata) FL_NOEXCEPT
static JRESULT restart(JDEC *jd, uint16_t rstn) FL_NOEXCEPT
fl::i16 int16_t
Definition coder.h:215
JRESULT jd_decomp_progressive(JDEC_Progressive *jpd, int(*outfunc)(JDEC *, void *, JRECT *), uint8_t scale, uint16_t max_mcus_per_call, uint8_t *more_data_needed, uint8_t *processing_complete) FL_NOEXCEPT
fl::i32 int32_t
Definition coder.h:220
unsigned char uint8_t
Definition coder.h:209
static JRESULT mcu_load(JDEC *jd) FL_NOEXCEPT
static JRESULT mcu_output(JDEC *jd, int(*outfunc)(JDEC *, void *, JRECT *), unsigned int x, unsigned int y) FL_NOEXCEPT
static const uint16_t Ipsf[64]
Definition tjpgd.cpp.hpp:64
static int huffext(JDEC *jd, unsigned int id, unsigned int cls) FL_NOEXCEPT
uint8_t jd_yuv_t
Definition tjpgd.h:19
uint8_t qtid[3]
Definition tjpgd.h:57
jd_yuv_t * mcubuf
Definition tjpgd.h:76
uint8_t * dptr
Definition tjpgd.h:52
size_t(* infunc)(JDEC *, uint8_t *, size_t)
Definition tjpgd.h:79
int16_t dcv[3]
Definition tjpgd.h:59
uint8_t * inbuf
Definition tjpgd.h:53
uint16_t height
Definition tjpgd.h:61
uint8_t * huffbits[2][2]
Definition tjpgd.h:62
int32_t * qttbl[4]
Definition tjpgd.h:65
u8 u8 height
Definition blur.h:186
void * memset(void *s, int c, size_t n) FL_NOEXCEPT
u8 width
Definition blur.h:186
unsigned char uint8_t
Definition s16x16x4.h:209
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NOEXCEPT
#define LDB_WORD(ptr)
#define JD_SZBUF
Definition tjpgdcnf.h:5
#define JD_FORMAT
Definition tjpgdcnf.h:8
#define JD_FASTDECODE
Definition tjpgdcnf.h:27
#define JD_USE_SCALE
Definition tjpgdcnf.h:15