blob: 06c9d7c6cf67289432c902a777a367573a91cb7d [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;
420 break;
421 }
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++;
459 if (b == 0xff && (m = *in->p++) != 0) {
460 if (m == M_EOF) {
461 if (in->func && (m = in->func(in->data)) == 0)
462 continue;
463 }
464 in->marker = m;
465 if (le <= 16)
466 bi = bi << 16, le += 16;
467 break;
468 }
469 bi = bi << 8 | b;
470 le += 8;
471 }
472 in->bits = bi; /* tmp... 2 return values needed */
473 return le;
474}
475
476static int dec_readmarker(struct in *in)
477{
478 int m;
479
480 in->left = fillbits(in, in->left, in->bits);
481 if ((m = in->marker) == 0)
482 return 0;
483 in->left = 0;
484 in->marker = 0;
485 return m;
486}
487
488#define LEBI_DCL int le, bi
489#define LEBI_GET(in) (le = in->left, bi = in->bits)
490#define LEBI_PUT(in) (in->left = le, in->bits = bi)
491
Lee Leahye20a3192017-03-09 16:21:34 -0800492#define GETBITS(in, n) ( \
493 (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0), \
494 (le -= (n)), \
495 bi >> le & ((1 << (n)) - 1) \
496 )
Stefan Reinauerd650e992010-02-22 04:33:13 +0000497
498#define UNGETBITS(in, n) ( \
Lee Leahye20a3192017-03-09 16:21:34 -0800499 le += (n) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000500)
501
502
503static int dec_rec2(struct in *in, struct dec_hufftbl *hu, int *runp, int c,
504 int i)
505{
506 LEBI_DCL;
507
508 LEBI_GET(in);
509 if (i) {
510 UNGETBITS(in, i & 127);
511 *runp = i >> 8 & 15;
512 i >>= 16;
513 } else {
Lee Leahy73402172017-03-10 15:23:24 -0800514 for (i = DECBITS; (c = ((c << 1) | GETBITS(in, 1)))
515 >= (hu->maxcode[i]); i++)
Lee Leahyb6ee0f92017-03-09 13:35:26 -0800516 ;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000517 if (i >= 16) {
518 in->marker = M_BADHUFF;
519 return 0;
520 }
521 i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];
522 *runp = i >> 4;
523 i &= 15;
524 }
525 if (i == 0) { /* sigh, 0xf0 is 11 bit */
526 LEBI_PUT(in);
527 return 0;
528 }
529 /* receive part */
530 c = GETBITS(in, i);
531 if (c < (1 << (i - 1)))
532 c += (-1 << i) + 1;
533 LEBI_PUT(in);
534 return c;
535}
536
Lee Leahye20a3192017-03-09 16:21:34 -0800537#define DEC_REC(in, hu, r, i) ( \
538 r = GETBITS(in, DECBITS), \
539 i = hu->llvals[r], \
540 i & 128 ? \
541 ( \
542 UNGETBITS(in, i & 127), \
543 r = i >> 8 & 15, \
544 i >> 16 \
545 ) \
546 : \
547 ( \
548 LEBI_PUT(in), \
549 i = dec_rec2(in, hu, &r, r, i), \
550 LEBI_GET(in), \
551 i \
552 ) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000553)
554
Lee Leahy73402172017-03-10 15:23:24 -0800555static void decode_mcus(struct in *in, int *dct, int n, struct scan *sc,
556 int *maxp)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000557{
558 struct dec_hufftbl *hu;
559 int i, r, t;
560 LEBI_DCL;
561
562 memset(dct, 0, n * 64 * sizeof(*dct));
563 LEBI_GET(in);
564 while (n-- > 0) {
565 hu = sc->hudc.dhuff;
566 *dct++ = (sc->dc += DEC_REC(in, hu, r, t));
567
568 hu = sc->huac.dhuff;
569 i = 63;
570 while (i > 0) {
571 t = DEC_REC(in, hu, r, t);
572 if (t == 0 && r == 0) {
573 dct += i;
574 break;
575 }
576 dct += r;
577 *dct++ = t;
578 i -= r + 1;
579 }
580 *maxp++ = 64 - i;
581 if (n == sc->next)
582 sc++;
583 }
584 LEBI_PUT(in);
585}
586
Lee Leahy73402172017-03-10 15:23:24 -0800587static void dec_makehuff(struct dec_hufftbl *hu, int *hufflen,
588 unsigned char *huffvals)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000589{
590 int code, k, i, j, d, x, c, v;
591 for (i = 0; i < (1 << DECBITS); i++)
592 hu->llvals[i] = 0;
593
594/*
595 * llvals layout:
596 *
597 * value v already known, run r, backup u bits:
598 * vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu
599 * value unknown, size b bits, run r, backup u bits:
600 * 000000000000bbbb 0000 rrrr 0 uuuuuuu
601 * value and size unknown:
602 * 0000000000000000 0000 0000 0 0000000
603 */
604 code = 0;
605 k = 0;
606 for (i = 0; i < 16; i++, code <<= 1) { /* sizes */
607 hu->valptr[i] = k;
608 for (j = 0; j < hufflen[i]; j++) {
609 hu->vals[k] = *huffvals++;
610 if (i < DECBITS) {
611 c = code << (DECBITS - 1 - i);
612 v = hu->vals[k] & 0x0f; /* size */
613 for (d = 1 << (DECBITS - 1 - i); --d >= 0;) {
Lee Leahy73402172017-03-10 15:23:24 -0800614 /* both fit in table */
615 if (v + i < DECBITS) {
Stefan Reinauerd650e992010-02-22 04:33:13 +0000616 x = d >> (DECBITS - 1 - v -
617 i);
618 if (v && x < (1 << (v - 1)))
619 x += (-1 << v) + 1;
Lee Leahy73402172017-03-10 15:23:24 -0800620 x = x << 16 | (hu->vals[k]
621 & 0xf0) << 4 |
622 (DECBITS - (i + 1 + v))
623 | 128;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000624 } else
Lee Leahy73402172017-03-10 15:23:24 -0800625 x = v << 16 | (hu->vals[k]
626 & 0xf0) << 4 |
Lee Leahye20a3192017-03-09 16:21:34 -0800627 (DECBITS - (i + 1));
Stefan Reinauerd650e992010-02-22 04:33:13 +0000628 hu->llvals[c | d] = x;
629 }
630 }
631 code++;
632 k++;
633 }
634 hu->maxcode[i] = code;
635 }
636 hu->maxcode[16] = 0x20000; /* always terminate decode */
637}
638
639/****************************************************************/
640/************** idct ***************/
641/****************************************************************/
642
643#define ONE ((PREC)IFIX(1.))
644#define S2 ((PREC)IFIX(0.382683432))
645#define C2 ((PREC)IFIX(0.923879532))
646#define C4 ((PREC)IFIX(0.707106781))
647
648#define S22 ((PREC)IFIX(2 * 0.382683432))
649#define C22 ((PREC)IFIX(2 * 0.923879532))
650#define IC4 ((PREC)IFIX(1 / 0.707106781))
651
652#define C3IC1 ((PREC)IFIX(0.847759065)) /* c3/c1 */
653#define C5IC1 ((PREC)IFIX(0.566454497)) /* c5/c1 */
654#define C7IC1 ((PREC)IFIX(0.198912367)) /* c7/c1 */
655
Lee Leahy35af5c42017-03-09 17:35:28 -0800656#define XPP(a, b) (t = a + b, b = a - b, a = t)
657#define XMP(a, b) (t = a - b, b = a + b, a = t)
658#define XPM(a, b) (t = a + b, b = b - a, a = t)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000659
Lee Leahy35af5c42017-03-09 17:35:28 -0800660#define ROT(a, b, s, c) (t = IMULT(a + b, s), \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000661 a = IMULT(a, c - s) + t, \
662 b = IMULT(b, c + s) - t)
663
Lee Leahye20a3192017-03-09 16:21:34 -0800664#define IDCT \
665( \
666 XPP(t0, t1), \
667 XMP(t2, t3), \
668 t2 = IMULT(t2, IC4) - t3, \
669 XPP(t0, t3), \
670 XPP(t1, t2), \
671 XMP(t4, t7), \
672 XPP(t5, t6), \
673 XMP(t5, t7), \
674 t5 = IMULT(t5, IC4), \
675 ROT(t4, t6, S22, C22), \
676 t6 -= t7, \
677 t5 -= t6, \
678 t4 -= t5, \
679 XPP(t0, t7), \
680 XPP(t1, t6), \
681 XPP(t2, t5), \
682 XPP(t3, t4) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000683)
684
685static unsigned char zig2[64] = {
686 0, 2, 3, 9, 10, 20, 21, 35,
687 14, 16, 25, 31, 39, 46, 50, 57,
688 5, 7, 12, 18, 23, 33, 37, 48,
689 27, 29, 41, 44, 52, 55, 59, 62,
690 15, 26, 30, 40, 45, 51, 56, 58,
691 1, 4, 8, 11, 19, 22, 34, 36,
692 28, 42, 43, 53, 54, 60, 61, 63,
693 6, 13, 17, 24, 32, 38, 47, 49
694};
695
Stefan Reinauer87489e12010-03-17 04:03:22 +0000696void idct(int *in, int *out, PREC *lquant, PREC off, int max)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000697{
698 PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
699 PREC tmp[64], *tmpp;
700 int i, j;
701 unsigned char *zig2p;
702
703 t0 = off;
704 if (max == 1) {
Stefan Reinauer87489e12010-03-17 04:03:22 +0000705 t0 += in[0] * lquant[0];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000706 for (i = 0; i < 64; i++)
707 out[i] = ITOINT(t0);
708 return;
709 }
710 zig2p = zig2;
711 tmpp = tmp;
712 for (i = 0; i < 8; i++) {
713 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000714 t0 += in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000715 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000716 t5 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000717 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000718 t2 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000719 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000720 t7 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000721 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000722 t1 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000723 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000724 t4 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000725 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000726 t3 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000727 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000728 t6 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000729 IDCT;
730 tmpp[0 * 8] = t0;
731 tmpp[1 * 8] = t1;
732 tmpp[2 * 8] = t2;
733 tmpp[3 * 8] = t3;
734 tmpp[4 * 8] = t4;
735 tmpp[5 * 8] = t5;
736 tmpp[6 * 8] = t6;
737 tmpp[7 * 8] = t7;
738 tmpp++;
739 t0 = 0;
740 }
741 for (i = 0; i < 8; i++) {
742 t0 = tmp[8 * i + 0];
743 t1 = tmp[8 * i + 1];
744 t2 = tmp[8 * i + 2];
745 t3 = tmp[8 * i + 3];
746 t4 = tmp[8 * i + 4];
747 t5 = tmp[8 * i + 5];
748 t6 = tmp[8 * i + 6];
749 t7 = tmp[8 * i + 7];
750 IDCT;
751 out[8 * i + 0] = ITOINT(t0);
752 out[8 * i + 1] = ITOINT(t1);
753 out[8 * i + 2] = ITOINT(t2);
754 out[8 * i + 3] = ITOINT(t3);
755 out[8 * i + 4] = ITOINT(t4);
756 out[8 * i + 5] = ITOINT(t5);
757 out[8 * i + 6] = ITOINT(t6);
758 out[8 * i + 7] = ITOINT(t7);
759 }
760}
761
762static unsigned char zig[64] = {
763 0, 1, 5, 6, 14, 15, 27, 28,
764 2, 4, 7, 13, 16, 26, 29, 42,
765 3, 8, 12, 17, 25, 30, 41, 43,
766 9, 11, 18, 24, 31, 40, 44, 53,
767 10, 19, 23, 32, 39, 45, 52, 54,
768 20, 22, 33, 38, 46, 51, 55, 60,
769 21, 34, 37, 47, 50, 56, 59, 61,
770 35, 36, 48, 49, 57, 58, 62, 63
771};
772
773static PREC aaidct[8] = {
774 IFIX(0.3535533906), IFIX(0.4903926402),
775 IFIX(0.4619397663), IFIX(0.4157348062),
776 IFIX(0.3535533906), IFIX(0.2777851165),
777 IFIX(0.1913417162), IFIX(0.0975451610)
778};
779
780
781static void idctqtab(unsigned char *qin, PREC *qout)
782{
783 int i, j;
784
785 for (i = 0; i < 8; i++)
786 for (j = 0; j < 8; j++)
787 qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] *
Lee Leahye20a3192017-03-09 16:21:34 -0800788 IMULT(aaidct[i], aaidct[j]);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000789}
790
791static void scaleidctqtab(PREC *q, PREC sc)
792{
793 int i;
794
795 for (i = 0; i < 64; i++)
796 q[i] = IMULT(q[i], sc);
797}
798
799/****************************************************************/
800/************** color decoder ***************/
801/****************************************************************/
802
803#define ROUND
804
805/*
806 * YCbCr Color transformation:
807 *
808 * y:0..255 Cb:-128..127 Cr:-128..127
809 *
810 * R = Y + 1.40200 * Cr
811 * G = Y - 0.34414 * Cb - 0.71414 * Cr
812 * B = Y + 1.77200 * Cb
813 *
814 * =>
815 * Cr *= 1.40200;
816 * Cb *= 1.77200;
817 * Cg = 0.19421 * Cb + .50937 * Cr;
818 * R = Y + Cr;
819 * G = Y - Cg;
820 * B = Y + Cb;
821 *
822 * =>
823 * Cg = (50 * Cb + 130 * Cr + 128) >> 8;
824 */
825
826static void initcol(PREC q[][64])
827{
828 scaleidctqtab(q[1], IFIX(1.77200));
829 scaleidctqtab(q[2], IFIX(1.40200));
830}
831
832/* This is optimized for the stupid sun SUNWspro compiler. */
Lee Leahy35af5c42017-03-09 17:35:28 -0800833#define STORECLAMP(a, x) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000834( \
Lee Leahye20a3192017-03-09 16:21:34 -0800835 (a) = (x), \
836 (unsigned int)(x) >= 256 ? \
837 ((a) = (x) < 0 ? 0 : 255) \
838 : \
839 0 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000840)
841
842#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x))
843
844#ifdef ROUND
845
846#define CBCRCG(yin, xin) \
847( \
Lee Leahy35af5c42017-03-09 17:35:28 -0800848 cb = outc[0 + yin * 8 + xin], \
849 cr = outc[64 + yin * 8 + xin], \
Lee Leahye20a3192017-03-09 16:21:34 -0800850 cg = (50 * cb + 130 * cr + 128) >> 8 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000851)
852
853#else
854
855#define CBCRCG(yin, xin) \
856( \
Lee Leahy35af5c42017-03-09 17:35:28 -0800857 cb = outc[0 + yin*8 + xin], \
858 cr = outc[64 + yin*8 + xin], \
Lee Leahye20a3192017-03-09 16:21:34 -0800859 cg = (3 * cb + 8 * cr) >> 4 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000860)
861
862#endif
863
864#define PIC(yin, xin, p, xout) \
865( \
Lee Leahye20a3192017-03-09 16:21:34 -0800866 y = outy[(yin) * 8 + xin], \
867 STORECLAMP(p[(xout) * 3 + 0], y + cr), \
868 STORECLAMP(p[(xout) * 3 + 1], y - cg), \
869 STORECLAMP(p[(xout) * 3 + 2], y + cb) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000870)
871
872#ifdef __LITTLE_ENDIAN
Lee Leahye20a3192017-03-09 16:21:34 -0800873#define PIC_16(yin, xin, p, xout, add) \
874( \
875 y = outy[(yin) * 8 + xin], \
876 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
877 ((CLAMP(y - cg + add) & 0xfc) << 3) | \
878 ((CLAMP(y + cb + add*2+1)) >> 3), \
879 p[(xout) * 2 + 0] = y & 0xff, \
880 p[(xout) * 2 + 1] = y >> 8 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000881)
882#else
883#ifdef CONFIG_PPC
Lee Leahye20a3192017-03-09 16:21:34 -0800884#define PIC_16(yin, xin, p, xout, add) \
885( \
886 y = outy[(yin) * 8 + xin], \
887 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 7) | \
888 ((CLAMP(y - cg + add*2+1) & 0xf8) << 2) | \
889 ((CLAMP(y + cb + add*2+1)) >> 3), \
890 p[(xout) * 2 + 0] = y >> 8, \
891 p[(xout) * 2 + 1] = y & 0xff \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000892)
893#else
Lee Leahye20a3192017-03-09 16:21:34 -0800894#define PIC_16(yin, xin, p, xout, add) \
895( \
896 y = outy[(yin) * 8 + xin], \
897 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
898 ((CLAMP(y - cg + add) & 0xfc) << 3) | \
899 ((CLAMP(y + cb + add*2+1)) >> 3), \
900 p[(xout) * 2 + 0] = y >> 8, \
901 p[(xout) * 2 + 1] = y & 0xff \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000902)
903#endif
904#endif
905
906#define PIC_32(yin, xin, p, xout) \
907( \
Lee Leahye20a3192017-03-09 16:21:34 -0800908 y = outy[(yin) * 8 + xin], \
909 STORECLAMP(p[(xout) * 4 + 0], y + cr), \
910 STORECLAMP(p[(xout) * 4 + 1], y - cg), \
911 STORECLAMP(p[(xout) * 4 + 2], y + cb), \
912 p[(xout) * 4 + 3] = 0 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000913)
914
Lee Leahye20a3192017-03-09 16:21:34 -0800915#define PIC221111(xin) \
916( \
917 CBCRCG(0, xin), \
918 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
919 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
920 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
921 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000922)
923
Lee Leahye20a3192017-03-09 16:21:34 -0800924#define PIC221111_16(xin) \
925( \
926 CBCRCG(0, xin), \
927 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3), \
928 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0), \
929 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1), \
930 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000931)
932
Lee Leahye20a3192017-03-09 16:21:34 -0800933#define PIC221111_32(xin) \
934( \
935 CBCRCG(0, xin), \
936 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
937 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
938 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
939 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000940)
941
942static void col221111(int *out, unsigned char *pic, int width)
943{
944 int i, j, k;
945 unsigned char *pic0, *pic1;
946 int *outy, *outc;
947 int cr, cg, cb, y;
948
949 pic0 = pic;
950 pic1 = pic + width;
951 outy = out;
952 outc = out + 64 * 4;
953 for (i = 2; i > 0; i--) {
954 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800955 for (k = 0; k < 8; k++)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000956 PIC221111(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000957 outc += 8;
958 outy += 16;
959 pic0 += 2 * width;
960 pic1 += 2 * width;
961 }
962 outy += 64 * 2 - 16 * 4;
963 }
964}
965
966static void col221111_16(int *out, unsigned char *pic, int width)
967{
968 int i, j, k;
969 unsigned char *pic0, *pic1;
970 int *outy, *outc;
971 int cr, cg, cb, y;
972
973 pic0 = pic;
974 pic1 = pic + width;
975 outy = out;
976 outc = out + 64 * 4;
977 for (i = 2; i > 0; i--) {
978 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800979 for (k = 0; k < 8; k++)
Lee Leahye20a3192017-03-09 16:21:34 -0800980 PIC221111_16(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000981 outc += 8;
982 outy += 16;
983 pic0 += 2 * width;
984 pic1 += 2 * width;
985 }
986 outy += 64 * 2 - 16 * 4;
987 }
988}
989
990static void col221111_32(int *out, unsigned char *pic, int width)
991{
992 int i, j, k;
993 unsigned char *pic0, *pic1;
994 int *outy, *outc;
995 int cr, cg, cb, y;
996
997 pic0 = pic;
998 pic1 = pic + width;
999 outy = out;
1000 outc = out + 64 * 4;
1001 for (i = 2; i > 0; i--) {
1002 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -08001003 for (k = 0; k < 8; k++)
Stefan Reinauerd650e992010-02-22 04:33:13 +00001004 PIC221111_32(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +00001005 outc += 8;
1006 outy += 16;
1007 pic0 += 2 * width;
1008 pic1 += 2 * width;
1009 }
1010 outy += 64 * 2 - 16 * 4;
1011 }
1012}