blob: c2138edabe8a0b2002f6620b45a3ed426e6c624f [file] [log] [blame]
Kevin O'Connorafbed1b2010-06-28 07:34:53 -04001/*
2 * Copyright (C) 2001, Novell Inc.
Kevin O'Connorbbc47222010-07-30 13:07:08 -04003 * Copyright (C) 2010 Kevin O'Connor <kevin@koconnor.net>
Kevin O'Connorafbed1b2010-06-28 07:34:53 -04004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of Novell nor the names of the contributors may
18 * be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35/*
36 * a tiny jpeg decoder.
37 *
38 * written in August 2001 by Michael Schroeder <mls@suse.de>
39 *
40 */
41
42#define __LITTLE_ENDIAN
Kevin O'Connor9dea5902013-09-14 20:23:54 -040043#include "malloc.h"
Kevin O'Connorfa9c66a2013-09-14 19:10:40 -040044#include "string.h"
Kevin O'Connor07cf73b2013-09-15 00:31:17 -040045#include "util.h"
Kevin O'Connorafbed1b2010-06-28 07:34:53 -040046#define ISHIFT 11
47
48#define IFIX(a) ((int)((a) * (1 << ISHIFT) + .5))
49#define IMULT(a, b) (((a) * (b)) >> ISHIFT)
50#define ITOINT(a) ((a) >> ISHIFT)
51
52#ifndef __P
53# define __P(x) x
54#endif
55
56/* special markers */
57#define M_BADHUFF -1
58#define M_EOF 0x80
59
60struct in {
61 unsigned char *p;
62 unsigned int bits;
63 int left;
64 int marker;
65
66 int (*func) __P((void *));
67 void *data;
68};
69
70/*********************************/
71struct dec_hufftbl;
72struct enc_hufftbl;
73
74union hufftblp {
75 struct dec_hufftbl *dhuff;
76 struct enc_hufftbl *ehuff;
77};
78
79struct scan {
80 int dc; /* old dc value */
81
82 union hufftblp hudc;
83 union hufftblp huac;
84 int next; /* when to switch to next scan */
85
86 int cid; /* component id */
87 int hv; /* horiz/vert, copied from comp */
88 int tq; /* quant tbl, copied from comp */
89};
90
91/*********************************/
92
93#define DECBITS 10 /* seems to be the optimum */
94
95struct dec_hufftbl {
96 int maxcode[17];
97 int valptr[16];
98 unsigned char vals[256];
99 unsigned int llvals[1 << DECBITS];
100};
101
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400102static void decode_mcus __P((struct in *, int *, int, struct scan *, int *));
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400103static int dec_readmarker __P((struct in *));
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400104static void dec_makehuff __P((struct dec_hufftbl *, int *, unsigned char *));
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400105
106static void setinput __P((struct in *, unsigned char *));
107/*********************************/
108
109#undef PREC
110#define PREC int
111
112static void idctqtab __P((unsigned char *, PREC *));
113static void idct __P((int *, int *, PREC *, PREC, int));
114static void scaleidctqtab __P((PREC *, PREC));
115
116/*********************************/
117
118static void initcol __P((PREC[][64]));
119
120static void col221111 __P((int *, unsigned char *, int));
121static void col221111_16 __P((int *, unsigned char *, int));
122static void col221111_32 __P((int *, unsigned char *, int));
123
124/*********************************/
125
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400126#define ERR_NO_SOI 1
127#define ERR_NOT_8BIT 2
128#define ERR_HEIGHT_MISMATCH 3
129#define ERR_WIDTH_MISMATCH 4
130#define ERR_BAD_WIDTH_OR_HEIGHT 5
131#define ERR_TOO_MANY_COMPPS 6
132#define ERR_ILLEGAL_HV 7
133#define ERR_QUANT_TABLE_SELECTOR 8
134#define ERR_NOT_YCBCR_221111 9
135#define ERR_UNKNOWN_CID_IN_SCAN 10
136#define ERR_NOT_SEQUENTIAL_DCT 11
137#define ERR_WRONG_MARKER 12
138#define ERR_NO_EOI 13
139#define ERR_BAD_TABLES 14
140#define ERR_DEPTH_MISMATCH 15
141
142/*********************************/
143
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400144#define M_SOI 0xd8
145#define M_APP0 0xe0
146#define M_DQT 0xdb
147#define M_SOF0 0xc0
148#define M_DHT 0xc4
149#define M_DRI 0xdd
150#define M_SOS 0xda
151#define M_RST0 0xd0
152#define M_EOI 0xd9
153#define M_COM 0xfe
154
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400155struct comp {
156 int cid;
157 int hv;
158 int tq;
159};
160
161#define MAXCOMP 4
162struct jpginfo {
163 int nc; /* number of components */
164 int ns; /* number of scans */
165 int dri; /* restart interval */
166 int nm; /* mcus til next marker */
167 int rm; /* next restart marker */
168};
169
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400170struct jpeg_decdata {
171 int dcts[6 * 64 + 16];
172 int out[64 * 6];
173 int dquant[3][64];
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400174
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400175 unsigned char *datap;
176 struct jpginfo info;
177 struct comp comps[MAXCOMP];
178 struct scan dscans[MAXCOMP];
179 unsigned char quant[4][64];
180 struct dec_hufftbl dhuff[4];
181 struct in in;
Kevin O'Connorbbc47222010-07-30 13:07:08 -0400182
183 int height, width;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400184};
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400185
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400186static int getbyte(struct jpeg_decdata *jpeg)
187{
188 return *jpeg->datap++;
189}
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400190
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400191static int getword(struct jpeg_decdata *jpeg)
192{
193 int c1, c2;
194 c1 = *jpeg->datap++;
195 c2 = *jpeg->datap++;
196 return c1 << 8 | c2;
197}
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400198
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400199static int readtables(struct jpeg_decdata *jpeg, int till)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400200{
201 int m, l, i, j, lq, pq, tq;
202 int tc, th, tt;
203
204 for (;;) {
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400205 if (getbyte(jpeg) != 0xff)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400206 return -1;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400207 if ((m = getbyte(jpeg)) == till)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400208 break;
209
210 switch (m) {
211 case 0xc2:
212 return 0;
213
214 case M_DQT:
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400215 lq = getword(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400216 while (lq > 2) {
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400217 pq = getbyte(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400218 tq = pq & 15;
219 if (tq > 3)
220 return -1;
221 pq >>= 4;
222 if (pq != 0)
223 return -1;
224 for (i = 0; i < 64; i++)
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400225 jpeg->quant[tq][i] = getbyte(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400226 lq -= 64 + 1;
227 }
228 break;
229
230 case M_DHT:
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400231 l = getword(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400232 while (l > 2) {
233 int hufflen[16], k;
234 unsigned char huffvals[256];
235
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400236 tc = getbyte(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400237 th = tc & 15;
238 tc >>= 4;
239 tt = tc * 2 + th;
240 if (tc > 1 || th > 1)
241 return -1;
242 for (i = 0; i < 16; i++)
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400243 hufflen[i] = getbyte(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400244 l -= 1 + 16;
245 k = 0;
246 for (i = 0; i < 16; i++) {
247 for (j = 0; j < hufflen[i]; j++)
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400248 huffvals[k++] = getbyte(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400249 l -= hufflen[i];
250 }
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400251 dec_makehuff(jpeg->dhuff + tt, hufflen, huffvals);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400252 }
253 break;
254
255 case M_DRI:
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400256 l = getword(jpeg);
257 jpeg->info.dri = getword(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400258 break;
259
260 default:
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400261 l = getword(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400262 while (l-- > 2)
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400263 getbyte(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400264 break;
265 }
266 }
267 return 0;
268}
269
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400270static void dec_initscans(struct jpeg_decdata *jpeg)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400271{
272 int i;
273
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400274 jpeg->info.nm = jpeg->info.dri + 1;
275 jpeg->info.rm = M_RST0;
276 for (i = 0; i < jpeg->info.ns; i++)
277 jpeg->dscans[i].dc = 0;
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400278}
279
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400280static int dec_checkmarker(struct jpeg_decdata *jpeg)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400281{
282 int i;
283
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400284 if (dec_readmarker(&jpeg->in) != jpeg->info.rm)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400285 return -1;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400286 jpeg->info.nm = jpeg->info.dri;
287 jpeg->info.rm = (jpeg->info.rm + 1) & ~0x08;
288 for (i = 0; i < jpeg->info.ns; i++)
289 jpeg->dscans[i].dc = 0;
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400290 return 0;
291}
292
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400293struct jpeg_decdata *jpeg_alloc(void)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400294{
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400295 struct jpeg_decdata *jpeg = malloc_tmphigh(sizeof(*jpeg));
296 return jpeg;
297}
298
Kevin O'Connorbbc47222010-07-30 13:07:08 -0400299int jpeg_decode(struct jpeg_decdata *jpeg, unsigned char *buf)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400300{
301 int i, j, m, tac, tdc;
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400302
Kevin O'Connorbbc47222010-07-30 13:07:08 -0400303 if (!jpeg || !buf)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400304 return -1;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400305 jpeg->datap = buf;
306 if (getbyte(jpeg) != 0xff)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400307 return ERR_NO_SOI;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400308 if (getbyte(jpeg) != M_SOI)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400309 return ERR_NO_SOI;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400310 if (readtables(jpeg, M_SOF0))
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400311 return ERR_BAD_TABLES;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400312 getword(jpeg);
313 i = getbyte(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400314 if (i != 8)
315 return ERR_NOT_8BIT;
Kevin O'Connorbbc47222010-07-30 13:07:08 -0400316 jpeg->height = getword(jpeg);
317 jpeg->width = getword(jpeg);
318 if ((jpeg->height & 15) || (jpeg->width & 15))
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400319 return ERR_BAD_WIDTH_OR_HEIGHT;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400320 jpeg->info.nc = getbyte(jpeg);
321 if (jpeg->info.nc > MAXCOMP)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400322 return ERR_TOO_MANY_COMPPS;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400323 for (i = 0; i < jpeg->info.nc; i++) {
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400324 int h, v;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400325 jpeg->comps[i].cid = getbyte(jpeg);
326 jpeg->comps[i].hv = getbyte(jpeg);
327 v = jpeg->comps[i].hv & 15;
328 h = jpeg->comps[i].hv >> 4;
329 jpeg->comps[i].tq = getbyte(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400330 if (h > 3 || v > 3)
331 return ERR_ILLEGAL_HV;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400332 if (jpeg->comps[i].tq > 3)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400333 return ERR_QUANT_TABLE_SELECTOR;
334 }
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400335 if (readtables(jpeg, M_SOS))
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400336 return ERR_BAD_TABLES;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400337 getword(jpeg);
338 jpeg->info.ns = getbyte(jpeg);
339 if (jpeg->info.ns != 3)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400340 return ERR_NOT_YCBCR_221111;
341 for (i = 0; i < 3; i++) {
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400342 jpeg->dscans[i].cid = getbyte(jpeg);
343 tdc = getbyte(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400344 tac = tdc & 15;
345 tdc >>= 4;
346 if (tdc > 1 || tac > 1)
347 return ERR_QUANT_TABLE_SELECTOR;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400348 for (j = 0; j < jpeg->info.nc; j++)
349 if (jpeg->comps[j].cid == jpeg->dscans[i].cid)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400350 break;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400351 if (j == jpeg->info.nc)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400352 return ERR_UNKNOWN_CID_IN_SCAN;
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400353 jpeg->dscans[i].hv = jpeg->comps[j].hv;
354 jpeg->dscans[i].tq = jpeg->comps[j].tq;
355 jpeg->dscans[i].hudc.dhuff = &jpeg->dhuff[tdc];
356 jpeg->dscans[i].huac.dhuff = &jpeg->dhuff[2 + tac];
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400357 }
358
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400359 i = getbyte(jpeg);
360 j = getbyte(jpeg);
361 m = getbyte(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400362
363 if (i != 0 || j != 63 || m != 0)
364 return ERR_NOT_SEQUENTIAL_DCT;
365
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400366 if (jpeg->dscans[0].cid != 1 || jpeg->dscans[1].cid != 2
367 || jpeg->dscans[2].cid != 3)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400368 return ERR_NOT_YCBCR_221111;
369
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400370 if (jpeg->dscans[0].hv != 0x22 || jpeg->dscans[1].hv != 0x11
371 || jpeg->dscans[2].hv != 0x11)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400372 return ERR_NOT_YCBCR_221111;
373
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400374 idctqtab(jpeg->quant[jpeg->dscans[0].tq], jpeg->dquant[0]);
375 idctqtab(jpeg->quant[jpeg->dscans[1].tq], jpeg->dquant[1]);
376 idctqtab(jpeg->quant[jpeg->dscans[2].tq], jpeg->dquant[2]);
377 initcol(jpeg->dquant);
378 setinput(&jpeg->in, jpeg->datap);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400379
380#if 0
381 /* landing zone */
382 img[len] = 0;
383 img[len + 1] = 0xff;
384 img[len + 2] = M_EOF;
385#endif
386
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400387 dec_initscans(jpeg);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400388
Kevin O'Connorbbc47222010-07-30 13:07:08 -0400389 return 0;
390}
391
392void jpeg_get_size(struct jpeg_decdata *jpeg, int *width, int *height)
393{
394 *width = jpeg->width;
395 *height = jpeg->height;
396}
397
Wayne Xia8031efa2011-07-08 11:03:16 +0800398int jpeg_show(struct jpeg_decdata *jpeg, unsigned char *pic, int width
399 , int height, int depth, int bytes_per_line_dest)
Kevin O'Connorbbc47222010-07-30 13:07:08 -0400400{
Wayne Xia8031efa2011-07-08 11:03:16 +0800401 int m, mcusx, mcusy, mx, my, mloffset, jpgbpl;
Kevin O'Connorbbc47222010-07-30 13:07:08 -0400402 int max[6];
403
404 if (jpeg->height != height)
405 return ERR_HEIGHT_MISMATCH;
406 if (jpeg->width != width)
407 return ERR_WIDTH_MISMATCH;
408
Wayne Xia8031efa2011-07-08 11:03:16 +0800409 jpgbpl = width * depth / 8;
410 mloffset = bytes_per_line_dest > jpgbpl ? bytes_per_line_dest : jpgbpl;
411
Kevin O'Connorbbc47222010-07-30 13:07:08 -0400412 mcusx = jpeg->width >> 4;
413 mcusy = jpeg->height >> 4;
414
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400415 jpeg->dscans[0].next = 6 - 4;
416 jpeg->dscans[1].next = 6 - 4 - 1;
417 jpeg->dscans[2].next = 6 - 4 - 1 - 1; /* 411 encoding */
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400418 for (my = 0; my < mcusy; my++) {
419 for (mx = 0; mx < mcusx; mx++) {
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400420 if (jpeg->info.dri && !--jpeg->info.nm)
421 if (dec_checkmarker(jpeg))
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400422 return ERR_WRONG_MARKER;
423
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400424 decode_mcus(&jpeg->in, jpeg->dcts, 6, jpeg->dscans, max);
425 idct(jpeg->dcts, jpeg->out, jpeg->dquant[0],
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400426 IFIX(128.5), max[0]);
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400427 idct(jpeg->dcts + 64, jpeg->out + 64, jpeg->dquant[0],
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400428 IFIX(128.5), max[1]);
Kevin O'Connor06644f42010-08-28 14:58:15 -0400429 idct(jpeg->dcts + 128, jpeg->out + 128, jpeg->dquant[0],
430 IFIX(128.5), max[2]);
431 idct(jpeg->dcts + 192, jpeg->out + 192, jpeg->dquant[0],
432 IFIX(128.5), max[3]);
433 idct(jpeg->dcts + 256, jpeg->out + 256, jpeg->dquant[1],
434 IFIX(0.5), max[4]);
435 idct(jpeg->dcts + 320, jpeg->out + 320, jpeg->dquant[2],
436 IFIX(0.5), max[5]);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400437
438 switch (depth) {
439 case 32:
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400440 col221111_32(jpeg->out,
Wayne Xia8031efa2011-07-08 11:03:16 +0800441 pic + (my * 16 * mloffset + mx * 16 * 4),
442 mloffset);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400443 break;
444 case 24:
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400445 col221111(jpeg->out,
Wayne Xia8031efa2011-07-08 11:03:16 +0800446 pic + (my * 16 * mloffset + mx * 16 * 3),
447 mloffset);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400448 break;
449 case 16:
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400450 col221111_16(jpeg->out,
Wayne Xia8031efa2011-07-08 11:03:16 +0800451 pic + (my * 16 * mloffset + mx * 16 * 2),
452 mloffset);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400453 break;
454 default:
455 return ERR_DEPTH_MISMATCH;
456 break;
457 }
458 }
459 }
460
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400461 m = dec_readmarker(&jpeg->in);
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400462 if (m != M_EOI)
463 return ERR_NO_EOI;
464
465 return 0;
466}
467
468/****************************************************************/
469/************** huffman decoder ***************/
470/****************************************************************/
471
472static int fillbits __P((struct in *, int, unsigned int));
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400473static int dec_rec2 __P((struct in *, struct dec_hufftbl *, int *, int, int));
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400474
475static void setinput(struct in *in, unsigned char *p)
476{
477 in->p = p;
478 in->left = 0;
479 in->bits = 0;
480 in->marker = 0;
481}
482
483static int fillbits(struct in *in, int le, unsigned int bi)
484{
485 int b, m;
486
487 if (in->marker) {
488 if (le <= 16)
489 in->bits = bi << 16, le += 16;
490 return le;
491 }
492 while (le <= 24) {
493 b = *in->p++;
494 if (b == 0xff && (m = *in->p++) != 0) {
495 if (m == M_EOF) {
496 if (in->func && (m = in->func(in->data)) == 0)
497 continue;
498 }
499 in->marker = m;
500 if (le <= 16)
501 bi = bi << 16, le += 16;
502 break;
503 }
504 bi = bi << 8 | b;
505 le += 8;
506 }
507 in->bits = bi; /* tmp... 2 return values needed */
508 return le;
509}
510
511static int dec_readmarker(struct in *in)
512{
513 int m;
514
515 in->left = fillbits(in, in->left, in->bits);
516 if ((m = in->marker) == 0)
517 return 0;
518 in->left = 0;
519 in->marker = 0;
520 return m;
521}
522
523#define LEBI_DCL int le, bi
524#define LEBI_GET(in) (le = in->left, bi = in->bits)
525#define LEBI_PUT(in) (in->left = le, in->bits = bi)
526
527#define GETBITS(in, n) ( \
528 (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0), \
529 (le -= (n)), \
530 bi >> le & ((1 << (n)) - 1) \
531)
532
533#define UNGETBITS(in, n) ( \
534 le += (n) \
535)
536
537
538static int dec_rec2(struct in *in, struct dec_hufftbl *hu, int *runp,
539 int c, int i)
540{
541 LEBI_DCL;
542
543 LEBI_GET(in);
544 if (i) {
545 UNGETBITS(in, i & 127);
546 *runp = i >> 8 & 15;
547 i >>= 16;
548 } else {
549 for (i = DECBITS;
550 (c = ((c << 1) | GETBITS(in, 1))) >= (hu->maxcode[i]); i++);
551 if (i >= 16) {
552 in->marker = M_BADHUFF;
553 return 0;
554 }
555 i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];
556 *runp = i >> 4;
557 i &= 15;
558 }
559 if (i == 0) { /* sigh, 0xf0 is 11 bit */
560 LEBI_PUT(in);
561 return 0;
562 }
563 /* receive part */
564 c = GETBITS(in, i);
565 if (c < (1 << (i - 1)))
566 c += (-1 << i) + 1;
567 LEBI_PUT(in);
568 return c;
569}
570
571#define DEC_REC(in, hu, r, i) ( \
572 r = GETBITS(in, DECBITS), \
573 i = hu->llvals[r], \
574 i & 128 ? \
575 ( \
576 UNGETBITS(in, i & 127), \
577 r = i >> 8 & 15, \
578 i >> 16 \
579 ) \
580 : \
581 ( \
582 LEBI_PUT(in), \
583 i = dec_rec2(in, hu, &r, r, i), \
584 LEBI_GET(in), \
585 i \
586 ) \
587)
588
589static void decode_mcus(struct in *in, int *dct, int n, struct scan *sc,
590 int *maxp)
591{
592 struct dec_hufftbl *hu;
593 int i, r, t;
594 LEBI_DCL;
595
596 memset(dct, 0, n * 64 * sizeof(*dct));
597 LEBI_GET(in);
598 while (n-- > 0) {
599 hu = sc->hudc.dhuff;
600 *dct++ = (sc->dc += DEC_REC(in, hu, r, t));
601
602 hu = sc->huac.dhuff;
603 i = 63;
604 while (i > 0) {
605 t = DEC_REC(in, hu, r, t);
606 if (t == 0 && r == 0) {
607 dct += i;
608 break;
609 }
610 dct += r;
611 *dct++ = t;
612 i -= r + 1;
613 }
614 *maxp++ = 64 - i;
615 if (n == sc->next)
616 sc++;
617 }
618 LEBI_PUT(in);
619}
620
621static void dec_makehuff(struct dec_hufftbl *hu, int *hufflen,
622 unsigned char *huffvals)
623{
624 int code, k, i, j, d, x, c, v;
625 for (i = 0; i < (1 << DECBITS); i++)
626 hu->llvals[i] = 0;
627
628 /*
629 * llvals layout:
630 *
631 * value v already known, run r, backup u bits:
632 * vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu
633 * value unknown, size b bits, run r, backup u bits:
634 * 000000000000bbbb 0000 rrrr 0 uuuuuuu
635 * value and size unknown:
636 * 0000000000000000 0000 0000 0 0000000
637 */
638
639 code = 0;
640 k = 0;
641 for (i = 0; i < 16; i++, code <<= 1) { /* sizes */
642 hu->valptr[i] = k;
643 for (j = 0; j < hufflen[i]; j++) {
644 hu->vals[k] = *huffvals++;
645 if (i < DECBITS) {
646 c = code << (DECBITS - 1 - i);
647 v = hu->vals[k] & 0x0f; /* size */
648 for (d = 1 << (DECBITS - 1 - i); --d >= 0;) {
649 if (v + i < DECBITS) { /* both fit in table */
650 x = d >> (DECBITS - 1 - v - i);
651 if (v && x < (1 << (v - 1)))
652 x += (-1 << v) + 1;
653 x = x << 16 | (hu->vals[k] & 0xf0) << 4 |
654 (DECBITS - (i + 1 + v)) | 128;
655 } else
656 x = v << 16 | (hu->vals[k] & 0xf0) << 4 |
657 (DECBITS - (i + 1));
658 hu->llvals[c | d] = x;
659 }
660 }
661 code++;
662 k++;
663 }
664 hu->maxcode[i] = code;
665 }
666 hu->maxcode[16] = 0x20000; /* always terminate decode */
667}
668
669/****************************************************************/
670/************** idct ***************/
671/****************************************************************/
672
673#define ONE ((PREC)IFIX(1.))
674#define S2 ((PREC)IFIX(0.382683432))
675#define C2 ((PREC)IFIX(0.923879532))
676#define C4 ((PREC)IFIX(0.707106781))
677
678#define S22 ((PREC)IFIX(2 * 0.382683432))
679#define C22 ((PREC)IFIX(2 * 0.923879532))
680#define IC4 ((PREC)IFIX(1 / 0.707106781))
681
682#define C3IC1 ((PREC)IFIX(0.847759065)) /* c3/c1 */
683#define C5IC1 ((PREC)IFIX(0.566454497)) /* c5/c1 */
684#define C7IC1 ((PREC)IFIX(0.198912367)) /* c7/c1 */
685
686#define XPP(a,b) (t = a + b, b = a - b, a = t)
687#define XMP(a,b) (t = a - b, b = a + b, a = t)
688#define XPM(a,b) (t = a + b, b = b - a, a = t)
689
690#define ROT(a,b,s,c) ( t = IMULT(a + b, s), \
691 a = IMULT(a, c - s) + t, \
692 b = IMULT(b, c + s) - t)
693
694#define IDCT \
695( \
696 XPP(t0, t1), \
697 XMP(t2, t3), \
698 t2 = IMULT(t2, IC4) - t3, \
699 XPP(t0, t3), \
700 XPP(t1, t2), \
701 XMP(t4, t7), \
702 XPP(t5, t6), \
703 XMP(t5, t7), \
704 t5 = IMULT(t5, IC4), \
705 ROT(t4, t6, S22, C22), \
706 t6 -= t7, \
707 t5 -= t6, \
708 t4 -= t5, \
709 XPP(t0, t7), \
710 XPP(t1, t6), \
711 XPP(t2, t5), \
712 XPP(t3, t4) \
713)
714
715static unsigned char zig2[64] = {
716 0, 2, 3, 9, 10, 20, 21, 35,
717 14, 16, 25, 31, 39, 46, 50, 57,
718 5, 7, 12, 18, 23, 33, 37, 48,
719 27, 29, 41, 44, 52, 55, 59, 62,
720 15, 26, 30, 40, 45, 51, 56, 58,
721 1, 4, 8, 11, 19, 22, 34, 36,
722 28, 42, 43, 53, 54, 60, 61, 63,
723 6, 13, 17, 24, 32, 38, 47, 49
724};
725
Kevin O'Connor2976dd42010-07-30 12:27:14 -0400726static void idct(int *in, int *out, PREC * quant, PREC off, int max)
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400727{
728 PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
729 PREC tmp[64], *tmpp;
730 int i, j;
731 unsigned char *zig2p;
732
733 t0 = off;
734 if (max == 1) {
735 t0 += in[0] * quant[0];
736 for (i = 0; i < 64; i++)
737 out[i] = ITOINT(t0);
738 return;
739 }
740 zig2p = zig2;
741 tmpp = tmp;
742 for (i = 0; i < 8; i++) {
743 j = *zig2p++;
744 t0 += in[j] * quant[j];
745 j = *zig2p++;
746 t5 = in[j] * quant[j];
747 j = *zig2p++;
748 t2 = in[j] * quant[j];
749 j = *zig2p++;
750 t7 = in[j] * quant[j];
751 j = *zig2p++;
752 t1 = in[j] * quant[j];
753 j = *zig2p++;
754 t4 = in[j] * quant[j];
755 j = *zig2p++;
756 t3 = in[j] * quant[j];
757 j = *zig2p++;
758 t6 = in[j] * quant[j];
759 IDCT;
760 tmpp[0 * 8] = t0;
761 tmpp[1 * 8] = t1;
762 tmpp[2 * 8] = t2;
763 tmpp[3 * 8] = t3;
764 tmpp[4 * 8] = t4;
765 tmpp[5 * 8] = t5;
766 tmpp[6 * 8] = t6;
767 tmpp[7 * 8] = t7;
768 tmpp++;
769 t0 = 0;
770 }
771 for (i = 0; i < 8; i++) {
772 t0 = tmp[8 * i + 0];
773 t1 = tmp[8 * i + 1];
774 t2 = tmp[8 * i + 2];
775 t3 = tmp[8 * i + 3];
776 t4 = tmp[8 * i + 4];
777 t5 = tmp[8 * i + 5];
778 t6 = tmp[8 * i + 6];
779 t7 = tmp[8 * i + 7];
780 IDCT;
781 out[8 * i + 0] = ITOINT(t0);
782 out[8 * i + 1] = ITOINT(t1);
783 out[8 * i + 2] = ITOINT(t2);
784 out[8 * i + 3] = ITOINT(t3);
785 out[8 * i + 4] = ITOINT(t4);
786 out[8 * i + 5] = ITOINT(t5);
787 out[8 * i + 6] = ITOINT(t6);
788 out[8 * i + 7] = ITOINT(t7);
789 }
790}
791
792static unsigned char zig[64] = {
793 0, 1, 5, 6, 14, 15, 27, 28,
794 2, 4, 7, 13, 16, 26, 29, 42,
795 3, 8, 12, 17, 25, 30, 41, 43,
796 9, 11, 18, 24, 31, 40, 44, 53,
797 10, 19, 23, 32, 39, 45, 52, 54,
798 20, 22, 33, 38, 46, 51, 55, 60,
799 21, 34, 37, 47, 50, 56, 59, 61,
800 35, 36, 48, 49, 57, 58, 62, 63
801};
802
803static PREC aaidct[8] = {
804 IFIX(0.3535533906), IFIX(0.4903926402),
805 IFIX(0.4619397663), IFIX(0.4157348062),
806 IFIX(0.3535533906), IFIX(0.2777851165),
807 IFIX(0.1913417162), IFIX(0.0975451610)
808};
809
810
811static void idctqtab(unsigned char *qin, PREC * qout)
812{
813 int i, j;
814
815 for (i = 0; i < 8; i++)
816 for (j = 0; j < 8; j++)
817 qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] *
818 IMULT(aaidct[i], aaidct[j]);
819}
820
821static void scaleidctqtab(PREC * q, PREC sc)
822{
823 int i;
824
825 for (i = 0; i < 64; i++)
826 q[i] = IMULT(q[i], sc);
827}
828
829/****************************************************************/
830/************** color decoder ***************/
831/****************************************************************/
832
833#define ROUND
834
835/*
836 * YCbCr Color transformation:
837 *
838 * y:0..255 Cb:-128..127 Cr:-128..127
839 *
840 * R = Y + 1.40200 * Cr
841 * G = Y - 0.34414 * Cb - 0.71414 * Cr
842 * B = Y + 1.77200 * Cb
843 *
844 * =>
845 * Cr *= 1.40200;
846 * Cb *= 1.77200;
847 * Cg = 0.19421 * Cb + .50937 * Cr;
848 * R = Y + Cr;
849 * G = Y - Cg;
850 * B = Y + Cb;
851 *
852 * =>
853 * Cg = (50 * Cb + 130 * Cr + 128) >> 8;
854 */
855
856static void initcol(PREC q[][64])
857{
858 scaleidctqtab(q[1], IFIX(1.77200));
859 scaleidctqtab(q[2], IFIX(1.40200));
860}
861
862/* This is optimized for the stupid sun SUNWspro compiler. */
863#define STORECLAMP(a,x) \
864( \
865 (a) = (x), \
866 (unsigned int)(x) >= 256 ? \
867 ((a) = (x) < 0 ? 0 : 255) \
868 : \
869 0 \
870)
871
872#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x))
873
874#ifdef ROUND
875
876#define CBCRCG(yin, xin) \
877( \
878 cb = outc[0 +yin*8+xin], \
879 cr = outc[64+yin*8+xin], \
880 cg = (50 * cb + 130 * cr + 128) >> 8 \
881)
882
883#else
884
885#define CBCRCG(yin, xin) \
886( \
887 cb = outc[0 +yin*8+xin], \
888 cr = outc[64+yin*8+xin], \
889 cg = (3 * cb + 8 * cr) >> 4 \
890)
891
892#endif
893
Wayne Xia8031efa2011-07-08 11:03:16 +0800894#ifdef __LITTLE_ENDIAN
895#define PIC(yin, xin, p, xout) \
896( \
897 y = outy[(yin) * 8 + xin], \
898 STORECLAMP(p[(xout) * 3 + 2], y + cr), \
899 STORECLAMP(p[(xout) * 3 + 1], y - cg), \
900 STORECLAMP(p[(xout) * 3 + 0], y + cb) \
901)
902#else
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400903#define PIC(yin, xin, p, xout) \
904( \
905 y = outy[(yin) * 8 + xin], \
906 STORECLAMP(p[(xout) * 3 + 0], y + cr), \
907 STORECLAMP(p[(xout) * 3 + 1], y - cg), \
908 STORECLAMP(p[(xout) * 3 + 2], y + cb) \
909)
Wayne Xia8031efa2011-07-08 11:03:16 +0800910#endif
Kevin O'Connorafbed1b2010-06-28 07:34:53 -0400911
912#ifdef __LITTLE_ENDIAN
913#define PIC_16(yin, xin, p, xout, add) \
914( \
915 y = outy[(yin) * 8 + xin], \
916 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
917 ((CLAMP(y - cg + add ) & 0xfc) << 3) | \
918 ((CLAMP(y + cb + add*2+1) ) >> 3), \
919 p[(xout) * 2 + 0] = y & 0xff, \
920 p[(xout) * 2 + 1] = y >> 8 \
921)
922#else
923#ifdef CONFIG_PPC
924#define PIC_16(yin, xin, p, xout, add) \
925( \
926 y = outy[(yin) * 8 + xin], \
927 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 7) | \
928 ((CLAMP(y - cg + add*2+1) & 0xf8) << 2) | \
929 ((CLAMP(y + cb + add*2+1) ) >> 3), \
930 p[(xout) * 2 + 0] = y >> 8, \
931 p[(xout) * 2 + 1] = y & 0xff \
932)
933#else
934#define PIC_16(yin, xin, p, xout, add) \
935( \
936 y = outy[(yin) * 8 + xin], \
937 y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
938 ((CLAMP(y - cg + add ) & 0xfc) << 3) | \
939 ((CLAMP(y + cb + add*2+1) ) >> 3), \
940 p[(xout) * 2 + 0] = y >> 8, \
941 p[(xout) * 2 + 1] = y & 0xff \
942)
943#endif
944#endif
945
946#define PIC_32(yin, xin, p, xout) \
947( \
948 y = outy[(yin) * 8 + xin], \
949 STORECLAMP(p[(xout) * 4 + 0], y + cr), \
950 STORECLAMP(p[(xout) * 4 + 1], y - cg), \
951 STORECLAMP(p[(xout) * 4 + 2], y + cb), \
952 p[(xout) * 4 + 3] = 0 \
953)
954
955#define PIC221111(xin) \
956( \
957 CBCRCG(0, xin), \
958 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
959 PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
960 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
961 PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
962)
963
964#define PIC221111_16(xin) \
965( \
966 CBCRCG(0, xin), \
967 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3), \
968 PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0), \
969 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1), \
970 PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2) \
971)
972
973#define PIC221111_32(xin) \
974( \
975 CBCRCG(0, xin), \
976 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
977 PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
978 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
979 PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
980)
981
982static void col221111(int *out, unsigned char *pic, int width)
983{
984 int i, j, k;
985 unsigned char *pic0, *pic1;
986 int *outy, *outc;
987 int cr, cg, cb, y;
988
989 pic0 = pic;
990 pic1 = pic + width;
991 outy = out;
992 outc = out + 64 * 4;
993 for (i = 2; i > 0; i--) {
994 for (j = 4; j > 0; j--) {
995 for (k = 0; k < 8; k++) {
996 PIC221111(k);
997 }
998 outc += 8;
999 outy += 16;
1000 pic0 += 2 * width;
1001 pic1 += 2 * width;
1002 }
1003 outy += 64 * 2 - 16 * 4;
1004 }
1005}
1006
1007static void col221111_16(int *out, unsigned char *pic, int width)
1008{
1009 int i, j, k;
1010 unsigned char *pic0, *pic1;
1011 int *outy, *outc;
1012 int cr, cg, cb, y;
1013
1014 pic0 = pic;
1015 pic1 = pic + width;
1016 outy = out;
1017 outc = out + 64 * 4;
1018 for (i = 2; i > 0; i--) {
1019 for (j = 4; j > 0; j--) {
1020 for (k = 0; k < 8; k++) {
1021 PIC221111_16(k);
1022 }
1023 outc += 8;
1024 outy += 16;
1025 pic0 += 2 * width;
1026 pic1 += 2 * width;
1027 }
1028 outy += 64 * 2 - 16 * 4;
1029 }
1030}
1031
1032static void col221111_32(int *out, unsigned char *pic, int width)
1033{
1034 int i, j, k;
1035 unsigned char *pic0, *pic1;
1036 int *outy, *outc;
1037 int cr, cg, cb, y;
1038
1039 pic0 = pic;
1040 pic1 = pic + width;
1041 outy = out;
1042 outc = out + 64 * 4;
1043 for (i = 2; i > 0; i--) {
1044 for (j = 4; j > 0; j--) {
1045 for (k = 0; k < 8; k++) {
1046 PIC221111_32(k);
1047 }
1048 outc += 8;
1049 outy += 16;
1050 pic0 += 2 * width;
1051 pic1 += 2 * width;
1052 }
1053 outy += 64 * 2 - 16 * 4;
1054 }
1055}