make the dialog box asking about replacing an up-to-date bootloader less confusing.
[Rockbox.git] / apps / plugins / jpeg.c
blob09f7455f8b53800b62d07b2b13cfa874f9d6aba2
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"
29 #include "oldmenuapi.h"
30 #include "helper.h"
32 #ifdef HAVE_LCD_BITMAP
33 #include "gray.h"
34 #include "xlcd.h"
36 #ifdef HAVE_LCD_COLOR
37 #include "lib/configfile.h"
38 #endif
40 PLUGIN_HEADER
42 /* variable button definitions */
43 #if CONFIG_KEYPAD == RECORDER_PAD
44 #define JPEG_ZOOM_IN BUTTON_PLAY
45 #define JPEG_ZOOM_OUT BUTTON_ON
46 #define JPEG_UP BUTTON_UP
47 #define JPEG_DOWN BUTTON_DOWN
48 #define JPEG_LEFT BUTTON_LEFT
49 #define JPEG_RIGHT BUTTON_RIGHT
50 #define JPEG_NEXT BUTTON_F3
51 #define JPEG_PREVIOUS BUTTON_F2
52 #define JPEG_MENU BUTTON_OFF
54 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
55 #define JPEG_ZOOM_IN BUTTON_SELECT
56 #define JPEG_ZOOM_OUT BUTTON_ON
57 #define JPEG_UP BUTTON_UP
58 #define JPEG_DOWN BUTTON_DOWN
59 #define JPEG_LEFT BUTTON_LEFT
60 #define JPEG_RIGHT BUTTON_RIGHT
61 #define JPEG_NEXT BUTTON_F3
62 #define JPEG_PREVIOUS BUTTON_F2
63 #define JPEG_MENU BUTTON_OFF
65 #elif CONFIG_KEYPAD == ONDIO_PAD
66 #define JPEG_ZOOM_PRE BUTTON_MENU
67 #define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
68 #define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
69 #define JPEG_UP BUTTON_UP
70 #define JPEG_DOWN BUTTON_DOWN
71 #define JPEG_LEFT BUTTON_LEFT
72 #define JPEG_RIGHT BUTTON_RIGHT
73 #define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
74 #define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
75 #define JPEG_MENU BUTTON_OFF
77 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
78 (CONFIG_KEYPAD == IRIVER_H300_PAD)
79 #define JPEG_ZOOM_IN BUTTON_SELECT
80 #define JPEG_ZOOM_OUT BUTTON_MODE
81 #define JPEG_UP BUTTON_UP
82 #define JPEG_DOWN BUTTON_DOWN
83 #define JPEG_LEFT BUTTON_LEFT
84 #define JPEG_RIGHT BUTTON_RIGHT
85 #if (CONFIG_KEYPAD == IRIVER_H100_PAD)
86 #define JPEG_NEXT BUTTON_ON
87 #define JPEG_PREVIOUS BUTTON_REC
88 #else
89 #define JPEG_NEXT BUTTON_REC
90 #define JPEG_PREVIOUS BUTTON_ON
91 #endif
92 #define JPEG_MENU BUTTON_OFF
93 #define JPEG_RC_MENU BUTTON_RC_STOP
95 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
96 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
97 #define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
98 #define JPEG_ZOOM_OUT BUTTON_SCROLL_BACK
99 #define JPEG_UP BUTTON_MENU
100 #define JPEG_DOWN BUTTON_PLAY
101 #define JPEG_LEFT BUTTON_LEFT
102 #define JPEG_RIGHT BUTTON_RIGHT
103 #define JPEG_MENU (BUTTON_SELECT | BUTTON_MENU)
104 #define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
105 #define JPEG_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
107 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
108 #define JPEG_ZOOM_PRE BUTTON_SELECT
109 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
110 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
111 #define JPEG_UP BUTTON_UP
112 #define JPEG_DOWN BUTTON_DOWN
113 #define JPEG_LEFT BUTTON_LEFT
114 #define JPEG_RIGHT BUTTON_RIGHT
115 #define JPEG_MENU BUTTON_POWER
116 #define JPEG_NEXT BUTTON_PLAY
117 #define JPEG_PREVIOUS BUTTON_REC
119 #elif CONFIG_KEYPAD == GIGABEAT_PAD
120 #define JPEG_ZOOM_IN BUTTON_VOL_UP
121 #define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
122 #define JPEG_UP BUTTON_UP
123 #define JPEG_DOWN BUTTON_DOWN
124 #define JPEG_LEFT BUTTON_LEFT
125 #define JPEG_RIGHT BUTTON_RIGHT
126 #define JPEG_MENU BUTTON_MENU
127 #define JPEG_NEXT (BUTTON_A | BUTTON_RIGHT)
128 #define JPEG_PREVIOUS (BUTTON_A | BUTTON_LEFT)
130 #elif CONFIG_KEYPAD == SANSA_E200_PAD
131 #define JPEG_ZOOM_PRE BUTTON_SELECT
132 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
133 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
134 #define JPEG_UP BUTTON_UP
135 #define JPEG_DOWN BUTTON_DOWN
136 #define JPEG_LEFT BUTTON_LEFT
137 #define JPEG_RIGHT BUTTON_RIGHT
138 #define JPEG_MENU BUTTON_POWER
139 #define JPEG_SLIDE_SHOW BUTTON_REC
140 #define JPEG_NEXT BUTTON_SCROLL_DOWN
141 #define JPEG_NEXT_REPEAT (BUTTON_SCROLL_DOWN|BUTTON_REPEAT)
142 #define JPEG_PREVIOUS BUTTON_SCROLL_UP
143 #define JPEG_PREVIOUS_REPEAT (BUTTON_SCROLL_UP|BUTTON_REPEAT)
145 #elif CONFIG_KEYPAD == SANSA_C200_PAD
146 #define JPEG_ZOOM_PRE BUTTON_SELECT
147 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
148 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
149 #define JPEG_UP BUTTON_UP
150 #define JPEG_DOWN BUTTON_DOWN
151 #define JPEG_LEFT BUTTON_LEFT
152 #define JPEG_RIGHT BUTTON_RIGHT
153 #define JPEG_MENU BUTTON_POWER
154 #define JPEG_SLIDE_SHOW BUTTON_REC
155 #define JPEG_NEXT BUTTON_VOL_UP
156 #define JPEG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
157 #define JPEG_PREVIOUS BUTTON_VOL_DOWN
158 #define JPEG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
160 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
161 #define JPEG_ZOOM_PRE BUTTON_PLAY
162 #define JPEG_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
163 #define JPEG_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
164 #define JPEG_UP BUTTON_SCROLL_UP
165 #define JPEG_DOWN BUTTON_SCROLL_DOWN
166 #define JPEG_LEFT BUTTON_LEFT
167 #define JPEG_RIGHT BUTTON_RIGHT
168 #define JPEG_MENU BUTTON_POWER
169 #define JPEG_NEXT BUTTON_FF
170 #define JPEG_PREVIOUS BUTTON_REW
172 #endif
174 /* different graphics libraries */
175 #if LCD_DEPTH < 8
176 #define USEGSLIB
177 #define MYLCD(fn) gray_ub_ ## fn
178 #define MYLCD_UPDATE()
179 #define MYXLCD(fn) gray_ub_ ## fn
180 #else
181 #define MYLCD(fn) rb->lcd_ ## fn
182 #define MYLCD_UPDATE() rb->lcd_update();
183 #define MYXLCD(fn) xlcd_ ## fn
184 #endif
186 #define MAX_X_SIZE LCD_WIDTH*8
188 /* Min memory allowing us to use the plugin buffer
189 * and thus not stopping the music
190 * *Very* rough estimation:
191 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
192 * + 20k code size = 60 000
193 * + 50k min for jpeg = 120 000
195 #define MIN_MEM 120000
197 /* Headings */
198 #define DIR_PREV 1
199 #define DIR_NEXT -1
200 #define DIR_NONE 0
202 #define PLUGIN_OTHER 10 /* State code for output with return. */
204 /******************************* Globals ***********************************/
206 static struct plugin_api* rb;
207 MEM_FUNCTION_WRAPPERS(rb);
209 /* for portability of below JPEG code */
210 #define MEMSET(p,v,c) rb->memset(p,v,c)
211 #define MEMCPY(d,s,c) rb->memcpy(d,s,c)
212 #define INLINE static inline
213 #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
215 static int slideshow_enabled = false; /* run slideshow */
216 static int running_slideshow = false; /* loading image because of slideshw */
217 #ifndef SIMULATOR
218 static int immediate_ata_off = false; /* power down disk after loading */
219 #endif
220 static int button_timeout = HZ*5;
222 #ifdef HAVE_LCD_COLOR
224 /* Persistent configuration - only needed for color displays atm */
225 #define JPEG_CONFIGFILE "jpeg.cfg"
226 #define JPEG_SETTINGS_MINVERSION 1
227 #define JPEG_SETTINGS_VERSION 1
229 enum color_modes
231 COLOURMODE_COLOUR = 0,
232 COLOURMODE_GRAY,
233 COLOUR_NUM_MODES
236 enum dither_modes
238 DITHER_NONE = 0, /* No dithering */
239 DITHER_ORDERED, /* Bayer ordered */
240 DITHER_DIFFUSION, /* Floyd/Steinberg error diffusion */
241 DITHER_NUM_MODES
244 struct jpeg_settings
246 int colour_mode;
247 int dither_mode;
250 static struct jpeg_settings jpeg_settings =
251 { COLOURMODE_COLOUR, DITHER_NONE };
252 static struct jpeg_settings old_settings;
254 static struct configdata jpeg_config[] =
256 { TYPE_ENUM, 0, COLOUR_NUM_MODES, &jpeg_settings.colour_mode,
257 "Colour Mode", (char *[]){ "Colour", "Grayscale" }, NULL },
258 { TYPE_ENUM, 0, DITHER_NUM_MODES, &jpeg_settings.dither_mode,
259 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" }, NULL },
262 #endif /* HAVE_LCD_COLOR */
263 #if LCD_DEPTH > 1
264 fb_data* old_backdrop;
265 #endif
267 /**************** begin JPEG code ********************/
269 INLINE unsigned range_limit(int value)
271 #if CONFIG_CPU == SH7034
272 unsigned tmp;
273 asm ( /* Note: Uses knowledge that only low byte of result is used */
274 "mov #-128,%[t] \n"
275 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
276 "extu.b %[v],%[t] \n"
277 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
278 "bt 1f \n" /* yes: no overflow */
279 "cmp/pz %[v] \n" /* overflow: positive? */
280 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
281 "1: \n"
282 : /* outputs */
283 [v]"+r"(value),
284 [t]"=&r"(tmp)
286 return value;
287 #elif defined(CPU_COLDFIRE)
288 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
289 "add.l #128,%[v] \n" /* value += 128; */
290 "cmp.l #255,%[v] \n" /* overflow? */
291 "bls.b 1f \n" /* no: return value */
292 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
293 "1: \n"
294 : /* outputs */
295 [v]"+d"(value)
297 return value;
298 #elif defined(CPU_ARM)
299 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
300 "add %[v], %[v], #128 \n" /* value += 128 */
301 "cmp %[v], #255 \n" /* out of range 0..255? */
302 "mvnhi %[v], %[v], asr #31 \n" /* yes: set all bits to ~(sign_bit) */
303 : /* outputs */
304 [v]"+r"(value)
306 return value;
307 #else
308 value += 128;
310 if ((unsigned)value <= 255)
311 return value;
313 if (value < 0)
314 return 0;
316 return 255;
317 #endif
320 /* IDCT implementation */
323 #define CONST_BITS 13
324 #define PASS1_BITS 2
327 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
328 * causing a lot of useless floating-point operations at run time.
329 * To get around this we use the following pre-calculated constants.
330 * If you change CONST_BITS you may want to add appropriate values.
331 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
333 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
334 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
335 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
336 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
337 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
338 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
339 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
340 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
341 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
342 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
343 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
344 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
348 /* Multiply an long variable by an long constant to yield an long result.
349 * For 8-bit samples with the recommended scaling, all the variable
350 * and constant values involved are no more than 16 bits wide, so a
351 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
352 * For 12-bit samples, a full 32-bit multiplication will be needed.
354 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
357 /* Dequantize a coefficient by multiplying it by the multiplier-table
358 * entry; produce an int result. In this module, both inputs and result
359 * are 16 bits or less, so either int or short multiply will work.
361 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
362 #define DEQUANTIZE MULTIPLY16
364 /* Descale and correctly round an int value that's scaled by N bits.
365 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
366 * the fudge factor is correct for either sign of X.
368 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
373 * Perform dequantization and inverse DCT on one block of coefficients,
374 * producing a reduced-size 1x1 output block.
376 void idct1x1(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
378 (void)skip_line; /* unused */
379 *p_byte = range_limit(inptr[0] * quantptr[0] >> 3);
385 * Perform dequantization and inverse DCT on one block of coefficients,
386 * producing a reduced-size 2x2 output block.
388 void idct2x2(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
390 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
391 unsigned char* outptr;
393 /* Pass 1: process columns from input, store into work array. */
395 /* Column 0 */
396 tmp4 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
397 tmp5 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
399 tmp0 = tmp4 + tmp5;
400 tmp2 = tmp4 - tmp5;
402 /* Column 1 */
403 tmp4 = DEQUANTIZE(inptr[8*0+1], quantptr[8*0+1]);
404 tmp5 = DEQUANTIZE(inptr[8*1+1], quantptr[8*1+1]);
406 tmp1 = tmp4 + tmp5;
407 tmp3 = tmp4 - tmp5;
409 /* Pass 2: process 2 rows, store into output array. */
411 /* Row 0 */
412 outptr = p_byte;
414 outptr[0] = range_limit((int) DESCALE(tmp0 + tmp1, 3));
415 outptr[1] = range_limit((int) DESCALE(tmp0 - tmp1, 3));
417 /* Row 1 */
418 outptr = p_byte + skip_line;
420 outptr[0] = range_limit((int) DESCALE(tmp2 + tmp3, 3));
421 outptr[1] = range_limit((int) DESCALE(tmp2 - tmp3, 3));
427 * Perform dequantization and inverse DCT on one block of coefficients,
428 * producing a reduced-size 4x4 output block.
430 void idct4x4(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
432 int tmp0, tmp2, tmp10, tmp12;
433 int z1, z2, z3;
434 int * wsptr;
435 unsigned char* outptr;
436 int ctr;
437 int workspace[4*4]; /* buffers data between passes */
439 /* Pass 1: process columns from input, store into work array. */
441 wsptr = workspace;
442 for (ctr = 0; ctr < 4; ctr++, inptr++, quantptr++, wsptr++)
444 /* Even part */
446 tmp0 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
447 tmp2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
449 tmp10 = (tmp0 + tmp2) << PASS1_BITS;
450 tmp12 = (tmp0 - tmp2) << PASS1_BITS;
452 /* Odd part */
453 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
455 z2 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
456 z3 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
458 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
459 tmp0 = DESCALE(z1 + MULTIPLY16(z3, - FIX_1_847759065), CONST_BITS-PASS1_BITS);
460 tmp2 = DESCALE(z1 + MULTIPLY16(z2, FIX_0_765366865), CONST_BITS-PASS1_BITS);
462 /* Final output stage */
464 wsptr[4*0] = (int) (tmp10 + tmp2);
465 wsptr[4*3] = (int) (tmp10 - tmp2);
466 wsptr[4*1] = (int) (tmp12 + tmp0);
467 wsptr[4*2] = (int) (tmp12 - tmp0);
470 /* Pass 2: process 4 rows from work array, store into output array. */
472 wsptr = workspace;
473 for (ctr = 0; ctr < 4; ctr++)
475 outptr = p_byte + (ctr*skip_line);
476 /* Even part */
478 tmp0 = (int) wsptr[0];
479 tmp2 = (int) wsptr[2];
481 tmp10 = (tmp0 + tmp2) << CONST_BITS;
482 tmp12 = (tmp0 - tmp2) << CONST_BITS;
484 /* Odd part */
485 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
487 z2 = (int) wsptr[1];
488 z3 = (int) wsptr[3];
490 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
491 tmp0 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
492 tmp2 = z1 + MULTIPLY16(z2, FIX_0_765366865);
494 /* Final output stage */
496 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp2,
497 CONST_BITS+PASS1_BITS+3));
498 outptr[3] = range_limit((int) DESCALE(tmp10 - tmp2,
499 CONST_BITS+PASS1_BITS+3));
500 outptr[1] = range_limit((int) DESCALE(tmp12 + tmp0,
501 CONST_BITS+PASS1_BITS+3));
502 outptr[2] = range_limit((int) DESCALE(tmp12 - tmp0,
503 CONST_BITS+PASS1_BITS+3));
505 wsptr += 4; /* advance pointer to next row */
512 * Perform dequantization and inverse DCT on one block of coefficients.
514 void idct8x8(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
516 long tmp0, tmp1, tmp2, tmp3;
517 long tmp10, tmp11, tmp12, tmp13;
518 long z1, z2, z3, z4, z5;
519 int * wsptr;
520 unsigned char* outptr;
521 int ctr;
522 int workspace[64]; /* buffers data between passes */
524 /* Pass 1: process columns from input, store into work array. */
525 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
526 /* furthermore, we scale the results by 2**PASS1_BITS. */
528 wsptr = workspace;
529 for (ctr = 8; ctr > 0; ctr--)
531 /* Due to quantization, we will usually find that many of the input
532 * coefficients are zero, especially the AC terms. We can exploit this
533 * by short-circuiting the IDCT calculation for any column in which all
534 * the AC terms are zero. In that case each output is equal to the
535 * DC coefficient (with scale factor as needed).
536 * With typical images and quantization tables, half or more of the
537 * column DCT calculations can be simplified this way.
540 if ((inptr[8*1] | inptr[8*2] | inptr[8*3]
541 | inptr[8*4] | inptr[8*5] | inptr[8*6] | inptr[8*7]) == 0)
543 /* AC terms all zero */
544 int dcval = DEQUANTIZE(inptr[8*0], quantptr[8*0]) << PASS1_BITS;
546 wsptr[8*0] = wsptr[8*1] = wsptr[8*2] = wsptr[8*3] = wsptr[8*4]
547 = wsptr[8*5] = wsptr[8*6] = wsptr[8*7] = dcval;
548 inptr++; /* advance pointers to next column */
549 quantptr++;
550 wsptr++;
551 continue;
554 /* Even part: reverse the even part of the forward DCT. */
555 /* The rotator is sqrt(2)*c(-6). */
557 z2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
558 z3 = DEQUANTIZE(inptr[8*6], quantptr[8*6]);
560 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
561 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
562 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
564 z2 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
565 z3 = DEQUANTIZE(inptr[8*4], quantptr[8*4]);
567 tmp0 = (z2 + z3) << CONST_BITS;
568 tmp1 = (z2 - z3) << CONST_BITS;
570 tmp10 = tmp0 + tmp3;
571 tmp13 = tmp0 - tmp3;
572 tmp11 = tmp1 + tmp2;
573 tmp12 = tmp1 - tmp2;
575 /* Odd part per figure 8; the matrix is unitary and hence its
576 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
578 tmp0 = DEQUANTIZE(inptr[8*7], quantptr[8*7]);
579 tmp1 = DEQUANTIZE(inptr[8*5], quantptr[8*5]);
580 tmp2 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
581 tmp3 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
583 z1 = tmp0 + tmp3;
584 z2 = tmp1 + tmp2;
585 z3 = tmp0 + tmp2;
586 z4 = tmp1 + tmp3;
587 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
589 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
590 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
591 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
592 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
593 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
594 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
595 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
596 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
598 z3 += z5;
599 z4 += z5;
601 tmp0 += z1 + z3;
602 tmp1 += z2 + z4;
603 tmp2 += z2 + z3;
604 tmp3 += z1 + z4;
606 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
608 wsptr[8*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
609 wsptr[8*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
610 wsptr[8*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
611 wsptr[8*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
612 wsptr[8*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
613 wsptr[8*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
614 wsptr[8*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
615 wsptr[8*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
617 inptr++; /* advance pointers to next column */
618 quantptr++;
619 wsptr++;
622 /* Pass 2: process rows from work array, store into output array. */
623 /* Note that we must descale the results by a factor of 8 == 2**3, */
624 /* and also undo the PASS1_BITS scaling. */
626 wsptr = workspace;
627 for (ctr = 0; ctr < 8; ctr++)
629 outptr = p_byte + (ctr*skip_line);
630 /* Rows of zeroes can be exploited in the same way as we did with columns.
631 * However, the column calculation has created many nonzero AC terms, so
632 * the simplification applies less often (typically 5% to 10% of the time).
633 * On machines with very fast multiplication, it's possible that the
634 * test takes more time than it's worth. In that case this section
635 * may be commented out.
638 #ifndef NO_ZERO_ROW_TEST
639 if ((wsptr[1] | wsptr[2] | wsptr[3]
640 | wsptr[4] | wsptr[5] | wsptr[6] | wsptr[7]) == 0)
642 /* AC terms all zero */
643 unsigned char dcval = range_limit((int) DESCALE((long) wsptr[0],
644 PASS1_BITS+3));
646 outptr[0] = dcval;
647 outptr[1] = dcval;
648 outptr[2] = dcval;
649 outptr[3] = dcval;
650 outptr[4] = dcval;
651 outptr[5] = dcval;
652 outptr[6] = dcval;
653 outptr[7] = dcval;
655 wsptr += 8; /* advance pointer to next row */
656 continue;
658 #endif
660 /* Even part: reverse the even part of the forward DCT. */
661 /* The rotator is sqrt(2)*c(-6). */
663 z2 = (long) wsptr[2];
664 z3 = (long) wsptr[6];
666 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
667 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
668 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
670 tmp0 = ((long) wsptr[0] + (long) wsptr[4]) << CONST_BITS;
671 tmp1 = ((long) wsptr[0] - (long) wsptr[4]) << CONST_BITS;
673 tmp10 = tmp0 + tmp3;
674 tmp13 = tmp0 - tmp3;
675 tmp11 = tmp1 + tmp2;
676 tmp12 = tmp1 - tmp2;
678 /* Odd part per figure 8; the matrix is unitary and hence its
679 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
681 tmp0 = (long) wsptr[7];
682 tmp1 = (long) wsptr[5];
683 tmp2 = (long) wsptr[3];
684 tmp3 = (long) wsptr[1];
686 z1 = tmp0 + tmp3;
687 z2 = tmp1 + tmp2;
688 z3 = tmp0 + tmp2;
689 z4 = tmp1 + tmp3;
690 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
692 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
693 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
694 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
695 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
696 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
697 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
698 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
699 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
701 z3 += z5;
702 z4 += z5;
704 tmp0 += z1 + z3;
705 tmp1 += z2 + z4;
706 tmp2 += z2 + z3;
707 tmp3 += z1 + z4;
709 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
711 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp3,
712 CONST_BITS+PASS1_BITS+3));
713 outptr[7] = range_limit((int) DESCALE(tmp10 - tmp3,
714 CONST_BITS+PASS1_BITS+3));
715 outptr[1] = range_limit((int) DESCALE(tmp11 + tmp2,
716 CONST_BITS+PASS1_BITS+3));
717 outptr[6] = range_limit((int) DESCALE(tmp11 - tmp2,
718 CONST_BITS+PASS1_BITS+3));
719 outptr[2] = range_limit((int) DESCALE(tmp12 + tmp1,
720 CONST_BITS+PASS1_BITS+3));
721 outptr[5] = range_limit((int) DESCALE(tmp12 - tmp1,
722 CONST_BITS+PASS1_BITS+3));
723 outptr[3] = range_limit((int) DESCALE(tmp13 + tmp0,
724 CONST_BITS+PASS1_BITS+3));
725 outptr[4] = range_limit((int) DESCALE(tmp13 - tmp0,
726 CONST_BITS+PASS1_BITS+3));
728 wsptr += 8; /* advance pointer to next row */
734 /* JPEG decoder implementation */
737 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
739 struct derived_tbl
741 /* Basic tables: (element [0] of each array is unused) */
742 long mincode[17]; /* smallest code of length k */
743 long maxcode[18]; /* largest code of length k (-1 if none) */
744 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
745 int valptr[17]; /* huffval[] index of 1st symbol of length k */
747 /* Back link to public Huffman table (needed only in slow_DECODE) */
748 int* pub;
750 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
751 the input data stream. If the next Huffman code is no more
752 than HUFF_LOOKAHEAD bits long, we can obtain its length and
753 the corresponding symbol directly from these tables. */
754 int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
755 unsigned char look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
758 #define QUANT_TABLE_LENGTH 64
760 /* for type of Huffman table */
761 #define DC_LEN 28
762 #define AC_LEN 178
764 struct huffman_table
765 { /* length and code according to JFIF format */
766 int huffmancodes_dc[DC_LEN];
767 int huffmancodes_ac[AC_LEN];
770 struct frame_component
772 int ID;
773 int horizontal_sampling;
774 int vertical_sampling;
775 int quanttable_select;
778 struct scan_component
780 int ID;
781 int DC_select;
782 int AC_select;
785 struct bitstream
787 unsigned long get_buffer; /* current bit-extraction buffer */
788 int bits_left; /* # of unused bits in it */
789 unsigned char* next_input_byte;
790 unsigned char* input_end; /* upper limit +1 */
793 struct jpeg
795 int x_size, y_size; /* size of image (can be less than block boundary) */
796 int x_phys, y_phys; /* physical size, block aligned */
797 int x_mbl; /* x dimension of MBL */
798 int y_mbl; /* y dimension of MBL */
799 int blocks; /* blocks per MB */
800 int restart_interval; /* number of MCUs between RSTm markers */
801 int store_pos[4]; /* for Y block ordering */
803 unsigned char* p_entropy_data;
804 unsigned char* p_entropy_end;
806 int quanttable[4][QUANT_TABLE_LENGTH]; /* raw quantization tables 0-3 */
807 int qt_idct[2][QUANT_TABLE_LENGTH]; /* quantization tables for IDCT */
809 struct huffman_table hufftable[2]; /* Huffman tables */
810 struct derived_tbl dc_derived_tbls[2]; /* Huffman-LUTs */
811 struct derived_tbl ac_derived_tbls[2];
813 struct frame_component frameheader[3]; /* Component descriptor */
814 struct scan_component scanheader[3]; /* currently not used */
816 int mcu_membership[6]; /* info per block */
817 int tab_membership[6];
818 int subsample_x[3]; /* info per component */
819 int subsample_y[3];
823 /* possible return flags for process_markers() */
824 #define HUFFTAB 0x0001 /* with huffman table */
825 #define QUANTTAB 0x0002 /* with quantization table */
826 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
827 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
828 #define SOF0 0x0010 /* with SOF0-Segment */
829 #define DHT 0x0020 /* with Definition of huffman tables */
830 #define SOS 0x0040 /* with Start-of-Scan segment */
831 #define DQT 0x0080 /* with definition of quantization table */
833 /* Preprocess the JPEG JFIF file */
834 int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
836 unsigned char* p_bytes = p_src;
837 int marker_size; /* variable length of marker segment */
838 int i, j, n;
839 int ret = 0; /* returned flags */
841 p_jpeg->p_entropy_end = p_src + size;
843 while (p_src < p_bytes + size)
845 if (*p_src++ != 0xFF) /* no marker? */
847 p_src--; /* it's image data, put it back */
848 p_jpeg->p_entropy_data = p_src;
849 break; /* exit marker processing */
852 switch (*p_src++)
854 case 0xFF: /* Fill byte */
855 ret |= FILL_FF;
856 case 0x00: /* Zero stuffed byte - entropy data */
857 p_src--; /* put it back */
858 continue;
860 case 0xC0: /* SOF Huff - Baseline DCT */
862 ret |= SOF0;
863 marker_size = *p_src++ << 8; /* Highbyte */
864 marker_size |= *p_src++; /* Lowbyte */
865 n = *p_src++; /* sample precision (= 8 or 12) */
866 if (n != 8)
868 return(-1); /* Unsupported sample precision */
870 p_jpeg->y_size = *p_src++ << 8; /* Highbyte */
871 p_jpeg->y_size |= *p_src++; /* Lowbyte */
872 p_jpeg->x_size = *p_src++ << 8; /* Highbyte */
873 p_jpeg->x_size |= *p_src++; /* Lowbyte */
875 n = (marker_size-2-6)/3;
876 if (*p_src++ != n || (n != 1 && n != 3))
878 return(-2); /* Unsupported SOF0 component specification */
880 for (i=0; i<n; i++)
882 p_jpeg->frameheader[i].ID = *p_src++; /* Component info */
883 p_jpeg->frameheader[i].horizontal_sampling = *p_src >> 4;
884 p_jpeg->frameheader[i].vertical_sampling = *p_src++ & 0x0F;
885 p_jpeg->frameheader[i].quanttable_select = *p_src++;
886 if (p_jpeg->frameheader[i].horizontal_sampling > 2
887 || p_jpeg->frameheader[i].vertical_sampling > 2)
888 return -3; /* Unsupported SOF0 subsampling */
890 p_jpeg->blocks = n;
892 break;
894 case 0xC1: /* SOF Huff - Extended sequential DCT*/
895 case 0xC2: /* SOF Huff - Progressive DCT*/
896 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
897 case 0xC5: /* SOF Huff - Differential sequential DCT*/
898 case 0xC6: /* SOF Huff - Differential progressive DCT*/
899 case 0xC7: /* SOF Huff - Differential spatial*/
900 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
901 case 0xC9: /* SOF Arith - Extended sequential DCT*/
902 case 0xCA: /* SOF Arith - Progressive DCT*/
903 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
904 case 0xCD: /* SOF Arith - Differential sequential DCT*/
905 case 0xCE: /* SOF Arith - Differential progressive DCT*/
906 case 0xCF: /* SOF Arith - Differential spatial*/
908 return (-4); /* other DCT model than baseline not implemented */
911 case 0xC4: /* Define Huffman Table(s) */
913 unsigned char* p_temp;
915 ret |= DHT;
916 marker_size = *p_src++ << 8; /* Highbyte */
917 marker_size |= *p_src++; /* Lowbyte */
919 p_temp = p_src;
920 while (p_src < p_temp+marker_size-2-17) /* another table */
922 int sum = 0;
923 i = *p_src & 0x0F; /* table index */
924 if (i > 1)
926 return (-5); /* Huffman table index out of range */
928 else if (*p_src++ & 0xF0) /* AC table */
930 for (j=0; j<16; j++)
932 sum += *p_src;
933 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
935 if(16 + sum > AC_LEN)
936 return -10; /* longer than allowed */
938 for (; j < 16 + sum; j++)
939 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
941 else /* DC table */
943 for (j=0; j<16; j++)
945 sum += *p_src;
946 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
948 if(16 + sum > DC_LEN)
949 return -11; /* longer than allowed */
951 for (; j < 16 + sum; j++)
952 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
954 } /* while */
955 p_src = p_temp+marker_size - 2; /* skip possible residue */
957 break;
959 case 0xCC: /* Define Arithmetic coding conditioning(s) */
960 return(-6); /* Arithmetic coding not supported */
962 case 0xD8: /* Start of Image */
963 case 0xD9: /* End of Image */
964 case 0x01: /* for temp private use arith code */
965 break; /* skip parameterless marker */
968 case 0xDA: /* Start of Scan */
970 ret |= SOS;
971 marker_size = *p_src++ << 8; /* Highbyte */
972 marker_size |= *p_src++; /* Lowbyte */
974 n = (marker_size-2-1-3)/2;
975 if (*p_src++ != n || (n != 1 && n != 3))
977 return (-7); /* Unsupported SOS component specification */
979 for (i=0; i<n; i++)
981 p_jpeg->scanheader[i].ID = *p_src++;
982 p_jpeg->scanheader[i].DC_select = *p_src >> 4;
983 p_jpeg->scanheader[i].AC_select = *p_src++ & 0x0F;
985 p_src += 3; /* skip spectral information */
987 break;
989 case 0xDB: /* Define quantization Table(s) */
991 ret |= DQT;
992 marker_size = *p_src++ << 8; /* Highbyte */
993 marker_size |= *p_src++; /* Lowbyte */
994 n = (marker_size-2)/(QUANT_TABLE_LENGTH+1); /* # of tables */
995 for (i=0; i<n; i++)
997 int id = *p_src++; /* ID */
998 if (id >= 4)
1000 return (-8); /* Unsupported quantization table */
1002 /* Read Quantisation table: */
1003 for (j=0; j<QUANT_TABLE_LENGTH; j++)
1004 p_jpeg->quanttable[id][j] = *p_src++;
1007 break;
1009 case 0xDD: /* Define Restart Interval */
1011 marker_size = *p_src++ << 8; /* Highbyte */
1012 marker_size |= *p_src++; /* Lowbyte */
1013 p_jpeg->restart_interval = *p_src++ << 8; /* Highbyte */
1014 p_jpeg->restart_interval |= *p_src++; /* Lowbyte */
1015 p_src += marker_size-4; /* skip segment */
1017 break;
1019 case 0xDC: /* Define Number of Lines */
1020 case 0xDE: /* Define Hierarchical progression */
1021 case 0xDF: /* Expand Reference Component(s) */
1022 case 0xE0: /* Application Field 0*/
1023 case 0xE1: /* Application Field 1*/
1024 case 0xE2: /* Application Field 2*/
1025 case 0xE3: /* Application Field 3*/
1026 case 0xE4: /* Application Field 4*/
1027 case 0xE5: /* Application Field 5*/
1028 case 0xE6: /* Application Field 6*/
1029 case 0xE7: /* Application Field 7*/
1030 case 0xE8: /* Application Field 8*/
1031 case 0xE9: /* Application Field 9*/
1032 case 0xEA: /* Application Field 10*/
1033 case 0xEB: /* Application Field 11*/
1034 case 0xEC: /* Application Field 12*/
1035 case 0xED: /* Application Field 13*/
1036 case 0xEE: /* Application Field 14*/
1037 case 0xEF: /* Application Field 15*/
1038 case 0xFE: /* Comment */
1040 marker_size = *p_src++ << 8; /* Highbyte */
1041 marker_size |= *p_src++; /* Lowbyte */
1042 p_src += marker_size-2; /* skip segment */
1044 break;
1046 case 0xF0: /* Reserved for JPEG extensions */
1047 case 0xF1: /* Reserved for JPEG extensions */
1048 case 0xF2: /* Reserved for JPEG extensions */
1049 case 0xF3: /* Reserved for JPEG extensions */
1050 case 0xF4: /* Reserved for JPEG extensions */
1051 case 0xF5: /* Reserved for JPEG extensions */
1052 case 0xF6: /* Reserved for JPEG extensions */
1053 case 0xF7: /* Reserved for JPEG extensions */
1054 case 0xF8: /* Reserved for JPEG extensions */
1055 case 0xF9: /* Reserved for JPEG extensions */
1056 case 0xFA: /* Reserved for JPEG extensions */
1057 case 0xFB: /* Reserved for JPEG extensions */
1058 case 0xFC: /* Reserved for JPEG extensions */
1059 case 0xFD: /* Reserved for JPEG extensions */
1060 case 0x02: /* Reserved */
1061 default:
1062 return (-9); /* Unknown marker */
1063 } /* switch */
1064 } /* while */
1066 return (ret); /* return flags with seen markers */
1070 void default_huff_tbl(struct jpeg* p_jpeg)
1072 static const struct huffman_table luma_table =
1075 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
1076 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1079 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
1080 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
1081 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
1082 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
1083 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
1084 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1085 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1086 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
1087 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
1088 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
1089 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1090 0xF9,0xFA
1094 static const struct huffman_table chroma_table =
1097 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
1098 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1101 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
1102 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
1103 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1104 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1105 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1106 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1107 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1108 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1109 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1110 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1111 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1112 0xF9,0xFA
1116 MEMCPY(&p_jpeg->hufftable[0], &luma_table, sizeof(luma_table));
1117 MEMCPY(&p_jpeg->hufftable[1], &chroma_table, sizeof(chroma_table));
1119 return;
1122 /* Compute the derived values for a Huffman table */
1123 void fix_huff_tbl(int* htbl, struct derived_tbl* dtbl)
1125 int p, i, l, si;
1126 int lookbits, ctr;
1127 char huffsize[257];
1128 unsigned int huffcode[257];
1129 unsigned int code;
1131 dtbl->pub = htbl; /* fill in back link */
1133 /* Figure C.1: make table of Huffman code length for each symbol */
1134 /* Note that this is in code-length order. */
1136 p = 0;
1137 for (l = 1; l <= 16; l++)
1138 { /* all possible code length */
1139 for (i = 1; i <= (int) htbl[l-1]; i++) /* all codes per length */
1140 huffsize[p++] = (char) l;
1142 huffsize[p] = 0;
1144 /* Figure C.2: generate the codes themselves */
1145 /* Note that this is in code-length order. */
1147 code = 0;
1148 si = huffsize[0];
1149 p = 0;
1150 while (huffsize[p])
1152 while (((int) huffsize[p]) == si)
1154 huffcode[p++] = code;
1155 code++;
1157 code <<= 1;
1158 si++;
1161 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1163 p = 0;
1164 for (l = 1; l <= 16; l++)
1166 if (htbl[l-1])
1168 dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */
1169 dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */
1170 p += htbl[l-1];
1171 dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
1173 else
1175 dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
1178 dtbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */
1180 /* Compute lookahead tables to speed up decoding.
1181 * First we set all the table entries to 0, indicating "too long";
1182 * then we iterate through the Huffman codes that are short enough and
1183 * fill in all the entries that correspond to bit sequences starting
1184 * with that code.
1187 MEMSET(dtbl->look_nbits, 0, sizeof(dtbl->look_nbits));
1189 p = 0;
1190 for (l = 1; l <= HUFF_LOOKAHEAD; l++)
1192 for (i = 1; i <= (int) htbl[l-1]; i++, p++)
1194 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1195 /* Generate left-justified code followed by all possible bit sequences */
1196 lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
1197 for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--)
1199 dtbl->look_nbits[lookbits] = l;
1200 dtbl->look_sym[lookbits] = htbl[16+p];
1201 lookbits++;
1208 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1209 * If the incoming data is corrupted, decode_mcu could attempt to
1210 * reference values beyond the end of the array. To avoid a wild store,
1211 * we put some extra zeroes after the real entries.
1213 static const int zag[] =
1215 0, 1, 8, 16, 9, 2, 3, 10,
1216 17, 24, 32, 25, 18, 11, 4, 5,
1217 12, 19, 26, 33, 40, 48, 41, 34,
1218 27, 20, 13, 6, 7, 14, 21, 28,
1219 35, 42, 49, 56, 57, 50, 43, 36,
1220 29, 22, 15, 23, 30, 37, 44, 51,
1221 58, 59, 52, 45, 38, 31, 39, 46,
1222 53, 60, 61, 54, 47, 55, 62, 63,
1223 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1224 0, 0, 0, 0, 0, 0, 0, 0
1227 void build_lut(struct jpeg* p_jpeg)
1229 int i;
1230 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_dc,
1231 &p_jpeg->dc_derived_tbls[0]);
1232 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_ac,
1233 &p_jpeg->ac_derived_tbls[0]);
1234 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_dc,
1235 &p_jpeg->dc_derived_tbls[1]);
1236 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_ac,
1237 &p_jpeg->ac_derived_tbls[1]);
1239 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1240 for (i=0; i<64; i++)
1242 p_jpeg->qt_idct[0][zag[i]] = p_jpeg->quanttable[0][i];
1243 p_jpeg->qt_idct[1][zag[i]] = p_jpeg->quanttable[1][i];
1246 for (i=0; i<4; i++)
1247 p_jpeg->store_pos[i] = i; /* default ordering */
1249 /* assignments for the decoding of blocks */
1250 if (p_jpeg->frameheader[0].horizontal_sampling == 2
1251 && p_jpeg->frameheader[0].vertical_sampling == 1)
1252 { /* 4:2:2 */
1253 p_jpeg->blocks = 4;
1254 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1255 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1256 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1257 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1258 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1259 p_jpeg->mcu_membership[1] = 0;
1260 p_jpeg->mcu_membership[2] = 1;
1261 p_jpeg->mcu_membership[3] = 2;
1262 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1263 p_jpeg->tab_membership[1] = 0;
1264 p_jpeg->tab_membership[2] = 1;
1265 p_jpeg->tab_membership[3] = 1;
1266 p_jpeg->subsample_x[0] = 1;
1267 p_jpeg->subsample_x[1] = 2;
1268 p_jpeg->subsample_x[2] = 2;
1269 p_jpeg->subsample_y[0] = 1;
1270 p_jpeg->subsample_y[1] = 1;
1271 p_jpeg->subsample_y[2] = 1;
1273 if (p_jpeg->frameheader[0].horizontal_sampling == 1
1274 && p_jpeg->frameheader[0].vertical_sampling == 2)
1275 { /* 4:2:2 vertically subsampled */
1276 p_jpeg->store_pos[1] = 2; /* block positions are mirrored */
1277 p_jpeg->store_pos[2] = 1;
1278 p_jpeg->blocks = 4;
1279 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1280 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1281 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1282 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1283 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1284 p_jpeg->mcu_membership[1] = 0;
1285 p_jpeg->mcu_membership[2] = 1;
1286 p_jpeg->mcu_membership[3] = 2;
1287 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1288 p_jpeg->tab_membership[1] = 0;
1289 p_jpeg->tab_membership[2] = 1;
1290 p_jpeg->tab_membership[3] = 1;
1291 p_jpeg->subsample_x[0] = 1;
1292 p_jpeg->subsample_x[1] = 1;
1293 p_jpeg->subsample_x[2] = 1;
1294 p_jpeg->subsample_y[0] = 1;
1295 p_jpeg->subsample_y[1] = 2;
1296 p_jpeg->subsample_y[2] = 2;
1298 else if (p_jpeg->frameheader[0].horizontal_sampling == 2
1299 && p_jpeg->frameheader[0].vertical_sampling == 2)
1300 { /* 4:2:0 */
1301 p_jpeg->blocks = 6;
1302 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1303 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1304 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1305 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1306 p_jpeg->mcu_membership[0] = 0;
1307 p_jpeg->mcu_membership[1] = 0;
1308 p_jpeg->mcu_membership[2] = 0;
1309 p_jpeg->mcu_membership[3] = 0;
1310 p_jpeg->mcu_membership[4] = 1;
1311 p_jpeg->mcu_membership[5] = 2;
1312 p_jpeg->tab_membership[0] = 0;
1313 p_jpeg->tab_membership[1] = 0;
1314 p_jpeg->tab_membership[2] = 0;
1315 p_jpeg->tab_membership[3] = 0;
1316 p_jpeg->tab_membership[4] = 1;
1317 p_jpeg->tab_membership[5] = 1;
1318 p_jpeg->subsample_x[0] = 1;
1319 p_jpeg->subsample_x[1] = 2;
1320 p_jpeg->subsample_x[2] = 2;
1321 p_jpeg->subsample_y[0] = 1;
1322 p_jpeg->subsample_y[1] = 2;
1323 p_jpeg->subsample_y[2] = 2;
1325 else if (p_jpeg->frameheader[0].horizontal_sampling == 1
1326 && p_jpeg->frameheader[0].vertical_sampling == 1)
1327 { /* 4:4:4 */
1328 /* don't overwrite p_jpeg->blocks */
1329 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1330 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1331 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1332 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1333 p_jpeg->mcu_membership[0] = 0;
1334 p_jpeg->mcu_membership[1] = 1;
1335 p_jpeg->mcu_membership[2] = 2;
1336 p_jpeg->tab_membership[0] = 0;
1337 p_jpeg->tab_membership[1] = 1;
1338 p_jpeg->tab_membership[2] = 1;
1339 p_jpeg->subsample_x[0] = 1;
1340 p_jpeg->subsample_x[1] = 1;
1341 p_jpeg->subsample_x[2] = 1;
1342 p_jpeg->subsample_y[0] = 1;
1343 p_jpeg->subsample_y[1] = 1;
1344 p_jpeg->subsample_y[2] = 1;
1346 else
1348 /* error */
1355 * These functions/macros provide the in-line portion of bit fetching.
1356 * Use check_bit_buffer to ensure there are N bits in get_buffer
1357 * before using get_bits, peek_bits, or drop_bits.
1358 * check_bit_buffer(state,n,action);
1359 * Ensure there are N bits in get_buffer; if suspend, take action.
1360 * val = get_bits(n);
1361 * Fetch next N bits.
1362 * val = peek_bits(n);
1363 * Fetch next N bits without removing them from the buffer.
1364 * drop_bits(n);
1365 * Discard next N bits.
1366 * The value N should be a simple variable, not an expression, because it
1367 * is evaluated multiple times.
1370 INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
1372 if (pb->bits_left < nbits)
1373 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1374 unsigned char byte;
1376 byte = *pb->next_input_byte++;
1377 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1378 { /* simplification: just skip the (one-byte) marker code */
1379 pb->next_input_byte++;
1381 pb->get_buffer = (pb->get_buffer << 8) | byte;
1383 byte = *pb->next_input_byte++;
1384 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1385 { /* simplification: just skip the (one-byte) marker code */
1386 pb->next_input_byte++;
1388 pb->get_buffer = (pb->get_buffer << 8) | byte;
1390 pb->bits_left += 16;
1394 INLINE int get_bits(struct bitstream* pb, int nbits)
1396 return ((int) (pb->get_buffer >> (pb->bits_left -= nbits))) & ((1<<nbits)-1);
1399 INLINE int peek_bits(struct bitstream* pb, int nbits)
1401 return ((int) (pb->get_buffer >> (pb->bits_left - nbits))) & ((1<<nbits)-1);
1404 INLINE void drop_bits(struct bitstream* pb, int nbits)
1406 pb->bits_left -= nbits;
1409 /* re-synchronize to entropy data (skip restart marker) */
1410 void search_restart(struct bitstream* pb)
1412 pb->next_input_byte--; /* we may have overread it, taking 2 bytes */
1413 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1414 while (pb->next_input_byte < pb->input_end &&
1415 (pb->next_input_byte[-2] != 0xFF || pb->next_input_byte[-1] == 0x00))
1417 pb->next_input_byte++;
1419 pb->bits_left = 0;
1422 /* Figure F.12: extend sign bit. */
1423 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1425 static const int extend_test[16] = /* entry n is 2**(n-1) */
1427 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1428 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1431 static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
1433 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1434 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1435 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1436 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1439 /* Decode a single value */
1440 INLINE int huff_decode_dc(struct bitstream* bs, struct derived_tbl* tbl)
1442 int nb, look, s, r;
1444 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1445 look = peek_bits(bs, HUFF_LOOKAHEAD);
1446 if ((nb = tbl->look_nbits[look]) != 0)
1448 drop_bits(bs, nb);
1449 s = tbl->look_sym[look];
1450 check_bit_buffer(bs, s);
1451 r = get_bits(bs, s);
1452 s = HUFF_EXTEND(r, s);
1454 else
1455 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1456 long code;
1457 nb=HUFF_LOOKAHEAD+1;
1458 check_bit_buffer(bs, nb);
1459 code = get_bits(bs, nb);
1460 while (code > tbl->maxcode[nb])
1462 code <<= 1;
1463 check_bit_buffer(bs, 1);
1464 code |= get_bits(bs, 1);
1465 nb++;
1467 if (nb > 16) /* error in Huffman */
1469 s=0; /* fake a zero, this is most safe */
1471 else
1473 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1474 check_bit_buffer(bs, s);
1475 r = get_bits(bs, s);
1476 s = HUFF_EXTEND(r, s);
1478 } /* end slow decode */
1479 return s;
1482 INLINE int huff_decode_ac(struct bitstream* bs, struct derived_tbl* tbl)
1484 int nb, look, s;
1486 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1487 look = peek_bits(bs, HUFF_LOOKAHEAD);
1488 if ((nb = tbl->look_nbits[look]) != 0)
1490 drop_bits(bs, nb);
1491 s = tbl->look_sym[look];
1493 else
1494 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1495 long code;
1496 nb=HUFF_LOOKAHEAD+1;
1497 check_bit_buffer(bs, nb);
1498 code = get_bits(bs, nb);
1499 while (code > tbl->maxcode[nb])
1501 code <<= 1;
1502 check_bit_buffer(bs, 1);
1503 code |= get_bits(bs, 1);
1504 nb++;
1506 if (nb > 16) /* error in Huffman */
1508 s=0; /* fake a zero, this is most safe */
1510 else
1512 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1514 } /* end slow decode */
1515 return s;
1519 #ifdef HAVE_LCD_COLOR
1521 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1522 /* Note: it keeps the original color subsampling, even if resized. */
1523 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1524 int downscale, void (*pf_progress)(int current, int total))
1526 struct bitstream bs; /* bitstream "object" */
1527 int block[64]; /* decoded DCT coefficients */
1529 int width, height;
1530 int skip_line[3]; /* bytes from one line to the next (skip_line) */
1531 int skip_strip[3], skip_mcu[3]; /* bytes to next DCT row / column */
1533 int i, x, y; /* loop counter */
1535 unsigned char* p_line[3] = {p_pixel[0], p_pixel[1], p_pixel[2]};
1536 unsigned char* p_byte[3]; /* bitmap pointer */
1538 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1539 int k_need; /* AC coefficients needed up to here */
1540 int zero_need; /* init the block with this many zeros */
1542 int last_dc_val[3] = {0, 0, 0}; /* or 128 for chroma? */
1543 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1544 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1546 /* pick the IDCT we want, determine how to work with coefs */
1547 if (downscale == 1)
1549 pf_idct = idct8x8;
1550 k_need = 64; /* all */
1551 zero_need = 63; /* all */
1553 else if (downscale == 2)
1555 pf_idct = idct4x4;
1556 k_need = 25; /* this far in zig-zag to cover 4*4 */
1557 zero_need = 27; /* clear this far in linear order */
1559 else if (downscale == 4)
1561 pf_idct = idct2x2;
1562 k_need = 5; /* this far in zig-zag to cover 2*2 */
1563 zero_need = 9; /* clear this far in linear order */
1565 else if (downscale == 8)
1567 pf_idct = idct1x1;
1568 k_need = 0; /* no AC, not needed */
1569 zero_need = 0; /* no AC, not needed */
1571 else return -1; /* not supported */
1573 /* init bitstream, fake a restart to make it start */
1574 bs.next_input_byte = p_jpeg->p_entropy_data;
1575 bs.bits_left = 0;
1576 bs.input_end = p_jpeg->p_entropy_end;
1578 width = p_jpeg->x_phys / downscale;
1579 height = p_jpeg->y_phys / downscale;
1580 for (i=0; i<3; i++) /* calculate some strides */
1582 skip_line[i] = width / p_jpeg->subsample_x[i];
1583 skip_strip[i] = skip_line[i]
1584 * (height / p_jpeg->y_mbl) / p_jpeg->subsample_y[i];
1585 skip_mcu[i] = width/p_jpeg->x_mbl / p_jpeg->subsample_x[i];
1588 /* prepare offsets about where to store the different blocks */
1589 store_offs[p_jpeg->store_pos[0]] = 0;
1590 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1591 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1592 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1594 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1596 for (i=0; i<3; i++) /* scan line init */
1598 p_byte[i] = p_line[i];
1599 p_line[i] += skip_strip[i];
1601 for (x=0; x<p_jpeg->x_mbl; x++)
1603 int blkn;
1605 /* Outer loop handles each block in the MCU */
1606 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1607 { /* Decode a single block's worth of coefficients */
1608 int k = 1; /* coefficient index */
1609 int s, r; /* huffman values */
1610 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1611 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1612 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1613 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1615 /* Section F.2.2.1: decode the DC coefficient difference */
1616 s = huff_decode_dc(&bs, dctbl);
1618 last_dc_val[ci] += s;
1619 block[0] = last_dc_val[ci]; /* output it (assumes zag[0] = 0) */
1621 /* coefficient buffer must be cleared */
1622 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1624 /* Section F.2.2.2: decode the AC coefficients */
1625 for (; k < k_need; k++)
1627 s = huff_decode_ac(&bs, actbl);
1628 r = s >> 4;
1629 s &= 15;
1631 if (s)
1633 k += r;
1634 check_bit_buffer(&bs, s);
1635 r = get_bits(&bs, s);
1636 block[zag[k]] = HUFF_EXTEND(r, s);
1638 else
1640 if (r != 15)
1642 k = 64;
1643 break;
1645 k += r;
1647 } /* for k */
1648 /* In this path we just discard the values */
1649 for (; k < 64; k++)
1651 s = huff_decode_ac(&bs, actbl);
1652 r = s >> 4;
1653 s &= 15;
1655 if (s)
1657 k += r;
1658 check_bit_buffer(&bs, s);
1659 drop_bits(&bs, s);
1661 else
1663 if (r != 15)
1664 break;
1665 k += r;
1667 } /* for k */
1669 if (ci == 0)
1670 { /* Y component needs to bother about block store */
1671 pf_idct(p_byte[0]+store_offs[blkn], block,
1672 p_jpeg->qt_idct[ti], skip_line[0]);
1674 else
1675 { /* chroma */
1676 pf_idct(p_byte[ci], block, p_jpeg->qt_idct[ti],
1677 skip_line[ci]);
1679 } /* for blkn */
1680 p_byte[0] += skip_mcu[0]; /* unrolled for (i=0; i<3; i++) loop */
1681 p_byte[1] += skip_mcu[1];
1682 p_byte[2] += skip_mcu[2];
1683 if (p_jpeg->restart_interval && --restart == 0)
1684 { /* if a restart marker is due: */
1685 restart = p_jpeg->restart_interval; /* count again */
1686 search_restart(&bs); /* align the bitstream */
1687 last_dc_val[0] = last_dc_val[1] =
1688 last_dc_val[2] = 0; /* reset decoder */
1690 } /* for x */
1691 if (pf_progress != NULL)
1692 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1693 } /* for y */
1695 return 0; /* success */
1697 #else /* !HAVE_LCD_COLOR */
1699 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1700 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[1], int downscale,
1701 void (*pf_progress)(int current, int total))
1703 struct bitstream bs; /* bitstream "object" */
1704 int block[64]; /* decoded DCT coefficients */
1706 int width, height;
1707 int skip_line; /* bytes from one line to the next (skip_line) */
1708 int skip_strip, skip_mcu; /* bytes to next DCT row / column */
1710 int x, y; /* loop counter */
1712 unsigned char* p_line = p_pixel[0];
1713 unsigned char* p_byte; /* bitmap pointer */
1715 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1716 int k_need; /* AC coefficients needed up to here */
1717 int zero_need; /* init the block with this many zeros */
1719 int last_dc_val = 0;
1720 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1721 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1723 /* pick the IDCT we want, determine how to work with coefs */
1724 if (downscale == 1)
1726 pf_idct = idct8x8;
1727 k_need = 64; /* all */
1728 zero_need = 63; /* all */
1730 else if (downscale == 2)
1732 pf_idct = idct4x4;
1733 k_need = 25; /* this far in zig-zag to cover 4*4 */
1734 zero_need = 27; /* clear this far in linear order */
1736 else if (downscale == 4)
1738 pf_idct = idct2x2;
1739 k_need = 5; /* this far in zig-zag to cover 2*2 */
1740 zero_need = 9; /* clear this far in linear order */
1742 else if (downscale == 8)
1744 pf_idct = idct1x1;
1745 k_need = 0; /* no AC, not needed */
1746 zero_need = 0; /* no AC, not needed */
1748 else return -1; /* not supported */
1750 /* init bitstream, fake a restart to make it start */
1751 bs.next_input_byte = p_jpeg->p_entropy_data;
1752 bs.bits_left = 0;
1753 bs.input_end = p_jpeg->p_entropy_end;
1755 width = p_jpeg->x_phys / downscale;
1756 height = p_jpeg->y_phys / downscale;
1757 skip_line = width;
1758 skip_strip = skip_line * (height / p_jpeg->y_mbl);
1759 skip_mcu = (width/p_jpeg->x_mbl);
1761 /* prepare offsets about where to store the different blocks */
1762 store_offs[p_jpeg->store_pos[0]] = 0;
1763 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1764 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1765 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1767 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1769 p_byte = p_line;
1770 p_line += skip_strip;
1771 for (x=0; x<p_jpeg->x_mbl; x++)
1773 int blkn;
1775 /* Outer loop handles each block in the MCU */
1776 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1777 { /* Decode a single block's worth of coefficients */
1778 int k = 1; /* coefficient index */
1779 int s, r; /* huffman values */
1780 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1781 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1782 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1783 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1785 /* Section F.2.2.1: decode the DC coefficient difference */
1786 s = huff_decode_dc(&bs, dctbl);
1788 if (ci == 0) /* only for Y component */
1790 last_dc_val += s;
1791 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
1793 /* coefficient buffer must be cleared */
1794 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1796 /* Section F.2.2.2: decode the AC coefficients */
1797 for (; k < k_need; k++)
1799 s = huff_decode_ac(&bs, actbl);
1800 r = s >> 4;
1801 s &= 15;
1803 if (s)
1805 k += r;
1806 check_bit_buffer(&bs, s);
1807 r = get_bits(&bs, s);
1808 block[zag[k]] = HUFF_EXTEND(r, s);
1810 else
1812 if (r != 15)
1814 k = 64;
1815 break;
1817 k += r;
1819 } /* for k */
1821 /* In this path we just discard the values */
1822 for (; k < 64; k++)
1824 s = huff_decode_ac(&bs, actbl);
1825 r = s >> 4;
1826 s &= 15;
1828 if (s)
1830 k += r;
1831 check_bit_buffer(&bs, s);
1832 drop_bits(&bs, s);
1834 else
1836 if (r != 15)
1837 break;
1838 k += r;
1840 } /* for k */
1842 if (ci == 0)
1843 { /* only for Y component */
1844 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
1845 skip_line);
1847 } /* for blkn */
1848 p_byte += skip_mcu;
1849 if (p_jpeg->restart_interval && --restart == 0)
1850 { /* if a restart marker is due: */
1851 restart = p_jpeg->restart_interval; /* count again */
1852 search_restart(&bs); /* align the bitstream */
1853 last_dc_val = 0; /* reset decoder */
1855 } /* for x */
1856 if (pf_progress != NULL)
1857 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1858 } /* for y */
1860 return 0; /* success */
1862 #endif /* !HAVE_LCD_COLOR */
1864 /**************** end JPEG code ********************/
1868 /**************** begin Application ********************/
1871 /************************* Types ***************************/
1873 struct t_disp
1875 #ifdef HAVE_LCD_COLOR
1876 unsigned char* bitmap[3]; /* Y, Cr, Cb */
1877 int csub_x, csub_y;
1878 #else
1879 unsigned char* bitmap[1]; /* Y only */
1880 #endif
1881 int width;
1882 int height;
1883 int stride;
1884 int x, y;
1887 /************************* Globals ***************************/
1889 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1890 struct t_disp disp[9];
1892 /* my memory pool (from the mp3 buffer) */
1893 char print[32]; /* use a common snprintf() buffer */
1894 unsigned char* buf; /* up to here currently used by image(s) */
1896 /* the remaining free part of the buffer for compressed+uncompressed images */
1897 unsigned char* buf_images;
1899 ssize_t buf_size, buf_images_size;
1900 /* the root of the images, hereafter are decompresed ones */
1901 unsigned char* buf_root;
1902 int root_size;
1904 int ds, ds_min, ds_max; /* downscaling and limits */
1905 static struct jpeg jpg; /* too large for stack */
1907 static struct tree_context *tree;
1909 /* the current full file name */
1910 static char np_file[MAX_PATH];
1911 int curfile = 0, direction = DIR_NONE, entries = 0;
1913 /* list of the jpeg files */
1914 char **file_pt;
1915 /* are we using the plugin buffer or the audio buffer? */
1916 bool plug_buf = false;
1919 /************************* Implementation ***************************/
1921 #ifdef HAVE_LCD_COLOR
1923 * Conversion of full 0-255 range YCrCb to RGB:
1924 * |R| |1.000000 -0.000001 1.402000| |Y'|
1925 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
1926 * |B| |1.000000 1.772000 0.000000| |Pr|
1927 * Scaled (yields s15-bit output):
1928 * |R| |128 0 179| |Y |
1929 * |G| = |128 -43 -91| |Cb - 128|
1930 * |B| |128 227 0| |Cr - 128|
1932 #define YFAC 128
1933 #define RVFAC 179
1934 #define GUFAC (-43)
1935 #define GVFAC (-91)
1936 #define BUFAC 227
1937 #define YUV_WHITE (255*YFAC)
1938 #define NODITHER_DELTA (127*YFAC)
1939 #define COMPONENT_SHIFT 15
1940 #define MATRIX_SHIFT 7
1942 static inline int clamp_component(int x)
1944 if ((unsigned)x > YUV_WHITE)
1945 x = x < 0 ? 0 : YUV_WHITE;
1946 return x;
1949 static inline int clamp_component_bits(int x, int bits)
1951 if ((unsigned)x > (1u << bits) - 1)
1952 x = x < 0 ? 0 : (1 << bits) - 1;
1953 return x;
1956 static inline int component_to_lcd(int x, int bits, int delta)
1958 /* Formula used in core bitmap loader. */
1959 return (((1 << bits) - 1)*x + (x >> (8 - bits)) + delta) >> COMPONENT_SHIFT;
1962 static inline int lcd_to_component(int x, int bits, int delta)
1964 /* Reasonable, approximate reversal to get a full range back from the
1965 quantized value. */
1966 return YUV_WHITE*x / ((1 << bits) - 1);
1967 (void)delta;
1970 #define RED 0
1971 #define GRN 1
1972 #define BLU 2
1974 struct rgb_err
1976 int16_t errbuf[LCD_WIDTH+2]; /* Error record for line below */
1977 } rgb_err_buffers[3];
1979 fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
1980 DITHER_DIFFUSION is set */
1982 struct rgb_pixel
1984 int r, g, b; /* Current pixel components in s16.0 */
1985 int inc; /* Current line increment (-1 or 1) */
1986 int row; /* Current row in source image */
1987 int col; /* Current column in source image */
1988 int ce[3]; /* Errors to apply to current pixel */
1989 struct rgb_err *e; /* RED, GRN, BLU */
1990 int epos; /* Current position in error record */
1993 struct rgb_pixel *pixel;
1995 /** round and truncate to lcd depth **/
1996 static fb_data pixel_to_lcd_colour(void)
1998 struct rgb_pixel *p = pixel;
1999 int r, g, b;
2001 r = component_to_lcd(p->r, LCD_RED_BITS, NODITHER_DELTA);
2002 r = clamp_component_bits(r, LCD_RED_BITS);
2004 g = component_to_lcd(p->g, LCD_GREEN_BITS, NODITHER_DELTA);
2005 g = clamp_component_bits(g, LCD_GREEN_BITS);
2007 b = component_to_lcd(p->b, LCD_BLUE_BITS, NODITHER_DELTA);
2008 b = clamp_component_bits(b, LCD_BLUE_BITS);
2010 return LCD_RGBPACK_LCD(r, g, b);
2013 /** write a monochrome pixel to the colour LCD **/
2014 static fb_data pixel_to_lcd_gray(void)
2016 int r, g, b;
2018 g = clamp_component(pixel->g);
2019 r = component_to_lcd(g, LCD_RED_BITS, NODITHER_DELTA);
2020 b = component_to_lcd(g, LCD_BLUE_BITS, NODITHER_DELTA);
2021 g = component_to_lcd(g, LCD_GREEN_BITS, NODITHER_DELTA);
2023 return LCD_RGBPACK_LCD(r, g, b);
2027 * Bayer ordered dithering - swiped from the core bitmap loader.
2029 static fb_data pixel_odither_to_lcd(void)
2031 /* canonical ordered dither matrix */
2032 static const unsigned char dither_matrix[16][16] = {
2033 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
2034 { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
2035 { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
2036 { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
2037 { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
2038 { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
2039 { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
2040 { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
2041 { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
2042 { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
2043 { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
2044 { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
2045 { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
2046 { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
2047 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
2048 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
2051 struct rgb_pixel *p = pixel;
2052 int r, g, b, delta;
2054 delta = dither_matrix[p->col & 15][p->row & 15] << MATRIX_SHIFT;
2056 r = component_to_lcd(p->r, LCD_RED_BITS, delta);
2057 r = clamp_component_bits(r, LCD_RED_BITS);
2059 g = component_to_lcd(p->g, LCD_GREEN_BITS, delta);
2060 g = clamp_component_bits(g, LCD_GREEN_BITS);
2062 b = component_to_lcd(p->b, LCD_BLUE_BITS, delta);
2063 b = clamp_component_bits(b, LCD_BLUE_BITS);
2065 p->col += p->inc;
2067 return LCD_RGBPACK_LCD(r, g, b);
2071 * Floyd/Steinberg dither to lcd depth.
2073 * Apply filter to each component in serpentine pattern. Kernel shown for
2074 * L->R scan. Kernel is reversed for R->L.
2075 * * 7
2076 * 3 5 1 (1/16)
2078 static inline void distribute_error(int *ce, struct rgb_err *e,
2079 int err, int epos, int inc)
2081 *ce = (7*err >> 4) + e->errbuf[epos+inc];
2082 e->errbuf[epos+inc] = err >> 4;
2083 e->errbuf[epos] += 5*err >> 4;
2084 e->errbuf[epos-inc] += 3*err >> 4;
2087 static fb_data pixel_fsdither_to_lcd(void)
2089 struct rgb_pixel *p = pixel;
2090 int rc, gc, bc, r, g, b;
2091 int inc, epos;
2093 /* Full components with error terms */
2094 rc = p->r + p->ce[RED];
2095 r = component_to_lcd(rc, LCD_RED_BITS, 0);
2096 r = clamp_component_bits(r, LCD_RED_BITS);
2098 gc = p->g + p->ce[GRN];
2099 g = component_to_lcd(gc, LCD_GREEN_BITS, 0);
2100 g = clamp_component_bits(g, LCD_GREEN_BITS);
2102 bc = p->b + p->ce[BLU];
2103 b = component_to_lcd(bc, LCD_BLUE_BITS, 0);
2104 b = clamp_component_bits(b, LCD_BLUE_BITS);
2106 /* Get pixel errors */
2107 rc -= lcd_to_component(r, LCD_RED_BITS, 0);
2108 gc -= lcd_to_component(g, LCD_GREEN_BITS, 0);
2109 bc -= lcd_to_component(b, LCD_BLUE_BITS, 0);
2111 /* Spead error to surrounding pixels. */
2112 inc = p->inc;
2113 epos = p->epos;
2114 p->epos += inc;
2116 distribute_error(&p->ce[RED], &p->e[RED], rc, epos, inc);
2117 distribute_error(&p->ce[GRN], &p->e[GRN], gc, epos, inc);
2118 distribute_error(&p->ce[BLU], &p->e[BLU], bc, epos, inc);
2120 /* Pack and return pixel */
2121 return LCD_RGBPACK_LCD(r, g, b);
2124 /* Functions for each output mode, colour then grayscale. */
2125 static fb_data (* const pixel_funcs[COLOUR_NUM_MODES][DITHER_NUM_MODES])(void) =
2127 [COLOURMODE_COLOUR] =
2129 [DITHER_NONE] = pixel_to_lcd_colour,
2130 [DITHER_ORDERED] = pixel_odither_to_lcd,
2131 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2133 [COLOURMODE_GRAY] =
2135 [DITHER_NONE] = pixel_to_lcd_gray,
2136 [DITHER_ORDERED] = pixel_odither_to_lcd,
2137 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2142 * Draw a partial YUV colour bitmap
2144 * Runs serpentine pattern when dithering is DITHER_DIFFUSION, else scan is
2145 * always L->R.
2147 void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
2148 int src_x, int src_y, int stride,
2149 int x, int y, int width, int height)
2151 fb_data *dst, *dst_end;
2152 fb_data (*pixel_func)(void);
2153 struct rgb_pixel px;
2155 if (x + width > LCD_WIDTH)
2156 width = LCD_WIDTH - x; /* Clip right */
2157 if (x < 0)
2158 width += x, x = 0; /* Clip left */
2159 if (width <= 0)
2160 return; /* nothing left to do */
2162 if (y + height > LCD_HEIGHT)
2163 height = LCD_HEIGHT - y; /* Clip bottom */
2164 if (y < 0)
2165 height += y, y = 0; /* Clip top */
2166 if (height <= 0)
2167 return; /* nothing left to do */
2169 pixel = &px;
2171 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
2172 dst_end = dst + LCD_WIDTH * height;
2174 if (jpeg_settings.colour_mode == COLOURMODE_GRAY)
2175 csub_y = 0; /* Ignore Cb, Cr */
2177 pixel_func = pixel_funcs[jpeg_settings.colour_mode]
2178 [jpeg_settings.dither_mode];
2180 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2182 /* Reset error terms. */
2183 px.e = rgb_err_buffers;
2184 px.ce[RED] = px.ce[GRN] = px.ce[BLU] = 0;
2185 rb->memset(px.e, 0, 3*sizeof (struct rgb_err));
2190 fb_data *dst_row, *row_end;
2191 const unsigned char *ysrc;
2192 px.inc = 1;
2194 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2196 /* Use R->L scan on odd lines */
2197 px.inc -= (src_y & 1) << 1;
2198 px.epos = x + 1;
2200 if (px.inc < 0)
2201 px.epos += width - 1;
2204 if (px.inc == 1)
2206 /* Scan is L->R */
2207 dst_row = dst;
2208 row_end = dst_row + width;
2209 px.col = src_x;
2211 else
2213 /* Scan is R->L */
2214 row_end = dst - 1;
2215 dst_row = row_end + width;
2216 px.col = src_x + width - 1;
2219 ysrc = src[0] + stride * src_y + px.col;
2220 px.row = src_y;
2222 /* Do one row of pixels */
2223 if (csub_y) /* colour */
2225 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
2226 const unsigned char *usrc, *vsrc;
2228 usrc = src[1] + (stride/csub_x) * (src_y/csub_y)
2229 + (px.col/csub_x);
2230 vsrc = src[2] + (stride/csub_x) * (src_y/csub_y)
2231 + (px.col/csub_x);
2232 int xphase = px.col % csub_x;
2233 int xphase_reset = px.inc * csub_x;
2234 int y, v, u, rv, guv, bu;
2236 v = *vsrc - 128;
2237 vsrc += px.inc;
2238 u = *usrc - 128;
2239 usrc += px.inc;
2240 rv = RVFAC*v;
2241 guv = GUFAC*u + GVFAC*v;
2242 bu = BUFAC*u;
2244 while (1)
2246 y = YFAC*(*ysrc);
2247 ysrc += px.inc;
2248 px.r = y + rv;
2249 px.g = y + guv;
2250 px.b = y + bu;
2252 *dst_row = pixel_func();
2253 dst_row += px.inc;
2255 if (dst_row == row_end)
2256 break;
2258 xphase += px.inc;
2259 if ((unsigned)xphase < (unsigned)csub_x)
2260 continue;
2262 /* fetch new chromas */
2263 v = *vsrc - 128;
2264 vsrc += px.inc;
2265 u = *usrc - 128;
2266 usrc += px.inc;
2267 rv = RVFAC*v;
2268 guv = GUFAC*u + GVFAC*v;
2269 bu = BUFAC*u;
2271 xphase -= xphase_reset;
2274 else /* monochrome */
2278 /* Set all components the same for dithering purposes */
2279 px.g = px.r = px.b = YFAC*(*ysrc);
2280 *dst_row = pixel_func();
2281 ysrc += px.inc;
2282 dst_row += px.inc;
2284 while (dst_row != row_end);
2287 src_y++;
2288 dst += LCD_WIDTH;
2290 while (dst < dst_end);
2293 #endif /* HAVE_LCD_COLOR */
2296 /* support function for qsort() */
2297 static int compare(const void* p1, const void* p2)
2299 return rb->strcasecmp(*((char **)p1), *((char **)p2));
2302 bool jpg_ext(const char ext[])
2304 if(!ext)
2305 return false;
2306 if(!rb->strcasecmp(ext,".jpg") ||
2307 !rb->strcasecmp(ext,".jpe") ||
2308 !rb->strcasecmp(ext,".jpeg"))
2309 return true;
2310 else
2311 return false;
2314 /*Read directory contents for scrolling. */
2315 void get_pic_list(void)
2317 int i;
2318 long int str_len = 0;
2319 char *pname;
2320 tree = rb->tree_get_context();
2322 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2323 file_pt = rb->plugin_get_buffer((size_t *)&buf_size);
2324 #else
2325 file_pt = rb->plugin_get_audio_buffer((size_t *)&buf_size);
2326 #endif
2328 for(i = 0; i < tree->filesindir; i++)
2330 if(jpg_ext(rb->strrchr(&tree->name_buffer[str_len],'.')))
2331 file_pt[entries++] = &tree->name_buffer[str_len];
2333 str_len += rb->strlen(&tree->name_buffer[str_len]) + 1;
2336 rb->qsort(file_pt, entries, sizeof(char**), compare);
2338 /* Remove path and leave only the name.*/
2339 pname = rb->strrchr(np_file,'/');
2340 pname++;
2342 /* Find Selected File. */
2343 for(i = 0; i < entries; i++)
2344 if(!rb->strcmp(file_pt[i], pname))
2345 curfile = i;
2348 int change_filename(int direct)
2350 int count = 0;
2351 direction = direct;
2353 if(direct == DIR_PREV)
2357 count++;
2358 if(curfile == 0)
2359 curfile = entries - 1;
2360 else
2361 curfile--;
2362 }while(file_pt[curfile] == '\0' && count < entries);
2363 /* we "erase" the file name if we encounter
2364 * a non-supported file, so skip it now */
2366 else /* DIR_NEXT/DIR_NONE */
2370 count++;
2371 if(curfile == entries - 1)
2372 curfile = 0;
2373 else
2374 curfile++;
2375 }while(file_pt[curfile] == '\0' && count < entries);
2378 if(count == entries && file_pt[curfile] == '\0')
2380 rb->splash(HZ, "No supported files");
2381 return PLUGIN_ERROR;
2383 if(rb->strlen(tree->currdir) > 1)
2385 rb->strcpy(np_file, tree->currdir);
2386 rb->strcat(np_file, "/");
2388 else
2389 rb->strcpy(np_file, tree->currdir);
2391 rb->strcat(np_file, file_pt[curfile]);
2393 return PLUGIN_OTHER;
2396 /* switch off overlay, for handling SYS_ events */
2397 void cleanup(void *parameter)
2399 (void)parameter;
2400 #ifdef USEGSLIB
2401 gray_show(false);
2402 #endif
2405 #define VSCROLL (LCD_HEIGHT/8)
2406 #define HSCROLL (LCD_WIDTH/10)
2408 #define ZOOM_IN 100 /* return codes for below function */
2409 #define ZOOM_OUT 101
2411 #ifdef HAVE_LCD_COLOR
2412 bool set_option_grayscale(void)
2414 bool gray = jpeg_settings.colour_mode == COLOURMODE_GRAY;
2415 rb->set_bool("Grayscale", &gray);
2416 jpeg_settings.colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
2417 return false;
2420 bool set_option_dithering(void)
2422 static const struct opt_items dithering[DITHER_NUM_MODES] = {
2423 [DITHER_NONE] = { "Off", -1 },
2424 [DITHER_ORDERED] = { "Ordered", -1 },
2425 [DITHER_DIFFUSION] = { "Diffusion", -1 },
2428 rb->set_option("Dithering", &jpeg_settings.dither_mode, INT,
2429 dithering, DITHER_NUM_MODES, NULL);
2430 return false;
2433 static void display_options(void)
2435 static const struct menu_item items[] = {
2436 { "Grayscale", set_option_grayscale },
2437 { "Dithering", set_option_dithering },
2440 int m = menu_init(rb, items, ARRAYLEN(items),
2441 NULL, NULL, NULL, NULL);
2442 menu_run(m);
2443 menu_exit(m);
2445 #endif /* HAVE_LCD_COLOR */
2447 int show_menu(void) /* return 1 to quit */
2449 #if LCD_DEPTH > 1
2450 rb->lcd_set_backdrop(old_backdrop);
2451 #ifdef HAVE_LCD_COLOR
2452 rb->lcd_set_foreground(rb->global_settings->fg_color);
2453 rb->lcd_set_background(rb->global_settings->bg_color);
2454 #else
2455 rb->lcd_set_foreground(LCD_BLACK);
2456 rb->lcd_set_background(LCD_WHITE);
2457 #endif
2458 #endif
2459 int m;
2460 int result;
2462 enum menu_id
2464 MIID_QUIT = 0,
2465 MIID_TOGGLE_SS_MODE,
2466 MIID_CHANGE_SS_MODE,
2467 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2468 MIID_SHOW_PLAYBACK_MENU,
2469 #endif
2470 #ifdef HAVE_LCD_COLOR
2471 MIID_DISPLAY_OPTIONS,
2472 #endif
2473 MIID_RETURN,
2476 static const struct menu_item items[] = {
2477 [MIID_QUIT] =
2478 { "Quit", NULL },
2479 [MIID_TOGGLE_SS_MODE] =
2480 { "Toggle Slideshow Mode", NULL },
2481 [MIID_CHANGE_SS_MODE] =
2482 { "Change Slideshow Time", NULL },
2483 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2484 [MIID_SHOW_PLAYBACK_MENU] =
2485 { "Show Playback Menu", NULL },
2486 #endif
2487 #ifdef HAVE_LCD_COLOR
2488 [MIID_DISPLAY_OPTIONS] =
2489 { "Display Options", NULL },
2490 #endif
2491 [MIID_RETURN] =
2492 { "Return", NULL },
2495 static const struct opt_items slideshow[2] = {
2496 { "Disable", -1 },
2497 { "Enable", -1 },
2500 static const struct opt_items timeout[12] = {
2501 { "1 second", -1 },
2502 { "2 seconds", -1 },
2503 { "3 seconds", -1 },
2504 { "4 seconds", -1 },
2505 { "5 seconds", -1 },
2506 { "6 seconds", -1 },
2507 { "7 seconds", -1 },
2508 { "8 seconds", -1 },
2509 { "9 seconds", -1 },
2510 { "10 seconds", -1 },
2511 { "15 seconds", -1 },
2512 { "20 seconds", -1 },
2515 m = menu_init(rb, items, sizeof(items) / sizeof(*items),
2516 NULL, NULL, NULL, NULL);
2517 result=menu_show(m);
2519 switch (result)
2521 case MIID_QUIT:
2522 menu_exit(m);
2523 return 1;
2524 break;
2525 case MIID_TOGGLE_SS_MODE:
2526 rb->set_option("Toggle Slideshow", &slideshow_enabled, INT,
2527 slideshow , 2, NULL);
2528 break;
2529 case MIID_CHANGE_SS_MODE:
2530 switch (button_timeout/HZ)
2532 case 10: result = 9; break;
2533 case 15: result = 10; break;
2534 case 20: result = 11; break;
2535 default: result = (button_timeout/HZ)-1; break;
2537 rb->set_option("Slideshow Time", &result, INT,
2538 timeout , 12, NULL);
2539 switch (result)
2541 case 9: button_timeout = 10*HZ; break;
2542 case 10: button_timeout = 15*HZ; break;
2543 case 11: button_timeout = 20*HZ; break;
2544 default: button_timeout = (result+1)*HZ; break;
2546 break;
2547 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2548 case MIID_SHOW_PLAYBACK_MENU:
2549 playback_control(rb);
2550 break;
2551 #endif
2552 #ifdef HAVE_LCD_COLOR
2553 case MIID_DISPLAY_OPTIONS:
2554 display_options();
2555 break;
2556 #endif
2557 case MIID_RETURN:
2558 break;
2561 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
2562 /* change ata spindown time based on slideshow time setting */
2563 immediate_ata_off = false;
2564 rb->ata_spindown(rb->global_settings->disk_spindown);
2566 if (slideshow_enabled)
2568 if(button_timeout/HZ < 10)
2570 /* slideshow times < 10s keep disk spinning */
2571 rb->ata_spindown(0);
2573 else if (!rb->mp3_is_playing())
2575 /* slideshow times > 10s and not playing: ata_off after load */
2576 immediate_ata_off = true;
2579 #endif
2580 #if LCD_DEPTH > 1
2581 rb->lcd_set_backdrop(NULL);
2582 rb->lcd_set_foreground(LCD_WHITE);
2583 rb->lcd_set_background(LCD_BLACK);
2584 #endif
2585 rb->lcd_clear_display();
2586 menu_exit(m);
2587 return 0;
2589 /* interactively scroll around the image */
2590 int scroll_bmp(struct t_disp* pdisp)
2592 int lastbutton = 0;
2594 while (true)
2596 int button;
2597 int move;
2599 if (slideshow_enabled)
2600 button = rb->button_get_w_tmo(button_timeout);
2601 else button = rb->button_get(true);
2603 running_slideshow = false;
2605 switch(button)
2607 case JPEG_LEFT:
2608 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2609 return change_filename(DIR_PREV);
2610 case JPEG_LEFT | BUTTON_REPEAT:
2611 move = MIN(HSCROLL, pdisp->x);
2612 if (move > 0)
2614 MYXLCD(scroll_right)(move); /* scroll right */
2615 pdisp->x -= move;
2616 #ifdef HAVE_LCD_COLOR
2617 yuv_bitmap_part(
2618 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2619 pdisp->x, pdisp->y, pdisp->stride,
2620 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2621 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2622 #else
2623 MYXLCD(gray_bitmap_part)(
2624 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2625 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2626 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2627 #endif
2628 MYLCD_UPDATE();
2630 break;
2632 case JPEG_RIGHT:
2633 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2634 return change_filename(DIR_NEXT);
2635 case JPEG_RIGHT | BUTTON_REPEAT:
2636 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
2637 if (move > 0)
2639 MYXLCD(scroll_left)(move); /* scroll left */
2640 pdisp->x += move;
2641 #ifdef HAVE_LCD_COLOR
2642 yuv_bitmap_part(
2643 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2644 pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride,
2645 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2646 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2647 #else
2648 MYXLCD(gray_bitmap_part)(
2649 pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move,
2650 pdisp->y, pdisp->stride,
2651 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2652 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2653 #endif
2654 MYLCD_UPDATE();
2656 break;
2658 case JPEG_UP:
2659 case JPEG_UP | BUTTON_REPEAT:
2660 move = MIN(VSCROLL, pdisp->y);
2661 if (move > 0)
2663 MYXLCD(scroll_down)(move); /* scroll down */
2664 pdisp->y -= move;
2665 #ifdef HAVE_LCD_COLOR
2666 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2668 /* Draw over the band at the top of the last update
2669 caused by lack of error history on line zero. */
2670 move = MIN(move + 1, pdisp->y + pdisp->height);
2673 yuv_bitmap_part(
2674 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2675 pdisp->x, pdisp->y, pdisp->stride,
2676 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2677 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2678 #else
2679 MYXLCD(gray_bitmap_part)(
2680 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2681 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2682 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2683 #endif
2684 MYLCD_UPDATE();
2686 break;
2688 case JPEG_DOWN:
2689 case JPEG_DOWN | BUTTON_REPEAT:
2690 move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT);
2691 if (move > 0)
2693 MYXLCD(scroll_up)(move); /* scroll up */
2694 pdisp->y += move;
2695 #ifdef HAVE_LCD_COLOR
2696 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2698 /* Save the line that was on the last line of the display
2699 and draw one extra line above then recover the line with
2700 image data that had an error history when it was drawn.
2702 move++, pdisp->y--;
2703 MEMCPY(rgb_linebuf,
2704 rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2705 LCD_WIDTH*sizeof (fb_data));
2708 yuv_bitmap_part(
2709 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x,
2710 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2711 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2712 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2714 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2716 /* Cover the first row drawn with previous image data. */
2717 MEMCPY(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2718 rgb_linebuf,
2719 LCD_WIDTH*sizeof (fb_data));
2720 pdisp->y++;
2722 #else
2723 MYXLCD(gray_bitmap_part)(
2724 pdisp->bitmap[0], pdisp->x,
2725 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2726 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2727 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2728 #endif
2729 MYLCD_UPDATE();
2731 break;
2732 case BUTTON_NONE:
2733 if (!slideshow_enabled)
2734 break;
2735 running_slideshow = true;
2736 if (entries > 0)
2737 return change_filename(DIR_NEXT);
2738 break;
2740 #ifdef JPEG_SLIDE_SHOW
2741 case JPEG_SLIDE_SHOW:
2742 slideshow_enabled = !slideshow_enabled;
2743 running_slideshow = slideshow_enabled;
2744 break;
2745 #endif
2747 #ifdef JPEG_NEXT_REPEAT
2748 case JPEG_NEXT_REPEAT:
2749 #endif
2750 case JPEG_NEXT:
2751 if (entries > 0)
2752 return change_filename(DIR_NEXT);
2753 break;
2755 #ifdef JPEG_PREVIOUS_REPEAT
2756 case JPEG_PREVIOUS_REPEAT:
2757 #endif
2758 case JPEG_PREVIOUS:
2759 if (entries > 0)
2760 return change_filename(DIR_PREV);
2761 break;
2763 case JPEG_ZOOM_IN:
2764 #ifdef JPEG_ZOOM_PRE
2765 if (lastbutton != JPEG_ZOOM_PRE)
2766 break;
2767 #endif
2768 return ZOOM_IN;
2769 break;
2771 case JPEG_ZOOM_OUT:
2772 #ifdef JPEG_ZOOM_PRE
2773 if (lastbutton != JPEG_ZOOM_PRE)
2774 break;
2775 #endif
2776 return ZOOM_OUT;
2777 break;
2778 #ifdef JPEG_RC_MENU
2779 case JPEG_RC_MENU:
2780 #endif
2781 case JPEG_MENU:
2782 #ifdef USEGSLIB
2783 gray_show(false); /* switch off grayscale overlay */
2784 #endif
2785 if (show_menu() == 1)
2786 return PLUGIN_OK;
2788 #ifdef USEGSLIB
2789 gray_show(true); /* switch on grayscale overlay */
2790 #else
2791 yuv_bitmap_part(
2792 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2793 pdisp->x, pdisp->y, pdisp->stride,
2794 MAX(0, (LCD_WIDTH - pdisp->width) / 2),
2795 MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
2796 MIN(LCD_WIDTH, pdisp->width),
2797 MIN(LCD_HEIGHT, pdisp->height));
2798 MYLCD_UPDATE();
2799 #endif
2800 break;
2801 default:
2802 if (rb->default_event_handler_ex(button, cleanup, NULL)
2803 == SYS_USB_CONNECTED)
2804 return PLUGIN_USB_CONNECTED;
2805 break;
2807 } /* switch */
2809 if (button != BUTTON_NONE)
2810 lastbutton = button;
2811 } /* while (true) */
2814 /********************* main function *************************/
2816 /* callback updating a progress meter while JPEG decoding */
2817 void cb_progess(int current, int total)
2819 rb->yield(); /* be nice to the other threads */
2820 if(!running_slideshow)
2822 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-8, LCD_WIDTH, 8, total, 0,
2823 current, HORIZONTAL);
2824 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
2826 #ifndef USEGSLIB
2827 else
2829 /* in slideshow mode, keep gui interference to a minimum */
2830 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-4, LCD_WIDTH, 4, total, 0,
2831 current, HORIZONTAL);
2832 rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4);
2834 #endif
2837 int jpegmem(struct jpeg *p_jpg, int ds)
2839 int size;
2841 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
2842 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
2843 #ifdef HAVE_LCD_COLOR
2844 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
2846 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
2847 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
2848 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
2849 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
2851 #endif
2852 return size;
2855 /* how far can we zoom in without running out of memory */
2856 int min_downscale(struct jpeg *p_jpg, int bufsize)
2858 int downscale = 8;
2860 if (jpegmem(p_jpg, 8) > bufsize)
2861 return 0; /* error, too large, even 1:8 doesn't fit */
2863 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
2864 downscale /= 2;
2866 return downscale;
2870 /* how far can we zoom out, to fit image into the LCD */
2871 int max_downscale(struct jpeg *p_jpg)
2873 int downscale = 1;
2875 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale
2876 || p_jpg->y_size > LCD_HEIGHT*downscale))
2878 downscale *= 2;
2881 return downscale;
2885 /* return decoded or cached image */
2886 struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2888 int w, h; /* used to center output */
2889 int size; /* decompressed image size */
2890 long time; /* measured ticks */
2891 int status;
2893 struct t_disp* p_disp = &disp[ds]; /* short cut */
2895 if (p_disp->bitmap[0] != NULL)
2897 return p_disp; /* we still have it */
2900 /* assign image buffer */
2902 /* physical size needed for decoding */
2903 size = jpegmem(p_jpg, ds);
2904 if (buf_size <= size)
2905 { /* have to discard the current */
2906 int i;
2907 for (i=1; i<=8; i++)
2908 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
2909 buf = buf_root; /* start again from the beginning of the buffer */
2910 buf_size = root_size;
2913 #ifdef HAVE_LCD_COLOR
2914 if (p_jpg->blocks > 1) /* colour jpeg */
2916 int i;
2918 for (i = 1; i < 3; i++)
2920 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
2921 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
2922 p_disp->bitmap[i] = buf;
2923 buf += size;
2924 buf_size -= size;
2926 p_disp->csub_x = p_jpg->subsample_x[1];
2927 p_disp->csub_y = p_jpg->subsample_y[1];
2929 else
2931 p_disp->csub_x = p_disp->csub_y = 0;
2932 p_disp->bitmap[1] = p_disp->bitmap[2] = buf;
2934 #endif
2935 /* size may be less when decoded (if height is not block aligned) */
2936 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
2937 p_disp->bitmap[0] = buf;
2938 buf += size;
2939 buf_size -= size;
2941 if(!running_slideshow)
2943 rb->snprintf(print, sizeof(print), "decoding %d*%d",
2944 p_jpg->x_size/ds, p_jpg->y_size/ds);
2945 rb->lcd_puts(0, 3, print);
2946 rb->lcd_update();
2949 /* update image properties */
2950 p_disp->width = p_jpg->x_size / ds;
2951 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
2952 p_disp->height = p_jpg->y_size / ds;
2954 /* the actual decoding */
2955 time = *rb->current_tick;
2956 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2957 rb->cpu_boost(true);
2958 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2959 rb->cpu_boost(false);
2960 #else
2961 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2962 #endif
2963 if (status)
2965 rb->splash(HZ, "decode error %d", status);
2966 file_pt[curfile] = '\0';
2967 return NULL;
2969 time = *rb->current_tick - time;
2971 if(!running_slideshow)
2973 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
2974 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
2975 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
2976 rb->lcd_update();
2979 return p_disp;
2983 /* set the view to the given center point, limit if necessary */
2984 void set_view (struct t_disp* p_disp, int cx, int cy)
2986 int x, y;
2988 /* plain center to available width/height */
2989 x = cx - MIN(LCD_WIDTH, p_disp->width) / 2;
2990 y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2;
2992 /* limit against upper image size */
2993 x = MIN(p_disp->width - LCD_WIDTH, x);
2994 y = MIN(p_disp->height - LCD_HEIGHT, y);
2996 /* limit against negative side */
2997 x = MAX(0, x);
2998 y = MAX(0, y);
3000 p_disp->x = x; /* set the values */
3001 p_disp->y = y;
3005 /* calculate the view center based on the bitmap position */
3006 void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
3008 *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2;
3009 *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2;
3013 /* load, decode, display the image */
3014 int load_and_show(char* filename)
3016 int fd;
3017 int filesize;
3018 unsigned char* buf_jpeg; /* compressed JPEG image */
3019 int status;
3020 struct t_disp* p_disp; /* currenly displayed image */
3021 int cx, cy; /* view center */
3023 fd = rb->open(filename, O_RDONLY);
3024 if (fd < 0)
3026 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
3027 rb->splash(HZ, print);
3028 return PLUGIN_ERROR;
3030 filesize = rb->filesize(fd);
3031 rb->memset(&disp, 0, sizeof(disp));
3033 buf = buf_images + filesize;
3034 buf_size = buf_images_size - filesize;
3035 /* allocate JPEG buffer */
3036 buf_jpeg = buf_images;
3038 buf_root = buf; /* we can start the decompressed images behind it */
3039 root_size = buf_size;
3041 if (buf_size <= 0)
3043 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
3044 if(plug_buf)
3046 rb->close(fd);
3047 rb->lcd_setfont(FONT_SYSFIXED);
3048 rb->lcd_clear_display();
3049 rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
3050 rb->lcd_puts(0,0,print);
3051 rb->lcd_puts(0,1,"Not enough plugin memory!");
3052 rb->lcd_puts(0,2,"Zoom In: Stop playback.");
3053 if(entries>1)
3054 rb->lcd_puts(0,3,"Left/Right: Skip File.");
3055 rb->lcd_puts(0,4,"Off: Quit.");
3056 rb->lcd_update();
3057 rb->lcd_setfont(FONT_UI);
3059 rb->button_clear_queue();
3061 while (1)
3063 int button = rb->button_get(true);
3064 switch(button)
3066 case JPEG_ZOOM_IN:
3067 plug_buf = false;
3068 buf_images = rb->plugin_get_audio_buffer(
3069 (size_t *)&buf_images_size);
3070 /*try again this file, now using the audio buffer */
3071 return PLUGIN_OTHER;
3072 #ifdef JPEG_RC_MENU
3073 case JPEG_RC_MENU:
3074 #endif
3075 case JPEG_MENU:
3076 return PLUGIN_OK;
3078 case JPEG_LEFT:
3079 if(entries>1)
3081 rb->lcd_clear_display();
3082 return change_filename(DIR_PREV);
3084 break;
3086 case JPEG_RIGHT:
3087 if(entries>1)
3089 rb->lcd_clear_display();
3090 return change_filename(DIR_NEXT);
3092 break;
3093 default:
3094 if(rb->default_event_handler_ex(button, cleanup, NULL)
3095 == SYS_USB_CONNECTED)
3096 return PLUGIN_USB_CONNECTED;
3101 else
3102 #endif
3104 rb->splash(HZ, "Out of Memory");
3105 rb->close(fd);
3106 return PLUGIN_ERROR;
3110 if(!running_slideshow)
3112 #if LCD_DEPTH > 1
3113 rb->lcd_set_foreground(LCD_WHITE);
3114 rb->lcd_set_background(LCD_BLACK);
3115 rb->lcd_set_backdrop(NULL);
3116 #endif
3118 rb->lcd_clear_display();
3119 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
3120 rb->lcd_puts(0, 0, print);
3121 rb->lcd_update();
3123 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
3124 rb->lcd_puts(0, 1, print);
3125 rb->lcd_update();
3128 rb->read(fd, buf_jpeg, filesize);
3129 rb->close(fd);
3131 if(!running_slideshow)
3133 rb->snprintf(print, sizeof(print), "decoding markers");
3134 rb->lcd_puts(0, 2, print);
3135 rb->lcd_update();
3137 #ifndef SIMULATOR
3138 else if(immediate_ata_off)
3140 /* running slideshow and time is long enough: power down disk */
3141 rb->ata_sleep();
3143 #endif
3145 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
3146 /* process markers, unstuffing */
3147 status = process_markers(buf_jpeg, filesize, &jpg);
3149 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
3150 { /* bad format or minimum components not contained */
3151 rb->splash(HZ, "unsupported %d", status);
3152 file_pt[curfile] = '\0';
3153 return change_filename(direction);
3156 if (!(status & DHT)) /* if no Huffman table present: */
3157 default_huff_tbl(&jpg); /* use default */
3158 build_lut(&jpg); /* derive Huffman and other lookup-tables */
3160 if(!running_slideshow)
3162 rb->snprintf(print, sizeof(print), "image %dx%d", jpg.x_size, jpg.y_size);
3163 rb->lcd_puts(0, 2, print);
3164 rb->lcd_update();
3166 ds_max = max_downscale(&jpg); /* check display constraint */
3167 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */
3168 if (ds_min == 0)
3170 rb->splash(HZ, "too large");
3171 file_pt[curfile] = '\0';
3172 return change_filename(direction);
3175 ds = ds_max; /* initials setting */
3176 cx = jpg.x_size/ds/2; /* center the view */
3177 cy = jpg.y_size/ds/2;
3179 do /* loop the image prepare and decoding when zoomed */
3181 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */
3182 if (p_disp == NULL)
3183 return change_filename(direction);
3185 set_view(p_disp, cx, cy);
3187 if(!running_slideshow)
3189 rb->snprintf(print, sizeof(print), "showing %dx%d",
3190 p_disp->width, p_disp->height);
3191 rb->lcd_puts(0, 3, print);
3192 rb->lcd_update();
3194 MYLCD(clear_display)();
3195 #ifdef HAVE_LCD_COLOR
3196 yuv_bitmap_part(
3197 p_disp->bitmap, p_disp->csub_x, p_disp->csub_y,
3198 p_disp->x, p_disp->y, p_disp->stride,
3199 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3200 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3201 MIN(LCD_WIDTH, p_disp->width),
3202 MIN(LCD_HEIGHT, p_disp->height));
3203 #else
3204 MYXLCD(gray_bitmap_part)(
3205 p_disp->bitmap[0], p_disp->x, p_disp->y, p_disp->stride,
3206 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3207 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3208 MIN(LCD_WIDTH, p_disp->width),
3209 MIN(LCD_HEIGHT, p_disp->height));
3210 #endif
3211 MYLCD_UPDATE();
3213 #ifdef USEGSLIB
3214 gray_show(true); /* switch on grayscale overlay */
3215 #endif
3217 /* drawing is now finished, play around with scrolling
3218 * until you press OFF or connect USB
3220 while (1)
3222 status = scroll_bmp(p_disp);
3223 if (status == ZOOM_IN)
3225 if (ds > ds_min)
3227 ds /= 2; /* reduce downscaling to zoom in */
3228 get_view(p_disp, &cx, &cy);
3229 cx *= 2; /* prepare the position in the new image */
3230 cy *= 2;
3232 else
3233 continue;
3236 if (status == ZOOM_OUT)
3238 if (ds < ds_max)
3240 ds *= 2; /* increase downscaling to zoom out */
3241 get_view(p_disp, &cx, &cy);
3242 cx /= 2; /* prepare the position in the new image */
3243 cy /= 2;
3245 else
3246 continue;
3248 break;
3251 #ifdef USEGSLIB
3252 gray_show(false); /* switch off overlay */
3253 #endif
3254 rb->lcd_clear_display();
3256 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
3257 && status != PLUGIN_OTHER);
3258 #ifdef USEGSLIB
3259 rb->lcd_update();
3260 #endif
3261 return status;
3264 /******************** Plugin entry point *********************/
3266 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
3268 rb = api;
3270 int condition;
3271 #ifdef USEGSLIB
3272 int grayscales;
3273 long graysize; /* helper */
3274 #endif
3275 #if LCD_DEPTH > 1
3276 old_backdrop = rb->lcd_get_backdrop();
3277 #endif
3279 if(!parameter) return PLUGIN_ERROR;
3281 rb->strcpy(np_file, parameter);
3282 get_pic_list();
3284 if(!entries) return PLUGIN_ERROR;
3286 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
3287 if(rb->audio_status())
3289 buf = rb->plugin_get_buffer((size_t *)&buf_size) +
3290 (entries * sizeof(char**));
3291 buf_size -= (entries * sizeof(char**));
3292 plug_buf = true;
3294 else
3295 buf = rb->plugin_get_audio_buffer((size_t *)&buf_size);
3296 #else
3297 buf = rb->plugin_get_audio_buffer(&buf_size) +
3298 (entries * sizeof(char**));
3299 buf_size -= (entries * sizeof(char**));
3300 #endif
3302 #ifdef USEGSLIB
3303 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */
3304 grayscales = gray_init(rb, buf, buf_size, false, LCD_WIDTH, LCD_HEIGHT,
3305 32, 2<<8, &graysize) + 1;
3306 buf += graysize;
3307 buf_size -= graysize;
3308 if (grayscales < 33 || buf_size <= 0)
3310 rb->splash(HZ, "gray buf error");
3311 return PLUGIN_ERROR;
3313 #else
3314 xlcd_init(rb);
3315 #endif
3317 #ifdef HAVE_LCD_COLOR
3318 /* should be ok to just load settings since a parameter is present
3319 here and the drive should be spinning */
3320 configfile_init(rb);
3321 configfile_load(JPEG_CONFIGFILE, jpeg_config,
3322 ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION);
3323 old_settings = jpeg_settings;
3324 #endif
3326 buf_images = buf; buf_images_size = buf_size;
3328 /* Turn off backlight timeout */
3329 backlight_force_on(rb); /* backlight control in lib/helper.c */
3333 condition = load_and_show(np_file);
3334 }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
3335 && condition != PLUGIN_ERROR);
3337 #ifdef HAVE_LCD_COLOR
3338 if (rb->memcmp(&jpeg_settings, &old_settings, sizeof (jpeg_settings)))
3340 /* Just in case drive has to spin, keep it from looking locked */
3341 rb->splash(0, "Saving Settings");
3342 configfile_save(JPEG_CONFIGFILE, jpeg_config,
3343 ARRAYLEN(jpeg_config), JPEG_SETTINGS_VERSION);
3345 #endif
3347 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
3348 /* set back ata spindown time in case we changed it */
3349 rb->ata_spindown(rb->global_settings->disk_spindown);
3350 #endif
3352 /* Turn on backlight timeout (revert to settings) */
3353 backlight_use_settings(rb); /* backlight control in lib/helper.c */
3355 #ifdef USEGSLIB
3356 gray_release(); /* deinitialize */
3357 #endif
3359 return condition;
3362 #endif /* HAVE_LCD_BITMAP */