blob: 7fb151d9b8122b4a806912b25f4d1255a2aa3b94 [file] [log] [blame]
Stefan Reinauerd650e992010-02-22 04:33:13 +00001/*
2 * This file is part of the coreboot project.
Uwe Hermann548dbe72010-02-22 16:41:49 +00003 *
4 * Copyright (C) 2001 Michael Schroeder
Stefan Reinauerd650e992010-02-22 04:33:13 +00005 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
Uwe Hermann548dbe72010-02-22 16:41:49 +00008 * published by the Free Software Foundation; version 2 of the License.
Stefan Reinauerd650e992010-02-22 04:33:13 +00009 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Stefan Reinauerd650e992010-02-22 04:33:13 +000014 */
15
16/*
17 * a tiny jpeg decoder.
18 *
19 * written in August 2001 by Michael Schroeder <mls@suse.de>
20 *
21 */
22
23#define __LITTLE_ENDIAN
24#include <string.h>
25#include "jpeg.h"
26#define ISHIFT 11
27
28#define IFIX(a) ((int)((a) * (1 << ISHIFT) + .5))
29#define IMULT(a, b) (((a) * (b)) >> ISHIFT)
30#define ITOINT(a) ((a) >> ISHIFT)
31
32#ifndef __P
33# define __P(x) x
34#endif
35
36/* special markers */
37#define M_BADHUFF -1
38#define M_EOF 0x80
39
40struct in {
41 unsigned char *p;
42 unsigned int bits;
43 int left;
44 int marker;
45
46 int (*func) __P((void *));
47 void *data;
48};
49
50/*********************************/
51struct dec_hufftbl;
52struct enc_hufftbl;
53
54union hufftblp {
55 struct dec_hufftbl *dhuff;
56 struct enc_hufftbl *ehuff;
57};
58
59struct scan {
60 int dc; /* old dc value */
61
62 union hufftblp hudc;
63 union hufftblp huac;
64 int next; /* when to switch to next scan */
65
66 int cid; /* component id */
67 int hv; /* horiz/vert, copied from comp */
68 int tq; /* quant tbl, copied from comp */
69};
70
71/*********************************/
72
73#define DECBITS 10 /* seems to be the optimum */
74
75struct dec_hufftbl {
76 int maxcode[17];
77 int valptr[16];
78 unsigned char vals[256];
79 unsigned int llvals[1 << DECBITS];
80};
81
82static void decode_mcus __P((struct in *, int *, int, struct scan *, int *));
83static int dec_readmarker __P((struct in *));
84static void dec_makehuff __P((struct dec_hufftbl *, int *, unsigned char *));
85
86static void setinput __P((struct in *, unsigned char *));
87/*********************************/
88
89#undef PREC
90#define PREC int
91
92static void idctqtab __P((unsigned char *, PREC *));
93static void idct __P((int *, int *, PREC *, PREC, int));
94static void scaleidctqtab __P((PREC *, PREC));
95
96/*********************************/
97
98static void initcol __P((PREC[][64]));
99
100static void col221111 __P((int *, unsigned char *, int));
101static void col221111_16 __P((int *, unsigned char *, int));
102static void col221111_32 __P((int *, unsigned char *, int));
103
104/*********************************/
105
106#define M_SOI 0xd8
107#define M_APP0 0xe0
108#define M_DQT 0xdb
109#define M_SOF0 0xc0
110#define M_DHT 0xc4
111#define M_DRI 0xdd
112#define M_SOS 0xda
113#define M_RST0 0xd0
114#define M_EOI 0xd9
115#define M_COM 0xfe
116
117static unsigned char *datap;
118
119static int getbyte(void)
120{
121 return *datap++;
122}
123
124static int getword(void)
125{
126 int c1, c2;
127 c1 = *datap++;
128 c2 = *datap++;
129 return c1 << 8 | c2;
130}
131
132struct comp {
133 int cid;
134 int hv;
135 int tq;
136};
137
138#define MAXCOMP 4
139struct jpginfo {
140 int nc; /* number of components */
141 int ns; /* number of scans */
142 int dri; /* restart interval */
143 int nm; /* mcus til next marker */
144 int rm; /* next restart marker */
145};
146
147static struct jpginfo info;
148static struct comp comps[MAXCOMP];
149
150static struct scan dscans[MAXCOMP];
151
152static unsigned char quant[4][64];
153
154static struct dec_hufftbl dhuff[4];
155
156#define dec_huffdc (dhuff + 0)
157#define dec_huffac (dhuff + 2)
158
Stefan Reinauer87489e12010-03-17 04:03:22 +0000159static struct in glob_in;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000160
161static int readtables(int till)
162{
163 int m, l, i, j, lq, pq, tq;
164 int tc, th, tt;
165
166 for (;;) {
167 if (getbyte() != 0xff)
168 return -1;
169 if ((m = getbyte()) == till)
170 break;
171
172 switch (m) {
173 case 0xc2:
174 return 0;
175
176 case M_DQT:
177 lq = getword();
178 while (lq > 2) {
179 pq = getbyte();
180 tq = pq & 15;
181 if (tq > 3)
182 return -1;
183 pq >>= 4;
184 if (pq != 0)
185 return -1;
186 for (i = 0; i < 64; i++)
187 quant[tq][i] = getbyte();
188 lq -= 64 + 1;
189 }
190 break;
191
192 case M_DHT:
193 l = getword();
194 while (l > 2) {
195 int hufflen[16], k;
196 unsigned char huffvals[256];
197
198 tc = getbyte();
199 th = tc & 15;
200 tc >>= 4;
201 tt = tc * 2 + th;
202 if (tc > 1 || th > 1)
203 return -1;
204 for (i = 0; i < 16; i++)
205 hufflen[i] = getbyte();
206 l -= 1 + 16;
207 k = 0;
208 for (i = 0; i < 16; i++) {
209 for (j = 0; j < hufflen[i]; j++)
210 huffvals[k++] = getbyte();
211 l -= hufflen[i];
212 }
213 dec_makehuff(dhuff + tt, hufflen,
214 huffvals);
215 }
216 break;
217
218 case M_DRI:
219 l = getword();
220 info.dri = getword();
221 break;
222
223 default:
224 l = getword();
225 while (l-- > 2)
226 getbyte();
227 break;
228 }
229 }
230 return 0;
231}
232
233static void dec_initscans(void)
234{
235 int i;
236
237 info.nm = info.dri + 1;
238 info.rm = M_RST0;
239 for (i = 0; i < info.ns; i++)
240 dscans[i].dc = 0;
241}
242
243static int dec_checkmarker(void)
244{
245 int i;
246
Stefan Reinauer87489e12010-03-17 04:03:22 +0000247 if (dec_readmarker(&glob_in) != info.rm)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000248 return -1;
249 info.nm = info.dri;
250 info.rm = (info.rm + 1) & ~0x08;
251 for (i = 0; i < info.ns; i++)
252 dscans[i].dc = 0;
253 return 0;
254}
255
Patrick Georgi246179a2015-08-09 18:23:10 +0200256void jpeg_fetch_size(unsigned char *buf, int *width, int *height)
257{
258 datap = buf;
259 getbyte();
260 getbyte();
261 readtables(M_SOF0);
262 getword();
263 getbyte();
264 *height = getword();
265 *width = getword();
266}
267
Stefan Reinauerd650e992010-02-22 04:33:13 +0000268int jpeg_check_size(unsigned char *buf, int width, int height)
269{
Lee Leahye20a3192017-03-09 16:21:34 -0800270 datap = buf;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000271 getbyte();
272 getbyte();
273 readtables(M_SOF0);
274 getword();
275 getbyte();
Lee Leahye20a3192017-03-09 16:21:34 -0800276 if (height != getword() || width != getword())
Stefan Reinauerd650e992010-02-22 04:33:13 +0000277 return 0;
Lee Leahye20a3192017-03-09 16:21:34 -0800278 return 1;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000279}
280
Stefan Reinauer14e22772010-04-27 06:56:47 +0000281int jpeg_decode(unsigned char *buf, unsigned char *pic,
Stefan Reinauerd650e992010-02-22 04:33:13 +0000282 int width, int height, int depth, struct jpeg_decdata *decdata)
283{
284 int i, j, m, tac, tdc;
285 int mcusx, mcusy, mx, my;
286 int max[6];
287
288 if (!decdata || !buf || !pic)
289 return -1;
290 datap = buf;
291 if (getbyte() != 0xff)
292 return ERR_NO_SOI;
293 if (getbyte() != M_SOI)
294 return ERR_NO_SOI;
295 if (readtables(M_SOF0))
296 return ERR_BAD_TABLES;
297 getword();
298 i = getbyte();
299 if (i != 8)
300 return ERR_NOT_8BIT;
301 if (((getword() + 15) & ~15) != height)
302 return ERR_HEIGHT_MISMATCH;
303 if (((getword() + 15) & ~15) != width)
304 return ERR_WIDTH_MISMATCH;
305 if ((height & 15) || (width & 15))
306 return ERR_BAD_WIDTH_OR_HEIGHT;
307 info.nc = getbyte();
308 if (info.nc > MAXCOMP)
309 return ERR_TOO_MANY_COMPPS;
310 for (i = 0; i < info.nc; i++) {
311 int h, v;
312 comps[i].cid = getbyte();
313 comps[i].hv = getbyte();
314 v = comps[i].hv & 15;
315 h = comps[i].hv >> 4;
316 comps[i].tq = getbyte();
317 if (h > 3 || v > 3)
318 return ERR_ILLEGAL_HV;
319 if (comps[i].tq > 3)
320 return ERR_QUANT_TABLE_SELECTOR;
321 }
322 if (readtables(M_SOS))
323 return ERR_BAD_TABLES;
324 getword();
325 info.ns = getbyte();
326 if (info.ns != 3)
327 return ERR_NOT_YCBCR_221111;
328 for (i = 0; i < 3; i++) {
329 dscans[i].cid = getbyte();
330 tdc = getbyte();
331 tac = tdc & 15;
332 tdc >>= 4;
333 if (tdc > 1 || tac > 1)
334 return ERR_QUANT_TABLE_SELECTOR;
335 for (j = 0; j < info.nc; j++)
336 if (comps[j].cid == dscans[i].cid)
337 break;
338 if (j == info.nc)
339 return ERR_UNKNOWN_CID_IN_SCAN;
340 dscans[i].hv = comps[j].hv;
341 dscans[i].tq = comps[j].tq;
342 dscans[i].hudc.dhuff = dec_huffdc + tdc;
343 dscans[i].huac.dhuff = dec_huffac + tac;
344 }
345
346 i = getbyte();
347 j = getbyte();
348 m = getbyte();
349
350 if (i != 0 || j != 63 || m != 0)
351 return ERR_NOT_SEQUENTIAL_DCT;
352
353 if (dscans[0].cid != 1 || dscans[1].cid != 2 || dscans[2].cid != 3)
354 return ERR_NOT_YCBCR_221111;
355
356 if (dscans[0].hv != 0x22 || dscans[1].hv != 0x11 || dscans[2].hv != 0x11)
357 return ERR_NOT_YCBCR_221111;
358
359 mcusx = width >> 4;
360 mcusy = height >> 4;
361
362
363 idctqtab(quant[dscans[0].tq], decdata->dquant[0]);
364 idctqtab(quant[dscans[1].tq], decdata->dquant[1]);
365 idctqtab(quant[dscans[2].tq], decdata->dquant[2]);
366 initcol(decdata->dquant);
Stefan Reinauer87489e12010-03-17 04:03:22 +0000367 setinput(&glob_in, datap);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000368
369#if 0
370 /* landing zone */
371 img[len] = 0;
372 img[len + 1] = 0xff;
373 img[len + 2] = M_EOF;
374#endif
375
376 dec_initscans();
377
378 dscans[0].next = 6 - 4;
379 dscans[1].next = 6 - 4 - 1;
380 dscans[2].next = 6 - 4 - 1 - 1; /* 411 encoding */
381 for (my = 0; my < mcusy; my++) {
382 for (mx = 0; mx < mcusx; mx++) {
383 if (info.dri && !--info.nm)
384 if (dec_checkmarker())
385 return ERR_WRONG_MARKER;
386
Stefan Reinauer87489e12010-03-17 04:03:22 +0000387 decode_mcus(&glob_in, decdata->dcts, 6, dscans, max);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000388 idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]);
389 idct(decdata->dcts + 64, decdata->out + 64, decdata->dquant[0], IFIX(128.5), max[1]);
390 idct(decdata->dcts + 128, decdata->out + 128, decdata->dquant[0], IFIX(128.5), max[2]);
391 idct(decdata->dcts + 192, decdata->out + 192, decdata->dquant[0], IFIX(128.5), max[3]);
392 idct(decdata->dcts + 256, decdata->out + 256, decdata->dquant[1], IFIX(0.5), max[4]);
393 idct(decdata->dcts + 320, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]);
394
395 switch (depth) {
396 case 32:
397 col221111_32(decdata->out, pic + (my * 16 * mcusx + mx) * 16 * 4, mcusx * 16 * 4);
398 break;
399 case 24:
400 col221111(decdata->out, pic + (my * 16 * mcusx + mx) * 16 * 3, mcusx * 16 * 3);
401 break;
402 case 16:
403 col221111_16(decdata->out, pic + (my * 16 * mcusx + mx) * (16 * 2), mcusx * (16 * 2));
404 break;
405 default:
406 return ERR_DEPTH_MISMATCH;
407 break;
408 }
409 }
410 }
411
Stefan Reinauer87489e12010-03-17 04:03:22 +0000412 m = dec_readmarker(&glob_in);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000413 if (m != M_EOI)
414 return ERR_NO_EOI;
415
416 return 0;
417}
418
419/****************************************************************/
420/************** huffman decoder ***************/
421/****************************************************************/
422
423static int fillbits __P((struct in *, int, unsigned int));
424static int dec_rec2
425__P((struct in *, struct dec_hufftbl *, int *, int, int));
426
427static void setinput(struct in *in, unsigned char *p)
428{
429 in->p = p;
430 in->left = 0;
431 in->bits = 0;
432 in->marker = 0;
433}
434
435static int fillbits(struct in *in, int le, unsigned int bi)
436{
437 int b, m;
438
439 if (in->marker) {
440 if (le <= 16)
441 in->bits = bi << 16, le += 16;
442 return le;
443 }
444 while (le <= 24) {
445 b = *in->p++;
446 if (b == 0xff && (m = *in->p++) != 0) {
447 if (m == M_EOF) {
448 if (in->func && (m = in->func(in->data)) == 0)
449 continue;
450 }
451 in->marker = m;
452 if (le <= 16)
453 bi = bi << 16, le += 16;
454 break;
455 }
456 bi = bi << 8 | b;
457 le += 8;
458 }
459 in->bits = bi; /* tmp... 2 return values needed */
460 return le;
461}
462
463static int dec_readmarker(struct in *in)
464{
465 int m;
466
467 in->left = fillbits(in, in->left, in->bits);
468 if ((m = in->marker) == 0)
469 return 0;
470 in->left = 0;
471 in->marker = 0;
472 return m;
473}
474
475#define LEBI_DCL int le, bi
476#define LEBI_GET(in) (le = in->left, bi = in->bits)
477#define LEBI_PUT(in) (in->left = le, in->bits = bi)
478
Lee Leahye20a3192017-03-09 16:21:34 -0800479#define GETBITS(in, n) ( \
480 (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0), \
481 (le -= (n)), \
482 bi >> le & ((1 << (n)) - 1) \
483 )
Stefan Reinauerd650e992010-02-22 04:33:13 +0000484
485#define UNGETBITS(in, n) ( \
Lee Leahye20a3192017-03-09 16:21:34 -0800486 le += (n) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000487)
488
489
490static int dec_rec2(struct in *in, struct dec_hufftbl *hu, int *runp, int c,
491 int i)
492{
493 LEBI_DCL;
494
495 LEBI_GET(in);
496 if (i) {
497 UNGETBITS(in, i & 127);
498 *runp = i >> 8 & 15;
499 i >>= 16;
500 } else {
Lee Leahyb6ee0f92017-03-09 13:35:26 -0800501 for (i = DECBITS; (c = ((c << 1) | GETBITS(in, 1))) >= (hu->maxcode[i]); i++)
502 ;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000503 if (i >= 16) {
504 in->marker = M_BADHUFF;
505 return 0;
506 }
507 i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];
508 *runp = i >> 4;
509 i &= 15;
510 }
511 if (i == 0) { /* sigh, 0xf0 is 11 bit */
512 LEBI_PUT(in);
513 return 0;
514 }
515 /* receive part */
516 c = GETBITS(in, i);
517 if (c < (1 << (i - 1)))
518 c += (-1 << i) + 1;
519 LEBI_PUT(in);
520 return c;
521}
522
Lee Leahye20a3192017-03-09 16:21:34 -0800523#define DEC_REC(in, hu, r, i) ( \
524 r = GETBITS(in, DECBITS), \
525 i = hu->llvals[r], \
526 i & 128 ? \
527 ( \
528 UNGETBITS(in, i & 127), \
529 r = i >> 8 & 15, \
530 i >> 16 \
531 ) \
532 : \
533 ( \
534 LEBI_PUT(in), \
535 i = dec_rec2(in, hu, &r, r, i), \
536 LEBI_GET(in), \
537 i \
538 ) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000539)
540
541static void decode_mcus(struct in *in, int *dct, int n, struct scan *sc, int *maxp)
542{
543 struct dec_hufftbl *hu;
544 int i, r, t;
545 LEBI_DCL;
546
547 memset(dct, 0, n * 64 * sizeof(*dct));
548 LEBI_GET(in);
549 while (n-- > 0) {
550 hu = sc->hudc.dhuff;
551 *dct++ = (sc->dc += DEC_REC(in, hu, r, t));
552
553 hu = sc->huac.dhuff;
554 i = 63;
555 while (i > 0) {
556 t = DEC_REC(in, hu, r, t);
557 if (t == 0 && r == 0) {
558 dct += i;
559 break;
560 }
561 dct += r;
562 *dct++ = t;
563 i -= r + 1;
564 }
565 *maxp++ = 64 - i;
566 if (n == sc->next)
567 sc++;
568 }
569 LEBI_PUT(in);
570}
571
572static void dec_makehuff(struct dec_hufftbl *hu, int *hufflen, unsigned char *huffvals)
573{
574 int code, k, i, j, d, x, c, v;
575 for (i = 0; i < (1 << DECBITS); i++)
576 hu->llvals[i] = 0;
577
578/*
579 * llvals layout:
580 *
581 * value v already known, run r, backup u bits:
582 * vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu
583 * value unknown, size b bits, run r, backup u bits:
584 * 000000000000bbbb 0000 rrrr 0 uuuuuuu
585 * value and size unknown:
586 * 0000000000000000 0000 0000 0 0000000
587 */
588 code = 0;
589 k = 0;
590 for (i = 0; i < 16; i++, code <<= 1) { /* sizes */
591 hu->valptr[i] = k;
592 for (j = 0; j < hufflen[i]; j++) {
593 hu->vals[k] = *huffvals++;
594 if (i < DECBITS) {
595 c = code << (DECBITS - 1 - i);
596 v = hu->vals[k] & 0x0f; /* size */
597 for (d = 1 << (DECBITS - 1 - i); --d >= 0;) {
598 if (v + i < DECBITS) { /* both fit in table */
599 x = d >> (DECBITS - 1 - v -
600 i);
601 if (v && x < (1 << (v - 1)))
602 x += (-1 << v) + 1;
Lee Leahy35af5c42017-03-09 17:35:28 -0800603 x = x << 16 | (hu->vals[k] & 0xf0) << 4 |
Stefan Reinauerd650e992010-02-22 04:33:13 +0000604 (DECBITS - (i + 1 + v)) | 128;
605 } else
Lee Leahy35af5c42017-03-09 17:35:28 -0800606 x = v << 16 | (hu->vals[k] & 0xf0) << 4 |
Lee Leahye20a3192017-03-09 16:21:34 -0800607 (DECBITS - (i + 1));
Stefan Reinauerd650e992010-02-22 04:33:13 +0000608 hu->llvals[c | d] = x;
609 }
610 }
611 code++;
612 k++;
613 }
614 hu->maxcode[i] = code;
615 }
616 hu->maxcode[16] = 0x20000; /* always terminate decode */
617}
618
619/****************************************************************/
620/************** idct ***************/
621/****************************************************************/
622
623#define ONE ((PREC)IFIX(1.))
624#define S2 ((PREC)IFIX(0.382683432))
625#define C2 ((PREC)IFIX(0.923879532))
626#define C4 ((PREC)IFIX(0.707106781))
627
628#define S22 ((PREC)IFIX(2 * 0.382683432))
629#define C22 ((PREC)IFIX(2 * 0.923879532))
630#define IC4 ((PREC)IFIX(1 / 0.707106781))
631
632#define C3IC1 ((PREC)IFIX(0.847759065)) /* c3/c1 */
633#define C5IC1 ((PREC)IFIX(0.566454497)) /* c5/c1 */
634#define C7IC1 ((PREC)IFIX(0.198912367)) /* c7/c1 */
635
Lee Leahy35af5c42017-03-09 17:35:28 -0800636#define XPP(a, b) (t = a + b, b = a - b, a = t)
637#define XMP(a, b) (t = a - b, b = a + b, a = t)
638#define XPM(a, b) (t = a + b, b = b - a, a = t)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000639
Lee Leahy35af5c42017-03-09 17:35:28 -0800640#define ROT(a, b, s, c) (t = IMULT(a + b, s), \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000641 a = IMULT(a, c - s) + t, \
642 b = IMULT(b, c + s) - t)
643
Lee Leahye20a3192017-03-09 16:21:34 -0800644#define IDCT \
645( \
646 XPP(t0, t1), \
647 XMP(t2, t3), \
648 t2 = IMULT(t2, IC4) - t3, \
649 XPP(t0, t3), \
650 XPP(t1, t2), \
651 XMP(t4, t7), \
652 XPP(t5, t6), \
653 XMP(t5, t7), \
654 t5 = IMULT(t5, IC4), \
655 ROT(t4, t6, S22, C22), \
656 t6 -= t7, \
657 t5 -= t6, \
658 t4 -= t5, \
659 XPP(t0, t7), \
660 XPP(t1, t6), \
661 XPP(t2, t5), \
662 XPP(t3, t4) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000663)
664
665static unsigned char zig2[64] = {
666 0, 2, 3, 9, 10, 20, 21, 35,
667 14, 16, 25, 31, 39, 46, 50, 57,
668 5, 7, 12, 18, 23, 33, 37, 48,
669 27, 29, 41, 44, 52, 55, 59, 62,
670 15, 26, 30, 40, 45, 51, 56, 58,
671 1, 4, 8, 11, 19, 22, 34, 36,
672 28, 42, 43, 53, 54, 60, 61, 63,
673 6, 13, 17, 24, 32, 38, 47, 49
674};
675
Stefan Reinauer87489e12010-03-17 04:03:22 +0000676void idct(int *in, int *out, PREC *lquant, PREC off, int max)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000677{
678 PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
679 PREC tmp[64], *tmpp;
680 int i, j;
681 unsigned char *zig2p;
682
683 t0 = off;
684 if (max == 1) {
Stefan Reinauer87489e12010-03-17 04:03:22 +0000685 t0 += in[0] * lquant[0];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000686 for (i = 0; i < 64; i++)
687 out[i] = ITOINT(t0);
688 return;
689 }
690 zig2p = zig2;
691 tmpp = tmp;
692 for (i = 0; i < 8; i++) {
693 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000694 t0 += in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000695 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000696 t5 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000697 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000698 t2 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000699 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000700 t7 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000701 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000702 t1 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000703 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000704 t4 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000705 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000706 t3 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000707 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000708 t6 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000709 IDCT;
710 tmpp[0 * 8] = t0;
711 tmpp[1 * 8] = t1;
712 tmpp[2 * 8] = t2;
713 tmpp[3 * 8] = t3;
714 tmpp[4 * 8] = t4;
715 tmpp[5 * 8] = t5;
716 tmpp[6 * 8] = t6;
717 tmpp[7 * 8] = t7;
718 tmpp++;
719 t0 = 0;
720 }
721 for (i = 0; i < 8; i++) {
722 t0 = tmp[8 * i + 0];
723 t1 = tmp[8 * i + 1];
724 t2 = tmp[8 * i + 2];
725 t3 = tmp[8 * i + 3];
726 t4 = tmp[8 * i + 4];
727 t5 = tmp[8 * i + 5];
728 t6 = tmp[8 * i + 6];
729 t7 = tmp[8 * i + 7];
730 IDCT;
731 out[8 * i + 0] = ITOINT(t0);
732 out[8 * i + 1] = ITOINT(t1);
733 out[8 * i + 2] = ITOINT(t2);
734 out[8 * i + 3] = ITOINT(t3);
735 out[8 * i + 4] = ITOINT(t4);
736 out[8 * i + 5] = ITOINT(t5);
737 out[8 * i + 6] = ITOINT(t6);
738 out[8 * i + 7] = ITOINT(t7);
739 }
740}
741
742static unsigned char zig[64] = {
743 0, 1, 5, 6, 14, 15, 27, 28,
744 2, 4, 7, 13, 16, 26, 29, 42,
745 3, 8, 12, 17, 25, 30, 41, 43,
746 9, 11, 18, 24, 31, 40, 44, 53,
747 10, 19, 23, 32, 39, 45, 52, 54,
748 20, 22, 33, 38, 46, 51, 55, 60,
749 21, 34, 37, 47, 50, 56, 59, 61,
750 35, 36, 48, 49, 57, 58, 62, 63
751};
752
753static PREC aaidct[8] = {
754 IFIX(0.3535533906), IFIX(0.4903926402),
755 IFIX(0.4619397663), IFIX(0.4157348062),
756 IFIX(0.3535533906), IFIX(0.2777851165),
757 IFIX(0.1913417162), IFIX(0.0975451610)
758};
759
760
761static void idctqtab(unsigned char *qin, PREC *qout)
762{
763 int i, j;
764
765 for (i = 0; i < 8; i++)
766 for (j = 0; j < 8; j++)
767 qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] *
Lee Leahye20a3192017-03-09 16:21:34 -0800768 IMULT(aaidct[i], aaidct[j]);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000769}
770
771static void scaleidctqtab(PREC *q, PREC sc)
772{
773 int i;
774
775 for (i = 0; i < 64; i++)
776 q[i] = IMULT(q[i], sc);
777}
778
779/****************************************************************/
780/************** color decoder ***************/
781/****************************************************************/
782
783#define ROUND
784
785/*
786 * YCbCr Color transformation:
787 *
788 * y:0..255 Cb:-128..127 Cr:-128..127
789 *
790 * R = Y + 1.40200 * Cr
791 * G = Y - 0.34414 * Cb - 0.71414 * Cr
792 * B = Y + 1.77200 * Cb
793 *
794 * =>
795 * Cr *= 1.40200;
796 * Cb *= 1.77200;
797 * Cg = 0.19421 * Cb + .50937 * Cr;
798 * R = Y + Cr;
799 * G = Y - Cg;
800 * B = Y + Cb;
801 *
802 * =>
803 * Cg = (50 * Cb + 130 * Cr + 128) >> 8;
804 */
805
806static void initcol(PREC q[][64])
807{
808 scaleidctqtab(q[1], IFIX(1.77200));
809 scaleidctqtab(q[2], IFIX(1.40200));
810}
811
812/* This is optimized for the stupid sun SUNWspro compiler. */
Lee Leahy35af5c42017-03-09 17:35:28 -0800813#define STORECLAMP(a, x) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000814( \
Lee Leahye20a3192017-03-09 16:21:34 -0800815 (a) = (x), \
816 (unsigned int)(x) >= 256 ? \
817 ((a) = (x) < 0 ? 0 : 255) \
818 : \
819 0 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000820)
821
822#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x))
823
824#ifdef ROUND
825
826#define CBCRCG(yin, xin) \
827( \
Lee Leahy35af5c42017-03-09 17:35:28 -0800828 cb = outc[0 + yin * 8 + xin], \
829 cr = outc[64 + yin * 8 + xin], \
Lee Leahye20a3192017-03-09 16:21:34 -0800830 cg = (50 * cb + 130 * cr + 128) >> 8 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000831)
832
833#else
834
835#define CBCRCG(yin, xin) \
836( \
Lee Leahy35af5c42017-03-09 17:35:28 -0800837 cb = outc[0 + yin*8 + xin], \
838 cr = outc[64 + yin*8 + xin], \
Lee Leahye20a3192017-03-09 16:21:34 -0800839 cg = (3 * cb + 8 * cr) >> 4 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000840)
841
842#endif
843
844#define PIC(yin, xin, p, xout) \
845( \
Lee Leahye20a3192017-03-09 16:21:34 -0800846 y = outy[(yin) * 8 + xin], \
847 STORECLAMP(p[(xout) * 3 + 0], y + cr), \
848 STORECLAMP(p[(xout) * 3 + 1], y - cg), \
849 STORECLAMP(p[(xout) * 3 + 2], y + cb) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000850)
851
852#ifdef __LITTLE_ENDIAN
Lee Leahye20a3192017-03-09 16:21:34 -0800853#define PIC_16(yin, xin, p, xout, add) \
854( \
855 y = outy[(yin) * 8 + xin], \
856 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
857 ((CLAMP(y - cg + add) & 0xfc) << 3) | \
858 ((CLAMP(y + cb + add*2+1)) >> 3), \
859 p[(xout) * 2 + 0] = y & 0xff, \
860 p[(xout) * 2 + 1] = y >> 8 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000861)
862#else
863#ifdef CONFIG_PPC
Lee Leahye20a3192017-03-09 16:21:34 -0800864#define PIC_16(yin, xin, p, xout, add) \
865( \
866 y = outy[(yin) * 8 + xin], \
867 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 7) | \
868 ((CLAMP(y - cg + add*2+1) & 0xf8) << 2) | \
869 ((CLAMP(y + cb + add*2+1)) >> 3), \
870 p[(xout) * 2 + 0] = y >> 8, \
871 p[(xout) * 2 + 1] = y & 0xff \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000872)
873#else
Lee Leahye20a3192017-03-09 16:21:34 -0800874#define PIC_16(yin, xin, p, xout, add) \
875( \
876 y = outy[(yin) * 8 + xin], \
877 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
878 ((CLAMP(y - cg + add) & 0xfc) << 3) | \
879 ((CLAMP(y + cb + add*2+1)) >> 3), \
880 p[(xout) * 2 + 0] = y >> 8, \
881 p[(xout) * 2 + 1] = y & 0xff \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000882)
883#endif
884#endif
885
886#define PIC_32(yin, xin, p, xout) \
887( \
Lee Leahye20a3192017-03-09 16:21:34 -0800888 y = outy[(yin) * 8 + xin], \
889 STORECLAMP(p[(xout) * 4 + 0], y + cr), \
890 STORECLAMP(p[(xout) * 4 + 1], y - cg), \
891 STORECLAMP(p[(xout) * 4 + 2], y + cb), \
892 p[(xout) * 4 + 3] = 0 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000893)
894
Lee Leahye20a3192017-03-09 16:21:34 -0800895#define PIC221111(xin) \
896( \
897 CBCRCG(0, xin), \
898 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
899 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
900 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
901 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000902)
903
Lee Leahye20a3192017-03-09 16:21:34 -0800904#define PIC221111_16(xin) \
905( \
906 CBCRCG(0, xin), \
907 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3), \
908 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0), \
909 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1), \
910 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000911)
912
Lee Leahye20a3192017-03-09 16:21:34 -0800913#define PIC221111_32(xin) \
914( \
915 CBCRCG(0, xin), \
916 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
917 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
918 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
919 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000920)
921
922static void col221111(int *out, unsigned char *pic, int width)
923{
924 int i, j, k;
925 unsigned char *pic0, *pic1;
926 int *outy, *outc;
927 int cr, cg, cb, y;
928
929 pic0 = pic;
930 pic1 = pic + width;
931 outy = out;
932 outc = out + 64 * 4;
933 for (i = 2; i > 0; i--) {
934 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800935 for (k = 0; k < 8; k++)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000936 PIC221111(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000937 outc += 8;
938 outy += 16;
939 pic0 += 2 * width;
940 pic1 += 2 * width;
941 }
942 outy += 64 * 2 - 16 * 4;
943 }
944}
945
946static void col221111_16(int *out, unsigned char *pic, int width)
947{
948 int i, j, k;
949 unsigned char *pic0, *pic1;
950 int *outy, *outc;
951 int cr, cg, cb, y;
952
953 pic0 = pic;
954 pic1 = pic + width;
955 outy = out;
956 outc = out + 64 * 4;
957 for (i = 2; i > 0; i--) {
958 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800959 for (k = 0; k < 8; k++)
Lee Leahye20a3192017-03-09 16:21:34 -0800960 PIC221111_16(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000961 outc += 8;
962 outy += 16;
963 pic0 += 2 * width;
964 pic1 += 2 * width;
965 }
966 outy += 64 * 2 - 16 * 4;
967 }
968}
969
970static void col221111_32(int *out, unsigned char *pic, int width)
971{
972 int i, j, k;
973 unsigned char *pic0, *pic1;
974 int *outy, *outc;
975 int cr, cg, cb, y;
976
977 pic0 = pic;
978 pic1 = pic + width;
979 outy = out;
980 outc = out + 64 * 4;
981 for (i = 2; i > 0; i--) {
982 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800983 for (k = 0; k < 8; k++)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000984 PIC221111_32(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000985 outc += 8;
986 outy += 16;
987 pic0 += 2 * width;
988 pic1 += 2 * width;
989 }
990 outy += 64 * 2 - 16 * 4;
991 }
992}