Patch #4936 from Jonathan Gordon with a small change by me. slideshow support for...
[kugel-rb.git] / apps / plugins / jpeg.c
blobc192eb632cce34d580089eadd39851de31a63894
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * JPEG image viewer
11 * (This is a real mess if it has to be coded in one single C file)
13 * File scrolling addition (C) 2005 Alexander Spyridakis
14 * Copyright (C) 2004 J�g Hohensohn aka [IDC]Dragon
15 * Grayscale framework (C) 2004 Jens Arnold
16 * Heavily borrowed from the IJG implementation (C) Thomas G. Lane
17 * Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
19 * All files in this archive are subject to the GNU General Public License.
20 * See the file COPYING in the source tree root for full license agreement.
22 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
23 * KIND, either express or implied.
25 ****************************************************************************/
27 #include "plugin.h"
28 #include "playback_control.h"
30 #ifdef HAVE_LCD_BITMAP
31 #include "gray.h"
32 #include "xlcd.h"
34 PLUGIN_HEADER
36 /* variable button definitions */
37 #if CONFIG_KEYPAD == RECORDER_PAD
38 #define JPEG_ZOOM_IN BUTTON_PLAY
39 #define JPEG_ZOOM_OUT BUTTON_ON
40 #define JPEG_UP BUTTON_UP
41 #define JPEG_DOWN BUTTON_DOWN
42 #define JPEG_LEFT BUTTON_LEFT
43 #define JPEG_RIGHT BUTTON_RIGHT
44 #define JPEG_NEXT BUTTON_F3
45 #define JPEG_PREVIOUS BUTTON_F2
46 #define JPEG_MENU BUTTON_OFF
49 #elif CONFIG_KEYPAD == ONDIO_PAD
50 #define JPEG_ZOOM_PRE BUTTON_MENU
51 #define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
52 #define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
53 #define JPEG_UP BUTTON_UP
54 #define JPEG_DOWN BUTTON_DOWN
55 #define JPEG_LEFT BUTTON_LEFT
56 #define JPEG_RIGHT BUTTON_RIGHT
57 #define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
58 #define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
59 #define JPEG_MENU BUTTON_OFF
61 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
62 (CONFIG_KEYPAD == IRIVER_H300_PAD)
63 #define JPEG_ZOOM_IN BUTTON_SELECT
64 #define JPEG_ZOOM_OUT BUTTON_MODE
65 #define JPEG_UP BUTTON_UP
66 #define JPEG_DOWN BUTTON_DOWN
67 #define JPEG_LEFT BUTTON_LEFT
68 #define JPEG_RIGHT BUTTON_RIGHT
69 #if (CONFIG_KEYPAD == IRIVER_H100_PAD)
70 #define JPEG_NEXT BUTTON_ON
71 #define JPEG_PREVIOUS BUTTON_REC
72 #else
73 #define JPEG_NEXT BUTTON_REC
74 #define JPEG_PREVIOUS BUTTON_ON
75 #endif
76 #define JPEG_MENU BUTTON_OFF
78 #elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
79 #define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
80 #define JPEG_ZOOM_OUT BUTTON_SCROLL_BACK
81 #define JPEG_UP BUTTON_MENU
82 #define JPEG_DOWN BUTTON_PLAY
83 #define JPEG_LEFT BUTTON_LEFT
84 #define JPEG_RIGHT BUTTON_RIGHT
85 #define JPEG_MENU (BUTTON_SELECT | BUTTON_MENU)
86 #define JPEG_NEXT_PRE (BUTTON_SELECT | BUTTON_RIGHT)
87 #define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT | BUTTON_REL)
88 #define JPEG_TOGGLE_SLIDESHOW (BUTTON_SELECT | BUTTON_RIGHT | BUTTON_REPEAT)
89 #define JPEG_PREVIOUS (BUTTON_SELECT |BUTTON_LEFT)
91 #elif CONFIG_KEYPAD == IAUDIO_X5_PAD
92 #define JPEG_ZOOM_IN_PRE BUTTON_SELECT
93 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
94 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
95 #define JPEG_UP BUTTON_UP
96 #define JPEG_DOWN BUTTON_DOWN
97 #define JPEG_LEFT BUTTON_LEFT
98 #define JPEG_RIGHT BUTTON_RIGHT
99 #define JPEG_MENU BUTTON_POWER
100 #define JPEG_NEXT_PRE BUTTON_PLAY
101 #define JPEG_NEXT (BUTTON_PLAY|BUTTON_REL)
102 #define JPEG_TOGGLE_SLIDESHOW (BUTTON_PLAY|BUTTON_REPEAT)
103 #define JPEG_PREVIOUS BUTTON_REC
105 #elif CONFIG_KEYPAD == GIGABEAT_PAD
106 #define JPEG_ZOOM_IN_PRE BUTTON_MENU
107 #define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
108 #define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_REPEAT)
109 #define JPEG_UP BUTTON_UP
110 #define JPEG_DOWN BUTTON_DOWN
111 #define JPEG_LEFT BUTTON_LEFT
112 #define JPEG_RIGHT BUTTON_RIGHT
113 #define JPEG_MENU BUTTON_A
114 #define JPEG_NEXT (BUTTON_POWER | BUTTON_RIGHT)
115 #define JPEG_PREVIOUS (BUTTON_POWER | BUTTON_LEFT)
117 #endif
119 /* different graphics libraries */
120 #if LCD_DEPTH < 8
121 #define USEGSLIB
122 #define MYLCD(fn) gray_ub_ ## fn
123 #define MYLCD_UPDATE()
124 #define MYXLCD(fn) gray_ub_ ## fn
125 #else
126 #define MYLCD(fn) rb->lcd_ ## fn
127 #define MYLCD_UPDATE() rb->lcd_update();
128 #define MYXLCD(fn) xlcd_ ## fn
129 #endif
131 #define MAX_X_SIZE LCD_WIDTH*8
133 /* Min memory allowing us to use the plugin buffer
134 * and thus not stopping the music
135 * *Very* rough estimation:
136 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
137 * + 20k code size = 60 000
138 * + 50k min for jpeg = 120 000
140 #define MIN_MEM 120000
142 /* Headings */
143 #define DIR_PREV 1
144 #define DIR_NEXT -1
145 #define DIR_NONE 0
147 #define PLUGIN_OTHER 10 /* State code for output with return. */
149 /******************************* Globals ***********************************/
151 static struct plugin_api* rb;
153 /* for portability of below JPEG code */
154 #define MEMSET(p,v,c) rb->memset(p,v,c)
155 #define MEMCPY(d,s,c) rb->memcpy(d,s,c)
156 #define INLINE static inline
157 #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
159 static int slideshow_enabled = false;
160 static int button_timeout = HZ*5;
162 /**************** begin JPEG code ********************/
164 INLINE unsigned range_limit(int value)
166 #if CONFIG_CPU == SH7034
167 unsigned tmp;
168 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
169 "mov #-128,%[t] \n"
170 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
171 "extu.b %[v],%[t] \n"
172 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
173 "bt 1f \n" /* yes: no overflow */
174 "cmp/pz %[v] \n" /* overflow: positive? */
175 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
176 "1: \n"
177 : /* outputs */
178 [v]"+r"(value),
179 [t]"=&r"(tmp)
181 return value;
182 #elif defined(CPU_COLDFIRE)
183 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
184 "add.l #128,%[v] \n" /* value += 128; */
185 "cmp.l #255,%[v] \n" /* overflow? */
186 "bls.b 1f \n" /* no: return value */
187 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
188 "1: \n"
189 : /* outputs */
190 [v]"+r"(value)
192 return value;
193 #elif defined(CPU_ARM)
194 asm (
195 "adds %[v], %[v], #128\n" /* value += 128 */
196 "movmi %[v], #0 \n" /* clip to 0 if negative result */
197 "cmp %[v], #255 \n" /* did we exceed 255? */
198 "movgt %[v], #255 \n" /* yes, clip to limit */
200 [v]"+r"(value)
202 return value;
203 #else
204 value += 128;
206 if ((unsigned)value <= 255)
207 return value;
209 if (value < 0)
210 return 0;
212 return 255;
213 #endif
216 /* IDCT implementation */
219 #define CONST_BITS 13
220 #define PASS1_BITS 2
223 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
224 * causing a lot of useless floating-point operations at run time.
225 * To get around this we use the following pre-calculated constants.
226 * If you change CONST_BITS you may want to add appropriate values.
227 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
229 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
230 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
231 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
232 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
233 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
234 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
235 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
236 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
237 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
238 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
239 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
240 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
244 /* Multiply an long variable by an long constant to yield an long result.
245 * For 8-bit samples with the recommended scaling, all the variable
246 * and constant values involved are no more than 16 bits wide, so a
247 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
248 * For 12-bit samples, a full 32-bit multiplication will be needed.
250 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
253 /* Dequantize a coefficient by multiplying it by the multiplier-table
254 * entry; produce an int result. In this module, both inputs and result
255 * are 16 bits or less, so either int or short multiply will work.
257 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
258 #define DEQUANTIZE MULTIPLY16
260 /* Descale and correctly round an int value that's scaled by N bits.
261 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
262 * the fudge factor is correct for either sign of X.
264 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
269 * Perform dequantization and inverse DCT on one block of coefficients,
270 * producing a reduced-size 1x1 output block.
272 void idct1x1(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
274 (void)skip_line; /* unused */
275 *p_byte = range_limit(inptr[0] * quantptr[0] >> 3);
281 * Perform dequantization and inverse DCT on one block of coefficients,
282 * producing a reduced-size 2x2 output block.
284 void idct2x2(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
286 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
287 unsigned char* outptr;
289 /* Pass 1: process columns from input, store into work array. */
291 /* Column 0 */
292 tmp4 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
293 tmp5 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
295 tmp0 = tmp4 + tmp5;
296 tmp2 = tmp4 - tmp5;
298 /* Column 1 */
299 tmp4 = DEQUANTIZE(inptr[8*0+1], quantptr[8*0+1]);
300 tmp5 = DEQUANTIZE(inptr[8*1+1], quantptr[8*1+1]);
302 tmp1 = tmp4 + tmp5;
303 tmp3 = tmp4 - tmp5;
305 /* Pass 2: process 2 rows, store into output array. */
307 /* Row 0 */
308 outptr = p_byte;
310 outptr[0] = range_limit((int) DESCALE(tmp0 + tmp1, 3));
311 outptr[1] = range_limit((int) DESCALE(tmp0 - tmp1, 3));
313 /* Row 1 */
314 outptr = p_byte + skip_line;
316 outptr[0] = range_limit((int) DESCALE(tmp2 + tmp3, 3));
317 outptr[1] = range_limit((int) DESCALE(tmp2 - tmp3, 3));
323 * Perform dequantization and inverse DCT on one block of coefficients,
324 * producing a reduced-size 4x4 output block.
326 void idct4x4(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
328 int tmp0, tmp2, tmp10, tmp12;
329 int z1, z2, z3;
330 int * wsptr;
331 unsigned char* outptr;
332 int ctr;
333 int workspace[4*4]; /* buffers data between passes */
335 /* Pass 1: process columns from input, store into work array. */
337 wsptr = workspace;
338 for (ctr = 0; ctr < 4; ctr++, inptr++, quantptr++, wsptr++)
340 /* Even part */
342 tmp0 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
343 tmp2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
345 tmp10 = (tmp0 + tmp2) << PASS1_BITS;
346 tmp12 = (tmp0 - tmp2) << PASS1_BITS;
348 /* Odd part */
349 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
351 z2 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
352 z3 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
354 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
355 tmp0 = DESCALE(z1 + MULTIPLY16(z3, - FIX_1_847759065), CONST_BITS-PASS1_BITS);
356 tmp2 = DESCALE(z1 + MULTIPLY16(z2, FIX_0_765366865), CONST_BITS-PASS1_BITS);
358 /* Final output stage */
360 wsptr[4*0] = (int) (tmp10 + tmp2);
361 wsptr[4*3] = (int) (tmp10 - tmp2);
362 wsptr[4*1] = (int) (tmp12 + tmp0);
363 wsptr[4*2] = (int) (tmp12 - tmp0);
366 /* Pass 2: process 4 rows from work array, store into output array. */
368 wsptr = workspace;
369 for (ctr = 0; ctr < 4; ctr++)
371 outptr = p_byte + (ctr*skip_line);
372 /* Even part */
374 tmp0 = (int) wsptr[0];
375 tmp2 = (int) wsptr[2];
377 tmp10 = (tmp0 + tmp2) << CONST_BITS;
378 tmp12 = (tmp0 - tmp2) << CONST_BITS;
380 /* Odd part */
381 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
383 z2 = (int) wsptr[1];
384 z3 = (int) wsptr[3];
386 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
387 tmp0 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
388 tmp2 = z1 + MULTIPLY16(z2, FIX_0_765366865);
390 /* Final output stage */
392 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp2,
393 CONST_BITS+PASS1_BITS+3));
394 outptr[3] = range_limit((int) DESCALE(tmp10 - tmp2,
395 CONST_BITS+PASS1_BITS+3));
396 outptr[1] = range_limit((int) DESCALE(tmp12 + tmp0,
397 CONST_BITS+PASS1_BITS+3));
398 outptr[2] = range_limit((int) DESCALE(tmp12 - tmp0,
399 CONST_BITS+PASS1_BITS+3));
401 wsptr += 4; /* advance pointer to next row */
408 * Perform dequantization and inverse DCT on one block of coefficients.
410 void idct8x8(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
412 long tmp0, tmp1, tmp2, tmp3;
413 long tmp10, tmp11, tmp12, tmp13;
414 long z1, z2, z3, z4, z5;
415 int * wsptr;
416 unsigned char* outptr;
417 int ctr;
418 int workspace[64]; /* buffers data between passes */
420 /* Pass 1: process columns from input, store into work array. */
421 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
422 /* furthermore, we scale the results by 2**PASS1_BITS. */
424 wsptr = workspace;
425 for (ctr = 8; ctr > 0; ctr--)
427 /* Due to quantization, we will usually find that many of the input
428 * coefficients are zero, especially the AC terms. We can exploit this
429 * by short-circuiting the IDCT calculation for any column in which all
430 * the AC terms are zero. In that case each output is equal to the
431 * DC coefficient (with scale factor as needed).
432 * With typical images and quantization tables, half or more of the
433 * column DCT calculations can be simplified this way.
436 if ((inptr[8*1] | inptr[8*2] | inptr[8*3]
437 | inptr[8*4] | inptr[8*5] | inptr[8*6] | inptr[8*7]) == 0)
439 /* AC terms all zero */
440 int dcval = DEQUANTIZE(inptr[8*0], quantptr[8*0]) << PASS1_BITS;
442 wsptr[8*0] = wsptr[8*1] = wsptr[8*2] = wsptr[8*3] = wsptr[8*4]
443 = wsptr[8*5] = wsptr[8*6] = wsptr[8*7] = dcval;
444 inptr++; /* advance pointers to next column */
445 quantptr++;
446 wsptr++;
447 continue;
450 /* Even part: reverse the even part of the forward DCT. */
451 /* The rotator is sqrt(2)*c(-6). */
453 z2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
454 z3 = DEQUANTIZE(inptr[8*6], quantptr[8*6]);
456 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
457 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
458 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
460 z2 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
461 z3 = DEQUANTIZE(inptr[8*4], quantptr[8*4]);
463 tmp0 = (z2 + z3) << CONST_BITS;
464 tmp1 = (z2 - z3) << CONST_BITS;
466 tmp10 = tmp0 + tmp3;
467 tmp13 = tmp0 - tmp3;
468 tmp11 = tmp1 + tmp2;
469 tmp12 = tmp1 - tmp2;
471 /* Odd part per figure 8; the matrix is unitary and hence its
472 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
474 tmp0 = DEQUANTIZE(inptr[8*7], quantptr[8*7]);
475 tmp1 = DEQUANTIZE(inptr[8*5], quantptr[8*5]);
476 tmp2 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
477 tmp3 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
479 z1 = tmp0 + tmp3;
480 z2 = tmp1 + tmp2;
481 z3 = tmp0 + tmp2;
482 z4 = tmp1 + tmp3;
483 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
485 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
486 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
487 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
488 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
489 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
490 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
491 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
492 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
494 z3 += z5;
495 z4 += z5;
497 tmp0 += z1 + z3;
498 tmp1 += z2 + z4;
499 tmp2 += z2 + z3;
500 tmp3 += z1 + z4;
502 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
504 wsptr[8*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
505 wsptr[8*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
506 wsptr[8*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
507 wsptr[8*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
508 wsptr[8*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
509 wsptr[8*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
510 wsptr[8*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
511 wsptr[8*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
513 inptr++; /* advance pointers to next column */
514 quantptr++;
515 wsptr++;
518 /* Pass 2: process rows from work array, store into output array. */
519 /* Note that we must descale the results by a factor of 8 == 2**3, */
520 /* and also undo the PASS1_BITS scaling. */
522 wsptr = workspace;
523 for (ctr = 0; ctr < 8; ctr++)
525 outptr = p_byte + (ctr*skip_line);
526 /* Rows of zeroes can be exploited in the same way as we did with columns.
527 * However, the column calculation has created many nonzero AC terms, so
528 * the simplification applies less often (typically 5% to 10% of the time).
529 * On machines with very fast multiplication, it's possible that the
530 * test takes more time than it's worth. In that case this section
531 * may be commented out.
534 #ifndef NO_ZERO_ROW_TEST
535 if ((wsptr[1] | wsptr[2] | wsptr[3]
536 | wsptr[4] | wsptr[5] | wsptr[6] | wsptr[7]) == 0)
538 /* AC terms all zero */
539 unsigned char dcval = range_limit((int) DESCALE((long) wsptr[0],
540 PASS1_BITS+3));
542 outptr[0] = dcval;
543 outptr[1] = dcval;
544 outptr[2] = dcval;
545 outptr[3] = dcval;
546 outptr[4] = dcval;
547 outptr[5] = dcval;
548 outptr[6] = dcval;
549 outptr[7] = dcval;
551 wsptr += 8; /* advance pointer to next row */
552 continue;
554 #endif
556 /* Even part: reverse the even part of the forward DCT. */
557 /* The rotator is sqrt(2)*c(-6). */
559 z2 = (long) wsptr[2];
560 z3 = (long) wsptr[6];
562 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
563 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
564 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
566 tmp0 = ((long) wsptr[0] + (long) wsptr[4]) << CONST_BITS;
567 tmp1 = ((long) wsptr[0] - (long) wsptr[4]) << CONST_BITS;
569 tmp10 = tmp0 + tmp3;
570 tmp13 = tmp0 - tmp3;
571 tmp11 = tmp1 + tmp2;
572 tmp12 = tmp1 - tmp2;
574 /* Odd part per figure 8; the matrix is unitary and hence its
575 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
577 tmp0 = (long) wsptr[7];
578 tmp1 = (long) wsptr[5];
579 tmp2 = (long) wsptr[3];
580 tmp3 = (long) wsptr[1];
582 z1 = tmp0 + tmp3;
583 z2 = tmp1 + tmp2;
584 z3 = tmp0 + tmp2;
585 z4 = tmp1 + tmp3;
586 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
588 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
589 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
590 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
591 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
592 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
593 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
594 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
595 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
597 z3 += z5;
598 z4 += z5;
600 tmp0 += z1 + z3;
601 tmp1 += z2 + z4;
602 tmp2 += z2 + z3;
603 tmp3 += z1 + z4;
605 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
607 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp3,
608 CONST_BITS+PASS1_BITS+3));
609 outptr[7] = range_limit((int) DESCALE(tmp10 - tmp3,
610 CONST_BITS+PASS1_BITS+3));
611 outptr[1] = range_limit((int) DESCALE(tmp11 + tmp2,
612 CONST_BITS+PASS1_BITS+3));
613 outptr[6] = range_limit((int) DESCALE(tmp11 - tmp2,
614 CONST_BITS+PASS1_BITS+3));
615 outptr[2] = range_limit((int) DESCALE(tmp12 + tmp1,
616 CONST_BITS+PASS1_BITS+3));
617 outptr[5] = range_limit((int) DESCALE(tmp12 - tmp1,
618 CONST_BITS+PASS1_BITS+3));
619 outptr[3] = range_limit((int) DESCALE(tmp13 + tmp0,
620 CONST_BITS+PASS1_BITS+3));
621 outptr[4] = range_limit((int) DESCALE(tmp13 - tmp0,
622 CONST_BITS+PASS1_BITS+3));
624 wsptr += 8; /* advance pointer to next row */
630 /* JPEG decoder implementation */
633 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
635 struct derived_tbl
637 /* Basic tables: (element [0] of each array is unused) */
638 long mincode[17]; /* smallest code of length k */
639 long maxcode[18]; /* largest code of length k (-1 if none) */
640 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
641 int valptr[17]; /* huffval[] index of 1st symbol of length k */
643 /* Back link to public Huffman table (needed only in slow_DECODE) */
644 int* pub;
646 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
647 the input data stream. If the next Huffman code is no more
648 than HUFF_LOOKAHEAD bits long, we can obtain its length and
649 the corresponding symbol directly from these tables. */
650 int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
651 unsigned char look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
654 #define QUANT_TABLE_LENGTH 64
656 /* for type of Huffman table */
657 #define DC_LEN 28
658 #define AC_LEN 178
660 struct huffman_table
661 { /* length and code according to JFIF format */
662 int huffmancodes_dc[DC_LEN];
663 int huffmancodes_ac[AC_LEN];
666 struct frame_component
668 int ID;
669 int horizontal_sampling;
670 int vertical_sampling;
671 int quanttable_select;
674 struct scan_component
676 int ID;
677 int DC_select;
678 int AC_select;
681 struct bitstream
683 unsigned long get_buffer; /* current bit-extraction buffer */
684 int bits_left; /* # of unused bits in it */
685 unsigned char* next_input_byte;
686 unsigned char* input_end; /* upper limit +1 */
689 struct jpeg
691 int x_size, y_size; /* size of image (can be less than block boundary) */
692 int x_phys, y_phys; /* physical size, block aligned */
693 int x_mbl; /* x dimension of MBL */
694 int y_mbl; /* y dimension of MBL */
695 int blocks; /* blocks per MB */
696 int restart_interval; /* number of MCUs between RSTm markers */
697 int store_pos[4]; /* for Y block ordering */
699 unsigned char* p_entropy_data;
700 unsigned char* p_entropy_end;
702 int quanttable[4][QUANT_TABLE_LENGTH]; /* raw quantization tables 0-3 */
703 int qt_idct[2][QUANT_TABLE_LENGTH]; /* quantization tables for IDCT */
705 struct huffman_table hufftable[2]; /* Huffman tables */
706 struct derived_tbl dc_derived_tbls[2]; /* Huffman-LUTs */
707 struct derived_tbl ac_derived_tbls[2];
709 struct frame_component frameheader[3]; /* Component descriptor */
710 struct scan_component scanheader[3]; /* currently not used */
712 int mcu_membership[6]; /* info per block */
713 int tab_membership[6];
714 int subsample_x[3]; /* info per component */
715 int subsample_y[3];
719 /* possible return flags for process_markers() */
720 #define HUFFTAB 0x0001 /* with huffman table */
721 #define QUANTTAB 0x0002 /* with quantization table */
722 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
723 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
724 #define SOF0 0x0010 /* with SOF0-Segment */
725 #define DHT 0x0020 /* with Definition of huffman tables */
726 #define SOS 0x0040 /* with Start-of-Scan segment */
727 #define DQT 0x0080 /* with definition of quantization table */
729 /* Preprocess the JPEG JFIF file */
730 int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
732 unsigned char* p_bytes = p_src;
733 int marker_size; /* variable length of marker segment */
734 int i, j, n;
735 int ret = 0; /* returned flags */
737 p_jpeg->p_entropy_end = p_src + size;
739 while (p_src < p_bytes + size)
741 if (*p_src++ != 0xFF) /* no marker? */
743 p_src--; /* it's image data, put it back */
744 p_jpeg->p_entropy_data = p_src;
745 break; /* exit marker processing */
748 switch (*p_src++)
750 case 0xFF: /* Fill byte */
751 ret |= FILL_FF;
752 case 0x00: /* Zero stuffed byte - entropy data */
753 p_src--; /* put it back */
754 continue;
756 case 0xC0: /* SOF Huff - Baseline DCT */
758 ret |= SOF0;
759 marker_size = *p_src++ << 8; /* Highbyte */
760 marker_size |= *p_src++; /* Lowbyte */
761 n = *p_src++; /* sample precision (= 8 or 12) */
762 if (n != 8)
764 return(-1); /* Unsupported sample precision */
766 p_jpeg->y_size = *p_src++ << 8; /* Highbyte */
767 p_jpeg->y_size |= *p_src++; /* Lowbyte */
768 p_jpeg->x_size = *p_src++ << 8; /* Highbyte */
769 p_jpeg->x_size |= *p_src++; /* Lowbyte */
771 n = (marker_size-2-6)/3;
772 if (*p_src++ != n || (n != 1 && n != 3))
774 return(-2); /* Unsupported SOF0 component specification */
776 for (i=0; i<n; i++)
778 p_jpeg->frameheader[i].ID = *p_src++; /* Component info */
779 p_jpeg->frameheader[i].horizontal_sampling = *p_src >> 4;
780 p_jpeg->frameheader[i].vertical_sampling = *p_src++ & 0x0F;
781 p_jpeg->frameheader[i].quanttable_select = *p_src++;
782 if (p_jpeg->frameheader[i].horizontal_sampling > 2
783 || p_jpeg->frameheader[i].vertical_sampling > 2)
784 return -3; /* Unsupported SOF0 subsampling */
786 p_jpeg->blocks = n;
788 break;
790 case 0xC1: /* SOF Huff - Extended sequential DCT*/
791 case 0xC2: /* SOF Huff - Progressive DCT*/
792 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
793 case 0xC5: /* SOF Huff - Differential sequential DCT*/
794 case 0xC6: /* SOF Huff - Differential progressive DCT*/
795 case 0xC7: /* SOF Huff - Differential spatial*/
796 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
797 case 0xC9: /* SOF Arith - Extended sequential DCT*/
798 case 0xCA: /* SOF Arith - Progressive DCT*/
799 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
800 case 0xCD: /* SOF Arith - Differential sequential DCT*/
801 case 0xCE: /* SOF Arith - Differential progressive DCT*/
802 case 0xCF: /* SOF Arith - Differential spatial*/
804 return (-4); /* other DCT model than baseline not implemented */
807 case 0xC4: /* Define Huffman Table(s) */
809 unsigned char* p_temp;
811 ret |= DHT;
812 marker_size = *p_src++ << 8; /* Highbyte */
813 marker_size |= *p_src++; /* Lowbyte */
815 p_temp = p_src;
816 while (p_src < p_temp+marker_size-2-17) /* another table */
818 int sum = 0;
819 i = *p_src & 0x0F; /* table index */
820 if (i > 1)
822 return (-5); /* Huffman table index out of range */
824 else if (*p_src++ & 0xF0) /* AC table */
826 for (j=0; j<16; j++)
828 sum += *p_src;
829 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
831 if(16 + sum > AC_LEN)
832 return -10; /* longer than allowed */
834 for (; j < 16 + sum; j++)
835 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
837 else /* DC table */
839 for (j=0; j<16; j++)
841 sum += *p_src;
842 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
844 if(16 + sum > DC_LEN)
845 return -11; /* longer than allowed */
847 for (; j < 16 + sum; j++)
848 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
850 } /* while */
851 p_src = p_temp+marker_size - 2; /* skip possible residue */
853 break;
855 case 0xCC: /* Define Arithmetic coding conditioning(s) */
856 return(-6); /* Arithmetic coding not supported */
858 case 0xD8: /* Start of Image */
859 case 0xD9: /* End of Image */
860 case 0x01: /* for temp private use arith code */
861 break; /* skip parameterless marker */
864 case 0xDA: /* Start of Scan */
866 ret |= SOS;
867 marker_size = *p_src++ << 8; /* Highbyte */
868 marker_size |= *p_src++; /* Lowbyte */
870 n = (marker_size-2-1-3)/2;
871 if (*p_src++ != n || (n != 1 && n != 3))
873 return (-7); /* Unsupported SOS component specification */
875 for (i=0; i<n; i++)
877 p_jpeg->scanheader[i].ID = *p_src++;
878 p_jpeg->scanheader[i].DC_select = *p_src >> 4;
879 p_jpeg->scanheader[i].AC_select = *p_src++ & 0x0F;
881 p_src += 3; /* skip spectral information */
883 break;
885 case 0xDB: /* Define quantization Table(s) */
887 ret |= DQT;
888 marker_size = *p_src++ << 8; /* Highbyte */
889 marker_size |= *p_src++; /* Lowbyte */
890 n = (marker_size-2)/(QUANT_TABLE_LENGTH+1); /* # of tables */
891 for (i=0; i<n; i++)
893 int id = *p_src++; /* ID */
894 if (id >= 4)
896 return (-8); /* Unsupported quantization table */
898 /* Read Quantisation table: */
899 for (j=0; j<QUANT_TABLE_LENGTH; j++)
900 p_jpeg->quanttable[id][j] = *p_src++;
903 break;
905 case 0xDD: /* Define Restart Interval */
907 marker_size = *p_src++ << 8; /* Highbyte */
908 marker_size |= *p_src++; /* Lowbyte */
909 p_jpeg->restart_interval = *p_src++ << 8; /* Highbyte */
910 p_jpeg->restart_interval |= *p_src++; /* Lowbyte */
911 p_src += marker_size-4; /* skip segment */
913 break;
915 case 0xDC: /* Define Number of Lines */
916 case 0xDE: /* Define Hierarchical progression */
917 case 0xDF: /* Expand Reference Component(s) */
918 case 0xE0: /* Application Field 0*/
919 case 0xE1: /* Application Field 1*/
920 case 0xE2: /* Application Field 2*/
921 case 0xE3: /* Application Field 3*/
922 case 0xE4: /* Application Field 4*/
923 case 0xE5: /* Application Field 5*/
924 case 0xE6: /* Application Field 6*/
925 case 0xE7: /* Application Field 7*/
926 case 0xE8: /* Application Field 8*/
927 case 0xE9: /* Application Field 9*/
928 case 0xEA: /* Application Field 10*/
929 case 0xEB: /* Application Field 11*/
930 case 0xEC: /* Application Field 12*/
931 case 0xED: /* Application Field 13*/
932 case 0xEE: /* Application Field 14*/
933 case 0xEF: /* Application Field 15*/
934 case 0xFE: /* Comment */
936 marker_size = *p_src++ << 8; /* Highbyte */
937 marker_size |= *p_src++; /* Lowbyte */
938 p_src += marker_size-2; /* skip segment */
940 break;
942 case 0xF0: /* Reserved for JPEG extensions */
943 case 0xF1: /* Reserved for JPEG extensions */
944 case 0xF2: /* Reserved for JPEG extensions */
945 case 0xF3: /* Reserved for JPEG extensions */
946 case 0xF4: /* Reserved for JPEG extensions */
947 case 0xF5: /* Reserved for JPEG extensions */
948 case 0xF6: /* Reserved for JPEG extensions */
949 case 0xF7: /* Reserved for JPEG extensions */
950 case 0xF8: /* Reserved for JPEG extensions */
951 case 0xF9: /* Reserved for JPEG extensions */
952 case 0xFA: /* Reserved for JPEG extensions */
953 case 0xFB: /* Reserved for JPEG extensions */
954 case 0xFC: /* Reserved for JPEG extensions */
955 case 0xFD: /* Reserved for JPEG extensions */
956 case 0x02: /* Reserved */
957 default:
958 return (-9); /* Unknown marker */
959 } /* switch */
960 } /* while */
962 return (ret); /* return flags with seen markers */
966 void default_huff_tbl(struct jpeg* p_jpeg)
968 static const struct huffman_table luma_table =
971 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
972 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
975 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
976 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
977 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
978 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
979 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
980 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
981 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
982 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
983 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
984 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
985 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
986 0xF9,0xFA
990 static const struct huffman_table chroma_table =
993 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
994 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
997 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
998 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
999 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1000 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1001 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1002 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1003 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1004 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1005 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1006 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1007 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1008 0xF9,0xFA
1012 MEMCPY(&p_jpeg->hufftable[0], &luma_table, sizeof(luma_table));
1013 MEMCPY(&p_jpeg->hufftable[1], &chroma_table, sizeof(chroma_table));
1015 return;
1018 /* Compute the derived values for a Huffman table */
1019 void fix_huff_tbl(int* htbl, struct derived_tbl* dtbl)
1021 int p, i, l, si;
1022 int lookbits, ctr;
1023 char huffsize[257];
1024 unsigned int huffcode[257];
1025 unsigned int code;
1027 dtbl->pub = htbl; /* fill in back link */
1029 /* Figure C.1: make table of Huffman code length for each symbol */
1030 /* Note that this is in code-length order. */
1032 p = 0;
1033 for (l = 1; l <= 16; l++)
1034 { /* all possible code length */
1035 for (i = 1; i <= (int) htbl[l-1]; i++) /* all codes per length */
1036 huffsize[p++] = (char) l;
1038 huffsize[p] = 0;
1040 /* Figure C.2: generate the codes themselves */
1041 /* Note that this is in code-length order. */
1043 code = 0;
1044 si = huffsize[0];
1045 p = 0;
1046 while (huffsize[p])
1048 while (((int) huffsize[p]) == si)
1050 huffcode[p++] = code;
1051 code++;
1053 code <<= 1;
1054 si++;
1057 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1059 p = 0;
1060 for (l = 1; l <= 16; l++)
1062 if (htbl[l-1])
1064 dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */
1065 dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */
1066 p += htbl[l-1];
1067 dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
1069 else
1071 dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
1074 dtbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */
1076 /* Compute lookahead tables to speed up decoding.
1077 * First we set all the table entries to 0, indicating "too long";
1078 * then we iterate through the Huffman codes that are short enough and
1079 * fill in all the entries that correspond to bit sequences starting
1080 * with that code.
1083 MEMSET(dtbl->look_nbits, 0, sizeof(dtbl->look_nbits));
1085 p = 0;
1086 for (l = 1; l <= HUFF_LOOKAHEAD; l++)
1088 for (i = 1; i <= (int) htbl[l-1]; i++, p++)
1090 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1091 /* Generate left-justified code followed by all possible bit sequences */
1092 lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
1093 for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--)
1095 dtbl->look_nbits[lookbits] = l;
1096 dtbl->look_sym[lookbits] = htbl[16+p];
1097 lookbits++;
1104 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1105 * If the incoming data is corrupted, decode_mcu could attempt to
1106 * reference values beyond the end of the array. To avoid a wild store,
1107 * we put some extra zeroes after the real entries.
1109 static const int zag[] =
1111 0, 1, 8, 16, 9, 2, 3, 10,
1112 17, 24, 32, 25, 18, 11, 4, 5,
1113 12, 19, 26, 33, 40, 48, 41, 34,
1114 27, 20, 13, 6, 7, 14, 21, 28,
1115 35, 42, 49, 56, 57, 50, 43, 36,
1116 29, 22, 15, 23, 30, 37, 44, 51,
1117 58, 59, 52, 45, 38, 31, 39, 46,
1118 53, 60, 61, 54, 47, 55, 62, 63,
1119 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1120 0, 0, 0, 0, 0, 0, 0, 0
1123 void build_lut(struct jpeg* p_jpeg)
1125 int i;
1126 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_dc,
1127 &p_jpeg->dc_derived_tbls[0]);
1128 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_ac,
1129 &p_jpeg->ac_derived_tbls[0]);
1130 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_dc,
1131 &p_jpeg->dc_derived_tbls[1]);
1132 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_ac,
1133 &p_jpeg->ac_derived_tbls[1]);
1135 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1136 for (i=0; i<64; i++)
1138 p_jpeg->qt_idct[0][zag[i]] = p_jpeg->quanttable[0][i];
1139 p_jpeg->qt_idct[1][zag[i]] = p_jpeg->quanttable[1][i];
1142 for (i=0; i<4; i++)
1143 p_jpeg->store_pos[i] = i; /* default ordering */
1145 /* assignments for the decoding of blocks */
1146 if (p_jpeg->frameheader[0].horizontal_sampling == 2
1147 && p_jpeg->frameheader[0].vertical_sampling == 1)
1148 { /* 4:2:2 */
1149 p_jpeg->blocks = 4;
1150 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1151 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1152 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1153 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1154 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1155 p_jpeg->mcu_membership[1] = 0;
1156 p_jpeg->mcu_membership[2] = 1;
1157 p_jpeg->mcu_membership[3] = 2;
1158 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1159 p_jpeg->tab_membership[1] = 0;
1160 p_jpeg->tab_membership[2] = 1;
1161 p_jpeg->tab_membership[3] = 1;
1162 p_jpeg->subsample_x[0] = 1;
1163 p_jpeg->subsample_x[1] = 2;
1164 p_jpeg->subsample_x[2] = 2;
1165 p_jpeg->subsample_y[0] = 1;
1166 p_jpeg->subsample_y[1] = 1;
1167 p_jpeg->subsample_y[2] = 1;
1169 if (p_jpeg->frameheader[0].horizontal_sampling == 1
1170 && p_jpeg->frameheader[0].vertical_sampling == 2)
1171 { /* 4:2:2 vertically subsampled */
1172 p_jpeg->store_pos[1] = 2; /* block positions are mirrored */
1173 p_jpeg->store_pos[2] = 1;
1174 p_jpeg->blocks = 4;
1175 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1176 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1177 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1178 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1179 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1180 p_jpeg->mcu_membership[1] = 0;
1181 p_jpeg->mcu_membership[2] = 1;
1182 p_jpeg->mcu_membership[3] = 2;
1183 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1184 p_jpeg->tab_membership[1] = 0;
1185 p_jpeg->tab_membership[2] = 1;
1186 p_jpeg->tab_membership[3] = 1;
1187 p_jpeg->subsample_x[0] = 1;
1188 p_jpeg->subsample_x[1] = 1;
1189 p_jpeg->subsample_x[2] = 1;
1190 p_jpeg->subsample_y[0] = 1;
1191 p_jpeg->subsample_y[1] = 2;
1192 p_jpeg->subsample_y[2] = 2;
1194 else if (p_jpeg->frameheader[0].horizontal_sampling == 2
1195 && p_jpeg->frameheader[0].vertical_sampling == 2)
1196 { /* 4:2:0 */
1197 p_jpeg->blocks = 6;
1198 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1199 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1200 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1201 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1202 p_jpeg->mcu_membership[0] = 0;
1203 p_jpeg->mcu_membership[1] = 0;
1204 p_jpeg->mcu_membership[2] = 0;
1205 p_jpeg->mcu_membership[3] = 0;
1206 p_jpeg->mcu_membership[4] = 1;
1207 p_jpeg->mcu_membership[5] = 2;
1208 p_jpeg->tab_membership[0] = 0;
1209 p_jpeg->tab_membership[1] = 0;
1210 p_jpeg->tab_membership[2] = 0;
1211 p_jpeg->tab_membership[3] = 0;
1212 p_jpeg->tab_membership[4] = 1;
1213 p_jpeg->tab_membership[5] = 1;
1214 p_jpeg->subsample_x[0] = 1;
1215 p_jpeg->subsample_x[1] = 2;
1216 p_jpeg->subsample_x[2] = 2;
1217 p_jpeg->subsample_y[0] = 1;
1218 p_jpeg->subsample_y[1] = 2;
1219 p_jpeg->subsample_y[2] = 2;
1221 else if (p_jpeg->frameheader[0].horizontal_sampling == 1
1222 && p_jpeg->frameheader[0].vertical_sampling == 1)
1223 { /* 4:4:4 */
1224 /* don't overwrite p_jpeg->blocks */
1225 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1226 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1227 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1228 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1229 p_jpeg->mcu_membership[0] = 0;
1230 p_jpeg->mcu_membership[1] = 1;
1231 p_jpeg->mcu_membership[2] = 2;
1232 p_jpeg->tab_membership[0] = 0;
1233 p_jpeg->tab_membership[1] = 1;
1234 p_jpeg->tab_membership[2] = 1;
1235 p_jpeg->subsample_x[0] = 1;
1236 p_jpeg->subsample_x[1] = 1;
1237 p_jpeg->subsample_x[2] = 1;
1238 p_jpeg->subsample_y[0] = 1;
1239 p_jpeg->subsample_y[1] = 1;
1240 p_jpeg->subsample_y[2] = 1;
1242 else
1244 /* error */
1251 * These functions/macros provide the in-line portion of bit fetching.
1252 * Use check_bit_buffer to ensure there are N bits in get_buffer
1253 * before using get_bits, peek_bits, or drop_bits.
1254 * check_bit_buffer(state,n,action);
1255 * Ensure there are N bits in get_buffer; if suspend, take action.
1256 * val = get_bits(n);
1257 * Fetch next N bits.
1258 * val = peek_bits(n);
1259 * Fetch next N bits without removing them from the buffer.
1260 * drop_bits(n);
1261 * Discard next N bits.
1262 * The value N should be a simple variable, not an expression, because it
1263 * is evaluated multiple times.
1266 INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
1268 if (pb->bits_left < nbits)
1269 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1270 unsigned char byte;
1272 byte = *pb->next_input_byte++;
1273 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1274 { /* simplification: just skip the (one-byte) marker code */
1275 pb->next_input_byte++;
1277 pb->get_buffer = (pb->get_buffer << 8) | byte;
1279 byte = *pb->next_input_byte++;
1280 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1281 { /* simplification: just skip the (one-byte) marker code */
1282 pb->next_input_byte++;
1284 pb->get_buffer = (pb->get_buffer << 8) | byte;
1286 pb->bits_left += 16;
1290 INLINE int get_bits(struct bitstream* pb, int nbits)
1292 return ((int) (pb->get_buffer >> (pb->bits_left -= nbits))) & ((1<<nbits)-1);
1295 INLINE int peek_bits(struct bitstream* pb, int nbits)
1297 return ((int) (pb->get_buffer >> (pb->bits_left - nbits))) & ((1<<nbits)-1);
1300 INLINE void drop_bits(struct bitstream* pb, int nbits)
1302 pb->bits_left -= nbits;
1305 /* re-synchronize to entropy data (skip restart marker) */
1306 void search_restart(struct bitstream* pb)
1308 pb->next_input_byte--; /* we may have overread it, taking 2 bytes */
1309 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1310 while (pb->next_input_byte < pb->input_end &&
1311 (pb->next_input_byte[-2] != 0xFF || pb->next_input_byte[-1] == 0x00))
1313 pb->next_input_byte++;
1315 pb->bits_left = 0;
1318 /* Figure F.12: extend sign bit. */
1319 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1321 static const int extend_test[16] = /* entry n is 2**(n-1) */
1323 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1324 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1327 static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
1329 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1330 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1331 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1332 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1335 /* Decode a single value */
1336 INLINE int huff_decode_dc(struct bitstream* bs, struct derived_tbl* tbl)
1338 int nb, look, s, r;
1340 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1341 look = peek_bits(bs, HUFF_LOOKAHEAD);
1342 if ((nb = tbl->look_nbits[look]) != 0)
1344 drop_bits(bs, nb);
1345 s = tbl->look_sym[look];
1346 check_bit_buffer(bs, s);
1347 r = get_bits(bs, s);
1348 s = HUFF_EXTEND(r, s);
1350 else
1351 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1352 long code;
1353 nb=HUFF_LOOKAHEAD+1;
1354 check_bit_buffer(bs, nb);
1355 code = get_bits(bs, nb);
1356 while (code > tbl->maxcode[nb])
1358 code <<= 1;
1359 check_bit_buffer(bs, 1);
1360 code |= get_bits(bs, 1);
1361 nb++;
1363 if (nb > 16) /* error in Huffman */
1365 s=0; /* fake a zero, this is most safe */
1367 else
1369 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1370 check_bit_buffer(bs, s);
1371 r = get_bits(bs, s);
1372 s = HUFF_EXTEND(r, s);
1374 } /* end slow decode */
1375 return s;
1378 INLINE int huff_decode_ac(struct bitstream* bs, struct derived_tbl* tbl)
1380 int nb, look, s;
1382 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1383 look = peek_bits(bs, HUFF_LOOKAHEAD);
1384 if ((nb = tbl->look_nbits[look]) != 0)
1386 drop_bits(bs, nb);
1387 s = tbl->look_sym[look];
1389 else
1390 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1391 long code;
1392 nb=HUFF_LOOKAHEAD+1;
1393 check_bit_buffer(bs, nb);
1394 code = get_bits(bs, nb);
1395 while (code > tbl->maxcode[nb])
1397 code <<= 1;
1398 check_bit_buffer(bs, 1);
1399 code |= get_bits(bs, 1);
1400 nb++;
1402 if (nb > 16) /* error in Huffman */
1404 s=0; /* fake a zero, this is most safe */
1406 else
1408 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1410 } /* end slow decode */
1411 return s;
1415 #ifdef HAVE_LCD_COLOR
1417 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1418 /* Note: it keeps the original color subsampling, even if resized. */
1419 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1420 int downscale, void (*pf_progress)(int current, int total))
1422 struct bitstream bs; /* bitstream "object" */
1423 int block[64]; /* decoded DCT coefficients */
1425 int width, height;
1426 int skip_line[3]; /* bytes from one line to the next (skip_line) */
1427 int skip_strip[3], skip_mcu[3]; /* bytes to next DCT row / column */
1429 int i, x, y; /* loop counter */
1431 unsigned char* p_line[3] = {p_pixel[0], p_pixel[1], p_pixel[2]};
1432 unsigned char* p_byte[3]; /* bitmap pointer */
1434 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1435 int k_need; /* AC coefficients needed up to here */
1436 int zero_need; /* init the block with this many zeros */
1438 int last_dc_val[3] = {0, 0, 0}; /* or 128 for chroma? */
1439 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1440 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1442 /* pick the IDCT we want, determine how to work with coefs */
1443 if (downscale == 1)
1445 pf_idct = idct8x8;
1446 k_need = 64; /* all */
1447 zero_need = 63; /* all */
1449 else if (downscale == 2)
1451 pf_idct = idct4x4;
1452 k_need = 25; /* this far in zig-zag to cover 4*4 */
1453 zero_need = 27; /* clear this far in linear order */
1455 else if (downscale == 4)
1457 pf_idct = idct2x2;
1458 k_need = 5; /* this far in zig-zag to cover 2*2 */
1459 zero_need = 9; /* clear this far in linear order */
1461 else if (downscale == 8)
1463 pf_idct = idct1x1;
1464 k_need = 0; /* no AC, not needed */
1465 zero_need = 0; /* no AC, not needed */
1467 else return -1; /* not supported */
1469 /* init bitstream, fake a restart to make it start */
1470 bs.next_input_byte = p_jpeg->p_entropy_data;
1471 bs.bits_left = 0;
1472 bs.input_end = p_jpeg->p_entropy_end;
1474 width = p_jpeg->x_phys / downscale;
1475 height = p_jpeg->y_phys / downscale;
1476 for (i=0; i<3; i++) /* calculate some strides */
1478 skip_line[i] = width / p_jpeg->subsample_x[i];
1479 skip_strip[i] = skip_line[i]
1480 * (height / p_jpeg->y_mbl) / p_jpeg->subsample_y[i];
1481 skip_mcu[i] = width/p_jpeg->x_mbl / p_jpeg->subsample_x[i];
1484 /* prepare offsets about where to store the different blocks */
1485 store_offs[p_jpeg->store_pos[0]] = 0;
1486 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1487 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1488 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1490 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1492 for (i=0; i<3; i++) /* scan line init */
1494 p_byte[i] = p_line[i];
1495 p_line[i] += skip_strip[i];
1497 for (x=0; x<p_jpeg->x_mbl; x++)
1499 int blkn;
1501 /* Outer loop handles each block in the MCU */
1502 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1503 { /* Decode a single block's worth of coefficients */
1504 int k = 1; /* coefficient index */
1505 int s, r; /* huffman values */
1506 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1507 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1508 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1509 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1511 /* Section F.2.2.1: decode the DC coefficient difference */
1512 s = huff_decode_dc(&bs, dctbl);
1514 last_dc_val[ci] += s;
1515 block[0] = last_dc_val[ci]; /* output it (assumes zag[0] = 0) */
1517 /* coefficient buffer must be cleared */
1518 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1520 /* Section F.2.2.2: decode the AC coefficients */
1521 for (; k < k_need; k++)
1523 s = huff_decode_ac(&bs, actbl);
1524 r = s >> 4;
1525 s &= 15;
1527 if (s)
1529 k += r;
1530 check_bit_buffer(&bs, s);
1531 r = get_bits(&bs, s);
1532 block[zag[k]] = HUFF_EXTEND(r, s);
1534 else
1536 if (r != 15)
1538 k = 64;
1539 break;
1541 k += r;
1543 } /* for k */
1544 /* In this path we just discard the values */
1545 for (; k < 64; k++)
1547 s = huff_decode_ac(&bs, actbl);
1548 r = s >> 4;
1549 s &= 15;
1551 if (s)
1553 k += r;
1554 check_bit_buffer(&bs, s);
1555 drop_bits(&bs, s);
1557 else
1559 if (r != 15)
1560 break;
1561 k += r;
1563 } /* for k */
1565 if (ci == 0)
1566 { /* Y component needs to bother about block store */
1567 pf_idct(p_byte[0]+store_offs[blkn], block,
1568 p_jpeg->qt_idct[ti], skip_line[0]);
1570 else
1571 { /* chroma */
1572 pf_idct(p_byte[ci], block, p_jpeg->qt_idct[ti],
1573 skip_line[ci]);
1575 } /* for blkn */
1576 p_byte[0] += skip_mcu[0]; /* unrolled for (i=0; i<3; i++) loop */
1577 p_byte[1] += skip_mcu[1];
1578 p_byte[2] += skip_mcu[2];
1579 if (p_jpeg->restart_interval && --restart == 0)
1580 { /* if a restart marker is due: */
1581 restart = p_jpeg->restart_interval; /* count again */
1582 search_restart(&bs); /* align the bitstream */
1583 last_dc_val[0] = last_dc_val[1] =
1584 last_dc_val[2] = 0; /* reset decoder */
1586 } /* for x */
1587 if (pf_progress != NULL)
1588 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1589 } /* for y */
1591 return 0; /* success */
1593 #else /* !HAVE_LCD_COLOR */
1595 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1596 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[1], int downscale,
1597 void (*pf_progress)(int current, int total))
1599 struct bitstream bs; /* bitstream "object" */
1600 int block[64]; /* decoded DCT coefficients */
1602 int width, height;
1603 int skip_line; /* bytes from one line to the next (skip_line) */
1604 int skip_strip, skip_mcu; /* bytes to next DCT row / column */
1606 int x, y; /* loop counter */
1608 unsigned char* p_line = p_pixel[0];
1609 unsigned char* p_byte; /* bitmap pointer */
1611 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1612 int k_need; /* AC coefficients needed up to here */
1613 int zero_need; /* init the block with this many zeros */
1615 int last_dc_val = 0;
1616 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1617 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1619 /* pick the IDCT we want, determine how to work with coefs */
1620 if (downscale == 1)
1622 pf_idct = idct8x8;
1623 k_need = 64; /* all */
1624 zero_need = 63; /* all */
1626 else if (downscale == 2)
1628 pf_idct = idct4x4;
1629 k_need = 25; /* this far in zig-zag to cover 4*4 */
1630 zero_need = 27; /* clear this far in linear order */
1632 else if (downscale == 4)
1634 pf_idct = idct2x2;
1635 k_need = 5; /* this far in zig-zag to cover 2*2 */
1636 zero_need = 9; /* clear this far in linear order */
1638 else if (downscale == 8)
1640 pf_idct = idct1x1;
1641 k_need = 0; /* no AC, not needed */
1642 zero_need = 0; /* no AC, not needed */
1644 else return -1; /* not supported */
1646 /* init bitstream, fake a restart to make it start */
1647 bs.next_input_byte = p_jpeg->p_entropy_data;
1648 bs.bits_left = 0;
1649 bs.input_end = p_jpeg->p_entropy_end;
1651 width = p_jpeg->x_phys / downscale;
1652 height = p_jpeg->y_phys / downscale;
1653 skip_line = width;
1654 skip_strip = skip_line * (height / p_jpeg->y_mbl);
1655 skip_mcu = (width/p_jpeg->x_mbl);
1657 /* prepare offsets about where to store the different blocks */
1658 store_offs[p_jpeg->store_pos[0]] = 0;
1659 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1660 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1661 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1663 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1665 p_byte = p_line;
1666 p_line += skip_strip;
1667 for (x=0; x<p_jpeg->x_mbl; x++)
1669 int blkn;
1671 /* Outer loop handles each block in the MCU */
1672 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1673 { /* Decode a single block's worth of coefficients */
1674 int k = 1; /* coefficient index */
1675 int s, r; /* huffman values */
1676 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1677 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1678 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1679 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1681 /* Section F.2.2.1: decode the DC coefficient difference */
1682 s = huff_decode_dc(&bs, dctbl);
1684 if (ci == 0) /* only for Y component */
1686 last_dc_val += s;
1687 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
1689 /* coefficient buffer must be cleared */
1690 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1692 /* Section F.2.2.2: decode the AC coefficients */
1693 for (; k < k_need; k++)
1695 s = huff_decode_ac(&bs, actbl);
1696 r = s >> 4;
1697 s &= 15;
1699 if (s)
1701 k += r;
1702 check_bit_buffer(&bs, s);
1703 r = get_bits(&bs, s);
1704 block[zag[k]] = HUFF_EXTEND(r, s);
1706 else
1708 if (r != 15)
1710 k = 64;
1711 break;
1713 k += r;
1715 } /* for k */
1717 /* In this path we just discard the values */
1718 for (; k < 64; k++)
1720 s = huff_decode_ac(&bs, actbl);
1721 r = s >> 4;
1722 s &= 15;
1724 if (s)
1726 k += r;
1727 check_bit_buffer(&bs, s);
1728 drop_bits(&bs, s);
1730 else
1732 if (r != 15)
1733 break;
1734 k += r;
1736 } /* for k */
1738 if (ci == 0)
1739 { /* only for Y component */
1740 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
1741 skip_line);
1743 } /* for blkn */
1744 p_byte += skip_mcu;
1745 if (p_jpeg->restart_interval && --restart == 0)
1746 { /* if a restart marker is due: */
1747 restart = p_jpeg->restart_interval; /* count again */
1748 search_restart(&bs); /* align the bitstream */
1749 last_dc_val = 0; /* reset decoder */
1751 } /* for x */
1752 if (pf_progress != NULL)
1753 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1754 } /* for y */
1756 return 0; /* success */
1758 #endif /* !HAVE_LCD_COLOR */
1760 /**************** end JPEG code ********************/
1764 /**************** begin Application ********************/
1767 /************************* Types ***************************/
1769 struct t_disp
1771 #ifdef HAVE_LCD_COLOR
1772 unsigned char* bitmap[3]; /* Y, Cr, Cb */
1773 int csub_x, csub_y;
1774 #else
1775 unsigned char* bitmap[1]; /* Y only */
1776 #endif
1777 int width;
1778 int height;
1779 int stride;
1780 int x, y;
1783 /************************* Globals ***************************/
1785 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1786 struct t_disp disp[9];
1788 /* my memory pool (from the mp3 buffer) */
1789 char print[32]; /* use a common snprintf() buffer */
1790 unsigned char* buf; /* up to here currently used by image(s) */
1792 /* the remaining free part of the buffer for compressed+uncompressed images */
1793 unsigned char* buf_images;
1795 int buf_size, buf_images_size;
1796 /* the root of the images, hereafter are decompresed ones */
1797 unsigned char* buf_root;
1798 int root_size;
1800 int ds, ds_min, ds_max; /* downscaling and limits */
1801 static struct jpeg jpg; /* too large for stack */
1803 static struct tree_context *tree;
1805 /* the current full file name */
1806 static char np_file[MAX_PATH];
1807 int curfile = 0, direction = DIR_NONE, entries = 0;
1809 /* list of the jpeg files */
1810 char **file_pt;
1811 /* are we using the plugin buffer or the audio buffer? */
1812 bool plug_buf = false;
1815 /************************* Implementation ***************************/
1817 #ifdef HAVE_LCD_COLOR
1819 #if (LCD_DEPTH == 16) && \
1820 ((LCD_PIXELFORMAT == RGB565) || (LCD_PIXELFORMAT == RGB565SWAPPED))
1821 #define RYFAC (31*257)
1822 #define GYFAC (63*257)
1823 #define BYFAC (31*257)
1824 #define RVFAC 11170 /* 31 * 257 * 1.402 */
1825 #define GVFAC (-11563) /* 63 * 257 * -0.714136 */
1826 #define GUFAC (-5572) /* 63 * 257 * -0.344136 */
1827 #define BUFAC 14118 /* 31 * 257 * 1.772 */
1828 #endif
1830 #define ROUNDOFFS (127*257)
1832 /* Draw a partial YUV colour bitmap */
1833 void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
1834 int src_x, int src_y, int stride,
1835 int x, int y, int width, int height)
1837 fb_data *dst, *dst_end;
1839 /* nothing to draw? */
1840 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
1841 || (x + width <= 0) || (y + height <= 0))
1842 return;
1844 /* clipping */
1845 if (x < 0)
1847 width += x;
1848 src_x -= x;
1849 x = 0;
1851 if (y < 0)
1853 height += y;
1854 src_y -= y;
1855 y = 0;
1857 if (x + width > LCD_WIDTH)
1858 width = LCD_WIDTH - x;
1859 if (y + height > LCD_HEIGHT)
1860 height = LCD_HEIGHT - y;
1862 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
1863 dst_end = dst + LCD_WIDTH * height;
1867 fb_data *dst_row = dst;
1868 fb_data *row_end = dst_row + width;
1869 const unsigned char *ysrc = src[0] + stride * src_y + src_x;
1870 int y, u, v;
1871 int red, green, blue;
1872 unsigned rbits, gbits, bbits;
1874 if (csub_y) /* colour */
1876 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
1877 const unsigned char *usrc = src[1] + (stride/csub_x) * (src_y/csub_y)
1878 + (src_x/csub_x);
1879 const unsigned char *vsrc = src[2] + (stride/csub_x) * (src_y/csub_y)
1880 + (src_x/csub_x);
1881 int xphase = src_x % csub_x;
1882 int rc, gc, bc;
1884 u = *usrc++ - 128;
1885 v = *vsrc++ - 128;
1886 rc = RVFAC * v + ROUNDOFFS;
1887 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
1888 bc = BUFAC * u + ROUNDOFFS;
1892 y = *ysrc++;
1893 red = RYFAC * y + rc;
1894 green = GYFAC * y + gc;
1895 blue = BYFAC * y + bc;
1897 if ((unsigned)red > (RYFAC*255+ROUNDOFFS))
1899 if (red < 0)
1900 red = 0;
1901 else
1902 red = (RYFAC*255+ROUNDOFFS);
1904 if ((unsigned)green > (GYFAC*255+ROUNDOFFS))
1906 if (green < 0)
1907 green = 0;
1908 else
1909 green = (GYFAC*255+ROUNDOFFS);
1911 if ((unsigned)blue > (BYFAC*255+ROUNDOFFS))
1913 if (blue < 0)
1914 blue = 0;
1915 else
1916 blue = (BYFAC*255+ROUNDOFFS);
1918 rbits = ((unsigned)red) >> 16 ;
1919 gbits = ((unsigned)green) >> 16 ;
1920 bbits = ((unsigned)blue) >> 16 ;
1921 #if LCD_PIXELFORMAT == RGB565
1922 *dst_row++ = (rbits << 11) | (gbits << 5) | bbits;
1923 #elif LCD_PIXELFORMAT == RGB565SWAPPED
1924 *dst_row++ = swap16((rbits << 11) | (gbits << 5) | bbits);
1925 #endif
1927 if (++xphase >= csub_x)
1929 u = *usrc++ - 128;
1930 v = *vsrc++ - 128;
1931 rc = RVFAC * v + ROUNDOFFS;
1932 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
1933 bc = BUFAC * u + ROUNDOFFS;
1934 xphase = 0;
1937 while (dst_row < row_end);
1939 else /* monochrome */
1943 y = *ysrc++;
1944 red = RYFAC * y + ROUNDOFFS; /* blue == red */
1945 green = GYFAC * y + ROUNDOFFS;
1946 rbits = ((unsigned)red) >> 16;
1947 gbits = ((unsigned)green) >> 16;
1948 #if LCD_PIXELFORMAT == RGB565
1949 *dst_row++ = (rbits << 11) | (gbits << 5) | rbits;
1950 #elif LCD_PIXELFORMAT == RGB565SWAPPED
1951 *dst_row++ = swap16((rbits << 11) | (gbits << 5) | rbits);
1952 #endif
1954 while (dst_row < row_end);
1957 src_y++;
1958 dst += LCD_WIDTH;
1960 while (dst < dst_end);
1962 #endif
1965 /* support function for qsort() */
1966 static int compare(const void* p1, const void* p2)
1968 return rb->strcasecmp(*((char **)p1), *((char **)p2));
1971 bool jpg_ext(const char ext[])
1973 if(!rb->strcasecmp(ext,".jpg") ||
1974 !rb->strcasecmp(ext,".jpe") ||
1975 !rb->strcasecmp(ext,".jpeg"))
1976 return true;
1977 else
1978 return false;
1981 /*Read directory contents for scrolling. */
1982 void get_pic_list(void)
1984 int i;
1985 long int str_len = 0;
1986 char *pname;
1987 tree = rb->tree_get_context();
1989 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
1990 file_pt = rb->plugin_get_buffer(&buf_size);
1991 #else
1992 file_pt = rb->plugin_get_audio_buffer(&buf_size);
1993 #endif
1995 for(i = 0; i < tree->filesindir; i++)
1997 if(jpg_ext(rb->strrchr(&tree->name_buffer[str_len],'.')))
1998 file_pt[entries++] = &tree->name_buffer[str_len];
2000 str_len += rb->strlen(&tree->name_buffer[str_len]) + 1;
2003 rb->qsort(file_pt, entries, sizeof(char**), compare);
2005 /* Remove path and leave only the name.*/
2006 pname = rb->strrchr(np_file,'/');
2007 pname++;
2009 /* Find Selected File. */
2010 for(i = 0; i < entries; i++)
2011 if(!rb->strcmp(file_pt[i], pname))
2012 curfile = i;
2015 int change_filename(int direct)
2017 int count = 0;
2018 direction = direct;
2020 if(direct == DIR_PREV)
2024 count++;
2025 if(curfile == 0)
2026 curfile = entries - 1;
2027 else
2028 curfile--;
2029 }while(file_pt[curfile] == '\0' && count < entries);
2030 /* we "erase" the file name if we encounter
2031 * a non-supported file, so skip it now */
2033 else /* DIR_NEXT/DIR_NONE */
2037 count++;
2038 if(curfile == entries - 1)
2039 curfile = 0;
2040 else
2041 curfile++;
2042 }while(file_pt[curfile] == '\0' && count < entries);
2045 if(count == entries && file_pt[curfile] == '\0')
2047 rb->splash(HZ,true,"No supported files");
2048 return PLUGIN_ERROR;
2050 if(rb->strlen(tree->currdir) > 1)
2052 rb->strcpy(np_file, tree->currdir);
2053 rb->strcat(np_file, "/");
2055 else
2056 rb->strcpy(np_file, tree->currdir);
2058 rb->strcat(np_file, file_pt[curfile]);
2060 return PLUGIN_OTHER;
2063 /* switch off overlay, for handling SYS_ events */
2064 void cleanup(void *parameter)
2066 (void)parameter;
2067 #ifdef USEGSLIB
2068 gray_show(false);
2069 #endif
2072 #define VSCROLL (LCD_HEIGHT/8)
2073 #define HSCROLL (LCD_WIDTH/10)
2075 #define ZOOM_IN 100 /* return codes for below function */
2076 #define ZOOM_OUT 101
2078 int show_menu() /* return 1 to quit */
2080 int m;
2081 int result;
2082 static const struct menu_item items[] = {
2083 { "Quit", NULL },
2084 { "Toggle Slideshow Mode", NULL },
2085 { "Change Slideshow Timeout", NULL },
2086 { "Show Playback Menu", NULL },
2087 { "Return", NULL },
2089 static const struct opt_items slideshow[2] = {
2090 {"Disable",NULL},
2091 {"Enable",NULL},
2093 static const struct opt_items timeout[12] = {
2094 { "1 second", NULL },
2095 { "2 seconds", NULL },
2096 { "3 seconds", NULL },
2097 { "4 seconds", NULL },
2098 { "5 seconds", NULL },
2099 { "6 seconds", NULL },
2100 { "7 seconds", NULL },
2101 { "8 seconds", NULL },
2102 { "9 seconds", NULL },
2103 { "10 seconds", NULL },
2104 { "15 seconds", NULL },
2105 { "20 seconds", NULL },
2107 m = rb->menu_init(items, sizeof(items) / sizeof(*items),
2108 NULL, NULL, NULL, NULL);
2109 result=rb->menu_show(m);
2110 switch (result)
2112 case 0:
2113 rb->menu_exit(m);
2114 return 1;
2115 break;
2116 case 1: //toggle slideshow
2117 rb->set_option("Toggle Slideshow", &slideshow_enabled, INT,
2118 slideshow , 2, NULL);
2119 break;
2120 case 2:
2121 switch (button_timeout/HZ)
2123 case 10: result = 9; break;
2124 case 15: result = 10; break;
2125 case 20: result = 11; break;
2126 default: result = (button_timeout/HZ)-1; break;
2128 rb->set_option("Slideshow Timeout", &result, INT,
2129 timeout , 12, NULL);
2130 switch (result)
2132 case 9: button_timeout = 10*HZ; break;
2133 case 10: button_timeout = 15*HZ; break;
2134 case 11: button_timeout = 20*HZ; break;
2135 default: button_timeout = (result+1)*HZ; break;
2137 break;
2138 case 3:
2139 playback_control(rb);
2140 break;
2141 case 4:
2142 MYLCD(clear_display)();
2143 break;
2145 rb->menu_exit(m);
2146 return 0;
2148 /* interactively scroll around the image */
2149 int scroll_bmp(struct t_disp* pdisp)
2151 int lastbutton = 0;
2153 while (true)
2155 int button;
2156 int move;
2158 if (slideshow_enabled)
2159 button = rb->button_get_w_tmo(button_timeout);
2160 else button = rb->button_get(true);
2162 switch(button)
2164 case JPEG_LEFT:
2165 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2166 return change_filename(DIR_PREV);
2167 case JPEG_LEFT | BUTTON_REPEAT:
2168 move = MIN(HSCROLL, pdisp->x);
2169 if (move > 0)
2171 MYXLCD(scroll_right)(move); /* scroll right */
2172 pdisp->x -= move;
2173 #ifdef HAVE_LCD_COLOR
2174 yuv_bitmap_part(
2175 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2176 pdisp->x, pdisp->y, pdisp->stride,
2177 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2178 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2179 #else
2180 MYXLCD(gray_bitmap_part)(
2181 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2182 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2183 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2184 #endif
2185 MYLCD_UPDATE();
2187 break;
2189 case JPEG_RIGHT:
2190 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2191 return change_filename(DIR_NEXT);
2192 case JPEG_RIGHT | BUTTON_REPEAT:
2193 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
2194 if (move > 0)
2196 MYXLCD(scroll_left)(move); /* scroll left */
2197 pdisp->x += move;
2198 #ifdef HAVE_LCD_COLOR
2199 yuv_bitmap_part(
2200 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2201 pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride,
2202 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2203 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2204 #else
2205 MYXLCD(gray_bitmap_part)(
2206 pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move,
2207 pdisp->y, pdisp->stride,
2208 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2209 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2210 #endif
2211 MYLCD_UPDATE();
2213 break;
2215 case JPEG_UP:
2216 case JPEG_UP | BUTTON_REPEAT:
2217 move = MIN(VSCROLL, pdisp->y);
2218 if (move > 0)
2220 MYXLCD(scroll_down)(move); /* scroll down */
2221 pdisp->y -= move;
2222 #ifdef HAVE_LCD_COLOR
2223 yuv_bitmap_part(
2224 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2225 pdisp->x, pdisp->y, pdisp->stride,
2226 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2227 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2228 #else
2229 MYXLCD(gray_bitmap_part)(
2230 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2231 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2232 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2233 #endif
2234 MYLCD_UPDATE();
2236 break;
2238 case JPEG_DOWN:
2239 case JPEG_DOWN | BUTTON_REPEAT:
2240 move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT);
2241 if (move > 0)
2243 MYXLCD(scroll_up)(move); /* scroll up */
2244 pdisp->y += move;
2245 #ifdef HAVE_LCD_COLOR
2246 yuv_bitmap_part(
2247 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x,
2248 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2249 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2250 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2251 #else
2252 MYXLCD(gray_bitmap_part)(
2253 pdisp->bitmap[0], pdisp->x,
2254 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2255 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2256 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2257 #endif
2258 MYLCD_UPDATE();
2260 break;
2261 case BUTTON_NONE:
2262 if (!slideshow_enabled)
2263 break;
2264 if (entries > 0)
2265 return change_filename(DIR_NEXT);
2266 break;
2267 case JPEG_NEXT:
2268 #ifdef JPEG_NEXT_PRE
2269 if (lastbutton != JPEG_NEXT_PRE)
2270 break;
2271 #endif
2272 if (entries > 0)
2273 return change_filename(DIR_NEXT);
2274 break;
2276 case JPEG_PREVIOUS:
2277 if (entries > 0)
2278 return change_filename(DIR_PREV);
2279 break;
2281 case JPEG_ZOOM_IN:
2282 #ifdef JPEG_ZOOM_PRE
2283 if (lastbutton != JPEG_ZOOM_PRE)
2284 break;
2285 #endif
2286 return ZOOM_IN;
2287 break;
2289 case JPEG_ZOOM_OUT:
2290 #ifdef JPEG_ZOOM_PRE
2291 if (lastbutton != JPEG_ZOOM_PRE)
2292 break;
2293 #endif
2294 return ZOOM_OUT;
2295 break;
2297 case JPEG_MENU:
2298 #ifdef USEGSLIB
2299 gray_show(false); /* switch off grayscale overlay */
2300 #endif
2301 if (show_menu() == 1)
2302 return PLUGIN_OK;
2303 #ifdef USEGSLIB
2304 gray_show(true); /* switch on grayscale overlay */
2305 #else
2306 yuv_bitmap_part(
2307 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2308 pdisp->x, pdisp->y, pdisp->stride,
2309 MAX(0, (LCD_WIDTH - pdisp->width) / 2),
2310 MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
2311 MIN(LCD_WIDTH, pdisp->width),
2312 MIN(LCD_HEIGHT, pdisp->height));
2313 MYLCD_UPDATE();
2314 #endif
2315 break;
2316 default:
2317 if (rb->default_event_handler_ex(button, cleanup, NULL)
2318 == SYS_USB_CONNECTED)
2319 return PLUGIN_USB_CONNECTED;
2320 break;
2322 } /* switch */
2324 if (button != BUTTON_NONE)
2325 lastbutton = button;
2326 } /* while (true) */
2329 /********************* main function *************************/
2331 /* callback updating a progress meter while JPEG decoding */
2332 void cb_progess(int current, int total)
2334 rb->yield(); /* be nice to the other threads */
2335 rb->scrollbar(0, LCD_HEIGHT-8, LCD_WIDTH, 8, total, 0,
2336 current, HORIZONTAL);
2337 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
2340 int jpegmem(struct jpeg *p_jpg, int ds)
2342 int size;
2344 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
2345 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
2346 #ifdef HAVE_LCD_COLOR
2347 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
2349 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
2350 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
2351 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
2352 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
2354 #endif
2355 return size;
2358 /* how far can we zoom in without running out of memory */
2359 int min_downscale(struct jpeg *p_jpg, int bufsize)
2361 int downscale = 8;
2363 if (jpegmem(p_jpg, 8) > bufsize)
2364 return 0; /* error, too large, even 1:8 doesn't fit */
2366 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
2367 downscale /= 2;
2369 return downscale;
2373 /* how far can we zoom out, to fit image into the LCD */
2374 int max_downscale(struct jpeg *p_jpg)
2376 int downscale = 1;
2378 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale
2379 || p_jpg->y_size > LCD_HEIGHT*downscale))
2381 downscale *= 2;
2384 return downscale;
2388 /* return decoded or cached image */
2389 struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2391 int w, h; /* used to center output */
2392 int size; /* decompressed image size */
2393 long time; /* measured ticks */
2394 int status;
2396 struct t_disp* p_disp = &disp[ds]; /* short cut */
2398 if (p_disp->bitmap[0] != NULL)
2400 return p_disp; /* we still have it */
2403 /* assign image buffer */
2405 /* physical size needed for decoding */
2406 size = jpegmem(p_jpg, ds);
2407 if (buf_size <= size)
2408 { /* have to discard the current */
2409 int i;
2410 for (i=1; i<=8; i++)
2411 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
2412 buf = buf_root; /* start again from the beginning of the buffer */
2413 buf_size = root_size;
2416 #ifdef HAVE_LCD_COLOR
2417 if (p_jpg->blocks > 1) /* colour jpeg */
2419 int i;
2421 for (i = 1; i < 3; i++)
2423 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
2424 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
2425 p_disp->bitmap[i] = buf;
2426 buf += size;
2427 buf_size -= size;
2429 p_disp->csub_x = p_jpg->subsample_x[1];
2430 p_disp->csub_y = p_jpg->subsample_y[1];
2432 else
2434 p_disp->csub_x = p_disp->csub_y = 0;
2435 p_disp->bitmap[1] = p_disp->bitmap[2] = buf;
2437 #endif
2438 /* size may be less when decoded (if height is not block aligned) */
2439 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
2440 p_disp->bitmap[0] = buf;
2441 buf += size;
2442 buf_size -= size;
2444 rb->snprintf(print, sizeof(print), "decoding %d*%d",
2445 p_jpg->x_size/ds, p_jpg->y_size/ds);
2446 rb->lcd_puts(0, 3, print);
2447 rb->lcd_update();
2449 /* update image properties */
2450 p_disp->width = p_jpg->x_size / ds;
2451 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
2452 p_disp->height = p_jpg->y_size / ds;
2454 /* the actual decoding */
2455 time = *rb->current_tick;
2456 #if !defined(SIMULATOR) && defined(HAVE_ADJUSTABLE_CPU_FREQ)
2457 rb->cpu_boost(true);
2458 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2459 rb->cpu_boost(false);
2460 #else
2461 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2462 #endif
2463 if (status)
2465 rb->splash(HZ, true, "decode error %d", status);
2466 file_pt[curfile] = '\0';
2467 return NULL;
2469 time = *rb->current_tick - time;
2470 rb->snprintf(print, sizeof(print), " %d.%02d sec ", time/HZ, time%HZ);
2471 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
2472 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
2473 rb->lcd_update();
2475 return p_disp;
2479 /* set the view to the given center point, limit if necessary */
2480 void set_view (struct t_disp* p_disp, int cx, int cy)
2482 int x, y;
2484 /* plain center to available width/height */
2485 x = cx - MIN(LCD_WIDTH, p_disp->width) / 2;
2486 y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2;
2488 /* limit against upper image size */
2489 x = MIN(p_disp->width - LCD_WIDTH, x);
2490 y = MIN(p_disp->height - LCD_HEIGHT, y);
2492 /* limit against negative side */
2493 x = MAX(0, x);
2494 y = MAX(0, y);
2496 p_disp->x = x; /* set the values */
2497 p_disp->y = y;
2501 /* calculate the view center based on the bitmap position */
2502 void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
2504 *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2;
2505 *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2;
2509 /* load, decode, display the image */
2510 int load_and_show(char* filename)
2512 int fd;
2513 int filesize;
2514 unsigned char* buf_jpeg; /* compressed JPEG image */
2515 int status;
2516 struct t_disp* p_disp; /* currenly displayed image */
2517 int cx, cy; /* view center */
2519 fd = rb->open(filename, O_RDONLY);
2520 if (fd < 0)
2522 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
2523 rb->splash(HZ, true, print);
2524 return PLUGIN_ERROR;
2526 filesize = rb->filesize(fd);
2527 rb->memset(&disp, 0, sizeof(disp));
2529 buf = buf_images + filesize;
2530 buf_size = buf_images_size - filesize;
2531 /* allocate JPEG buffer */
2532 buf_jpeg = buf_images;
2534 buf_root = buf; /* we can start the decompressed images behind it */
2535 root_size = buf_size;
2537 if (buf_size <= 0)
2539 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2540 if(plug_buf)
2542 rb->close(fd);
2543 rb->lcd_setfont(FONT_SYSFIXED);
2544 rb->lcd_clear_display();
2545 rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
2546 rb->lcd_puts(0,0,print);
2547 rb->lcd_puts(0,1,"Not enough plugin memory!");
2548 rb->lcd_puts(0,2,"Zoom In: Stop playback.");
2549 if(entries>1)
2550 rb->lcd_puts(0,3,"Left/Right: Skip File.");
2551 rb->lcd_puts(0,4,"Off: Quit.");
2552 rb->lcd_update();
2553 rb->lcd_setfont(FONT_UI);
2555 rb->button_clear_queue();
2557 while (1)
2559 int button = rb->button_get(true);
2560 switch(button)
2562 case JPEG_ZOOM_IN:
2563 plug_buf = false;
2564 buf_images =
2565 rb->plugin_get_audio_buffer(&buf_images_size);
2566 /*try again this file, now using the audio buffer */
2567 return PLUGIN_OTHER;
2569 case JPEG_MENU:
2570 return PLUGIN_OK;
2572 case JPEG_LEFT:
2573 if(entries>1)
2575 rb->lcd_clear_display();
2576 return change_filename(DIR_PREV);
2578 break;
2580 case JPEG_RIGHT:
2581 if(entries>1)
2583 rb->lcd_clear_display();
2584 return change_filename(DIR_NEXT);
2586 break;
2587 default:
2588 if(rb->default_event_handler_ex(button, cleanup, NULL)
2589 == SYS_USB_CONNECTED)
2590 return PLUGIN_USB_CONNECTED;
2595 else
2596 #endif
2598 rb->splash(HZ, true, "Out of Memory");
2599 rb->close(fd);
2600 return PLUGIN_ERROR;
2604 #ifdef HAVE_LCD_COLOR
2605 rb->lcd_set_foreground(LCD_WHITE);
2606 rb->lcd_set_background(LCD_BLACK);
2607 #endif
2609 rb->lcd_clear_display();
2610 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
2611 rb->lcd_puts(0, 0, print);
2612 rb->lcd_update();
2614 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
2615 rb->lcd_puts(0, 1, print);
2616 rb->lcd_update();
2618 rb->read(fd, buf_jpeg, filesize);
2619 rb->close(fd);
2621 rb->snprintf(print, sizeof(print), "decoding markers");
2622 rb->lcd_puts(0, 2, print);
2623 rb->lcd_update();
2627 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
2628 /* process markers, unstuffing */
2629 status = process_markers(buf_jpeg, filesize, &jpg);
2631 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
2632 { /* bad format or minimum components not contained */
2633 rb->splash(HZ, true, "unsupported %d", status);
2634 file_pt[curfile] = '\0';
2635 return change_filename(direction);
2638 if (!(status & DHT)) /* if no Huffman table present: */
2639 default_huff_tbl(&jpg); /* use default */
2640 build_lut(&jpg); /* derive Huffman and other lookup-tables */
2642 rb->snprintf(print, sizeof(print), "image %dx%d", jpg.x_size, jpg.y_size);
2643 rb->lcd_puts(0, 2, print);
2644 rb->lcd_update();
2646 ds_max = max_downscale(&jpg); /* check display constraint */
2647 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */
2648 if (ds_min == 0)
2650 rb->splash(HZ, true, "too large");
2651 file_pt[curfile] = '\0';
2652 return change_filename(direction);
2655 ds = ds_max; /* initials setting */
2656 cx = jpg.x_size/ds/2; /* center the view */
2657 cy = jpg.y_size/ds/2;
2659 do /* loop the image prepare and decoding when zoomed */
2661 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */
2662 if (p_disp == NULL)
2663 return change_filename(direction);
2665 set_view(p_disp, cx, cy);
2667 rb->snprintf(print, sizeof(print), "showing %dx%d",
2668 p_disp->width, p_disp->height);
2669 rb->lcd_puts(0, 3, print);
2670 rb->lcd_update();
2672 MYLCD(clear_display)();
2673 #ifdef HAVE_LCD_COLOR
2674 yuv_bitmap_part(
2675 p_disp->bitmap, p_disp->csub_x, p_disp->csub_y,
2676 p_disp->x, p_disp->y, p_disp->stride,
2677 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
2678 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
2679 MIN(LCD_WIDTH, p_disp->width),
2680 MIN(LCD_HEIGHT, p_disp->height));
2681 #else
2682 MYXLCD(gray_bitmap_part)(
2683 p_disp->bitmap[0], p_disp->x, p_disp->y, p_disp->stride,
2684 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
2685 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
2686 MIN(LCD_WIDTH, p_disp->width),
2687 MIN(LCD_HEIGHT, p_disp->height));
2688 #endif
2689 MYLCD_UPDATE();
2691 #ifdef USEGSLIB
2692 gray_show(true); /* switch on grayscale overlay */
2693 #endif
2695 /* drawing is now finished, play around with scrolling
2696 * until you press OFF or connect USB
2698 while (1)
2700 status = scroll_bmp(p_disp);
2701 if (status == ZOOM_IN)
2703 if (ds > ds_min)
2705 ds /= 2; /* reduce downscaling to zoom in */
2706 get_view(p_disp, &cx, &cy);
2707 cx *= 2; /* prepare the position in the new image */
2708 cy *= 2;
2710 else
2711 continue;
2714 if (status == ZOOM_OUT)
2716 if (ds < ds_max)
2718 ds *= 2; /* increase downscaling to zoom out */
2719 get_view(p_disp, &cx, &cy);
2720 cx /= 2; /* prepare the position in the new image */
2721 cy /= 2;
2723 else
2724 continue;
2726 break;
2729 #ifdef USEGSLIB
2730 gray_show(false); /* switch off overlay */
2731 #else
2732 rb->lcd_clear_display();
2733 #endif
2736 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
2737 && status != PLUGIN_OTHER);
2738 return status;
2741 /******************** Plugin entry point *********************/
2743 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
2745 rb = api;
2747 int condition;
2748 #ifdef USEGSLIB
2749 int grayscales;
2750 long graysize; /* helper */
2751 #endif
2753 rb->strcpy(np_file, parameter);
2754 get_pic_list();
2756 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
2757 #if CONFIG_CODEC == SWCODEC
2758 if(rb->pcm_is_playing())
2759 #else
2760 if(rb->mp3_is_playing())
2761 #endif
2763 buf = rb->plugin_get_buffer(&buf_size) +
2764 (entries * sizeof(char**));
2765 buf_size -= (entries * sizeof(char**));
2766 plug_buf = true;
2768 else
2769 buf = rb->plugin_get_audio_buffer(&buf_size);
2770 #else
2771 buf = rb->plugin_get_audio_buffer(&buf_size) +
2772 (entries * sizeof(char**));
2773 buf_size -= (entries * sizeof(char**));
2774 #endif
2776 #ifdef USEGSLIB
2777 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */
2778 grayscales = gray_init(rb, buf, buf_size, false, LCD_WIDTH, LCD_HEIGHT/8,
2779 32, &graysize) + 1;
2780 buf += graysize;
2781 buf_size -= graysize;
2782 if (grayscales < 33 || buf_size <= 0)
2784 rb->splash(HZ, true, "gray buf error");
2785 return PLUGIN_ERROR;
2787 #else
2788 xlcd_init(rb);
2789 #endif
2791 buf_images = buf; buf_images_size = buf_size;
2795 condition = load_and_show(np_file);
2796 }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
2797 && condition != PLUGIN_ERROR);
2799 #ifdef USEGSLIB
2800 gray_release(); /* deinitialize */
2801 #endif
2803 return condition;
2806 #endif /* HAVE_LCD_BITMAP */