blob: b3d4c89c5366fb627e21f452fef4b70babec5eaa [file] [log] [blame]
Angel Pons118a9c72020-04-02 23:48:34 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Stefan Reinauerd650e992010-02-22 04:33:13 +00002
3/*
4 * a tiny jpeg decoder.
5 *
6 * written in August 2001 by Michael Schroeder <mls@suse.de>
7 *
8 */
9
10#define __LITTLE_ENDIAN
11#include <string.h>
12#include "jpeg.h"
13#define ISHIFT 11
14
15#define IFIX(a) ((int)((a) * (1 << ISHIFT) + .5))
16#define IMULT(a, b) (((a) * (b)) >> ISHIFT)
17#define ITOINT(a) ((a) >> ISHIFT)
18
19#ifndef __P
20# define __P(x) x
21#endif
22
23/* special markers */
24#define M_BADHUFF -1
25#define M_EOF 0x80
26
27struct in {
28 unsigned char *p;
29 unsigned int bits;
30 int left;
31 int marker;
32
33 int (*func) __P((void *));
34 void *data;
35};
36
37/*********************************/
38struct dec_hufftbl;
39struct enc_hufftbl;
40
41union hufftblp {
42 struct dec_hufftbl *dhuff;
43 struct enc_hufftbl *ehuff;
44};
45
46struct scan {
47 int dc; /* old dc value */
48
49 union hufftblp hudc;
50 union hufftblp huac;
51 int next; /* when to switch to next scan */
52
53 int cid; /* component id */
54 int hv; /* horiz/vert, copied from comp */
55 int tq; /* quant tbl, copied from comp */
56};
57
58/*********************************/
59
60#define DECBITS 10 /* seems to be the optimum */
61
62struct dec_hufftbl {
63 int maxcode[17];
64 int valptr[16];
65 unsigned char vals[256];
66 unsigned int llvals[1 << DECBITS];
67};
68
69static void decode_mcus __P((struct in *, int *, int, struct scan *, int *));
70static int dec_readmarker __P((struct in *));
71static void dec_makehuff __P((struct dec_hufftbl *, int *, unsigned char *));
72
73static void setinput __P((struct in *, unsigned char *));
74/*********************************/
75
76#undef PREC
77#define PREC int
78
79static void idctqtab __P((unsigned char *, PREC *));
80static void idct __P((int *, int *, PREC *, PREC, int));
81static void scaleidctqtab __P((PREC *, PREC));
82
83/*********************************/
84
85static void initcol __P((PREC[][64]));
86
87static void col221111 __P((int *, unsigned char *, int));
88static void col221111_16 __P((int *, unsigned char *, int));
89static void col221111_32 __P((int *, unsigned char *, int));
90
91/*********************************/
92
93#define M_SOI 0xd8
94#define M_APP0 0xe0
95#define M_DQT 0xdb
96#define M_SOF0 0xc0
97#define M_DHT 0xc4
98#define M_DRI 0xdd
99#define M_SOS 0xda
100#define M_RST0 0xd0
101#define M_EOI 0xd9
102#define M_COM 0xfe
103
104static unsigned char *datap;
105
106static int getbyte(void)
107{
108 return *datap++;
109}
110
111static int getword(void)
112{
113 int c1, c2;
114 c1 = *datap++;
115 c2 = *datap++;
116 return c1 << 8 | c2;
117}
118
119struct comp {
120 int cid;
121 int hv;
122 int tq;
123};
124
125#define MAXCOMP 4
126struct jpginfo {
127 int nc; /* number of components */
128 int ns; /* number of scans */
129 int dri; /* restart interval */
130 int nm; /* mcus til next marker */
131 int rm; /* next restart marker */
132};
133
134static struct jpginfo info;
135static struct comp comps[MAXCOMP];
136
137static struct scan dscans[MAXCOMP];
138
139static unsigned char quant[4][64];
140
141static struct dec_hufftbl dhuff[4];
142
143#define dec_huffdc (dhuff + 0)
144#define dec_huffac (dhuff + 2)
145
Stefan Reinauer87489e12010-03-17 04:03:22 +0000146static struct in glob_in;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000147
148static int readtables(int till)
149{
150 int m, l, i, j, lq, pq, tq;
151 int tc, th, tt;
152
153 for (;;) {
154 if (getbyte() != 0xff)
155 return -1;
Lee Leahy491c5b62017-03-10 15:51:04 -0800156 m = getbyte();
157 if (m == till)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000158 break;
159
160 switch (m) {
161 case 0xc2:
162 return 0;
163
164 case M_DQT:
165 lq = getword();
166 while (lq > 2) {
167 pq = getbyte();
168 tq = pq & 15;
169 if (tq > 3)
170 return -1;
171 pq >>= 4;
172 if (pq != 0)
173 return -1;
174 for (i = 0; i < 64; i++)
175 quant[tq][i] = getbyte();
176 lq -= 64 + 1;
177 }
178 break;
179
180 case M_DHT:
181 l = getword();
182 while (l > 2) {
183 int hufflen[16], k;
184 unsigned char huffvals[256];
185
186 tc = getbyte();
187 th = tc & 15;
188 tc >>= 4;
189 tt = tc * 2 + th;
190 if (tc > 1 || th > 1)
191 return -1;
192 for (i = 0; i < 16; i++)
193 hufflen[i] = getbyte();
194 l -= 1 + 16;
195 k = 0;
196 for (i = 0; i < 16; i++) {
197 for (j = 0; j < hufflen[i]; j++)
198 huffvals[k++] = getbyte();
199 l -= hufflen[i];
200 }
201 dec_makehuff(dhuff + tt, hufflen,
202 huffvals);
203 }
204 break;
205
206 case M_DRI:
207 l = getword();
208 info.dri = getword();
209 break;
210
211 default:
212 l = getword();
213 while (l-- > 2)
214 getbyte();
215 break;
216 }
217 }
218 return 0;
219}
220
221static void dec_initscans(void)
222{
223 int i;
224
225 info.nm = info.dri + 1;
226 info.rm = M_RST0;
227 for (i = 0; i < info.ns; i++)
228 dscans[i].dc = 0;
229}
230
231static int dec_checkmarker(void)
232{
233 int i;
234
Stefan Reinauer87489e12010-03-17 04:03:22 +0000235 if (dec_readmarker(&glob_in) != info.rm)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000236 return -1;
237 info.nm = info.dri;
238 info.rm = (info.rm + 1) & ~0x08;
239 for (i = 0; i < info.ns; i++)
240 dscans[i].dc = 0;
241 return 0;
242}
243
Patrick Georgi246179a2015-08-09 18:23:10 +0200244void jpeg_fetch_size(unsigned char *buf, int *width, int *height)
245{
246 datap = buf;
247 getbyte();
248 getbyte();
249 readtables(M_SOF0);
250 getword();
251 getbyte();
252 *height = getword();
253 *width = getword();
254}
255
Stefan Reinauerd650e992010-02-22 04:33:13 +0000256int jpeg_check_size(unsigned char *buf, int width, int height)
257{
Lee Leahye20a3192017-03-09 16:21:34 -0800258 datap = buf;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000259 getbyte();
260 getbyte();
261 readtables(M_SOF0);
262 getword();
263 getbyte();
Lee Leahye20a3192017-03-09 16:21:34 -0800264 if (height != getword() || width != getword())
Stefan Reinauerd650e992010-02-22 04:33:13 +0000265 return 0;
Lee Leahye20a3192017-03-09 16:21:34 -0800266 return 1;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000267}
268
Stefan Reinauer14e22772010-04-27 06:56:47 +0000269int jpeg_decode(unsigned char *buf, unsigned char *pic,
Stefan Reinauerd650e992010-02-22 04:33:13 +0000270 int width, int height, int depth, struct jpeg_decdata *decdata)
271{
272 int i, j, m, tac, tdc;
273 int mcusx, mcusy, mx, my;
274 int max[6];
275
276 if (!decdata || !buf || !pic)
277 return -1;
278 datap = buf;
279 if (getbyte() != 0xff)
280 return ERR_NO_SOI;
281 if (getbyte() != M_SOI)
282 return ERR_NO_SOI;
283 if (readtables(M_SOF0))
284 return ERR_BAD_TABLES;
285 getword();
286 i = getbyte();
287 if (i != 8)
288 return ERR_NOT_8BIT;
289 if (((getword() + 15) & ~15) != height)
290 return ERR_HEIGHT_MISMATCH;
291 if (((getword() + 15) & ~15) != width)
292 return ERR_WIDTH_MISMATCH;
293 if ((height & 15) || (width & 15))
294 return ERR_BAD_WIDTH_OR_HEIGHT;
295 info.nc = getbyte();
296 if (info.nc > MAXCOMP)
297 return ERR_TOO_MANY_COMPPS;
298 for (i = 0; i < info.nc; i++) {
299 int h, v;
300 comps[i].cid = getbyte();
301 comps[i].hv = getbyte();
302 v = comps[i].hv & 15;
303 h = comps[i].hv >> 4;
304 comps[i].tq = getbyte();
305 if (h > 3 || v > 3)
306 return ERR_ILLEGAL_HV;
307 if (comps[i].tq > 3)
308 return ERR_QUANT_TABLE_SELECTOR;
309 }
310 if (readtables(M_SOS))
311 return ERR_BAD_TABLES;
312 getword();
313 info.ns = getbyte();
314 if (info.ns != 3)
315 return ERR_NOT_YCBCR_221111;
316 for (i = 0; i < 3; i++) {
317 dscans[i].cid = getbyte();
318 tdc = getbyte();
319 tac = tdc & 15;
320 tdc >>= 4;
321 if (tdc > 1 || tac > 1)
322 return ERR_QUANT_TABLE_SELECTOR;
323 for (j = 0; j < info.nc; j++)
324 if (comps[j].cid == dscans[i].cid)
325 break;
326 if (j == info.nc)
327 return ERR_UNKNOWN_CID_IN_SCAN;
328 dscans[i].hv = comps[j].hv;
329 dscans[i].tq = comps[j].tq;
330 dscans[i].hudc.dhuff = dec_huffdc + tdc;
331 dscans[i].huac.dhuff = dec_huffac + tac;
332 }
333
334 i = getbyte();
335 j = getbyte();
336 m = getbyte();
337
338 if (i != 0 || j != 63 || m != 0)
339 return ERR_NOT_SEQUENTIAL_DCT;
340
341 if (dscans[0].cid != 1 || dscans[1].cid != 2 || dscans[2].cid != 3)
342 return ERR_NOT_YCBCR_221111;
343
Lee Leahy73402172017-03-10 15:23:24 -0800344 if (dscans[0].hv != 0x22 || dscans[1].hv != 0x11
345 || dscans[2].hv != 0x11)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000346 return ERR_NOT_YCBCR_221111;
347
348 mcusx = width >> 4;
349 mcusy = height >> 4;
350
351
352 idctqtab(quant[dscans[0].tq], decdata->dquant[0]);
353 idctqtab(quant[dscans[1].tq], decdata->dquant[1]);
354 idctqtab(quant[dscans[2].tq], decdata->dquant[2]);
355 initcol(decdata->dquant);
Stefan Reinauer87489e12010-03-17 04:03:22 +0000356 setinput(&glob_in, datap);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000357
Stefan Reinauerd650e992010-02-22 04:33:13 +0000358 dec_initscans();
359
360 dscans[0].next = 6 - 4;
361 dscans[1].next = 6 - 4 - 1;
362 dscans[2].next = 6 - 4 - 1 - 1; /* 411 encoding */
363 for (my = 0; my < mcusy; my++) {
364 for (mx = 0; mx < mcusx; mx++) {
365 if (info.dri && !--info.nm)
366 if (dec_checkmarker())
367 return ERR_WRONG_MARKER;
368
Stefan Reinauer87489e12010-03-17 04:03:22 +0000369 decode_mcus(&glob_in, decdata->dcts, 6, dscans, max);
Lee Leahy73402172017-03-10 15:23:24 -0800370 idct(decdata->dcts, decdata->out, decdata->dquant[0],
371 IFIX(128.5), max[0]);
372 idct(decdata->dcts + 64, decdata->out + 64,
373 decdata->dquant[0], IFIX(128.5), max[1]);
374 idct(decdata->dcts + 128, decdata->out + 128,
375 decdata->dquant[0], IFIX(128.5), max[2]);
376 idct(decdata->dcts + 192, decdata->out + 192,
377 decdata->dquant[0], IFIX(128.5), max[3]);
378 idct(decdata->dcts + 256, decdata->out + 256,
379 decdata->dquant[1], IFIX(0.5), max[4]);
380 idct(decdata->dcts + 320, decdata->out + 320,
381 decdata->dquant[2], IFIX(0.5), max[5]);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000382
383 switch (depth) {
384 case 32:
Lee Leahy73402172017-03-10 15:23:24 -0800385 col221111_32(decdata->out, pic
386 + (my * 16 * mcusx + mx) * 16 * 4,
387 mcusx * 16 * 4);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000388 break;
389 case 24:
Lee Leahy73402172017-03-10 15:23:24 -0800390 col221111(decdata->out, pic
391 + (my * 16 * mcusx + mx) * 16 * 3,
392 mcusx * 16 * 3);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000393 break;
394 case 16:
Lee Leahy73402172017-03-10 15:23:24 -0800395 col221111_16(decdata->out, pic
396 + (my * 16 * mcusx + mx) * (16 * 2),
397 mcusx * (16 * 2));
Stefan Reinauerd650e992010-02-22 04:33:13 +0000398 break;
399 default:
400 return ERR_DEPTH_MISMATCH;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000401 }
402 }
403 }
404
Stefan Reinauer87489e12010-03-17 04:03:22 +0000405 m = dec_readmarker(&glob_in);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000406 if (m != M_EOI)
407 return ERR_NO_EOI;
408
409 return 0;
410}
411
412/****************************************************************/
413/************** huffman decoder ***************/
414/****************************************************************/
415
416static int fillbits __P((struct in *, int, unsigned int));
417static int dec_rec2
418__P((struct in *, struct dec_hufftbl *, int *, int, int));
419
420static void setinput(struct in *in, unsigned char *p)
421{
422 in->p = p;
423 in->left = 0;
424 in->bits = 0;
425 in->marker = 0;
426}
427
428static int fillbits(struct in *in, int le, unsigned int bi)
429{
430 int b, m;
431
432 if (in->marker) {
433 if (le <= 16)
434 in->bits = bi << 16, le += 16;
435 return le;
436 }
437 while (le <= 24) {
438 b = *in->p++;
Lee Leahy491c5b62017-03-10 15:51:04 -0800439 if (b == 0xff) {
440 m = *in->p++;
441 if (m != 0) {
442 if (m == M_EOF) {
443 if (in->func) {
444 m = in->func(in->data);
445 if (m == 0)
446 continue;
Martin Roth1d5e2402017-07-23 20:04:41 -0600447 }
Lee Leahy491c5b62017-03-10 15:51:04 -0800448 }
449 in->marker = m;
450 if (le <= 16)
451 bi = bi << 16, le += 16;
452 break;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000453 }
Stefan Reinauerd650e992010-02-22 04:33:13 +0000454 }
455 bi = bi << 8 | b;
456 le += 8;
457 }
458 in->bits = bi; /* tmp... 2 return values needed */
459 return le;
460}
461
462static int dec_readmarker(struct in *in)
463{
464 int m;
465
466 in->left = fillbits(in, in->left, in->bits);
Lee Leahy491c5b62017-03-10 15:51:04 -0800467 m = in->marker;
468 if (m == 0)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000469 return 0;
470 in->left = 0;
471 in->marker = 0;
472 return m;
473}
474
475#define LEBI_DCL int le, bi
476#define LEBI_GET(in) (le = in->left, bi = in->bits)
477#define LEBI_PUT(in) (in->left = le, in->bits = bi)
478
Lee Leahye20a3192017-03-09 16:21:34 -0800479#define GETBITS(in, n) ( \
480 (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0), \
481 (le -= (n)), \
482 bi >> le & ((1 << (n)) - 1) \
483 )
Stefan Reinauerd650e992010-02-22 04:33:13 +0000484
485#define UNGETBITS(in, n) ( \
Lee Leahye20a3192017-03-09 16:21:34 -0800486 le += (n) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000487)
488
489
490static int dec_rec2(struct in *in, struct dec_hufftbl *hu, int *runp, int c,
491 int i)
492{
493 LEBI_DCL;
494
495 LEBI_GET(in);
496 if (i) {
497 UNGETBITS(in, i & 127);
498 *runp = i >> 8 & 15;
499 i >>= 16;
500 } else {
Lee Leahy73402172017-03-10 15:23:24 -0800501 for (i = DECBITS; (c = ((c << 1) | GETBITS(in, 1)))
502 >= (hu->maxcode[i]); i++)
Lee Leahyb6ee0f92017-03-09 13:35:26 -0800503 ;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000504 if (i >= 16) {
505 in->marker = M_BADHUFF;
506 return 0;
507 }
508 i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];
509 *runp = i >> 4;
510 i &= 15;
511 }
512 if (i == 0) { /* sigh, 0xf0 is 11 bit */
513 LEBI_PUT(in);
514 return 0;
515 }
516 /* receive part */
517 c = GETBITS(in, i);
518 if (c < (1 << (i - 1)))
519 c += (-1 << i) + 1;
520 LEBI_PUT(in);
521 return c;
522}
523
Lee Leahye20a3192017-03-09 16:21:34 -0800524#define DEC_REC(in, hu, r, i) ( \
525 r = GETBITS(in, DECBITS), \
526 i = hu->llvals[r], \
527 i & 128 ? \
528 ( \
529 UNGETBITS(in, i & 127), \
530 r = i >> 8 & 15, \
531 i >> 16 \
532 ) \
533 : \
534 ( \
535 LEBI_PUT(in), \
536 i = dec_rec2(in, hu, &r, r, i), \
537 LEBI_GET(in), \
538 i \
539 ) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000540)
541
Lee Leahy73402172017-03-10 15:23:24 -0800542static void decode_mcus(struct in *in, int *dct, int n, struct scan *sc,
543 int *maxp)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000544{
545 struct dec_hufftbl *hu;
546 int i, r, t;
547 LEBI_DCL;
548
549 memset(dct, 0, n * 64 * sizeof(*dct));
550 LEBI_GET(in);
551 while (n-- > 0) {
552 hu = sc->hudc.dhuff;
553 *dct++ = (sc->dc += DEC_REC(in, hu, r, t));
554
555 hu = sc->huac.dhuff;
556 i = 63;
557 while (i > 0) {
558 t = DEC_REC(in, hu, r, t);
559 if (t == 0 && r == 0) {
560 dct += i;
561 break;
562 }
563 dct += r;
564 *dct++ = t;
565 i -= r + 1;
566 }
567 *maxp++ = 64 - i;
568 if (n == sc->next)
569 sc++;
570 }
571 LEBI_PUT(in);
572}
573
Lee Leahy73402172017-03-10 15:23:24 -0800574static void dec_makehuff(struct dec_hufftbl *hu, int *hufflen,
575 unsigned char *huffvals)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000576{
577 int code, k, i, j, d, x, c, v;
578 for (i = 0; i < (1 << DECBITS); i++)
579 hu->llvals[i] = 0;
580
581/*
582 * llvals layout:
583 *
584 * value v already known, run r, backup u bits:
585 * vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu
586 * value unknown, size b bits, run r, backup u bits:
587 * 000000000000bbbb 0000 rrrr 0 uuuuuuu
588 * value and size unknown:
589 * 0000000000000000 0000 0000 0 0000000
590 */
591 code = 0;
592 k = 0;
593 for (i = 0; i < 16; i++, code <<= 1) { /* sizes */
594 hu->valptr[i] = k;
595 for (j = 0; j < hufflen[i]; j++) {
596 hu->vals[k] = *huffvals++;
597 if (i < DECBITS) {
598 c = code << (DECBITS - 1 - i);
599 v = hu->vals[k] & 0x0f; /* size */
600 for (d = 1 << (DECBITS - 1 - i); --d >= 0;) {
Lee Leahy73402172017-03-10 15:23:24 -0800601 /* both fit in table */
602 if (v + i < DECBITS) {
Stefan Reinauerd650e992010-02-22 04:33:13 +0000603 x = d >> (DECBITS - 1 - v -
604 i);
605 if (v && x < (1 << (v - 1)))
606 x += (-1 << v) + 1;
Lee Leahy73402172017-03-10 15:23:24 -0800607 x = x << 16 | (hu->vals[k]
608 & 0xf0) << 4 |
609 (DECBITS - (i + 1 + v))
610 | 128;
Stefan Reinauerd650e992010-02-22 04:33:13 +0000611 } else
Lee Leahy73402172017-03-10 15:23:24 -0800612 x = v << 16 | (hu->vals[k]
613 & 0xf0) << 4 |
Lee Leahye20a3192017-03-09 16:21:34 -0800614 (DECBITS - (i + 1));
Stefan Reinauerd650e992010-02-22 04:33:13 +0000615 hu->llvals[c | d] = x;
616 }
617 }
618 code++;
619 k++;
620 }
621 hu->maxcode[i] = code;
622 }
623 hu->maxcode[16] = 0x20000; /* always terminate decode */
624}
625
626/****************************************************************/
627/************** idct ***************/
628/****************************************************************/
629
630#define ONE ((PREC)IFIX(1.))
631#define S2 ((PREC)IFIX(0.382683432))
632#define C2 ((PREC)IFIX(0.923879532))
633#define C4 ((PREC)IFIX(0.707106781))
634
635#define S22 ((PREC)IFIX(2 * 0.382683432))
636#define C22 ((PREC)IFIX(2 * 0.923879532))
637#define IC4 ((PREC)IFIX(1 / 0.707106781))
638
639#define C3IC1 ((PREC)IFIX(0.847759065)) /* c3/c1 */
640#define C5IC1 ((PREC)IFIX(0.566454497)) /* c5/c1 */
641#define C7IC1 ((PREC)IFIX(0.198912367)) /* c7/c1 */
642
Lee Leahy35af5c42017-03-09 17:35:28 -0800643#define XPP(a, b) (t = a + b, b = a - b, a = t)
644#define XMP(a, b) (t = a - b, b = a + b, a = t)
645#define XPM(a, b) (t = a + b, b = b - a, a = t)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000646
Lee Leahy35af5c42017-03-09 17:35:28 -0800647#define ROT(a, b, s, c) (t = IMULT(a + b, s), \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000648 a = IMULT(a, c - s) + t, \
649 b = IMULT(b, c + s) - t)
650
Lee Leahye20a3192017-03-09 16:21:34 -0800651#define IDCT \
652( \
653 XPP(t0, t1), \
654 XMP(t2, t3), \
655 t2 = IMULT(t2, IC4) - t3, \
656 XPP(t0, t3), \
657 XPP(t1, t2), \
658 XMP(t4, t7), \
659 XPP(t5, t6), \
660 XMP(t5, t7), \
661 t5 = IMULT(t5, IC4), \
662 ROT(t4, t6, S22, C22), \
663 t6 -= t7, \
664 t5 -= t6, \
665 t4 -= t5, \
666 XPP(t0, t7), \
667 XPP(t1, t6), \
668 XPP(t2, t5), \
669 XPP(t3, t4) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000670)
671
672static unsigned char zig2[64] = {
673 0, 2, 3, 9, 10, 20, 21, 35,
674 14, 16, 25, 31, 39, 46, 50, 57,
675 5, 7, 12, 18, 23, 33, 37, 48,
676 27, 29, 41, 44, 52, 55, 59, 62,
677 15, 26, 30, 40, 45, 51, 56, 58,
678 1, 4, 8, 11, 19, 22, 34, 36,
679 28, 42, 43, 53, 54, 60, 61, 63,
680 6, 13, 17, 24, 32, 38, 47, 49
681};
682
Stefan Reinauer87489e12010-03-17 04:03:22 +0000683void idct(int *in, int *out, PREC *lquant, PREC off, int max)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000684{
685 PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
686 PREC tmp[64], *tmpp;
687 int i, j;
688 unsigned char *zig2p;
689
690 t0 = off;
691 if (max == 1) {
Stefan Reinauer87489e12010-03-17 04:03:22 +0000692 t0 += in[0] * lquant[0];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000693 for (i = 0; i < 64; i++)
694 out[i] = ITOINT(t0);
695 return;
696 }
697 zig2p = zig2;
698 tmpp = tmp;
699 for (i = 0; i < 8; i++) {
700 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000701 t0 += in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000702 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000703 t5 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000704 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000705 t2 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000706 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000707 t7 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000708 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000709 t1 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000710 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000711 t4 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000712 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000713 t3 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000714 j = *zig2p++;
Stefan Reinauer87489e12010-03-17 04:03:22 +0000715 t6 = in[j] * lquant[j];
Stefan Reinauerd650e992010-02-22 04:33:13 +0000716 IDCT;
717 tmpp[0 * 8] = t0;
718 tmpp[1 * 8] = t1;
719 tmpp[2 * 8] = t2;
720 tmpp[3 * 8] = t3;
721 tmpp[4 * 8] = t4;
722 tmpp[5 * 8] = t5;
723 tmpp[6 * 8] = t6;
724 tmpp[7 * 8] = t7;
725 tmpp++;
726 t0 = 0;
727 }
728 for (i = 0; i < 8; i++) {
729 t0 = tmp[8 * i + 0];
730 t1 = tmp[8 * i + 1];
731 t2 = tmp[8 * i + 2];
732 t3 = tmp[8 * i + 3];
733 t4 = tmp[8 * i + 4];
734 t5 = tmp[8 * i + 5];
735 t6 = tmp[8 * i + 6];
736 t7 = tmp[8 * i + 7];
737 IDCT;
738 out[8 * i + 0] = ITOINT(t0);
739 out[8 * i + 1] = ITOINT(t1);
740 out[8 * i + 2] = ITOINT(t2);
741 out[8 * i + 3] = ITOINT(t3);
742 out[8 * i + 4] = ITOINT(t4);
743 out[8 * i + 5] = ITOINT(t5);
744 out[8 * i + 6] = ITOINT(t6);
745 out[8 * i + 7] = ITOINT(t7);
746 }
747}
748
749static unsigned char zig[64] = {
750 0, 1, 5, 6, 14, 15, 27, 28,
751 2, 4, 7, 13, 16, 26, 29, 42,
752 3, 8, 12, 17, 25, 30, 41, 43,
753 9, 11, 18, 24, 31, 40, 44, 53,
754 10, 19, 23, 32, 39, 45, 52, 54,
755 20, 22, 33, 38, 46, 51, 55, 60,
756 21, 34, 37, 47, 50, 56, 59, 61,
757 35, 36, 48, 49, 57, 58, 62, 63
758};
759
760static PREC aaidct[8] = {
761 IFIX(0.3535533906), IFIX(0.4903926402),
762 IFIX(0.4619397663), IFIX(0.4157348062),
763 IFIX(0.3535533906), IFIX(0.2777851165),
764 IFIX(0.1913417162), IFIX(0.0975451610)
765};
766
767
768static void idctqtab(unsigned char *qin, PREC *qout)
769{
770 int i, j;
771
772 for (i = 0; i < 8; i++)
773 for (j = 0; j < 8; j++)
774 qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] *
Lee Leahye20a3192017-03-09 16:21:34 -0800775 IMULT(aaidct[i], aaidct[j]);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000776}
777
778static void scaleidctqtab(PREC *q, PREC sc)
779{
780 int i;
781
782 for (i = 0; i < 64; i++)
783 q[i] = IMULT(q[i], sc);
784}
785
786/****************************************************************/
787/************** color decoder ***************/
788/****************************************************************/
789
790#define ROUND
791
792/*
793 * YCbCr Color transformation:
794 *
795 * y:0..255 Cb:-128..127 Cr:-128..127
796 *
797 * R = Y + 1.40200 * Cr
798 * G = Y - 0.34414 * Cb - 0.71414 * Cr
799 * B = Y + 1.77200 * Cb
800 *
801 * =>
802 * Cr *= 1.40200;
803 * Cb *= 1.77200;
804 * Cg = 0.19421 * Cb + .50937 * Cr;
805 * R = Y + Cr;
806 * G = Y - Cg;
807 * B = Y + Cb;
808 *
809 * =>
810 * Cg = (50 * Cb + 130 * Cr + 128) >> 8;
811 */
812
813static void initcol(PREC q[][64])
814{
815 scaleidctqtab(q[1], IFIX(1.77200));
816 scaleidctqtab(q[2], IFIX(1.40200));
817}
818
819/* This is optimized for the stupid sun SUNWspro compiler. */
Lee Leahy35af5c42017-03-09 17:35:28 -0800820#define STORECLAMP(a, x) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000821( \
Lee Leahye20a3192017-03-09 16:21:34 -0800822 (a) = (x), \
823 (unsigned int)(x) >= 256 ? \
824 ((a) = (x) < 0 ? 0 : 255) \
825 : \
826 0 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000827)
828
829#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x))
830
831#ifdef ROUND
832
833#define CBCRCG(yin, xin) \
834( \
Lee Leahy35af5c42017-03-09 17:35:28 -0800835 cb = outc[0 + yin * 8 + xin], \
836 cr = outc[64 + yin * 8 + xin], \
Lee Leahye20a3192017-03-09 16:21:34 -0800837 cg = (50 * cb + 130 * cr + 128) >> 8 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000838)
839
840#else
841
842#define CBCRCG(yin, xin) \
843( \
Lee Leahy35af5c42017-03-09 17:35:28 -0800844 cb = outc[0 + yin*8 + xin], \
845 cr = outc[64 + yin*8 + xin], \
Lee Leahye20a3192017-03-09 16:21:34 -0800846 cg = (3 * cb + 8 * cr) >> 4 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000847)
848
849#endif
850
851#define PIC(yin, xin, p, xout) \
852( \
Lee Leahye20a3192017-03-09 16:21:34 -0800853 y = outy[(yin) * 8 + xin], \
854 STORECLAMP(p[(xout) * 3 + 0], y + cr), \
855 STORECLAMP(p[(xout) * 3 + 1], y - cg), \
856 STORECLAMP(p[(xout) * 3 + 2], y + cb) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000857)
858
859#ifdef __LITTLE_ENDIAN
Lee Leahye20a3192017-03-09 16:21:34 -0800860#define PIC_16(yin, xin, p, xout, add) \
861( \
862 y = outy[(yin) * 8 + xin], \
863 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
864 ((CLAMP(y - cg + add) & 0xfc) << 3) | \
865 ((CLAMP(y + cb + add*2+1)) >> 3), \
866 p[(xout) * 2 + 0] = y & 0xff, \
867 p[(xout) * 2 + 1] = y >> 8 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000868)
869#else
870#ifdef CONFIG_PPC
Lee Leahye20a3192017-03-09 16:21:34 -0800871#define PIC_16(yin, xin, p, xout, add) \
872( \
873 y = outy[(yin) * 8 + xin], \
874 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 7) | \
875 ((CLAMP(y - cg + add*2+1) & 0xf8) << 2) | \
876 ((CLAMP(y + cb + add*2+1)) >> 3), \
877 p[(xout) * 2 + 0] = y >> 8, \
878 p[(xout) * 2 + 1] = y & 0xff \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000879)
880#else
Lee Leahye20a3192017-03-09 16:21:34 -0800881#define PIC_16(yin, xin, p, xout, add) \
882( \
883 y = outy[(yin) * 8 + xin], \
884 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
885 ((CLAMP(y - cg + add) & 0xfc) << 3) | \
886 ((CLAMP(y + cb + add*2+1)) >> 3), \
887 p[(xout) * 2 + 0] = y >> 8, \
888 p[(xout) * 2 + 1] = y & 0xff \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000889)
890#endif
891#endif
892
893#define PIC_32(yin, xin, p, xout) \
894( \
Lee Leahye20a3192017-03-09 16:21:34 -0800895 y = outy[(yin) * 8 + xin], \
896 STORECLAMP(p[(xout) * 4 + 0], y + cr), \
897 STORECLAMP(p[(xout) * 4 + 1], y - cg), \
898 STORECLAMP(p[(xout) * 4 + 2], y + cb), \
899 p[(xout) * 4 + 3] = 0 \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000900)
901
Lee Leahye20a3192017-03-09 16:21:34 -0800902#define PIC221111(xin) \
903( \
904 CBCRCG(0, xin), \
905 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
906 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
907 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
908 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000909)
910
Lee Leahye20a3192017-03-09 16:21:34 -0800911#define PIC221111_16(xin) \
912( \
913 CBCRCG(0, xin), \
914 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3), \
915 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0), \
916 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1), \
917 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000918)
919
Lee Leahye20a3192017-03-09 16:21:34 -0800920#define PIC221111_32(xin) \
921( \
922 CBCRCG(0, xin), \
923 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
924 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
925 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
926 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
Stefan Reinauerd650e992010-02-22 04:33:13 +0000927)
928
929static void col221111(int *out, unsigned char *pic, int width)
930{
931 int i, j, k;
932 unsigned char *pic0, *pic1;
933 int *outy, *outc;
934 int cr, cg, cb, y;
935
936 pic0 = pic;
937 pic1 = pic + width;
938 outy = out;
939 outc = out + 64 * 4;
940 for (i = 2; i > 0; i--) {
941 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800942 for (k = 0; k < 8; k++)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000943 PIC221111(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000944 outc += 8;
945 outy += 16;
946 pic0 += 2 * width;
947 pic1 += 2 * width;
948 }
949 outy += 64 * 2 - 16 * 4;
950 }
951}
952
953static void col221111_16(int *out, unsigned char *pic, int width)
954{
955 int i, j, k;
956 unsigned char *pic0, *pic1;
957 int *outy, *outc;
958 int cr, cg, cb, y;
959
960 pic0 = pic;
961 pic1 = pic + width;
962 outy = out;
963 outc = out + 64 * 4;
964 for (i = 2; i > 0; i--) {
965 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800966 for (k = 0; k < 8; k++)
Lee Leahye20a3192017-03-09 16:21:34 -0800967 PIC221111_16(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000968 outc += 8;
969 outy += 16;
970 pic0 += 2 * width;
971 pic1 += 2 * width;
972 }
973 outy += 64 * 2 - 16 * 4;
974 }
975}
976
977static void col221111_32(int *out, unsigned char *pic, int width)
978{
979 int i, j, k;
980 unsigned char *pic0, *pic1;
981 int *outy, *outc;
982 int cr, cg, cb, y;
983
984 pic0 = pic;
985 pic1 = pic + width;
986 outy = out;
987 outc = out + 64 * 4;
988 for (i = 2; i > 0; i--) {
989 for (j = 4; j > 0; j--) {
Lee Leahy2f919ec2017-03-08 17:37:06 -0800990 for (k = 0; k < 8; k++)
Stefan Reinauerd650e992010-02-22 04:33:13 +0000991 PIC221111_32(k);
Stefan Reinauerd650e992010-02-22 04:33:13 +0000992 outc += 8;
993 outy += 16;
994 pic0 += 2 * width;
995 pic1 += 2 * width;
996 }
997 outy += 64 * 2 - 16 * 4;
998 }
999}