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