GCC Code Coverage Report
Directory: ../src/ Exec Total Coverage
File: /home/joels/Current/lispbm/src/extensions/tjpgd.c Lines: 0 432 0.0 %
Date: 2025-01-19 11:10:47 Branches: 0 279 0.0 %

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