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