12 #include "../../gfx.h"
14 #if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_JPG
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")
25 #define JD_USE_SCALE 0
28 #define JD_WORKSZ (JD_SZBUF+2580+8)
31 gCoord left, right, top, bottom;
44 unsigned width, height;
61 typedef struct gdispImagePrivate_JPG {
63 } gdispImagePrivate_JPG;
66 gdispImagePrivate_JPG *priv;
72 return GDISP_IMAGE_ERR_BADFORMAT;
75 if (hdr[0] != 0xff || hdr[1] != 0xd8)
76 return GDISP_IMAGE_ERR_BADFORMAT;
79 img->type = GDISP_IMAGE_TYPE_JPG;
86 if (
gfileRead(img->f, hdr, 4) != 4 || hdr[0] != 0xFF)
87 return GDISP_IMAGE_ERR_BADDATA;
93 img->height = gdispImageGetAlignedBE16(hdr, 0);
94 img->width = gdispImageGetAlignedBE16(hdr, 2);
97 if (!(img->priv = gdispImageAlloc(img,
sizeof(gdispImagePrivate_JPG))))
98 return GDISP_IMAGE_ERR_NOMEMORY;
101 priv = (gdispImagePrivate_JPG *)img->priv;
102 priv->frame0cache = 0;
104 return GDISP_IMAGE_ERR_OK;
107 return GDISP_IMAGE_ERR_UNSUPPORTED;
111 if (hdr[1] >= 0xC1 && hdr[1] <= 0xCF)
112 return GDISP_IMAGE_ERR_UNSUPPORTED;
115 len = gdispImageGetAlignedBE16(hdr, 2);
116 if (len <= 2)
return GDISP_IMAGE_ERR_BADDATA;
122 void gdispImageClose_JPG(
gImage *img){
123 gdispImagePrivate_JPG *priv = (gdispImagePrivate_JPG *)img->priv;
125 if (priv->frame0cache){
126 gdispImageFree(img, (
void *)priv->frame0cache, img->width * img->height *
sizeof(
gPixel));
128 gdispImageFree(img, (
void*) priv,
sizeof(gdispImagePrivate_JPG));
132 static unsigned gdispImage_JPG_WriteToCache(
gImage *img,
void *bitmap, JRECT *rect)
134 gdispImagePrivate_JPG *priv;
139 priv = (gdispImagePrivate_JPG *)img->priv;
140 in = (
unsigned char *)bitmap;
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)
151 gdispImagePrivate_JPG *priv;
156 priv = (gdispImagePrivate_JPG *)img->priv;
157 if (priv->frame0cache)
158 return GDISP_IMAGE_ERR_OK;
161 priv->frame0cache = (
gPixel *)gdispImageAlloc(img, img->width * img->height *
sizeof(
gPixel));
162 if (!priv->frame0cache)
163 return GDISP_IMAGE_ERR_NOMEMORY;
165 if (!(jd = gdispImageAlloc(img,
sizeof(JDEC)+JD_WORKSZ)))
166 return GDISP_IMAGE_ERR_NOMEMORY;
170 if(!(r = jd_prepare(jd, jd+1, img))
171 && !(r = jd_decomp(jd, gdispImage_JPG_WriteToCache, 0)))
172 r = GDISP_IMAGE_ERR_OK;
174 gdispImageFree(img, jd,
sizeof(JDEC)+JD_WORKSZ);
180 gdispImagePrivate_JPG * priv;
182 priv = (gdispImagePrivate_JPG *)img->priv;
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;
190 if (!priv->frame0cache) {
196 gdispGBlitArea(g, x, y, cx, cy, sx, sy, img->width, priv->frame0cache);
198 return GDISP_IMAGE_ERR_OK;
201 gDelay gdispImageNext_JPG(
gImage *img) {
205 return gDelayForever;
233 #define ZIG(n) Zig[n]
236 const gU8 Zig[64] = {
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
250 #define IPSF(n) Ipsf[n]
253 const gU16 Ipsf[64] = {
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)
272 #define BYTECLIP(v) Clip8[(unsigned)(v) & 0x3FF]
275 const gU8 Clip8[1024] = {
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,
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,
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,
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
321 if (val < 0) val = 0;
322 if (val > 255) val = 255;
346 if (jd->sz_pool >= nd) {
348 rp = (
char*)jd->pool;
349 jd->pool = (
void*)(rp + nd);
363 unsigned create_qt_tbl (
375 if (ndata < 65)
return GDISP_IMAGE_ERR_BADDATA;
378 if (d & 0xF0)
return GDISP_IMAGE_ERR_BADDATA;
380 pb = alloc_pool(jd, 64 *
sizeof (gI32));
381 if (!pb)
return GDISP_IMAGE_ERR_NOMEMORY;
383 for (i = 0; i < 64; i++) {
385 pb[z] = (gI32)((gU32)*data++ * IPSF(z));
389 return GDISP_IMAGE_ERR_OK;
400 unsigned create_huffman_tbl (
406 unsigned i, j, b, np, cls, num;
412 if (ndata < 17)
return GDISP_IMAGE_ERR_BADDATA;
415 cls = (d >> 4); num = d & 0x0F;
416 if (d & 0xEE)
return GDISP_IMAGE_ERR_BADDATA;
417 pb = alloc_pool(jd, 16);
418 if (!pb)
return GDISP_IMAGE_ERR_NOMEMORY;
419 jd->huffbits[num][cls] = pb;
420 for (np = i = 0; i < 16; i++) {
425 ph = alloc_pool(jd, np *
sizeof (gU16));
426 if (!ph)
return GDISP_IMAGE_ERR_NOMEMORY;
427 jd->huffcode[num][cls] = ph;
429 for (j = i = 0; i < 16; i++) {
431 while (b--) ph[j++] = hc++;
435 if (ndata < np)
return GDISP_IMAGE_ERR_BADDATA;
437 pd = alloc_pool(jd, np);
438 if (!pd)
return GDISP_IMAGE_ERR_NOMEMORY;
439 jd->huffdata[num][cls] = pd;
440 for (i = 0; i < np; i++) {
442 if (!cls && d > 11)
return GDISP_IMAGE_ERR_BADDATA;
447 return GDISP_IMAGE_ERR_OK;
467 msk = jd->dmsk; dc = jd->dctr; dp = jd->dptr;
473 dc =
gfileRead(jd->img->f, dp, JD_SZBUF);
474 if (!dc)
return 0 - (int)GDISP_IMAGE_ERR_BADDATA;
481 if (*dp != 0)
return 0 - (int)GDISP_IMAGE_ERR_BADDATA;
496 jd->dmsk = msk; jd->dctr = dc; jd->dptr = dp;
517 unsigned dc, v, f, bl, nd;
520 msk = jd->dmsk; dc = jd->dctr; dp = jd->dptr;
527 dc =
gfileRead(jd->img->f, dp, JD_SZBUF);
528 if (!dc)
return 0 - (int)GDISP_IMAGE_ERR_BADDATA;
536 return 0 - (int)GDISP_IMAGE_ERR_BADDATA;
550 for (nd = *hbits++; nd; nd--) {
552 jd->dmsk = msk; jd->dctr = dc; jd->dptr = dp;
560 return 0 - (int)GDISP_IMAGE_ERR_BADDATA;
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;
582 for (i = 0; i < 8; i++) {
590 t11 = (v1 - v3) * M13 >> 12;
607 v5 = (t11 - v7) * M13 >> 12;
609 t13 = (t10 + t12) * M5 >> 12;
610 v4 = t13 - (t10 * M2 >> 12);
611 v6 = t13 - (t12 * M4 >> 12) - v7;
615 src[8 * 0] = v0 + v7;
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;
629 for (i = 0; i < 8; i++) {
630 v0 = src[0] + (128L << 8);
637 t11 = (v1 - v3) * M13 >> 12;
654 v5 = (t11 - v7) * M13 >> 12;
656 t13 = (t10 + t12) * M5 >> 12;
657 v4 = t13 - (t10 * M2 >> 12);
658 v6 = t13 - (t12 * M4 >> 12) - v7;
662 dst[0] = BYTECLIP((v0 + v7) >> 8);
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);
688 gI32 *tmp = (gI32*)jd->workbuf;
689 unsigned blk, nby, nbc, i, z,
id, cmp;
697 nby = jd->msx * jd->msy;
701 for (blk = 0; blk < nby + nbc; blk++) {
702 cmp = (blk < nby) ? 0 : blk - nby + 1;
706 hb = jd->huffbits[id][0];
707 hc = jd->huffcode[id][0];
708 hd = jd->huffdata[id][0];
709 b = huffext(jd, hb, hc, hd);
710 if (b < 0)
return 0 - b;
714 if (e < 0)
return 0 - e;
716 if (!(e & b)) e -= (b << 1) - 1;
718 jd->dcv[cmp] = (gI16)d;
720 dqf = jd->qttbl[jd->qtid[cmp]];
721 tmp[0] = d * dqf[0] >> 8;
724 for (i = 1; i < 64; i++) tmp[i] = 0;
725 hb = jd->huffbits[id][1];
726 hc = jd->huffcode[id][1];
727 hd = jd->huffdata[id][1];
730 b = huffext(jd, hb, hc, hd);
732 if (b < 0)
return 0 - b;
733 z = (unsigned)b >> 4;
736 if (i >= 64)
return GDISP_IMAGE_ERR_BADDATA;
740 if (d < 0)
return 0 - d;
742 if (!(d & b)) d -= (b << 1) - 1;
744 tmp[z] = d * dqf[z] >> 8;
748 if (JD_USE_SCALE && jd->scale == 3)
749 *bp = (*tmp / 256) + 128;
756 return GDISP_IMAGE_ERR_OK;
769 unsigned (*outfunc)(
gImage*,
void*, JRECT*),
774 const int CVACC = (
sizeof (int) > 2) ? 1024 : 128;
775 unsigned ix, iy, mx, my, rx, ry;
777 gU8 *py, *pc, *rgb24;
781 mx = jd->msx * 8; my = jd->msy * 8;
782 rx = (x + mx <= jd->width) ? mx : jd->width - x;
783 ry = (y + my <= jd->height) ? my : jd->height - y;
785 rx >>= jd->scale; ry >>= jd->scale;
786 if (!rx || !ry)
return GDISP_IMAGE_ERR_OK;
787 x >>= jd->scale; y >>= jd->scale;
789 rect.left = x; rect.right = x + rx - 1;
790 rect.top = y; rect.bottom = y + ry - 1;
793 if (!JD_USE_SCALE || jd->scale != 3) {
796 rgb24 = (gU8*)jd->workbuf;
797 for (iy = 0; iy < my; iy++) {
801 pc += 64 * 4 + (iy >> 1) * 8;
802 if (iy >= 8) py += 64;
804 pc += mx * 8 + iy * 8;
806 for (ix = 0; ix < mx; ix++) {
810 if (ix == 8) py += 64 - 8;
818 *rgb24++ = BYTECLIP(yy + ((
int)(1.402 * CVACC) * cr) / CVACC);
819 *rgb24++ = BYTECLIP(yy - ((
int)(0.344 * CVACC) * cb + (
int)(0.714 * CVACC) * cr) / CVACC);
820 *rgb24++ = BYTECLIP(yy + ((
int)(1.772 * CVACC) * cb) / CVACC);
825 if (JD_USE_SCALE && jd->scale) {
826 unsigned x, y, r, g, b, s, w, a;
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;
838 for (y = 0; y < w; y++) {
839 for (x = 0; x < w; x++) {
846 *op++ = (gU8)(r >> s);
847 *op++ = (gU8)(g >> s);
848 *op++ = (gU8)(b >> s);
856 rgb24 = (gU8*)jd->workbuf;
857 pc = jd->mcubuf + mx * my;
860 for (iy = 0; iy < my; iy += 8) {
862 if (iy == 8) py += 64 * 2;
863 for (ix = 0; ix < mx; ix += 8) {
868 *rgb24++ = BYTECLIP(yy + ((
int)(1.402 * CVACC) * cr / CVACC));
869 *rgb24++ = BYTECLIP(yy - ((
int)(0.344 * CVACC) * cb + (
int)(0.714 * CVACC) * cr) / CVACC);
870 *rgb24++ = BYTECLIP(yy + ((
int)(1.772 * CVACC) * cb / CVACC));
881 s = d = (gU8*)jd->workbuf;
882 for (y = 0; y < ry; y++) {
883 for (x = 0; x < rx; x++) {
894 if (JD_FORMAT == 1) {
895 gU8 *s = (gU8*)jd->workbuf;
896 gU16 w, *d = (gU16*)s;
897 unsigned n = rx * ry;
900 w = (*s++ & 0xF8) << 8;
901 w |= (*s++ & 0xFC) << 3;
909 return outfunc(jd->img, jd->workbuf, &rect) ? GDISP_IMAGE_ERR_OK : GDISP_IMAGE_ERR_BADDATA;
931 dp = jd->dptr; dc = jd->dctr;
933 for (i = 0; i < 2; i++) {
936 dc =
gfileRead(jd->img->f, dp, JD_SZBUF);
937 if (!dc)
return GDISP_IMAGE_ERR_BADDATA;
944 jd->dptr = dp; jd->dctr = dc; jd->dmsk = 0;
947 if ((d & 0xFFD8) != 0xFFD0 || (d & 7) != (rstn & 7))
948 return GDISP_IMAGE_ERR_BADDATA;
951 jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0;
953 return GDISP_IMAGE_ERR_OK;
972 unsigned n, i, j, len;
977 jd->sz_pool = JD_WORKSZ;
981 for (i = 0; i < 2; i++) {
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;
988 for (i = 0; i < 4; i++) jd->qttbl[i] = 0;
990 jd->inbuf = seg = alloc_pool(jd, JD_SZBUF);
991 if (!seg)
return GDISP_IMAGE_ERR_NOMEMORY;
993 if (
gfileRead(jd->img->f, seg, 2) != 2)
return GDISP_IMAGE_ERR_BADDATA;
994 if (gdispImageGetAlignedBE16(seg, 0) != 0xFFD8)
return GDISP_IMAGE_ERR_BADDATA;
999 if (
gfileRead(jd->img->f, seg, 4) != 4)
return GDISP_IMAGE_ERR_BADDATA;
1000 marker = gdispImageGetAlignedBE16(seg, 0);
1001 len = gdispImageGetAlignedBE16(seg, 2);
1002 if (len <= 2 || (marker >> 8) != 0xFF)
return GDISP_IMAGE_ERR_BADDATA;
1006 switch (marker & 0xFF) {
1009 if (len > JD_SZBUF)
return GDISP_IMAGE_ERR_NOMEMORY;
1010 if (
gfileRead(jd->img->f, seg, len) != len)
return GDISP_IMAGE_ERR_BADDATA;
1012 jd->width = gdispImageGetBE16(seg,3);
1013 jd->height = gdispImageGetBE16(seg,1);
1014 if (seg[5] != 3)
return GDISP_IMAGE_ERR_BADDATA;
1017 for (i = 0; i < 3; i++) {
1020 if (b != 0x11 && b != 0x22 && b != 0x21)
1021 return GDISP_IMAGE_ERR_BADDATA;
1022 jd->msx = b >> 4; jd->msy = b & 15;
1024 if (b != 0x11)
return GDISP_IMAGE_ERR_BADDATA;
1027 if (b > 3)
return GDISP_IMAGE_ERR_BADDATA;
1034 if (len > JD_SZBUF)
return GDISP_IMAGE_ERR_NOMEMORY;
1035 if (
gfileRead(jd->img->f, seg, len) != len)
return GDISP_IMAGE_ERR_BADDATA;
1038 jd->nrst = gdispImageGetAlignedBE16(seg, 0);
1043 if (len > JD_SZBUF)
return GDISP_IMAGE_ERR_NOMEMORY;
1044 if (
gfileRead(jd->img->f, seg, len) != len)
return GDISP_IMAGE_ERR_BADDATA;
1047 rc = create_huffman_tbl(jd, seg, len);
1053 if (len > JD_SZBUF)
return GDISP_IMAGE_ERR_NOMEMORY;
1054 if (
gfileRead(jd->img->f, seg, len) != len)
return GDISP_IMAGE_ERR_BADDATA;
1057 rc = create_qt_tbl(jd, seg, len);
1063 if (len > JD_SZBUF)
return GDISP_IMAGE_ERR_NOMEMORY;
1064 if (
gfileRead(jd->img->f, seg, len) != len)
return GDISP_IMAGE_ERR_BADDATA;
1066 if (!jd->width || !jd->height)
return GDISP_IMAGE_ERR_BADDATA;
1068 if (seg[0] != 3)
return GDISP_IMAGE_ERR_BADDATA;
1071 for (i = 0; i < 3; i++) {
1073 if (b != 0x00 && b != 0x11)
return GDISP_IMAGE_ERR_BADDATA;
1075 if (!jd->huffbits[b][0] || !jd->huffbits[b][1])
1076 return GDISP_IMAGE_ERR_BADDATA;
1077 if (!jd->qttbl[jd->qtid[i]])
return GDISP_IMAGE_ERR_BADDATA;
1081 n = jd->msy * jd->msx;
1082 if (!n)
return GDISP_IMAGE_ERR_BADDATA;
1083 len = n * 64 * 2 + 64;
1084 if (len < 256) len = 256;
1085 jd->workbuf = alloc_pool(jd, len);
1086 if (!jd->workbuf)
return GDISP_IMAGE_ERR_NOMEMORY;
1087 jd->mcubuf = alloc_pool(jd, (n + 2) * 64);
1088 if (!jd->mcubuf)
return GDISP_IMAGE_ERR_NOMEMORY;
1091 jd->dptr = seg; jd->dctr = 0; jd->dmsk = 0;
1092 if (ofs %= JD_SZBUF) {
1093 jd->dctr =
gfileRead(jd->img->f, seg + ofs, JD_SZBUF - (
unsigned)ofs);
1094 jd->dptr = seg + ofs - 1;
1097 return GDISP_IMAGE_ERR_OK;
1112 return GDISP_IMAGE_ERR_UNSUPPORTED;
1127 unsigned (*outfunc)(
gImage*,
void*, JRECT*),
1131 unsigned x, y, mx, my;
1136 if (scale > (JD_USE_SCALE ? 3 : 0))
return GDISP_IMAGE_ERR_UNSUPPORTED;
1139 mx = jd->msx * 8; my = jd->msy * 8;
1141 jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0;
1144 rc = GDISP_IMAGE_ERR_OK;
1145 for (y = 0; y < jd->height; y += my) {
1146 for (x = 0; x < jd->width; x += mx) {
1147 if (jd->nrst && rst++ == jd->nrst) {
1148 rc = restart(jd, rsc++);
1149 if (rc != GDISP_IMAGE_ERR_OK)
return rc;
1153 if (rc != GDISP_IMAGE_ERR_OK)
return rc;
1154 rc = mcu_output(jd, outfunc, x, y);
1155 if (rc != GDISP_IMAGE_ERR_OK)
return rc;
GDISP image support routines header file.
#define RGB2COLOR(r, g, b)
Convert red, green, blue (each 0 to 255) into a color value.
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.
gI16 gCoord
The type for a coordinate or length on the screen.
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.
The structure for an image.