blob: 06827ea4139c019c9cad9539f87ba6de0e7ba00f [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;
467 }
468 in->marker = m;
469 if (le <= 16)
470 bi = bi << 16, le += 16;
471 break;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000472 }
Stefan Reinauerd650e992010-02-22 04:33:13 +0000473 }
474 bi = bi << 8 | b;
475 le += 8;
476 }
477 in->bits = bi; /* tmp... 2 return values needed */
478 return le;
479}
480
481static int dec_readmarker(struct in *in)
482{
483 int m;
484
485 in->left = fillbits(in, in->left, in->bits);
Lee Leahy491c5b62017-03-10 15:51:04 -0800486 m = in->marker;
487 if (m == 0)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000488 return 0;
489 in->left = 0;
490 in->marker = 0;
491 return m;
492}
493
494#define LEBI_DCL int le, bi
495#define LEBI_GET(in) (le = in->left, bi = in->bits)
496#define LEBI_PUT(in) (in->left = le, in->bits = bi)
497
Lee Leahye20a3192017-03-09 16:21:34 -0800498#define GETBITS(in, n) ( \
499 (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0), \
500 (le -= (n)), \
501 bi >> le & ((1 << (n)) - 1) \
502 )
Stefan Reinauerd650e992010-02-22 04:33:13 +0000503
504#define UNGETBITS(in, n) ( \
Lee Leahye20a3192017-03-09 16:21:34 -0800505 le += (n) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000506)
507
508
509static int dec_rec2(struct in *in, struct dec_hufftbl *hu, int *runp, int c,
510 int i)
511{
512 LEBI_DCL;
513
514 LEBI_GET(in);
515 if (i) {
516 UNGETBITS(in, i & 127);
517 *runp = i >> 8 & 15;
518 i >>= 16;
519 } else {
Lee Leahy73402172017-03-10 15:23:24 -0800520 for (i = DECBITS; (c = ((c << 1) | GETBITS(in, 1)))
521 >= (hu->maxcode[i]); i++)
Lee Leahyb6ee0f92017-03-09 13:35:26 -0800522 ;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000523 if (i >= 16) {
524 in->marker = M_BADHUFF;
525 return 0;
526 }
527 i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];
528 *runp = i >> 4;
529 i &= 15;
530 }
531 if (i == 0) { /* sigh, 0xf0 is 11 bit */
532 LEBI_PUT(in);
533 return 0;
534 }
535 /* receive part */
536 c = GETBITS(in, i);
537 if (c < (1 << (i - 1)))
538 c += (-1 << i) + 1;
539 LEBI_PUT(in);
540 return c;
541}
542
Lee Leahye20a3192017-03-09 16:21:34 -0800543#define DEC_REC(in, hu, r, i) ( \
544 r = GETBITS(in, DECBITS), \
545 i = hu->llvals[r], \
546 i & 128 ? \
547 ( \
548 UNGETBITS(in, i & 127), \
549 r = i >> 8 & 15, \
550 i >> 16 \
551 ) \
552 : \
553 ( \
554 LEBI_PUT(in), \
555 i = dec_rec2(in, hu, &r, r, i), \
556 LEBI_GET(in), \
557 i \
558 ) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000559)
560
Lee Leahy73402172017-03-10 15:23:24 -0800561static void decode_mcus(struct in *in, int *dct, int n, struct scan *sc,
562 int *maxp)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000563{
564 struct dec_hufftbl *hu;
565 int i, r, t;
566 LEBI_DCL;
567
568 memset(dct, 0, n * 64 * sizeof(*dct));
569 LEBI_GET(in);
570 while (n-- > 0) {
571 hu = sc->hudc.dhuff;
572 *dct++ = (sc->dc += DEC_REC(in, hu, r, t));
573
574 hu = sc->huac.dhuff;
575 i = 63;
576 while (i > 0) {
577 t = DEC_REC(in, hu, r, t);
578 if (t == 0 && r == 0) {
579 dct += i;
580 break;
581 }
582 dct += r;
583 *dct++ = t;
584 i -= r + 1;
585 }
586 *maxp++ = 64 - i;
587 if (n == sc->next)
588 sc++;
589 }
590 LEBI_PUT(in);
591}
592
Lee Leahy73402172017-03-10 15:23:24 -0800593static void dec_makehuff(struct dec_hufftbl *hu, int *hufflen,
594 unsigned char *huffvals)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000595{
596 int code, k, i, j, d, x, c, v;
597 for (i = 0; i < (1 << DECBITS); i++)
598 hu->llvals[i] = 0;
599
600/*
601 * llvals layout:
602 *
603 * value v already known, run r, backup u bits:
604 * vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu
605 * value unknown, size b bits, run r, backup u bits:
606 * 000000000000bbbb 0000 rrrr 0 uuuuuuu
607 * value and size unknown:
608 * 0000000000000000 0000 0000 0 0000000
609 */
610 code = 0;
611 k = 0;
612 for (i = 0; i < 16; i++, code <<= 1) { /* sizes */
613 hu->valptr[i] = k;
614 for (j = 0; j < hufflen[i]; j++) {
615 hu->vals[k] = *huffvals++;
616 if (i < DECBITS) {
617 c = code << (DECBITS - 1 - i);
618 v = hu->vals[k] & 0x0f; /* size */
619 for (d = 1 << (DECBITS - 1 - i); --d >= 0;) {
Lee Leahy73402172017-03-10 15:23:24 -0800620 /* both fit in table */
621 if (v + i < DECBITS) {
Stefan Reinauerd650e992010-02-22 04:33:13 +0000622 x = d >> (DECBITS - 1 - v -
623 i);
624 if (v && x < (1 << (v - 1)))
625 x += (-1 << v) + 1;
Lee Leahy73402172017-03-10 15:23:24 -0800626 x = x << 16 | (hu->vals[k]
627 & 0xf0) << 4 |
628 (DECBITS - (i + 1 + v))
629 | 128;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000630 } else
Lee Leahy73402172017-03-10 15:23:24 -0800631 x = v << 16 | (hu->vals[k]
632 & 0xf0) << 4 |
Lee Leahye20a3192017-03-09 16:21:34 -0800633 (DECBITS - (i + 1));
Stefan Reinauerd650e992010-02-22 04:33:13 +0000634 hu->llvals[c | d] = x;
635 }
636 }
637 code++;
638 k++;
639 }
640 hu->maxcode[i] = code;
641 }
642 hu->maxcode[16] = 0x20000; /* always terminate decode */
643}
644
645/****************************************************************/
646/************** idct ***************/
647/****************************************************************/
648
649#define ONE ((PREC)IFIX(1.))
650#define S2 ((PREC)IFIX(0.382683432))
651#define C2 ((PREC)IFIX(0.923879532))
652#define C4 ((PREC)IFIX(0.707106781))
653
654#define S22 ((PREC)IFIX(2 * 0.382683432))
655#define C22 ((PREC)IFIX(2 * 0.923879532))
656#define IC4 ((PREC)IFIX(1 / 0.707106781))
657
658#define C3IC1 ((PREC)IFIX(0.847759065)) /* c3/c1 */
659#define C5IC1 ((PREC)IFIX(0.566454497)) /* c5/c1 */
660#define C7IC1 ((PREC)IFIX(0.198912367)) /* c7/c1 */
661
Lee Leahy35af5c42017-03-09 17:35:28 -0800662#define XPP(a, b) (t = a + b, b = a - b, a = t)
663#define XMP(a, b) (t = a - b, b = a + b, a = t)
664#define XPM(a, b) (t = a + b, b = b - a, a = t)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000665
Lee Leahy35af5c42017-03-09 17:35:28 -0800666#define ROT(a, b, s, c) (t = IMULT(a + b, s), \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000667 a = IMULT(a, c - s) + t, \
668 b = IMULT(b, c + s) - t)
669
Lee Leahye20a3192017-03-09 16:21:34 -0800670#define IDCT \
671( \
672 XPP(t0, t1), \
673 XMP(t2, t3), \
674 t2 = IMULT(t2, IC4) - t3, \
675 XPP(t0, t3), \
676 XPP(t1, t2), \
677 XMP(t4, t7), \
678 XPP(t5, t6), \
679 XMP(t5, t7), \
680 t5 = IMULT(t5, IC4), \
681 ROT(t4, t6, S22, C22), \
682 t6 -= t7, \
683 t5 -= t6, \
684 t4 -= t5, \
685 XPP(t0, t7), \
686 XPP(t1, t6), \
687 XPP(t2, t5), \
688 XPP(t3, t4) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000689)
690
691static unsigned char zig2[64] = {
692 0, 2, 3, 9, 10, 20, 21, 35,
693 14, 16, 25, 31, 39, 46, 50, 57,
694 5, 7, 12, 18, 23, 33, 37, 48,
695 27, 29, 41, 44, 52, 55, 59, 62,
696 15, 26, 30, 40, 45, 51, 56, 58,
697 1, 4, 8, 11, 19, 22, 34, 36,
698 28, 42, 43, 53, 54, 60, 61, 63,
699 6, 13, 17, 24, 32, 38, 47, 49
700};
701
Stefan Reinauer87489e12010-03-17 04:03:22 +0000702void idct(int *in, int *out, PREC *lquant, PREC off, int max)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000703{
704 PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
705 PREC tmp[64], *tmpp;
706 int i, j;
707 unsigned char *zig2p;
708
709 t0 = off;
710 if (max == 1) {
Stefan Reinauer87489e12010-03-17 04:03:22 +0000711 t0 += in[0] * lquant[0];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000712 for (i = 0; i < 64; i++)
713 out[i] = ITOINT(t0);
714 return;
715 }
716 zig2p = zig2;
717 tmpp = tmp;
718 for (i = 0; i < 8; i++) {
719 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000720 t0 += in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000721 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000722 t5 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000723 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000724 t2 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000725 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000726 t7 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000727 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000728 t1 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000729 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000730 t4 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000731 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000732 t3 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000733 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000734 t6 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000735 IDCT;
736 tmpp[0 * 8] = t0;
737 tmpp[1 * 8] = t1;
738 tmpp[2 * 8] = t2;
739 tmpp[3 * 8] = t3;
740 tmpp[4 * 8] = t4;
741 tmpp[5 * 8] = t5;
742 tmpp[6 * 8] = t6;
743 tmpp[7 * 8] = t7;
744 tmpp++;
745 t0 = 0;
746 }
747 for (i = 0; i < 8; i++) {
748 t0 = tmp[8 * i + 0];
749 t1 = tmp[8 * i + 1];
750 t2 = tmp[8 * i + 2];
751 t3 = tmp[8 * i + 3];
752 t4 = tmp[8 * i + 4];
753 t5 = tmp[8 * i + 5];
754 t6 = tmp[8 * i + 6];
755 t7 = tmp[8 * i + 7];
756 IDCT;
757 out[8 * i + 0] = ITOINT(t0);
758 out[8 * i + 1] = ITOINT(t1);
759 out[8 * i + 2] = ITOINT(t2);
760 out[8 * i + 3] = ITOINT(t3);
761 out[8 * i + 4] = ITOINT(t4);
762 out[8 * i + 5] = ITOINT(t5);
763 out[8 * i + 6] = ITOINT(t6);
764 out[8 * i + 7] = ITOINT(t7);
765 }
766}
767
768static unsigned char zig[64] = {
769 0, 1, 5, 6, 14, 15, 27, 28,
770 2, 4, 7, 13, 16, 26, 29, 42,
771 3, 8, 12, 17, 25, 30, 41, 43,
772 9, 11, 18, 24, 31, 40, 44, 53,
773 10, 19, 23, 32, 39, 45, 52, 54,
774 20, 22, 33, 38, 46, 51, 55, 60,
775 21, 34, 37, 47, 50, 56, 59, 61,
776 35, 36, 48, 49, 57, 58, 62, 63
777};
778
779static PREC aaidct[8] = {
780 IFIX(0.3535533906), IFIX(0.4903926402),
781 IFIX(0.4619397663), IFIX(0.4157348062),
782 IFIX(0.3535533906), IFIX(0.2777851165),
783 IFIX(0.1913417162), IFIX(0.0975451610)
784};
785
786
787static void idctqtab(unsigned char *qin, PREC *qout)
788{
789 int i, j;
790
791 for (i = 0; i < 8; i++)
792 for (j = 0; j < 8; j++)
793 qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] *
Lee Leahye20a3192017-03-09 16:21:34 -0800794 IMULT(aaidct[i], aaidct[j]);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000795}
796
797static void scaleidctqtab(PREC *q, PREC sc)
798{
799 int i;
800
801 for (i = 0; i < 64; i++)
802 q[i] = IMULT(q[i], sc);
803}
804
805/****************************************************************/
806/************** color decoder ***************/
807/****************************************************************/
808
809#define ROUND
810
811/*
812 * YCbCr Color transformation:
813 *
814 * y:0..255 Cb:-128..127 Cr:-128..127
815 *
816 * R = Y + 1.40200 * Cr
817 * G = Y - 0.34414 * Cb - 0.71414 * Cr
818 * B = Y + 1.77200 * Cb
819 *
820 * =>
821 * Cr *= 1.40200;
822 * Cb *= 1.77200;
823 * Cg = 0.19421 * Cb + .50937 * Cr;
824 * R = Y + Cr;
825 * G = Y - Cg;
826 * B = Y + Cb;
827 *
828 * =>
829 * Cg = (50 * Cb + 130 * Cr + 128) >> 8;
830 */
831
832static void initcol(PREC q[][64])
833{
834 scaleidctqtab(q[1], IFIX(1.77200));
835 scaleidctqtab(q[2], IFIX(1.40200));
836}
837
838/* This is optimized for the stupid sun SUNWspro compiler. */
Lee Leahy35af5c42017-03-09 17:35:28 -0800839#define STORECLAMP(a, x) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000840( \
Lee Leahye20a3192017-03-09 16:21:34 -0800841 (a) = (x), \
842 (unsigned int)(x) >= 256 ? \
843 ((a) = (x) < 0 ? 0 : 255) \
844 : \
845 0 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000846)
847
848#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x))
849
850#ifdef ROUND
851
852#define CBCRCG(yin, xin) \
853( \
Lee Leahy35af5c42017-03-09 17:35:28 -0800854 cb = outc[0 + yin * 8 + xin], \
855 cr = outc[64 + yin * 8 + xin], \
Lee Leahye20a3192017-03-09 16:21:34 -0800856 cg = (50 * cb + 130 * cr + 128) >> 8 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000857)
858
859#else
860
861#define CBCRCG(yin, xin) \
862( \
Lee Leahy35af5c42017-03-09 17:35:28 -0800863 cb = outc[0 + yin*8 + xin], \
864 cr = outc[64 + yin*8 + xin], \
Lee Leahye20a3192017-03-09 16:21:34 -0800865 cg = (3 * cb + 8 * cr) >> 4 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000866)
867
868#endif
869
870#define PIC(yin, xin, p, xout) \
871( \
Lee Leahye20a3192017-03-09 16:21:34 -0800872 y = outy[(yin) * 8 + xin], \
873 STORECLAMP(p[(xout) * 3 + 0], y + cr), \
874 STORECLAMP(p[(xout) * 3 + 1], y - cg), \
875 STORECLAMP(p[(xout) * 3 + 2], y + cb) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000876)
877
878#ifdef __LITTLE_ENDIAN
Lee Leahye20a3192017-03-09 16:21:34 -0800879#define PIC_16(yin, xin, p, xout, add) \
880( \
881 y = outy[(yin) * 8 + xin], \
882 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
883 ((CLAMP(y - cg + add) & 0xfc) << 3) | \
884 ((CLAMP(y + cb + add*2+1)) >> 3), \
885 p[(xout) * 2 + 0] = y & 0xff, \
886 p[(xout) * 2 + 1] = y >> 8 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000887)
888#else
889#ifdef CONFIG_PPC
Lee Leahye20a3192017-03-09 16:21:34 -0800890#define PIC_16(yin, xin, p, xout, add) \
891( \
892 y = outy[(yin) * 8 + xin], \
893 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 7) | \
894 ((CLAMP(y - cg + add*2+1) & 0xf8) << 2) | \
895 ((CLAMP(y + cb + add*2+1)) >> 3), \
896 p[(xout) * 2 + 0] = y >> 8, \
897 p[(xout) * 2 + 1] = y & 0xff \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000898)
899#else
Lee Leahye20a3192017-03-09 16:21:34 -0800900#define PIC_16(yin, xin, p, xout, add) \
901( \
902 y = outy[(yin) * 8 + xin], \
903 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
904 ((CLAMP(y - cg + add) & 0xfc) << 3) | \
905 ((CLAMP(y + cb + add*2+1)) >> 3), \
906 p[(xout) * 2 + 0] = y >> 8, \
907 p[(xout) * 2 + 1] = y & 0xff \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000908)
909#endif
910#endif
911
912#define PIC_32(yin, xin, p, xout) \
913( \
Lee Leahye20a3192017-03-09 16:21:34 -0800914 y = outy[(yin) * 8 + xin], \
915 STORECLAMP(p[(xout) * 4 + 0], y + cr), \
916 STORECLAMP(p[(xout) * 4 + 1], y - cg), \
917 STORECLAMP(p[(xout) * 4 + 2], y + cb), \
918 p[(xout) * 4 + 3] = 0 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000919)
920
Lee Leahye20a3192017-03-09 16:21:34 -0800921#define PIC221111(xin) \
922( \
923 CBCRCG(0, xin), \
924 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
925 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
926 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
927 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000928)
929
Lee Leahye20a3192017-03-09 16:21:34 -0800930#define PIC221111_16(xin) \
931( \
932 CBCRCG(0, xin), \
933 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3), \
934 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0), \
935 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1), \
936 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000937)
938
Lee Leahye20a3192017-03-09 16:21:34 -0800939#define PIC221111_32(xin) \
940( \
941 CBCRCG(0, xin), \
942 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
943 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
944 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
945 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000946)
947
948static void col221111(int *out, unsigned char *pic, int width)
949{
950 int i, j, k;
951 unsigned char *pic0, *pic1;
952 int *outy, *outc;
953 int cr, cg, cb, y;
954
955 pic0 = pic;
956 pic1 = pic + width;
957 outy = out;
958 outc = out + 64 * 4;
959 for (i = 2; i > 0; i--) {
960 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800961 for (k = 0; k < 8; k++)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000962 PIC221111(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000963 outc += 8;
964 outy += 16;
965 pic0 += 2 * width;
966 pic1 += 2 * width;
967 }
968 outy += 64 * 2 - 16 * 4;
969 }
970}
971
972static void col221111_16(int *out, unsigned char *pic, int width)
973{
974 int i, j, k;
975 unsigned char *pic0, *pic1;
976 int *outy, *outc;
977 int cr, cg, cb, y;
978
979 pic0 = pic;
980 pic1 = pic + width;
981 outy = out;
982 outc = out + 64 * 4;
983 for (i = 2; i > 0; i--) {
984 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800985 for (k = 0; k < 8; k++)
Lee Leahye20a3192017-03-09 16:21:34 -0800986 PIC221111_16(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000987 outc += 8;
988 outy += 16;
989 pic0 += 2 * width;
990 pic1 += 2 * width;
991 }
992 outy += 64 * 2 - 16 * 4;
993 }
994}
995
996static void col221111_32(int *out, unsigned char *pic, int width)
997{
998 int i, j, k;
999 unsigned char *pic0, *pic1;
1000 int *outy, *outc;
1001 int cr, cg, cb, y;
1002
1003 pic0 = pic;
1004 pic1 = pic + width;
1005 outy = out;
1006 outc = out + 64 * 4;
1007 for (i = 2; i > 0; i--) {
1008 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -08001009 for (k = 0; k < 8; k++)
Stefan Reinauerd650e992010-02-22 04:33:13 +00001010 PIC221111_32(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +00001011 outc += 8;
1012 outy += 16;
1013 pic0 += 2 * width;
1014 pic1 += 2 * width;
1015 }
1016 outy += 64 * 2 - 16 * 4;
1017 }
1018}