blob: f06d4903293b1520e1b6ddc3e2a34c8f94d6d236 [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
Lee Leahy73402172017-03-10 15:23:24 -0800356 if (dscans[0].hv != 0x22 || dscans[1].hv != 0x11
357 || dscans[2].hv != 0x11)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000358 return ERR_NOT_YCBCR_221111;
359
360 mcusx = width >> 4;
361 mcusy = height >> 4;
362
363
364 idctqtab(quant[dscans[0].tq], decdata->dquant[0]);
365 idctqtab(quant[dscans[1].tq], decdata->dquant[1]);
366 idctqtab(quant[dscans[2].tq], decdata->dquant[2]);
367 initcol(decdata->dquant);
Stefan Reinauer87489e12010-03-17 04:03:22 +0000368 setinput(&glob_in, datap);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000369
370#if 0
371 /* landing zone */
372 img[len] = 0;
373 img[len + 1] = 0xff;
374 img[len + 2] = M_EOF;
375#endif
376
377 dec_initscans();
378
379 dscans[0].next = 6 - 4;
380 dscans[1].next = 6 - 4 - 1;
381 dscans[2].next = 6 - 4 - 1 - 1; /* 411 encoding */
382 for (my = 0; my < mcusy; my++) {
383 for (mx = 0; mx < mcusx; mx++) {
384 if (info.dri && !--info.nm)
385 if (dec_checkmarker())
386 return ERR_WRONG_MARKER;
387
Stefan Reinauer87489e12010-03-17 04:03:22 +0000388 decode_mcus(&glob_in, decdata->dcts, 6, dscans, max);
Lee Leahy73402172017-03-10 15:23:24 -0800389 idct(decdata->dcts, decdata->out, decdata->dquant[0],
390 IFIX(128.5), max[0]);
391 idct(decdata->dcts + 64, decdata->out + 64,
392 decdata->dquant[0], IFIX(128.5), max[1]);
393 idct(decdata->dcts + 128, decdata->out + 128,
394 decdata->dquant[0], IFIX(128.5), max[2]);
395 idct(decdata->dcts + 192, decdata->out + 192,
396 decdata->dquant[0], IFIX(128.5), max[3]);
397 idct(decdata->dcts + 256, decdata->out + 256,
398 decdata->dquant[1], IFIX(0.5), max[4]);
399 idct(decdata->dcts + 320, decdata->out + 320,
400 decdata->dquant[2], IFIX(0.5), max[5]);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000401
402 switch (depth) {
403 case 32:
Lee Leahy73402172017-03-10 15:23:24 -0800404 col221111_32(decdata->out, pic
405 + (my * 16 * mcusx + mx) * 16 * 4,
406 mcusx * 16 * 4);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000407 break;
408 case 24:
Lee Leahy73402172017-03-10 15:23:24 -0800409 col221111(decdata->out, pic
410 + (my * 16 * mcusx + mx) * 16 * 3,
411 mcusx * 16 * 3);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000412 break;
413 case 16:
Lee Leahy73402172017-03-10 15:23:24 -0800414 col221111_16(decdata->out, pic
415 + (my * 16 * mcusx + mx) * (16 * 2),
416 mcusx * (16 * 2));
Stefan Reinauerd650e992010-02-22 04:33:13 +0000417 break;
418 default:
419 return ERR_DEPTH_MISMATCH;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000420 }
421 }
422 }
423
Stefan Reinauer87489e12010-03-17 04:03:22 +0000424 m = dec_readmarker(&glob_in);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000425 if (m != M_EOI)
426 return ERR_NO_EOI;
427
428 return 0;
429}
430
431/****************************************************************/
432/************** huffman decoder ***************/
433/****************************************************************/
434
435static int fillbits __P((struct in *, int, unsigned int));
436static int dec_rec2
437__P((struct in *, struct dec_hufftbl *, int *, int, int));
438
439static void setinput(struct in *in, unsigned char *p)
440{
441 in->p = p;
442 in->left = 0;
443 in->bits = 0;
444 in->marker = 0;
445}
446
447static int fillbits(struct in *in, int le, unsigned int bi)
448{
449 int b, m;
450
451 if (in->marker) {
452 if (le <= 16)
453 in->bits = bi << 16, le += 16;
454 return le;
455 }
456 while (le <= 24) {
457 b = *in->p++;
458 if (b == 0xff && (m = *in->p++) != 0) {
459 if (m == M_EOF) {
460 if (in->func && (m = in->func(in->data)) == 0)
461 continue;
462 }
463 in->marker = m;
464 if (le <= 16)
465 bi = bi << 16, le += 16;
466 break;
467 }
468 bi = bi << 8 | b;
469 le += 8;
470 }
471 in->bits = bi; /* tmp... 2 return values needed */
472 return le;
473}
474
475static int dec_readmarker(struct in *in)
476{
477 int m;
478
479 in->left = fillbits(in, in->left, in->bits);
480 if ((m = in->marker) == 0)
481 return 0;
482 in->left = 0;
483 in->marker = 0;
484 return m;
485}
486
487#define LEBI_DCL int le, bi
488#define LEBI_GET(in) (le = in->left, bi = in->bits)
489#define LEBI_PUT(in) (in->left = le, in->bits = bi)
490
Lee Leahye20a3192017-03-09 16:21:34 -0800491#define GETBITS(in, n) ( \
492 (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0), \
493 (le -= (n)), \
494 bi >> le & ((1 << (n)) - 1) \
495 )
Stefan Reinauerd650e992010-02-22 04:33:13 +0000496
497#define UNGETBITS(in, n) ( \
Lee Leahye20a3192017-03-09 16:21:34 -0800498 le += (n) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000499)
500
501
502static int dec_rec2(struct in *in, struct dec_hufftbl *hu, int *runp, int c,
503 int i)
504{
505 LEBI_DCL;
506
507 LEBI_GET(in);
508 if (i) {
509 UNGETBITS(in, i & 127);
510 *runp = i >> 8 & 15;
511 i >>= 16;
512 } else {
Lee Leahy73402172017-03-10 15:23:24 -0800513 for (i = DECBITS; (c = ((c << 1) | GETBITS(in, 1)))
514 >= (hu->maxcode[i]); i++)
Lee Leahyb6ee0f92017-03-09 13:35:26 -0800515 ;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000516 if (i >= 16) {
517 in->marker = M_BADHUFF;
518 return 0;
519 }
520 i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];
521 *runp = i >> 4;
522 i &= 15;
523 }
524 if (i == 0) { /* sigh, 0xf0 is 11 bit */
525 LEBI_PUT(in);
526 return 0;
527 }
528 /* receive part */
529 c = GETBITS(in, i);
530 if (c < (1 << (i - 1)))
531 c += (-1 << i) + 1;
532 LEBI_PUT(in);
533 return c;
534}
535
Lee Leahye20a3192017-03-09 16:21:34 -0800536#define DEC_REC(in, hu, r, i) ( \
537 r = GETBITS(in, DECBITS), \
538 i = hu->llvals[r], \
539 i & 128 ? \
540 ( \
541 UNGETBITS(in, i & 127), \
542 r = i >> 8 & 15, \
543 i >> 16 \
544 ) \
545 : \
546 ( \
547 LEBI_PUT(in), \
548 i = dec_rec2(in, hu, &r, r, i), \
549 LEBI_GET(in), \
550 i \
551 ) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000552)
553
Lee Leahy73402172017-03-10 15:23:24 -0800554static void decode_mcus(struct in *in, int *dct, int n, struct scan *sc,
555 int *maxp)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000556{
557 struct dec_hufftbl *hu;
558 int i, r, t;
559 LEBI_DCL;
560
561 memset(dct, 0, n * 64 * sizeof(*dct));
562 LEBI_GET(in);
563 while (n-- > 0) {
564 hu = sc->hudc.dhuff;
565 *dct++ = (sc->dc += DEC_REC(in, hu, r, t));
566
567 hu = sc->huac.dhuff;
568 i = 63;
569 while (i > 0) {
570 t = DEC_REC(in, hu, r, t);
571 if (t == 0 && r == 0) {
572 dct += i;
573 break;
574 }
575 dct += r;
576 *dct++ = t;
577 i -= r + 1;
578 }
579 *maxp++ = 64 - i;
580 if (n == sc->next)
581 sc++;
582 }
583 LEBI_PUT(in);
584}
585
Lee Leahy73402172017-03-10 15:23:24 -0800586static void dec_makehuff(struct dec_hufftbl *hu, int *hufflen,
587 unsigned char *huffvals)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000588{
589 int code, k, i, j, d, x, c, v;
590 for (i = 0; i < (1 << DECBITS); i++)
591 hu->llvals[i] = 0;
592
593/*
594 * llvals layout:
595 *
596 * value v already known, run r, backup u bits:
597 * vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu
598 * value unknown, size b bits, run r, backup u bits:
599 * 000000000000bbbb 0000 rrrr 0 uuuuuuu
600 * value and size unknown:
601 * 0000000000000000 0000 0000 0 0000000
602 */
603 code = 0;
604 k = 0;
605 for (i = 0; i < 16; i++, code <<= 1) { /* sizes */
606 hu->valptr[i] = k;
607 for (j = 0; j < hufflen[i]; j++) {
608 hu->vals[k] = *huffvals++;
609 if (i < DECBITS) {
610 c = code << (DECBITS - 1 - i);
611 v = hu->vals[k] & 0x0f; /* size */
612 for (d = 1 << (DECBITS - 1 - i); --d >= 0;) {
Lee Leahy73402172017-03-10 15:23:24 -0800613 /* both fit in table */
614 if (v + i < DECBITS) {
Stefan Reinauerd650e992010-02-22 04:33:13 +0000615 x = d >> (DECBITS - 1 - v -
616 i);
617 if (v && x < (1 << (v - 1)))
618 x += (-1 << v) + 1;
Lee Leahy73402172017-03-10 15:23:24 -0800619 x = x << 16 | (hu->vals[k]
620 & 0xf0) << 4 |
621 (DECBITS - (i + 1 + v))
622 | 128;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000623 } else
Lee Leahy73402172017-03-10 15:23:24 -0800624 x = v << 16 | (hu->vals[k]
625 & 0xf0) << 4 |
Lee Leahye20a3192017-03-09 16:21:34 -0800626 (DECBITS - (i + 1));
Stefan Reinauerd650e992010-02-22 04:33:13 +0000627 hu->llvals[c | d] = x;
628 }
629 }
630 code++;
631 k++;
632 }
633 hu->maxcode[i] = code;
634 }
635 hu->maxcode[16] = 0x20000; /* always terminate decode */
636}
637
638/****************************************************************/
639/************** idct ***************/
640/****************************************************************/
641
642#define ONE ((PREC)IFIX(1.))
643#define S2 ((PREC)IFIX(0.382683432))
644#define C2 ((PREC)IFIX(0.923879532))
645#define C4 ((PREC)IFIX(0.707106781))
646
647#define S22 ((PREC)IFIX(2 * 0.382683432))
648#define C22 ((PREC)IFIX(2 * 0.923879532))
649#define IC4 ((PREC)IFIX(1 / 0.707106781))
650
651#define C3IC1 ((PREC)IFIX(0.847759065)) /* c3/c1 */
652#define C5IC1 ((PREC)IFIX(0.566454497)) /* c5/c1 */
653#define C7IC1 ((PREC)IFIX(0.198912367)) /* c7/c1 */
654
Lee Leahy35af5c42017-03-09 17:35:28 -0800655#define XPP(a, b) (t = a + b, b = a - b, a = t)
656#define XMP(a, b) (t = a - b, b = a + b, a = t)
657#define XPM(a, b) (t = a + b, b = b - a, a = t)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000658
Lee Leahy35af5c42017-03-09 17:35:28 -0800659#define ROT(a, b, s, c) (t = IMULT(a + b, s), \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000660 a = IMULT(a, c - s) + t, \
661 b = IMULT(b, c + s) - t)
662
Lee Leahye20a3192017-03-09 16:21:34 -0800663#define IDCT \
664( \
665 XPP(t0, t1), \
666 XMP(t2, t3), \
667 t2 = IMULT(t2, IC4) - t3, \
668 XPP(t0, t3), \
669 XPP(t1, t2), \
670 XMP(t4, t7), \
671 XPP(t5, t6), \
672 XMP(t5, t7), \
673 t5 = IMULT(t5, IC4), \
674 ROT(t4, t6, S22, C22), \
675 t6 -= t7, \
676 t5 -= t6, \
677 t4 -= t5, \
678 XPP(t0, t7), \
679 XPP(t1, t6), \
680 XPP(t2, t5), \
681 XPP(t3, t4) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000682)
683
684static unsigned char zig2[64] = {
685 0, 2, 3, 9, 10, 20, 21, 35,
686 14, 16, 25, 31, 39, 46, 50, 57,
687 5, 7, 12, 18, 23, 33, 37, 48,
688 27, 29, 41, 44, 52, 55, 59, 62,
689 15, 26, 30, 40, 45, 51, 56, 58,
690 1, 4, 8, 11, 19, 22, 34, 36,
691 28, 42, 43, 53, 54, 60, 61, 63,
692 6, 13, 17, 24, 32, 38, 47, 49
693};
694
Stefan Reinauer87489e12010-03-17 04:03:22 +0000695void idct(int *in, int *out, PREC *lquant, PREC off, int max)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000696{
697 PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
698 PREC tmp[64], *tmpp;
699 int i, j;
700 unsigned char *zig2p;
701
702 t0 = off;
703 if (max == 1) {
Stefan Reinauer87489e12010-03-17 04:03:22 +0000704 t0 += in[0] * lquant[0];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000705 for (i = 0; i < 64; i++)
706 out[i] = ITOINT(t0);
707 return;
708 }
709 zig2p = zig2;
710 tmpp = tmp;
711 for (i = 0; i < 8; i++) {
712 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000713 t0 += in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000714 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000715 t5 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000716 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000717 t2 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000718 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000719 t7 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000720 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000721 t1 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000722 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000723 t4 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000724 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000725 t3 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000726 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000727 t6 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000728 IDCT;
729 tmpp[0 * 8] = t0;
730 tmpp[1 * 8] = t1;
731 tmpp[2 * 8] = t2;
732 tmpp[3 * 8] = t3;
733 tmpp[4 * 8] = t4;
734 tmpp[5 * 8] = t5;
735 tmpp[6 * 8] = t6;
736 tmpp[7 * 8] = t7;
737 tmpp++;
738 t0 = 0;
739 }
740 for (i = 0; i < 8; i++) {
741 t0 = tmp[8 * i + 0];
742 t1 = tmp[8 * i + 1];
743 t2 = tmp[8 * i + 2];
744 t3 = tmp[8 * i + 3];
745 t4 = tmp[8 * i + 4];
746 t5 = tmp[8 * i + 5];
747 t6 = tmp[8 * i + 6];
748 t7 = tmp[8 * i + 7];
749 IDCT;
750 out[8 * i + 0] = ITOINT(t0);
751 out[8 * i + 1] = ITOINT(t1);
752 out[8 * i + 2] = ITOINT(t2);
753 out[8 * i + 3] = ITOINT(t3);
754 out[8 * i + 4] = ITOINT(t4);
755 out[8 * i + 5] = ITOINT(t5);
756 out[8 * i + 6] = ITOINT(t6);
757 out[8 * i + 7] = ITOINT(t7);
758 }
759}
760
761static unsigned char zig[64] = {
762 0, 1, 5, 6, 14, 15, 27, 28,
763 2, 4, 7, 13, 16, 26, 29, 42,
764 3, 8, 12, 17, 25, 30, 41, 43,
765 9, 11, 18, 24, 31, 40, 44, 53,
766 10, 19, 23, 32, 39, 45, 52, 54,
767 20, 22, 33, 38, 46, 51, 55, 60,
768 21, 34, 37, 47, 50, 56, 59, 61,
769 35, 36, 48, 49, 57, 58, 62, 63
770};
771
772static PREC aaidct[8] = {
773 IFIX(0.3535533906), IFIX(0.4903926402),
774 IFIX(0.4619397663), IFIX(0.4157348062),
775 IFIX(0.3535533906), IFIX(0.2777851165),
776 IFIX(0.1913417162), IFIX(0.0975451610)
777};
778
779
780static void idctqtab(unsigned char *qin, PREC *qout)
781{
782 int i, j;
783
784 for (i = 0; i < 8; i++)
785 for (j = 0; j < 8; j++)
786 qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] *
Lee Leahye20a3192017-03-09 16:21:34 -0800787 IMULT(aaidct[i], aaidct[j]);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000788}
789
790static void scaleidctqtab(PREC *q, PREC sc)
791{
792 int i;
793
794 for (i = 0; i < 64; i++)
795 q[i] = IMULT(q[i], sc);
796}
797
798/****************************************************************/
799/************** color decoder ***************/
800/****************************************************************/
801
802#define ROUND
803
804/*
805 * YCbCr Color transformation:
806 *
807 * y:0..255 Cb:-128..127 Cr:-128..127
808 *
809 * R = Y + 1.40200 * Cr
810 * G = Y - 0.34414 * Cb - 0.71414 * Cr
811 * B = Y + 1.77200 * Cb
812 *
813 * =>
814 * Cr *= 1.40200;
815 * Cb *= 1.77200;
816 * Cg = 0.19421 * Cb + .50937 * Cr;
817 * R = Y + Cr;
818 * G = Y - Cg;
819 * B = Y + Cb;
820 *
821 * =>
822 * Cg = (50 * Cb + 130 * Cr + 128) >> 8;
823 */
824
825static void initcol(PREC q[][64])
826{
827 scaleidctqtab(q[1], IFIX(1.77200));
828 scaleidctqtab(q[2], IFIX(1.40200));
829}
830
831/* This is optimized for the stupid sun SUNWspro compiler. */
Lee Leahy35af5c42017-03-09 17:35:28 -0800832#define STORECLAMP(a, x) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000833( \
Lee Leahye20a3192017-03-09 16:21:34 -0800834 (a) = (x), \
835 (unsigned int)(x) >= 256 ? \
836 ((a) = (x) < 0 ? 0 : 255) \
837 : \
838 0 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000839)
840
841#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x))
842
843#ifdef ROUND
844
845#define CBCRCG(yin, xin) \
846( \
Lee Leahy35af5c42017-03-09 17:35:28 -0800847 cb = outc[0 + yin * 8 + xin], \
848 cr = outc[64 + yin * 8 + xin], \
Lee Leahye20a3192017-03-09 16:21:34 -0800849 cg = (50 * cb + 130 * cr + 128) >> 8 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000850)
851
852#else
853
854#define CBCRCG(yin, xin) \
855( \
Lee Leahy35af5c42017-03-09 17:35:28 -0800856 cb = outc[0 + yin*8 + xin], \
857 cr = outc[64 + yin*8 + xin], \
Lee Leahye20a3192017-03-09 16:21:34 -0800858 cg = (3 * cb + 8 * cr) >> 4 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000859)
860
861#endif
862
863#define PIC(yin, xin, p, xout) \
864( \
Lee Leahye20a3192017-03-09 16:21:34 -0800865 y = outy[(yin) * 8 + xin], \
866 STORECLAMP(p[(xout) * 3 + 0], y + cr), \
867 STORECLAMP(p[(xout) * 3 + 1], y - cg), \
868 STORECLAMP(p[(xout) * 3 + 2], y + cb) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000869)
870
871#ifdef __LITTLE_ENDIAN
Lee Leahye20a3192017-03-09 16:21:34 -0800872#define PIC_16(yin, xin, p, xout, add) \
873( \
874 y = outy[(yin) * 8 + xin], \
875 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
876 ((CLAMP(y - cg + add) & 0xfc) << 3) | \
877 ((CLAMP(y + cb + add*2+1)) >> 3), \
878 p[(xout) * 2 + 0] = y & 0xff, \
879 p[(xout) * 2 + 1] = y >> 8 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000880)
881#else
882#ifdef CONFIG_PPC
Lee Leahye20a3192017-03-09 16:21:34 -0800883#define PIC_16(yin, xin, p, xout, add) \
884( \
885 y = outy[(yin) * 8 + xin], \
886 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 7) | \
887 ((CLAMP(y - cg + add*2+1) & 0xf8) << 2) | \
888 ((CLAMP(y + cb + add*2+1)) >> 3), \
889 p[(xout) * 2 + 0] = y >> 8, \
890 p[(xout) * 2 + 1] = y & 0xff \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000891)
892#else
Lee Leahye20a3192017-03-09 16:21:34 -0800893#define PIC_16(yin, xin, p, xout, add) \
894( \
895 y = outy[(yin) * 8 + xin], \
896 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
897 ((CLAMP(y - cg + add) & 0xfc) << 3) | \
898 ((CLAMP(y + cb + add*2+1)) >> 3), \
899 p[(xout) * 2 + 0] = y >> 8, \
900 p[(xout) * 2 + 1] = y & 0xff \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000901)
902#endif
903#endif
904
905#define PIC_32(yin, xin, p, xout) \
906( \
Lee Leahye20a3192017-03-09 16:21:34 -0800907 y = outy[(yin) * 8 + xin], \
908 STORECLAMP(p[(xout) * 4 + 0], y + cr), \
909 STORECLAMP(p[(xout) * 4 + 1], y - cg), \
910 STORECLAMP(p[(xout) * 4 + 2], y + cb), \
911 p[(xout) * 4 + 3] = 0 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000912)
913
Lee Leahye20a3192017-03-09 16:21:34 -0800914#define PIC221111(xin) \
915( \
916 CBCRCG(0, xin), \
917 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
918 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
919 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
920 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000921)
922
Lee Leahye20a3192017-03-09 16:21:34 -0800923#define PIC221111_16(xin) \
924( \
925 CBCRCG(0, xin), \
926 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3), \
927 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0), \
928 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1), \
929 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000930)
931
Lee Leahye20a3192017-03-09 16:21:34 -0800932#define PIC221111_32(xin) \
933( \
934 CBCRCG(0, xin), \
935 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
936 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
937 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
938 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000939)
940
941static void col221111(int *out, unsigned char *pic, int width)
942{
943 int i, j, k;
944 unsigned char *pic0, *pic1;
945 int *outy, *outc;
946 int cr, cg, cb, y;
947
948 pic0 = pic;
949 pic1 = pic + width;
950 outy = out;
951 outc = out + 64 * 4;
952 for (i = 2; i > 0; i--) {
953 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800954 for (k = 0; k < 8; k++)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000955 PIC221111(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000956 outc += 8;
957 outy += 16;
958 pic0 += 2 * width;
959 pic1 += 2 * width;
960 }
961 outy += 64 * 2 - 16 * 4;
962 }
963}
964
965static void col221111_16(int *out, unsigned char *pic, int width)
966{
967 int i, j, k;
968 unsigned char *pic0, *pic1;
969 int *outy, *outc;
970 int cr, cg, cb, y;
971
972 pic0 = pic;
973 pic1 = pic + width;
974 outy = out;
975 outc = out + 64 * 4;
976 for (i = 2; i > 0; i--) {
977 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800978 for (k = 0; k < 8; k++)
Lee Leahye20a3192017-03-09 16:21:34 -0800979 PIC221111_16(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000980 outc += 8;
981 outy += 16;
982 pic0 += 2 * width;
983 pic1 += 2 * width;
984 }
985 outy += 64 * 2 - 16 * 4;
986 }
987}
988
989static void col221111_32(int *out, unsigned char *pic, int width)
990{
991 int i, j, k;
992 unsigned char *pic0, *pic1;
993 int *outy, *outc;
994 int cr, cg, cb, y;
995
996 pic0 = pic;
997 pic1 = pic + width;
998 outy = out;
999 outc = out + 64 * 4;
1000 for (i = 2; i > 0; i--) {
1001 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -08001002 for (k = 0; k < 8; k++)
Stefan Reinauerd650e992010-02-22 04:33:13 +00001003 PIC221111_32(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +00001004 outc += 8;
1005 outy += 16;
1006 pic0 += 2 * width;
1007 pic1 += 2 * width;
1008 }
1009 outy += 64 * 2 - 16 * 4;
1010 }
1011}