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