1 /*----------------------------------------------------------------------------/
2 / TJpgDec - Tiny JPEG Decompressor R0.01b (C)ChaN, 2012
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) 2012, 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,'11 R0.01 First release.
17 / Feb 19,'12 R0.01a Fixed decompression fails when scan starts with an escape seq.
18 / Sep 03,'12 R0.01b Added JD_TBLCLIP option.
19 /----------------------------------------------------------------------------*/
20
21 #include "esp_rom_caps.h"
22
23 #if !ESP_ROM_HAS_JPEG_DECODE
24
25 #include "esp_rom_tjpgd.h"
26
27 #define JD_SZBUF 512 /* Size of stream input buffer */
28 #define JD_FORMAT 0 /* Output pixel format 0:RGB888 (3 BYTE/pix), 1:RGB565 (1 WORD/pix) */
29 #define JD_USE_SCALE 1 /* Use descaling feature for output */
30 #define JD_TBLCLIP 1 /* Use table for saturation (might be a bit faster but increases 1K bytes of code size) */
31
32
33 /*-----------------------------------------------*/
34 /* Zigzag-order to raster-order conversion table */
35 /*-----------------------------------------------*/
36
37 #define ZIG(n) Zig[n]
38
39 static
40 const uint8_t Zig[64] = { /* Zigzag-order to raster-order conversion table */
41 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
42 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
43 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
44 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
45 };
46
47
48
49 /*-------------------------------------------------*/
50 /* Input scale factor of Arai algorithm */
51 /* (scaled up 16 bits for fixed point operations) */
52 /*-------------------------------------------------*/
53
54 #define IPSF(n) Ipsf[n]
55
56 static
57 const uint16_t Ipsf[64] = { /* See also aa_idct.png */
58 (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),
59 (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),
60 (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),
61 (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),
62 (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),
63 (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),
64 (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),
65 (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)
66 };
67
68
69
70 /*---------------------------------------------*/
71 /* Conversion table for fast clipping process */
72 /*---------------------------------------------*/
73
74 #if JD_TBLCLIP
75
76 #define BYTECLIP(v) Clip8[(uint32_t)(v) & 0x3FF]
77
78 static
79 const uint8_t Clip8[1024] = {
80 /* 0..255 */
81 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,
82 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,
83 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,
84 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,
85 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,
86 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,
87 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,
88 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,
89 /* 256..511 */
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 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 /* -512..-257 */
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 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 /* -256..-1 */
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 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 };
117
118 #else /* JD_TBLCLIP */
119
120 inline
BYTECLIP(int32_t val)121 uint8_t BYTECLIP (
122 int32_t val
123 )
124 {
125 if (val < 0) val = 0;
126 if (val > 255) val = 255;
127
128 return (uint8_t)val;
129 }
130
131 #endif
132
133
134
135 /*-----------------------------------------------------------------------*/
136 /* Allocate a memory block from memory pool */
137 /*-----------------------------------------------------------------------*/
138
139 static
alloc_pool(esp_rom_tjpgd_dec_t * jd,uint32_t nd)140 void* alloc_pool ( /* Pointer to allocated memory block (NULL:no memory available) */
141 esp_rom_tjpgd_dec_t* jd, /* Pointer to the decompressor object */
142 uint32_t nd /* Number of bytes to allocate */
143 )
144 {
145 char *rp = 0;
146
147
148 nd = (nd + 3) & ~3; /* Align block size to the word boundary */
149
150 if (jd->sz_pool >= nd) {
151 jd->sz_pool -= nd;
152 rp = (char*)jd->pool; /* Get start of available memory pool */
153 jd->pool = (void*)(rp + nd); /* Allocate requierd bytes */
154 }
155
156 return (void*)rp; /* Return allocated memory block (NULL:no memory to allocate) */
157 }
158
159
160
161
162 /*-----------------------------------------------------------------------*/
163 /* Create de-quantization and prescaling tables with a DQT segment */
164 /*-----------------------------------------------------------------------*/
165
166 static
create_qt_tbl(esp_rom_tjpgd_dec_t * jd,const uint8_t * data,uint32_t ndata)167 uint32_t create_qt_tbl ( /* 0:OK, !0:Failed */
168 esp_rom_tjpgd_dec_t* jd, /* Pointer to the decompressor object */
169 const uint8_t* data, /* Pointer to the quantizer tables */
170 uint32_t ndata /* Size of input data */
171 )
172 {
173 uint32_t i;
174 uint8_t d, z;
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 = 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 z = ZIG(i); /* Zigzag-order to raster-order conversion */
189 pb[z] = (int32_t)((uint32_t)*data++ * IPSF(z)); /* 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
203 static
create_huffman_tbl(esp_rom_tjpgd_dec_t * jd,const uint8_t * data,uint32_t ndata)204 uint32_t create_huffman_tbl ( /* 0:OK, !0:Failed */
205 esp_rom_tjpgd_dec_t* jd, /* Pointer to the decompressor object */
206 const uint8_t* data, /* Pointer to the packed huffman tables */
207 uint32_t ndata /* Size of input data */
208 )
209 {
210 uint32_t i, j, b, np, cls, num;
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 cls = (d >> 4); num = d & 0x0F; /* class = dc(0)/ac(1), table number = 0/1 */
220 if (d & 0xEE) return JDR_FMT1; /* Err: invalid class/number */
221 pb = 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 pb[i] = b = *data++;
226 np += b; /* Get sum of code words for each code */
227 }
228
229 ph = alloc_pool(jd, np * sizeof (uint16_t));/* Allocate a memory block for the code word table */
230 if (!ph) return JDR_MEM1; /* Err: not enough memory */
231 jd->huffcode[num][cls] = ph;
232 hc = 0;
233 for (j = i = 0; i < 16; i++) { /* Re-build huffman code word table */
234 b = pb[i];
235 while (b--) ph[j++] = hc++;
236 hc <<= 1;
237 }
238
239 if (ndata < np) return JDR_FMT1; /* Err: wrong data size */
240 ndata -= np;
241 pd = alloc_pool(jd, np); /* Allocate a memory block for the decoded data */
242 if (!pd) return JDR_MEM1; /* Err: not enough memory */
243 jd->huffdata[num][cls] = pd;
244 for (i = 0; i < np; i++) { /* Load decoded data corresponds to each code ward */
245 d = *data++;
246 if (!cls && d > 11) return JDR_FMT1;
247 *pd++ = d;
248 }
249 }
250
251 return JDR_OK;
252 }
253
254
255
256
257 /*-----------------------------------------------------------------------*/
258 /* Extract N bits from input stream */
259 /*-----------------------------------------------------------------------*/
260
261 static
bitext(esp_rom_tjpgd_dec_t * jd,uint32_t nbit)262 int32_t bitext ( /* >=0: extracted data, <0: error code */
263 esp_rom_tjpgd_dec_t* jd, /* Pointer to the decompressor object */
264 uint32_t nbit /* Number of bits to extract (1 to 11) */
265 )
266 {
267 uint8_t msk, s, *dp;
268 uint32_t dc, v, f;
269
270
271 msk = jd->dmsk; dc = jd->dctr; dp = jd->dptr; /* Bit mask, number of data available, read ptr */
272 s = *dp; v = f = 0;
273 do {
274 if (!msk) { /* Next byte? */
275 if (!dc) { /* No input data is available, re-fill input buffer */
276 dp = jd->inbuf; /* Top of input buffer */
277 dc = jd->infunc(jd, dp, JD_SZBUF);
278 if (!dc) return 0 - (int32_t)JDR_INP; /* Err: read error or wrong stream termination */
279 } else {
280 dp++; /* Next data ptr */
281 }
282 dc--; /* Decrement number of available bytes */
283 if (f) { /* In flag sequence? */
284 f = 0; /* Exit flag sequence */
285 if (*dp != 0) return 0 - (int32_t)JDR_FMT1; /* Err: unexpected flag is detected (may be collapted data) */
286 *dp = s = 0xFF; /* The flag is a data 0xFF */
287 } else {
288 s = *dp; /* Get next data byte */
289 if (s == 0xFF) { /* Is start of flag sequence? */
290 f = 1; continue; /* Enter flag sequence */
291 }
292 }
293 msk = 0x80; /* Read from MSB */
294 }
295 v <<= 1; /* Get a bit */
296 if (s & msk) v++;
297 msk >>= 1;
298 nbit--;
299 } while (nbit);
300 jd->dmsk = msk; jd->dctr = dc; jd->dptr = dp;
301
302 return (int32_t)v;
303 }
304
305
306
307
308 /*-----------------------------------------------------------------------*/
309 /* Extract a huffman decoded data from input stream */
310 /*-----------------------------------------------------------------------*/
311
312 static
huffext(esp_rom_tjpgd_dec_t * jd,const uint8_t * hbits,const uint16_t * hcode,const uint8_t * hdata)313 int32_t huffext ( /* >=0: decoded data, <0: error code */
314 esp_rom_tjpgd_dec_t* jd, /* Pointer to the decompressor object */
315 const uint8_t* hbits, /* Pointer to the bit distribution table */
316 const uint16_t* hcode, /* Pointer to the code word table */
317 const uint8_t* hdata /* Pointer to the data table */
318 )
319 {
320 uint8_t msk, s, *dp;
321 uint32_t dc, v, f, bl, nd;
322
323
324 msk = jd->dmsk; dc = jd->dctr; dp = jd->dptr; /* Bit mask, number of data available, read ptr */
325 s = *dp; v = f = 0;
326 bl = 16; /* Max code length */
327 do {
328 if (!msk) { /* Next byte? */
329 if (!dc) { /* No input data is available, re-fill input buffer */
330 dp = jd->inbuf; /* Top of input buffer */
331 dc = jd->infunc(jd, dp, JD_SZBUF);
332 if (!dc) return 0 - (int32_t)JDR_INP; /* Err: read error or wrong stream termination */
333 } else {
334 dp++; /* Next data ptr */
335 }
336 dc--; /* Decrement number of available bytes */
337 if (f) { /* In flag sequence? */
338 f = 0; /* Exit flag sequence */
339 if (*dp != 0)
340 return 0 - (int32_t)JDR_FMT1; /* Err: unexpected flag is detected (may be collapted data) */
341 *dp = s = 0xFF; /* The flag is a data 0xFF */
342 } else {
343 s = *dp; /* Get next data byte */
344 if (s == 0xFF) { /* Is start of flag sequence? */
345 f = 1; continue; /* Enter flag sequence, get trailing byte */
346 }
347 }
348 msk = 0x80; /* Read from MSB */
349 }
350 v <<= 1; /* Get a bit */
351 if (s & msk) v++;
352 msk >>= 1;
353
354 for (nd = *hbits++; nd; nd--) { /* Search the code word in this bit length */
355 if (v == *hcode++) { /* Matched? */
356 jd->dmsk = msk; jd->dctr = dc; jd->dptr = dp;
357 return *hdata; /* Return the decoded data */
358 }
359 hdata++;
360 }
361 bl--;
362 } while (bl);
363
364 return 0 - (int32_t)JDR_FMT1; /* Err: code not found (may be collapted data) */
365 }
366
367
368
369
370 /*-----------------------------------------------------------------------*/
371 /* Apply Inverse-DCT in Arai Algorithm (see also aa_idct.png) */
372 /*-----------------------------------------------------------------------*/
373
374 static
block_idct(int32_t * src,uint8_t * dst)375 void block_idct (
376 int32_t* src, /* Input block data (de-quantized and pre-scaled for Arai Algorithm) */
377 uint8_t* dst /* Pointer to the destination to store the block as byte array */
378 )
379 {
380 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);
381 int32_t v0, v1, v2, v3, v4, v5, v6, v7;
382 int32_t t10, t11, t12, t13;
383 uint32_t i;
384
385 /* Process columns */
386 for (i = 0; i < 8; i++) {
387 v0 = src[8 * 0]; /* Get even elements */
388 v1 = src[8 * 2];
389 v2 = src[8 * 4];
390 v3 = src[8 * 6];
391
392 t10 = v0 + v2; /* Process the even elements */
393 t12 = v0 - v2;
394 t11 = (v1 - v3) * M13 >> 12;
395 v3 += v1;
396 t11 -= v3;
397 v0 = t10 + v3;
398 v3 = t10 - v3;
399 v1 = t11 + t12;
400 v2 = t12 - t11;
401
402 v4 = src[8 * 7]; /* Get odd elements */
403 v5 = src[8 * 1];
404 v6 = src[8 * 5];
405 v7 = src[8 * 3];
406
407 t10 = v5 - v4; /* Process the odd elements */
408 t11 = v5 + v4;
409 t12 = v6 - v7;
410 v7 += v6;
411 v5 = (t11 - v7) * M13 >> 12;
412 v7 += t11;
413 t13 = (t10 + t12) * M5 >> 12;
414 v4 = t13 - (t10 * M2 >> 12);
415 v6 = t13 - (t12 * M4 >> 12) - v7;
416 v5 -= v6;
417 v4 -= v5;
418
419 src[8 * 0] = v0 + v7; /* Write-back transformed values */
420 src[8 * 7] = v0 - v7;
421 src[8 * 1] = v1 + v6;
422 src[8 * 6] = v1 - v6;
423 src[8 * 2] = v2 + v5;
424 src[8 * 5] = v2 - v5;
425 src[8 * 3] = v3 + v4;
426 src[8 * 4] = v3 - v4;
427
428 src++; /* Next column */
429 }
430
431 /* Process rows */
432 src -= 8;
433 for (i = 0; i < 8; i++) {
434 v0 = src[0] + (128L << 8); /* Get even elements (remove DC offset (-128) here) */
435 v1 = src[2];
436 v2 = src[4];
437 v3 = src[6];
438
439 t10 = v0 + v2; /* Process the even elements */
440 t12 = v0 - v2;
441 t11 = (v1 - v3) * M13 >> 12;
442 v3 += v1;
443 t11 -= v3;
444 v0 = t10 + v3;
445 v3 = t10 - v3;
446 v1 = t11 + t12;
447 v2 = t12 - t11;
448
449 v4 = src[7]; /* Get odd elements */
450 v5 = src[1];
451 v6 = src[5];
452 v7 = src[3];
453
454 t10 = v5 - v4; /* Process the odd elements */
455 t11 = v5 + v4;
456 t12 = v6 - v7;
457 v7 += v6;
458 v5 = (t11 - v7) * M13 >> 12;
459 v7 += t11;
460 t13 = (t10 + t12) * M5 >> 12;
461 v4 = t13 - (t10 * M2 >> 12);
462 v6 = t13 - (t12 * M4 >> 12) - v7;
463 v5 -= v6;
464 v4 -= v5;
465
466 dst[0] = BYTECLIP((v0 + v7) >> 8); /* Descale the transformed values 8 bits and output */
467 dst[7] = BYTECLIP((v0 - v7) >> 8);
468 dst[1] = BYTECLIP((v1 + v6) >> 8);
469 dst[6] = BYTECLIP((v1 - v6) >> 8);
470 dst[2] = BYTECLIP((v2 + v5) >> 8);
471 dst[5] = BYTECLIP((v2 - v5) >> 8);
472 dst[3] = BYTECLIP((v3 + v4) >> 8);
473 dst[4] = BYTECLIP((v3 - v4) >> 8);
474 dst += 8;
475
476 src += 8; /* Next row */
477 }
478 }
479
480
481
482
483 /*-----------------------------------------------------------------------*/
484 /* Load all blocks in the MCU into working buffer */
485 /*-----------------------------------------------------------------------*/
486
487 static
mcu_load(esp_rom_tjpgd_dec_t * jd)488 esp_rom_tjpgd_result_t mcu_load (
489 esp_rom_tjpgd_dec_t* jd /* Pointer to the decompressor object */
490 )
491 {
492 int32_t *tmp = (int32_t*)jd->workbuf; /* Block working buffer for de-quantize and IDCT */
493 uint32_t blk, nby, nbc, i, z, id, cmp;
494 int32_t b, d, e;
495 uint8_t *bp;
496 const uint8_t *hb, *hd;
497 const uint16_t *hc;
498 const int32_t *dqf;
499
500
501 nby = jd->msx * jd->msy; /* Number of Y blocks (1, 2 or 4) */
502 nbc = 2; /* Number of C blocks (2) */
503 bp = jd->mcubuf; /* Pointer to the first block */
504
505 for (blk = 0; blk < nby + nbc; blk++) {
506 cmp = (blk < nby) ? 0 : blk - nby + 1; /* Component number 0:Y, 1:Cb, 2:Cr */
507 id = cmp ? 1 : 0; /* Huffman table ID of the component */
508
509 /* Extract a DC element from input stream */
510 hb = jd->huffbits[id][0]; /* Huffman table for the DC element */
511 hc = jd->huffcode[id][0];
512 hd = jd->huffdata[id][0];
513 b = huffext(jd, hb, hc, hd); /* Extract a huffman coded data (bit length) */
514 if (b < 0) return 0 - b; /* Err: invalid code or input */
515 d = jd->dcv[cmp]; /* DC value of previous block */
516 if (b) { /* If there is any difference from previous block */
517 e = bitext(jd, b); /* Extract data bits */
518 if (e < 0) return 0 - e; /* Err: input */
519 b = 1 << (b - 1); /* MSB position */
520 if (!(e & b)) e -= (b << 1) - 1; /* Restore sign if needed */
521 d += e; /* Get current value */
522 jd->dcv[cmp] = (int16_t)d; /* Save current DC value for next block */
523 }
524 dqf = jd->qttbl[jd->qtid[cmp]]; /* De-quantizer table ID for this component */
525 tmp[0] = d * dqf[0] >> 8; /* De-quantize, apply scale factor of Arai algorithm and descale 8 bits */
526
527 /* Extract following 63 AC elements from input stream */
528 for (i = 1; i < 64; i++) tmp[i] = 0; /* Clear rest of elements */
529 hb = jd->huffbits[id][1]; /* Huffman table for the AC elements */
530 hc = jd->huffcode[id][1];
531 hd = jd->huffdata[id][1];
532 i = 1; /* Top of the AC elements */
533 do {
534 b = huffext(jd, hb, hc, hd); /* Extract a huffman coded value (zero runs and bit length) */
535 if (b == 0) break; /* EOB? */
536 if (b < 0) return 0 - b; /* Err: invalid code or input error */
537 z = (uint32_t)b >> 4; /* Number of leading zero elements */
538 if (z) {
539 i += z; /* Skip zero elements */
540 if (i >= 64) return JDR_FMT1; /* Too long zero run */
541 }
542 if (b &= 0x0F) { /* Bit length */
543 d = bitext(jd, b); /* Extract data bits */
544 if (d < 0) return 0 - d; /* Err: input device */
545 b = 1 << (b - 1); /* MSB position */
546 if (!(d & b)) d -= (b << 1) - 1;/* Restore negative value if needed */
547 z = ZIG(i); /* Zigzag-order to raster-order converted index */
548 tmp[z] = d * dqf[z] >> 8; /* De-quantize, apply scale factor of Arai algorithm and descale 8 bits */
549 }
550 } while (++i < 64); /* Next AC element */
551
552 if (JD_USE_SCALE && jd->scale == 3)
553 *bp = (*tmp / 256) + 128; /* If scale ratio is 1/8, IDCT can be ommited and only DC element is used */
554 else
555 block_idct(tmp, bp); /* Apply IDCT and store the block to the MCU buffer */
556
557 bp += 64; /* Next block */
558 }
559
560 return JDR_OK; /* All blocks have been loaded successfully */
561 }
562
563
564
565
566 /*-----------------------------------------------------------------------*/
567 /* Output an MCU: Convert YCrCb to RGB and output it in RGB form */
568 /*-----------------------------------------------------------------------*/
569
570 static
mcu_output(esp_rom_tjpgd_dec_t * jd,uint32_t (* outfunc)(esp_rom_tjpgd_dec_t *,void *,esp_rom_tjpgd_rect_t *),uint32_t x,uint32_t y)571 esp_rom_tjpgd_result_t mcu_output (
572 esp_rom_tjpgd_dec_t* jd, /* Pointer to the decompressor object */
573 uint32_t (*outfunc)(esp_rom_tjpgd_dec_t*, void*, esp_rom_tjpgd_rect_t*), /* RGB output function */
574 uint32_t x, /* MCU position in the image (left of the MCU) */
575 uint32_t y /* MCU position in the image (top of the MCU) */
576 )
577 {
578 const int32_t CVACC = (sizeof (int32_t) > 2) ? 1024 : 128;
579 uint32_t ix, iy, mx, my, rx, ry;
580 int32_t yy, cb, cr;
581 uint8_t *py, *pc, *rgb24;
582 esp_rom_tjpgd_rect_t rect;
583
584
585 mx = jd->msx * 8; my = jd->msy * 8; /* MCU size (pixel) */
586 rx = (x + mx <= jd->width) ? mx : jd->width - x; /* Output rectangular size (it may be clipped at right/bottom end) */
587 ry = (y + my <= jd->height) ? my : jd->height - y;
588 if (JD_USE_SCALE) {
589 rx >>= jd->scale; ry >>= jd->scale;
590 if (!rx || !ry) return JDR_OK; /* Skip this MCU if all pixel is to be rounded off */
591 x >>= jd->scale; y >>= jd->scale;
592 }
593 rect.left = x; rect.right = x + rx - 1; /* Rectangular area in the frame buffer */
594 rect.top = y; rect.bottom = y + ry - 1;
595
596
597 if (!JD_USE_SCALE || jd->scale != 3) { /* Not for 1/8 scaling */
598
599 /* Build an RGB MCU from discrete comopnents */
600 rgb24 = (uint8_t*)jd->workbuf;
601 for (iy = 0; iy < my; iy++) {
602 pc = jd->mcubuf;
603 py = pc + iy * 8;
604 if (my == 16) { /* Double block height? */
605 pc += 64 * 4 + (iy >> 1) * 8;
606 if (iy >= 8) py += 64;
607 } else { /* Single block height */
608 pc += mx * 8 + iy * 8;
609 }
610 for (ix = 0; ix < mx; ix++) {
611 cb = pc[0] - 128; /* Get Cb/Cr component and restore right level */
612 cr = pc[64] - 128;
613 if (mx == 16) { /* Double block width? */
614 if (ix == 8) py += 64 - 8; /* Jump to next block if double block heigt */
615 pc += ix & 1; /* Increase chroma pointer every two pixels */
616 } else { /* Single block width */
617 pc++; /* Increase chroma pointer every pixel */
618 }
619 yy = *py++; /* Get Y component */
620
621 /* Convert YCbCr to RGB */
622 *rgb24++ = /* R */ BYTECLIP(yy + ((int32_t)(1.402 * CVACC) * cr) / CVACC);
623 *rgb24++ = /* G */ BYTECLIP(yy - ((int32_t)(0.344 * CVACC) * cb + (int32_t)(0.714 * CVACC) * cr) / CVACC);
624 *rgb24++ = /* B */ BYTECLIP(yy + ((int32_t)(1.772 * CVACC) * cb) / CVACC);
625 }
626 }
627
628 /* Descale the MCU rectangular if needed */
629 if (JD_USE_SCALE && jd->scale) {
630 uint32_t x, y, r, g, b, s, w, a;
631 uint8_t *op;
632
633 /* Get averaged RGB value of each square correcponds to a pixel */
634 s = jd->scale * 2; /* Bumber of shifts for averaging */
635 w = 1 << jd->scale; /* Width of square */
636 a = (mx - w) * 3; /* Bytes to skip for next line in the square */
637 op = (uint8_t*)jd->workbuf;
638 for (iy = 0; iy < my; iy += w) {
639 for (ix = 0; ix < mx; ix += w) {
640 rgb24 = (uint8_t*)jd->workbuf + (iy * mx + ix) * 3;
641 r = g = b = 0;
642 for (y = 0; y < w; y++) { /* Accumulate RGB value in the square */
643 for (x = 0; x < w; x++) {
644 r += *rgb24++;
645 g += *rgb24++;
646 b += *rgb24++;
647 }
648 rgb24 += a;
649 } /* Put the averaged RGB value as a pixel */
650 *op++ = (uint8_t)(r >> s);
651 *op++ = (uint8_t)(g >> s);
652 *op++ = (uint8_t)(b >> s);
653 }
654 }
655 }
656
657 } else { /* For only 1/8 scaling (left-top pixel in each block are the DC value of the block) */
658
659 /* Build a 1/8 descaled RGB MCU from discrete comopnents */
660 rgb24 = (uint8_t*)jd->workbuf;
661 pc = jd->mcubuf + mx * my;
662 cb = pc[0] - 128; /* Get Cb/Cr component and restore right level */
663 cr = pc[64] - 128;
664 for (iy = 0; iy < my; iy += 8) {
665 py = jd->mcubuf;
666 if (iy == 8) py += 64 * 2;
667 for (ix = 0; ix < mx; ix += 8) {
668 yy = *py; /* Get Y component */
669 py += 64;
670
671 /* Convert YCbCr to RGB */
672 *rgb24++ = /* R */ BYTECLIP(yy + ((int32_t)(1.402 * CVACC) * cr / CVACC));
673 *rgb24++ = /* G */ BYTECLIP(yy - ((int32_t)(0.344 * CVACC) * cb + (int32_t)(0.714 * CVACC) * cr) / CVACC);
674 *rgb24++ = /* B */ BYTECLIP(yy + ((int32_t)(1.772 * CVACC) * cb / CVACC));
675 }
676 }
677 }
678
679 /* Squeeze up pixel table if a part of MCU is to be truncated */
680 mx >>= jd->scale;
681 if (rx < mx) {
682 uint8_t *s, *d;
683 uint32_t x, y;
684
685 s = d = (uint8_t*)jd->workbuf;
686 for (y = 0; y < ry; y++) {
687 for (x = 0; x < rx; x++) { /* Copy effective pixels */
688 *d++ = *s++;
689 *d++ = *s++;
690 *d++ = *s++;
691 }
692 s += (mx - rx) * 3; /* Skip truncated pixels */
693 }
694 }
695
696 /* Convert RGB888 to RGB565 if needed */
697 if (JD_FORMAT == 1) {
698 uint8_t *s = (uint8_t*)jd->workbuf;
699 uint16_t w, *d = (uint16_t*)s;
700 uint32_t n = rx * ry;
701
702 do {
703 w = (*s++ & 0xF8) << 8; /* RRRRR----------- */
704 w |= (*s++ & 0xFC) << 3; /* -----GGGGGG----- */
705 w |= *s++ >> 3; /* -----------BBBBB */
706 *d++ = w;
707 } while (--n);
708 }
709
710 /* Output the RGB rectangular */
711 return outfunc(jd, jd->workbuf, &rect) ? JDR_OK : JDR_INTR;
712 }
713
714
715
716
717 /*-----------------------------------------------------------------------*/
718 /* Process restart interval */
719 /*-----------------------------------------------------------------------*/
720
721 static
restart(esp_rom_tjpgd_dec_t * jd,uint16_t rstn)722 esp_rom_tjpgd_result_t restart (
723 esp_rom_tjpgd_dec_t* jd, /* Pointer to the decompressor object */
724 uint16_t rstn /* Expected restert sequense number */
725 )
726 {
727 uint32_t i, dc;
728 uint16_t d;
729 uint8_t *dp;
730
731
732 /* Discard padding bits and get two bytes from the input stream */
733 dp = jd->dptr; dc = jd->dctr;
734 d = 0;
735 for (i = 0; i < 2; i++) {
736 if (!dc) { /* No input data is available, re-fill input buffer */
737 dp = jd->inbuf;
738 dc = jd->infunc(jd, dp, JD_SZBUF);
739 if (!dc) return JDR_INP;
740 } else {
741 dp++;
742 }
743 dc--;
744 d = (d << 8) | *dp; /* Get a byte */
745 }
746 jd->dptr = dp; jd->dctr = dc; jd->dmsk = 0;
747
748 /* Check the marker */
749 if ((d & 0xFFD8) != 0xFFD0 || (d & 7) != (rstn & 7))
750 return JDR_FMT1; /* Err: expected RSTn marker is not detected (may be collapted data) */
751
752 /* Reset DC offset */
753 jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0;
754
755 return JDR_OK;
756 }
757
758
759
760
761 /*-----------------------------------------------------------------------*/
762 /* Analyze the JPEG image and Initialize decompressor object */
763 /*-----------------------------------------------------------------------*/
764
765 #define LDB_WORD(ptr) (uint16_t)(((uint16_t)*((uint8_t*)(ptr))<<8)|(uint16_t)*(uint8_t*)((ptr)+1))
766
767
esp_rom_tjpgd_prepare(esp_rom_tjpgd_dec_t * jd,uint32_t (* infunc)(esp_rom_tjpgd_dec_t *,uint8_t *,uint32_t),void * pool,uint32_t sz_pool,void * dev)768 esp_rom_tjpgd_result_t esp_rom_tjpgd_prepare (
769 esp_rom_tjpgd_dec_t* jd, /* Blank decompressor object */
770 uint32_t (*infunc)(esp_rom_tjpgd_dec_t*, uint8_t*, uint32_t), /* JPEG strem input function */
771 void* pool, /* Working buffer for the decompression session */
772 uint32_t sz_pool, /* Size of working buffer */
773 void* dev /* I/O device identifier for the session */
774 )
775 {
776 uint8_t *seg, b;
777 uint16_t marker;
778 uint32_t ofs;
779 uint32_t n, i, j, len;
780 esp_rom_tjpgd_result_t rc;
781
782
783 if (!pool) return JDR_PAR;
784
785 jd->pool = pool; /* Work memroy */
786 jd->sz_pool = sz_pool; /* Size of given work memory */
787 jd->infunc = infunc; /* Stream input function */
788 jd->device = dev; /* I/O device identifier */
789 jd->nrst = 0; /* No restart interval (default) */
790
791 for (i = 0; i < 2; i++) { /* Nulls pointers */
792 for (j = 0; j < 2; j++) {
793 jd->huffbits[i][j] = 0;
794 jd->huffcode[i][j] = 0;
795 jd->huffdata[i][j] = 0;
796 }
797 }
798 for (i = 0; i < 4; i++) jd->qttbl[i] = 0;
799
800 jd->inbuf = seg = alloc_pool(jd, JD_SZBUF); /* Allocate stream input buffer */
801 if (!seg) return JDR_MEM1;
802
803 if (jd->infunc(jd, seg, 2) != 2) return JDR_INP;/* Check SOI marker */
804 if (LDB_WORD(seg) != 0xFFD8) return JDR_FMT1; /* Err: SOI is not detected */
805 ofs = 2;
806
807 for (;;) {
808 /* Get a JPEG marker */
809 if (jd->infunc(jd, seg, 4) != 4) return JDR_INP;
810 marker = LDB_WORD(seg); /* Marker */
811 len = LDB_WORD(seg + 2); /* Length field */
812 if (len <= 2 || (marker >> 8) != 0xFF) return JDR_FMT1;
813 len -= 2; /* Content size excluding length field */
814 ofs += 4 + len; /* Number of bytes loaded */
815
816 switch (marker & 0xFF) {
817 case 0xC0: /* SOF0 (baseline JPEG) */
818 /* Load segment data */
819 if (len > JD_SZBUF) return JDR_MEM2;
820 if (jd->infunc(jd, seg, len) != len) return JDR_INP;
821
822 jd->width = LDB_WORD(seg+3); /* Image width in unit of pixel */
823 jd->height = LDB_WORD(seg+1); /* Image height in unit of pixel */
824 if (seg[5] != 3) return JDR_FMT3; /* Err: Supports only Y/Cb/Cr format */
825
826 /* Check three image components */
827 for (i = 0; i < 3; i++) {
828 b = seg[7 + 3 * i]; /* Get sampling factor */
829 if (!i) { /* Y component */
830 if (b != 0x11 && b != 0x22 && b != 0x21)/* Check sampling factor */
831 return JDR_FMT3; /* Err: Supports only 4:4:4, 4:2:0 or 4:2:2 */
832 jd->msx = b >> 4; jd->msy = b & 15; /* Size of MCU [blocks] */
833 } else { /* Cb/Cr component */
834 if (b != 0x11) return JDR_FMT3; /* Err: Sampling factor of Cr/Cb must be 1 */
835 }
836 b = seg[8 + 3 * i]; /* Get dequantizer table ID for this component */
837 if (b > 3) return JDR_FMT3; /* Err: Invalid ID */
838 jd->qtid[i] = b;
839 }
840 break;
841
842 case 0xDD: /* DRI */
843 /* Load segment data */
844 if (len > JD_SZBUF) return JDR_MEM2;
845 if (jd->infunc(jd, seg, len) != len) return JDR_INP;
846
847 /* Get restart interval (MCUs) */
848 jd->nrst = LDB_WORD(seg);
849 break;
850
851 case 0xC4: /* DHT */
852 /* Load segment data */
853 if (len > JD_SZBUF) return JDR_MEM2;
854 if (jd->infunc(jd, seg, len) != len) return JDR_INP;
855
856 /* Create huffman tables */
857 rc = create_huffman_tbl(jd, seg, len);
858 if (rc) return rc;
859 break;
860
861 case 0xDB: /* DQT */
862 /* Load segment data */
863 if (len > JD_SZBUF) return JDR_MEM2;
864 if (jd->infunc(jd, seg, len) != len) return JDR_INP;
865
866 /* Create de-quantizer tables */
867 rc = create_qt_tbl(jd, seg, len);
868 if (rc) return rc;
869 break;
870
871 case 0xDA: /* SOS */
872 /* Load segment data */
873 if (len > JD_SZBUF) return JDR_MEM2;
874 if (jd->infunc(jd, seg, len) != len) return JDR_INP;
875
876 if (!jd->width || !jd->height) return JDR_FMT1; /* Err: Invalid image size */
877
878 if (seg[0] != 3) return JDR_FMT3; /* Err: Supports only three color components format */
879
880 /* Check if all tables corresponding to each components have been loaded */
881 for (i = 0; i < 3; i++) {
882 b = seg[2 + 2 * i]; /* Get huffman table ID */
883 if (b != 0x00 && b != 0x11) return JDR_FMT3; /* Err: Different table number for DC/AC element */
884 b = i ? 1 : 0;
885 if (!jd->huffbits[b][0] || !jd->huffbits[b][1]) /* Check huffman table for this component */
886 return JDR_FMT1; /* Err: Huffman table not loaded */
887 if (!jd->qttbl[jd->qtid[i]]) return JDR_FMT1; /* Err: Dequantizer table not loaded */
888 }
889
890 /* Allocate working buffer for MCU and RGB */
891 n = jd->msy * jd->msx; /* Number of Y blocks in the MCU */
892 if (!n) return JDR_FMT1; /* Err: SOF0 has not been loaded */
893 len = n * 64 * 2 + 64; /* Allocate buffer for IDCT and RGB output */
894 if (len < 256) len = 256; /* but at least 256 byte is required for IDCT */
895 jd->workbuf = alloc_pool(jd, len); /* and it may occupy a part of following MCU working buffer for RGB output */
896 if (!jd->workbuf) return JDR_MEM1; /* Err: not enough memory */
897 jd->mcubuf = alloc_pool(jd, (n + 2) * 64); /* Allocate MCU working buffer */
898 if (!jd->mcubuf) return JDR_MEM1; /* Err: not enough memory */
899
900 /* Pre-load the JPEG data to extract it from the bit stream */
901 jd->dptr = seg; jd->dctr = 0; jd->dmsk = 0; /* Prepare to read bit stream */
902 if (ofs %= JD_SZBUF) { /* Align read offset to JD_SZBUF */
903 jd->dctr = jd->infunc(jd, seg + ofs, JD_SZBUF - (uint32_t)ofs);
904 jd->dptr = seg + ofs - 1;
905 }
906
907 return JDR_OK; /* Initialization succeeded. Ready to decompress the JPEG image. */
908
909 case 0xC1: /* SOF1 */
910 case 0xC2: /* SOF2 */
911 case 0xC3: /* SOF3 */
912 case 0xC5: /* SOF5 */
913 case 0xC6: /* SOF6 */
914 case 0xC7: /* SOF7 */
915 case 0xC9: /* SOF9 */
916 case 0xCA: /* SOF10 */
917 case 0xCB: /* SOF11 */
918 case 0xCD: /* SOF13 */
919 case 0xCE: /* SOF14 */
920 case 0xCF: /* SOF15 */
921 case 0xD9: /* EOI */
922 return JDR_FMT3; /* Unsuppoted JPEG standard (may be progressive JPEG) */
923
924 default: /* Unknown segment (comment, exif or etc..) */
925 /* Skip segment data */
926 if (jd->infunc(jd, 0, len) != len) /* Null pointer specifies to skip bytes of stream */
927 return JDR_INP;
928 }
929 }
930 }
931
932
933
934
935 /*-----------------------------------------------------------------------*/
936 /* Start to decompress the JPEG picture */
937 /*-----------------------------------------------------------------------*/
938
esp_rom_tjpgd_decomp(esp_rom_tjpgd_dec_t * jd,uint32_t (* outfunc)(esp_rom_tjpgd_dec_t *,void *,esp_rom_tjpgd_rect_t *),uint8_t scale)939 esp_rom_tjpgd_result_t esp_rom_tjpgd_decomp (
940 esp_rom_tjpgd_dec_t* jd, /* Initialized decompression object */
941 uint32_t (*outfunc)(esp_rom_tjpgd_dec_t*, void*, esp_rom_tjpgd_rect_t*), /* RGB output function */
942 uint8_t scale /* Output de-scaling factor (0 to 3) */
943 )
944 {
945 uint32_t x, y, mx, my;
946 uint16_t rst, rsc;
947 esp_rom_tjpgd_result_t rc;
948
949
950 if (scale > (JD_USE_SCALE ? 3 : 0)) return JDR_PAR;
951 jd->scale = scale;
952
953 mx = jd->msx * 8; my = jd->msy * 8; /* Size of the MCU (pixel) */
954
955 jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0; /* Initialize DC values */
956 rst = rsc = 0;
957
958 rc = JDR_OK;
959 for (y = 0; y < jd->height; y += my) { /* Vertical loop of MCUs */
960 for (x = 0; x < jd->width; x += mx) { /* Horizontal loop of MCUs */
961 if (jd->nrst && rst++ == jd->nrst) { /* Process restart interval if enabled */
962 rc = restart(jd, rsc++);
963 if (rc != JDR_OK) return rc;
964 rst = 1;
965 }
966 rc = mcu_load(jd); /* Load an MCU (decompress huffman coded stream and apply IDCT) */
967 if (rc != JDR_OK) return rc;
968 rc = mcu_output(jd, outfunc, x, y); /* Output the MCU (color space conversion, scaling and output) */
969 if (rc != JDR_OK) return rc;
970 }
971 }
972
973 return rc;
974 }
975
976 #endif // ESP_ROM_HAS_JPEG_DECODE
977