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