blob: e5b09ea7094ad6df771b1ff52c47af7d3fc1ac02 [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;
Lee Leahy491c5b62017-03-10 15:51:04 -0800169 m = getbyte();
170 if (m == till)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000171 break;
172
173 switch (m) {
174 case 0xc2:
175 return 0;
176
177 case M_DQT:
178 lq = getword();
179 while (lq > 2) {
180 pq = getbyte();
181 tq = pq & 15;
182 if (tq > 3)
183 return -1;
184 pq >>= 4;
185 if (pq != 0)
186 return -1;
187 for (i = 0; i < 64; i++)
188 quant[tq][i] = getbyte();
189 lq -= 64 + 1;
190 }
191 break;
192
193 case M_DHT:
194 l = getword();
195 while (l > 2) {
196 int hufflen[16], k;
197 unsigned char huffvals[256];
198
199 tc = getbyte();
200 th = tc & 15;
201 tc >>= 4;
202 tt = tc * 2 + th;
203 if (tc > 1 || th > 1)
204 return -1;
205 for (i = 0; i < 16; i++)
206 hufflen[i] = getbyte();
207 l -= 1 + 16;
208 k = 0;
209 for (i = 0; i < 16; i++) {
210 for (j = 0; j < hufflen[i]; j++)
211 huffvals[k++] = getbyte();
212 l -= hufflen[i];
213 }
214 dec_makehuff(dhuff + tt, hufflen,
215 huffvals);
216 }
217 break;
218
219 case M_DRI:
220 l = getword();
221 info.dri = getword();
222 break;
223
224 default:
225 l = getword();
226 while (l-- > 2)
227 getbyte();
228 break;
229 }
230 }
231 return 0;
232}
233
234static void dec_initscans(void)
235{
236 int i;
237
238 info.nm = info.dri + 1;
239 info.rm = M_RST0;
240 for (i = 0; i < info.ns; i++)
241 dscans[i].dc = 0;
242}
243
244static int dec_checkmarker(void)
245{
246 int i;
247
Stefan Reinauer87489e12010-03-17 04:03:22 +0000248 if (dec_readmarker(&glob_in) != info.rm)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000249 return -1;
250 info.nm = info.dri;
251 info.rm = (info.rm + 1) & ~0x08;
252 for (i = 0; i < info.ns; i++)
253 dscans[i].dc = 0;
254 return 0;
255}
256
Patrick Georgi246179a2015-08-09 18:23:10 +0200257void jpeg_fetch_size(unsigned char *buf, int *width, int *height)
258{
259 datap = buf;
260 getbyte();
261 getbyte();
262 readtables(M_SOF0);
263 getword();
264 getbyte();
265 *height = getword();
266 *width = getword();
267}
268
Stefan Reinauerd650e992010-02-22 04:33:13 +0000269int jpeg_check_size(unsigned char *buf, int width, int height)
270{
Lee Leahye20a3192017-03-09 16:21:34 -0800271 datap = buf;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000272 getbyte();
273 getbyte();
274 readtables(M_SOF0);
275 getword();
276 getbyte();
Lee Leahye20a3192017-03-09 16:21:34 -0800277 if (height != getword() || width != getword())
Stefan Reinauerd650e992010-02-22 04:33:13 +0000278 return 0;
Lee Leahye20a3192017-03-09 16:21:34 -0800279 return 1;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000280}
281
Stefan Reinauer14e22772010-04-27 06:56:47 +0000282int jpeg_decode(unsigned char *buf, unsigned char *pic,
Stefan Reinauerd650e992010-02-22 04:33:13 +0000283 int width, int height, int depth, struct jpeg_decdata *decdata)
284{
285 int i, j, m, tac, tdc;
286 int mcusx, mcusy, mx, my;
287 int max[6];
288
289 if (!decdata || !buf || !pic)
290 return -1;
291 datap = buf;
292 if (getbyte() != 0xff)
293 return ERR_NO_SOI;
294 if (getbyte() != M_SOI)
295 return ERR_NO_SOI;
296 if (readtables(M_SOF0))
297 return ERR_BAD_TABLES;
298 getword();
299 i = getbyte();
300 if (i != 8)
301 return ERR_NOT_8BIT;
302 if (((getword() + 15) & ~15) != height)
303 return ERR_HEIGHT_MISMATCH;
304 if (((getword() + 15) & ~15) != width)
305 return ERR_WIDTH_MISMATCH;
306 if ((height & 15) || (width & 15))
307 return ERR_BAD_WIDTH_OR_HEIGHT;
308 info.nc = getbyte();
309 if (info.nc > MAXCOMP)
310 return ERR_TOO_MANY_COMPPS;
311 for (i = 0; i < info.nc; i++) {
312 int h, v;
313 comps[i].cid = getbyte();
314 comps[i].hv = getbyte();
315 v = comps[i].hv & 15;
316 h = comps[i].hv >> 4;
317 comps[i].tq = getbyte();
318 if (h > 3 || v > 3)
319 return ERR_ILLEGAL_HV;
320 if (comps[i].tq > 3)
321 return ERR_QUANT_TABLE_SELECTOR;
322 }
323 if (readtables(M_SOS))
324 return ERR_BAD_TABLES;
325 getword();
326 info.ns = getbyte();
327 if (info.ns != 3)
328 return ERR_NOT_YCBCR_221111;
329 for (i = 0; i < 3; i++) {
330 dscans[i].cid = getbyte();
331 tdc = getbyte();
332 tac = tdc & 15;
333 tdc >>= 4;
334 if (tdc > 1 || tac > 1)
335 return ERR_QUANT_TABLE_SELECTOR;
336 for (j = 0; j < info.nc; j++)
337 if (comps[j].cid == dscans[i].cid)
338 break;
339 if (j == info.nc)
340 return ERR_UNKNOWN_CID_IN_SCAN;
341 dscans[i].hv = comps[j].hv;
342 dscans[i].tq = comps[j].tq;
343 dscans[i].hudc.dhuff = dec_huffdc + tdc;
344 dscans[i].huac.dhuff = dec_huffac + tac;
345 }
346
347 i = getbyte();
348 j = getbyte();
349 m = getbyte();
350
351 if (i != 0 || j != 63 || m != 0)
352 return ERR_NOT_SEQUENTIAL_DCT;
353
354 if (dscans[0].cid != 1 || dscans[1].cid != 2 || dscans[2].cid != 3)
355 return ERR_NOT_YCBCR_221111;
356
Lee Leahy73402172017-03-10 15:23:24 -0800357 if (dscans[0].hv != 0x22 || dscans[1].hv != 0x11
358 || dscans[2].hv != 0x11)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000359 return ERR_NOT_YCBCR_221111;
360
361 mcusx = width >> 4;
362 mcusy = height >> 4;
363
364
365 idctqtab(quant[dscans[0].tq], decdata->dquant[0]);
366 idctqtab(quant[dscans[1].tq], decdata->dquant[1]);
367 idctqtab(quant[dscans[2].tq], decdata->dquant[2]);
368 initcol(decdata->dquant);
Stefan Reinauer87489e12010-03-17 04:03:22 +0000369 setinput(&glob_in, datap);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000370
371#if 0
372 /* landing zone */
373 img[len] = 0;
374 img[len + 1] = 0xff;
375 img[len + 2] = M_EOF;
376#endif
377
378 dec_initscans();
379
380 dscans[0].next = 6 - 4;
381 dscans[1].next = 6 - 4 - 1;
382 dscans[2].next = 6 - 4 - 1 - 1; /* 411 encoding */
383 for (my = 0; my < mcusy; my++) {
384 for (mx = 0; mx < mcusx; mx++) {
385 if (info.dri && !--info.nm)
386 if (dec_checkmarker())
387 return ERR_WRONG_MARKER;
388
Stefan Reinauer87489e12010-03-17 04:03:22 +0000389 decode_mcus(&glob_in, decdata->dcts, 6, dscans, max);
Lee Leahy73402172017-03-10 15:23:24 -0800390 idct(decdata->dcts, decdata->out, decdata->dquant[0],
391 IFIX(128.5), max[0]);
392 idct(decdata->dcts + 64, decdata->out + 64,
393 decdata->dquant[0], IFIX(128.5), max[1]);
394 idct(decdata->dcts + 128, decdata->out + 128,
395 decdata->dquant[0], IFIX(128.5), max[2]);
396 idct(decdata->dcts + 192, decdata->out + 192,
397 decdata->dquant[0], IFIX(128.5), max[3]);
398 idct(decdata->dcts + 256, decdata->out + 256,
399 decdata->dquant[1], IFIX(0.5), max[4]);
400 idct(decdata->dcts + 320, decdata->out + 320,
401 decdata->dquant[2], IFIX(0.5), max[5]);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000402
403 switch (depth) {
404 case 32:
Lee Leahy73402172017-03-10 15:23:24 -0800405 col221111_32(decdata->out, pic
406 + (my * 16 * mcusx + mx) * 16 * 4,
407 mcusx * 16 * 4);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000408 break;
409 case 24:
Lee Leahy73402172017-03-10 15:23:24 -0800410 col221111(decdata->out, pic
411 + (my * 16 * mcusx + mx) * 16 * 3,
412 mcusx * 16 * 3);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000413 break;
414 case 16:
Lee Leahy73402172017-03-10 15:23:24 -0800415 col221111_16(decdata->out, pic
416 + (my * 16 * mcusx + mx) * (16 * 2),
417 mcusx * (16 * 2));
Stefan Reinauerd650e992010-02-22 04:33:13 +0000418 break;
419 default:
420 return ERR_DEPTH_MISMATCH;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000421 }
422 }
423 }
424
Stefan Reinauer87489e12010-03-17 04:03:22 +0000425 m = dec_readmarker(&glob_in);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000426 if (m != M_EOI)
427 return ERR_NO_EOI;
428
429 return 0;
430}
431
432/****************************************************************/
433/************** huffman decoder ***************/
434/****************************************************************/
435
436static int fillbits __P((struct in *, int, unsigned int));
437static int dec_rec2
438__P((struct in *, struct dec_hufftbl *, int *, int, int));
439
440static void setinput(struct in *in, unsigned char *p)
441{
442 in->p = p;
443 in->left = 0;
444 in->bits = 0;
445 in->marker = 0;
446}
447
448static int fillbits(struct in *in, int le, unsigned int bi)
449{
450 int b, m;
451
452 if (in->marker) {
453 if (le <= 16)
454 in->bits = bi << 16, le += 16;
455 return le;
456 }
457 while (le <= 24) {
458 b = *in->p++;
Lee Leahy491c5b62017-03-10 15:51:04 -0800459 if (b == 0xff) {
460 m = *in->p++;
461 if (m != 0) {
462 if (m == M_EOF) {
463 if (in->func) {
464 m = in->func(in->data);
465 if (m == 0)
466 continue;
Martin Roth1d5e2402017-07-23 20:04:41 -0600467 }
Lee Leahy491c5b62017-03-10 15:51:04 -0800468 }
469 in->marker = m;
470 if (le <= 16)
471 bi = bi << 16, le += 16;
472 break;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000473 }
Stefan Reinauerd650e992010-02-22 04:33:13 +0000474 }
475 bi = bi << 8 | b;
476 le += 8;
477 }
478 in->bits = bi; /* tmp... 2 return values needed */
479 return le;
480}
481
482static int dec_readmarker(struct in *in)
483{
484 int m;
485
486 in->left = fillbits(in, in->left, in->bits);
Lee Leahy491c5b62017-03-10 15:51:04 -0800487 m = in->marker;
488 if (m == 0)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000489 return 0;
490 in->left = 0;
491 in->marker = 0;
492 return m;
493}
494
495#define LEBI_DCL int le, bi
496#define LEBI_GET(in) (le = in->left, bi = in->bits)
497#define LEBI_PUT(in) (in->left = le, in->bits = bi)
498
Lee Leahye20a3192017-03-09 16:21:34 -0800499#define GETBITS(in, n) ( \
500 (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0), \
501 (le -= (n)), \
502 bi >> le & ((1 << (n)) - 1) \
503 )
Stefan Reinauerd650e992010-02-22 04:33:13 +0000504
505#define UNGETBITS(in, n) ( \
Lee Leahye20a3192017-03-09 16:21:34 -0800506 le += (n) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000507)
508
509
510static int dec_rec2(struct in *in, struct dec_hufftbl *hu, int *runp, int c,
511 int i)
512{
513 LEBI_DCL;
514
515 LEBI_GET(in);
516 if (i) {
517 UNGETBITS(in, i & 127);
518 *runp = i >> 8 & 15;
519 i >>= 16;
520 } else {
Lee Leahy73402172017-03-10 15:23:24 -0800521 for (i = DECBITS; (c = ((c << 1) | GETBITS(in, 1)))
522 >= (hu->maxcode[i]); i++)
Lee Leahyb6ee0f92017-03-09 13:35:26 -0800523 ;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000524 if (i >= 16) {
525 in->marker = M_BADHUFF;
526 return 0;
527 }
528 i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];
529 *runp = i >> 4;
530 i &= 15;
531 }
532 if (i == 0) { /* sigh, 0xf0 is 11 bit */
533 LEBI_PUT(in);
534 return 0;
535 }
536 /* receive part */
537 c = GETBITS(in, i);
538 if (c < (1 << (i - 1)))
539 c += (-1 << i) + 1;
540 LEBI_PUT(in);
541 return c;
542}
543
Lee Leahye20a3192017-03-09 16:21:34 -0800544#define DEC_REC(in, hu, r, i) ( \
545 r = GETBITS(in, DECBITS), \
546 i = hu->llvals[r], \
547 i & 128 ? \
548 ( \
549 UNGETBITS(in, i & 127), \
550 r = i >> 8 & 15, \
551 i >> 16 \
552 ) \
553 : \
554 ( \
555 LEBI_PUT(in), \
556 i = dec_rec2(in, hu, &r, r, i), \
557 LEBI_GET(in), \
558 i \
559 ) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000560)
561
Lee Leahy73402172017-03-10 15:23:24 -0800562static void decode_mcus(struct in *in, int *dct, int n, struct scan *sc,
563 int *maxp)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000564{
565 struct dec_hufftbl *hu;
566 int i, r, t;
567 LEBI_DCL;
568
569 memset(dct, 0, n * 64 * sizeof(*dct));
570 LEBI_GET(in);
571 while (n-- > 0) {
572 hu = sc->hudc.dhuff;
573 *dct++ = (sc->dc += DEC_REC(in, hu, r, t));
574
575 hu = sc->huac.dhuff;
576 i = 63;
577 while (i > 0) {
578 t = DEC_REC(in, hu, r, t);
579 if (t == 0 && r == 0) {
580 dct += i;
581 break;
582 }
583 dct += r;
584 *dct++ = t;
585 i -= r + 1;
586 }
587 *maxp++ = 64 - i;
588 if (n == sc->next)
589 sc++;
590 }
591 LEBI_PUT(in);
592}
593
Lee Leahy73402172017-03-10 15:23:24 -0800594static void dec_makehuff(struct dec_hufftbl *hu, int *hufflen,
595 unsigned char *huffvals)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000596{
597 int code, k, i, j, d, x, c, v;
598 for (i = 0; i < (1 << DECBITS); i++)
599 hu->llvals[i] = 0;
600
601/*
602 * llvals layout:
603 *
604 * value v already known, run r, backup u bits:
605 * vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu
606 * value unknown, size b bits, run r, backup u bits:
607 * 000000000000bbbb 0000 rrrr 0 uuuuuuu
608 * value and size unknown:
609 * 0000000000000000 0000 0000 0 0000000
610 */
611 code = 0;
612 k = 0;
613 for (i = 0; i < 16; i++, code <<= 1) { /* sizes */
614 hu->valptr[i] = k;
615 for (j = 0; j < hufflen[i]; j++) {
616 hu->vals[k] = *huffvals++;
617 if (i < DECBITS) {
618 c = code << (DECBITS - 1 - i);
619 v = hu->vals[k] & 0x0f; /* size */
620 for (d = 1 << (DECBITS - 1 - i); --d >= 0;) {
Lee Leahy73402172017-03-10 15:23:24 -0800621 /* both fit in table */
622 if (v + i < DECBITS) {
Stefan Reinauerd650e992010-02-22 04:33:13 +0000623 x = d >> (DECBITS - 1 - v -
624 i);
625 if (v && x < (1 << (v - 1)))
626 x += (-1 << v) + 1;
Lee Leahy73402172017-03-10 15:23:24 -0800627 x = x << 16 | (hu->vals[k]
628 & 0xf0) << 4 |
629 (DECBITS - (i + 1 + v))
630 | 128;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000631 } else
Lee Leahy73402172017-03-10 15:23:24 -0800632 x = v << 16 | (hu->vals[k]
633 & 0xf0) << 4 |
Lee Leahye20a3192017-03-09 16:21:34 -0800634 (DECBITS - (i + 1));
Stefan Reinauerd650e992010-02-22 04:33:13 +0000635 hu->llvals[c | d] = x;
636 }
637 }
638 code++;
639 k++;
640 }
641 hu->maxcode[i] = code;
642 }
643 hu->maxcode[16] = 0x20000; /* always terminate decode */
644}
645
646/****************************************************************/
647/************** idct ***************/
648/****************************************************************/
649
650#define ONE ((PREC)IFIX(1.))
651#define S2 ((PREC)IFIX(0.382683432))
652#define C2 ((PREC)IFIX(0.923879532))
653#define C4 ((PREC)IFIX(0.707106781))
654
655#define S22 ((PREC)IFIX(2 * 0.382683432))
656#define C22 ((PREC)IFIX(2 * 0.923879532))
657#define IC4 ((PREC)IFIX(1 / 0.707106781))
658
659#define C3IC1 ((PREC)IFIX(0.847759065)) /* c3/c1 */
660#define C5IC1 ((PREC)IFIX(0.566454497)) /* c5/c1 */
661#define C7IC1 ((PREC)IFIX(0.198912367)) /* c7/c1 */
662
Lee Leahy35af5c42017-03-09 17:35:28 -0800663#define XPP(a, b) (t = a + b, b = a - b, a = t)
664#define XMP(a, b) (t = a - b, b = a + b, a = t)
665#define XPM(a, b) (t = a + b, b = b - a, a = t)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000666
Lee Leahy35af5c42017-03-09 17:35:28 -0800667#define ROT(a, b, s, c) (t = IMULT(a + b, s), \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000668 a = IMULT(a, c - s) + t, \
669 b = IMULT(b, c + s) - t)
670
Lee Leahye20a3192017-03-09 16:21:34 -0800671#define IDCT \
672( \
673 XPP(t0, t1), \
674 XMP(t2, t3), \
675 t2 = IMULT(t2, IC4) - t3, \
676 XPP(t0, t3), \
677 XPP(t1, t2), \
678 XMP(t4, t7), \
679 XPP(t5, t6), \
680 XMP(t5, t7), \
681 t5 = IMULT(t5, IC4), \
682 ROT(t4, t6, S22, C22), \
683 t6 -= t7, \
684 t5 -= t6, \
685 t4 -= t5, \
686 XPP(t0, t7), \
687 XPP(t1, t6), \
688 XPP(t2, t5), \
689 XPP(t3, t4) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000690)
691
692static unsigned char zig2[64] = {
693 0, 2, 3, 9, 10, 20, 21, 35,
694 14, 16, 25, 31, 39, 46, 50, 57,
695 5, 7, 12, 18, 23, 33, 37, 48,
696 27, 29, 41, 44, 52, 55, 59, 62,
697 15, 26, 30, 40, 45, 51, 56, 58,
698 1, 4, 8, 11, 19, 22, 34, 36,
699 28, 42, 43, 53, 54, 60, 61, 63,
700 6, 13, 17, 24, 32, 38, 47, 49
701};
702
Stefan Reinauer87489e12010-03-17 04:03:22 +0000703void idct(int *in, int *out, PREC *lquant, PREC off, int max)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000704{
705 PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
706 PREC tmp[64], *tmpp;
707 int i, j;
708 unsigned char *zig2p;
709
710 t0 = off;
711 if (max == 1) {
Stefan Reinauer87489e12010-03-17 04:03:22 +0000712 t0 += in[0] * lquant[0];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000713 for (i = 0; i < 64; i++)
714 out[i] = ITOINT(t0);
715 return;
716 }
717 zig2p = zig2;
718 tmpp = tmp;
719 for (i = 0; i < 8; i++) {
720 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000721 t0 += in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000722 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000723 t5 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000724 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000725 t2 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000726 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000727 t7 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000728 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000729 t1 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000730 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000731 t4 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000732 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000733 t3 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000734 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000735 t6 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000736 IDCT;
737 tmpp[0 * 8] = t0;
738 tmpp[1 * 8] = t1;
739 tmpp[2 * 8] = t2;
740 tmpp[3 * 8] = t3;
741 tmpp[4 * 8] = t4;
742 tmpp[5 * 8] = t5;
743 tmpp[6 * 8] = t6;
744 tmpp[7 * 8] = t7;
745 tmpp++;
746 t0 = 0;
747 }
748 for (i = 0; i < 8; i++) {
749 t0 = tmp[8 * i + 0];
750 t1 = tmp[8 * i + 1];
751 t2 = tmp[8 * i + 2];
752 t3 = tmp[8 * i + 3];
753 t4 = tmp[8 * i + 4];
754 t5 = tmp[8 * i + 5];
755 t6 = tmp[8 * i + 6];
756 t7 = tmp[8 * i + 7];
757 IDCT;
758 out[8 * i + 0] = ITOINT(t0);
759 out[8 * i + 1] = ITOINT(t1);
760 out[8 * i + 2] = ITOINT(t2);
761 out[8 * i + 3] = ITOINT(t3);
762 out[8 * i + 4] = ITOINT(t4);
763 out[8 * i + 5] = ITOINT(t5);
764 out[8 * i + 6] = ITOINT(t6);
765 out[8 * i + 7] = ITOINT(t7);
766 }
767}
768
769static unsigned char zig[64] = {
770 0, 1, 5, 6, 14, 15, 27, 28,
771 2, 4, 7, 13, 16, 26, 29, 42,
772 3, 8, 12, 17, 25, 30, 41, 43,
773 9, 11, 18, 24, 31, 40, 44, 53,
774 10, 19, 23, 32, 39, 45, 52, 54,
775 20, 22, 33, 38, 46, 51, 55, 60,
776 21, 34, 37, 47, 50, 56, 59, 61,
777 35, 36, 48, 49, 57, 58, 62, 63
778};
779
780static PREC aaidct[8] = {
781 IFIX(0.3535533906), IFIX(0.4903926402),
782 IFIX(0.4619397663), IFIX(0.4157348062),
783 IFIX(0.3535533906), IFIX(0.2777851165),
784 IFIX(0.1913417162), IFIX(0.0975451610)
785};
786
787
788static void idctqtab(unsigned char *qin, PREC *qout)
789{
790 int i, j;
791
792 for (i = 0; i < 8; i++)
793 for (j = 0; j < 8; j++)
794 qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] *
Lee Leahye20a3192017-03-09 16:21:34 -0800795 IMULT(aaidct[i], aaidct[j]);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000796}
797
798static void scaleidctqtab(PREC *q, PREC sc)
799{
800 int i;
801
802 for (i = 0; i < 64; i++)
803 q[i] = IMULT(q[i], sc);
804}
805
806/****************************************************************/
807/************** color decoder ***************/
808/****************************************************************/
809
810#define ROUND
811
812/*
813 * YCbCr Color transformation:
814 *
815 * y:0..255 Cb:-128..127 Cr:-128..127
816 *
817 * R = Y + 1.40200 * Cr
818 * G = Y - 0.34414 * Cb - 0.71414 * Cr
819 * B = Y + 1.77200 * Cb
820 *
821 * =>
822 * Cr *= 1.40200;
823 * Cb *= 1.77200;
824 * Cg = 0.19421 * Cb + .50937 * Cr;
825 * R = Y + Cr;
826 * G = Y - Cg;
827 * B = Y + Cb;
828 *
829 * =>
830 * Cg = (50 * Cb + 130 * Cr + 128) >> 8;
831 */
832
833static void initcol(PREC q[][64])
834{
835 scaleidctqtab(q[1], IFIX(1.77200));
836 scaleidctqtab(q[2], IFIX(1.40200));
837}
838
839/* This is optimized for the stupid sun SUNWspro compiler. */
Lee Leahy35af5c42017-03-09 17:35:28 -0800840#define STORECLAMP(a, x) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000841( \
Lee Leahye20a3192017-03-09 16:21:34 -0800842 (a) = (x), \
843 (unsigned int)(x) >= 256 ? \
844 ((a) = (x) < 0 ? 0 : 255) \
845 : \
846 0 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000847)
848
849#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x))
850
851#ifdef ROUND
852
853#define CBCRCG(yin, xin) \
854( \
Lee Leahy35af5c42017-03-09 17:35:28 -0800855 cb = outc[0 + yin * 8 + xin], \
856 cr = outc[64 + yin * 8 + xin], \
Lee Leahye20a3192017-03-09 16:21:34 -0800857 cg = (50 * cb + 130 * cr + 128) >> 8 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000858)
859
860#else
861
862#define CBCRCG(yin, xin) \
863( \
Lee Leahy35af5c42017-03-09 17:35:28 -0800864 cb = outc[0 + yin*8 + xin], \
865 cr = outc[64 + yin*8 + xin], \
Lee Leahye20a3192017-03-09 16:21:34 -0800866 cg = (3 * cb + 8 * cr) >> 4 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000867)
868
869#endif
870
871#define PIC(yin, xin, p, xout) \
872( \
Lee Leahye20a3192017-03-09 16:21:34 -0800873 y = outy[(yin) * 8 + xin], \
874 STORECLAMP(p[(xout) * 3 + 0], y + cr), \
875 STORECLAMP(p[(xout) * 3 + 1], y - cg), \
876 STORECLAMP(p[(xout) * 3 + 2], y + cb) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000877)
878
879#ifdef __LITTLE_ENDIAN
Lee Leahye20a3192017-03-09 16:21:34 -0800880#define PIC_16(yin, xin, p, xout, add) \
881( \
882 y = outy[(yin) * 8 + xin], \
883 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
884 ((CLAMP(y - cg + add) & 0xfc) << 3) | \
885 ((CLAMP(y + cb + add*2+1)) >> 3), \
886 p[(xout) * 2 + 0] = y & 0xff, \
887 p[(xout) * 2 + 1] = y >> 8 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000888)
889#else
890#ifdef CONFIG_PPC
Lee Leahye20a3192017-03-09 16:21:34 -0800891#define PIC_16(yin, xin, p, xout, add) \
892( \
893 y = outy[(yin) * 8 + xin], \
894 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 7) | \
895 ((CLAMP(y - cg + add*2+1) & 0xf8) << 2) | \
896 ((CLAMP(y + cb + add*2+1)) >> 3), \
897 p[(xout) * 2 + 0] = y >> 8, \
898 p[(xout) * 2 + 1] = y & 0xff \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000899)
900#else
Lee Leahye20a3192017-03-09 16:21:34 -0800901#define PIC_16(yin, xin, p, xout, add) \
902( \
903 y = outy[(yin) * 8 + xin], \
904 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
905 ((CLAMP(y - cg + add) & 0xfc) << 3) | \
906 ((CLAMP(y + cb + add*2+1)) >> 3), \
907 p[(xout) * 2 + 0] = y >> 8, \
908 p[(xout) * 2 + 1] = y & 0xff \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000909)
910#endif
911#endif
912
913#define PIC_32(yin, xin, p, xout) \
914( \
Lee Leahye20a3192017-03-09 16:21:34 -0800915 y = outy[(yin) * 8 + xin], \
916 STORECLAMP(p[(xout) * 4 + 0], y + cr), \
917 STORECLAMP(p[(xout) * 4 + 1], y - cg), \
918 STORECLAMP(p[(xout) * 4 + 2], y + cb), \
919 p[(xout) * 4 + 3] = 0 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000920)
921
Lee Leahye20a3192017-03-09 16:21:34 -0800922#define PIC221111(xin) \
923( \
924 CBCRCG(0, xin), \
925 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
926 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
927 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
928 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000929)
930
Lee Leahye20a3192017-03-09 16:21:34 -0800931#define PIC221111_16(xin) \
932( \
933 CBCRCG(0, xin), \
934 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3), \
935 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0), \
936 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1), \
937 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000938)
939
Lee Leahye20a3192017-03-09 16:21:34 -0800940#define PIC221111_32(xin) \
941( \
942 CBCRCG(0, xin), \
943 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
944 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
945 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
946 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000947)
948
949static void col221111(int *out, unsigned char *pic, int width)
950{
951 int i, j, k;
952 unsigned char *pic0, *pic1;
953 int *outy, *outc;
954 int cr, cg, cb, y;
955
956 pic0 = pic;
957 pic1 = pic + width;
958 outy = out;
959 outc = out + 64 * 4;
960 for (i = 2; i > 0; i--) {
961 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800962 for (k = 0; k < 8; k++)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000963 PIC221111(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000964 outc += 8;
965 outy += 16;
966 pic0 += 2 * width;
967 pic1 += 2 * width;
968 }
969 outy += 64 * 2 - 16 * 4;
970 }
971}
972
973static void col221111_16(int *out, unsigned char *pic, int width)
974{
975 int i, j, k;
976 unsigned char *pic0, *pic1;
977 int *outy, *outc;
978 int cr, cg, cb, y;
979
980 pic0 = pic;
981 pic1 = pic + width;
982 outy = out;
983 outc = out + 64 * 4;
984 for (i = 2; i > 0; i--) {
985 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800986 for (k = 0; k < 8; k++)
Lee Leahye20a3192017-03-09 16:21:34 -0800987 PIC221111_16(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000988 outc += 8;
989 outy += 16;
990 pic0 += 2 * width;
991 pic1 += 2 * width;
992 }
993 outy += 64 * 2 - 16 * 4;
994 }
995}
996
997static void col221111_32(int *out, unsigned char *pic, int width)
998{
999 int i, j, k;
1000 unsigned char *pic0, *pic1;
1001 int *outy, *outc;
1002 int cr, cg, cb, y;
1003
1004 pic0 = pic;
1005 pic1 = pic + width;
1006 outy = out;
1007 outc = out + 64 * 4;
1008 for (i = 2; i > 0; i--) {
1009 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -08001010 for (k = 0; k < 8; k++)
Stefan Reinauerd650e992010-02-22 04:33:13 +00001011 PIC221111_32(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +00001012 outc += 8;
1013 outy += 16;
1014 pic0 += 2 * width;
1015 pic1 += 2 * width;
1016 }
1017 outy += 64 * 2 - 16 * 4;
1018 }
1019}