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