A bit of adapting.
[Rockbox.git] / apps / plugins / jpeg.c
blob9e11ca431b66bfa7429edb27e4111942b36d5a4b
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 #elif CONFIG_KEYPAD == MROBE500_PAD
173 #define JPEG_ZOOM_IN BUTTON_RC_VOL_UP
174 #define JPEG_ZOOM_OUT BUTTON_RC_VOL_DOWN
175 #define JPEG_UP BUTTON_RC_PLAY
176 #define JPEG_DOWN BUTTON_RC_DOWN
177 #define JPEG_LEFT BUTTON_LEFT
178 #define JPEG_RIGHT BUTTON_RIGHT
179 #define JPEG_MENU BUTTON_POWER
180 #define JPEG_NEXT BUTTON_RC_HEART
181 #define JPEG_PREVIOUS BUTTON_RC_MODE
183 #endif
185 /* different graphics libraries */
186 #if LCD_DEPTH < 8
187 #define USEGSLIB
188 #define MYLCD(fn) gray_ub_ ## fn
189 #define MYLCD_UPDATE()
190 #define MYXLCD(fn) gray_ub_ ## fn
191 #else
192 #define MYLCD(fn) rb->lcd_ ## fn
193 #define MYLCD_UPDATE() rb->lcd_update();
194 #define MYXLCD(fn) xlcd_ ## fn
195 #endif
197 #define MAX_X_SIZE LCD_WIDTH*8
199 /* Min memory allowing us to use the plugin buffer
200 * and thus not stopping the music
201 * *Very* rough estimation:
202 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
203 * + 20k code size = 60 000
204 * + 50k min for jpeg = 120 000
206 #define MIN_MEM 120000
208 /* Headings */
209 #define DIR_PREV 1
210 #define DIR_NEXT -1
211 #define DIR_NONE 0
213 #define PLUGIN_OTHER 10 /* State code for output with return. */
215 /******************************* Globals ***********************************/
217 static struct plugin_api* rb;
218 MEM_FUNCTION_WRAPPERS(rb);
220 /* for portability of below JPEG code */
221 #define MEMSET(p,v,c) rb->memset(p,v,c)
222 #define MEMCPY(d,s,c) rb->memcpy(d,s,c)
223 #define INLINE static inline
224 #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
226 static int slideshow_enabled = false; /* run slideshow */
227 static int running_slideshow = false; /* loading image because of slideshw */
228 #ifndef SIMULATOR
229 static int immediate_ata_off = false; /* power down disk after loading */
230 #endif
231 static int button_timeout = HZ*5;
233 #ifdef HAVE_LCD_COLOR
235 /* Persistent configuration - only needed for color displays atm */
236 #define JPEG_CONFIGFILE "jpeg.cfg"
237 #define JPEG_SETTINGS_MINVERSION 1
238 #define JPEG_SETTINGS_VERSION 1
240 enum color_modes
242 COLOURMODE_COLOUR = 0,
243 COLOURMODE_GRAY,
244 COLOUR_NUM_MODES
247 enum dither_modes
249 DITHER_NONE = 0, /* No dithering */
250 DITHER_ORDERED, /* Bayer ordered */
251 DITHER_DIFFUSION, /* Floyd/Steinberg error diffusion */
252 DITHER_NUM_MODES
255 struct jpeg_settings
257 int colour_mode;
258 int dither_mode;
261 static struct jpeg_settings jpeg_settings =
262 { COLOURMODE_COLOUR, DITHER_NONE };
263 static struct jpeg_settings old_settings;
265 static struct configdata jpeg_config[] =
267 { TYPE_ENUM, 0, COLOUR_NUM_MODES, &jpeg_settings.colour_mode,
268 "Colour Mode", (char *[]){ "Colour", "Grayscale" }, NULL },
269 { TYPE_ENUM, 0, DITHER_NUM_MODES, &jpeg_settings.dither_mode,
270 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" }, NULL },
273 #endif /* HAVE_LCD_COLOR */
274 #if LCD_DEPTH > 1
275 fb_data* old_backdrop;
276 #endif
278 /**************** begin JPEG code ********************/
280 INLINE unsigned range_limit(int value)
282 #if CONFIG_CPU == SH7034
283 unsigned tmp;
284 asm ( /* Note: Uses knowledge that only low byte of result is used */
285 "mov #-128,%[t] \n"
286 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
287 "extu.b %[v],%[t] \n"
288 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
289 "bt 1f \n" /* yes: no overflow */
290 "cmp/pz %[v] \n" /* overflow: positive? */
291 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
292 "1: \n"
293 : /* outputs */
294 [v]"+r"(value),
295 [t]"=&r"(tmp)
297 return value;
298 #elif defined(CPU_COLDFIRE)
299 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
300 "add.l #128,%[v] \n" /* value += 128; */
301 "cmp.l #255,%[v] \n" /* overflow? */
302 "bls.b 1f \n" /* no: return value */
303 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
304 "1: \n"
305 : /* outputs */
306 [v]"+d"(value)
308 return value;
309 #elif defined(CPU_ARM)
310 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
311 "add %[v], %[v], #128 \n" /* value += 128 */
312 "cmp %[v], #255 \n" /* out of range 0..255? */
313 "mvnhi %[v], %[v], asr #31 \n" /* yes: set all bits to ~(sign_bit) */
314 : /* outputs */
315 [v]"+r"(value)
317 return value;
318 #else
319 value += 128;
321 if ((unsigned)value <= 255)
322 return value;
324 if (value < 0)
325 return 0;
327 return 255;
328 #endif
331 /* IDCT implementation */
334 #define CONST_BITS 13
335 #define PASS1_BITS 2
338 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
339 * causing a lot of useless floating-point operations at run time.
340 * To get around this we use the following pre-calculated constants.
341 * If you change CONST_BITS you may want to add appropriate values.
342 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
344 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
345 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
346 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
347 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
348 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
349 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
350 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
351 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
352 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
353 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
354 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
355 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
359 /* Multiply an long variable by an long constant to yield an long result.
360 * For 8-bit samples with the recommended scaling, all the variable
361 * and constant values involved are no more than 16 bits wide, so a
362 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
363 * For 12-bit samples, a full 32-bit multiplication will be needed.
365 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
368 /* Dequantize a coefficient by multiplying it by the multiplier-table
369 * entry; produce an int result. In this module, both inputs and result
370 * are 16 bits or less, so either int or short multiply will work.
372 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
373 #define DEQUANTIZE MULTIPLY16
375 /* Descale and correctly round an int value that's scaled by N bits.
376 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
377 * the fudge factor is correct for either sign of X.
379 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
384 * Perform dequantization and inverse DCT on one block of coefficients,
385 * producing a reduced-size 1x1 output block.
387 void idct1x1(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
389 (void)skip_line; /* unused */
390 *p_byte = range_limit(inptr[0] * quantptr[0] >> 3);
396 * Perform dequantization and inverse DCT on one block of coefficients,
397 * producing a reduced-size 2x2 output block.
399 void idct2x2(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
401 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
402 unsigned char* outptr;
404 /* Pass 1: process columns from input, store into work array. */
406 /* Column 0 */
407 tmp4 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
408 tmp5 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
410 tmp0 = tmp4 + tmp5;
411 tmp2 = tmp4 - tmp5;
413 /* Column 1 */
414 tmp4 = DEQUANTIZE(inptr[8*0+1], quantptr[8*0+1]);
415 tmp5 = DEQUANTIZE(inptr[8*1+1], quantptr[8*1+1]);
417 tmp1 = tmp4 + tmp5;
418 tmp3 = tmp4 - tmp5;
420 /* Pass 2: process 2 rows, store into output array. */
422 /* Row 0 */
423 outptr = p_byte;
425 outptr[0] = range_limit((int) DESCALE(tmp0 + tmp1, 3));
426 outptr[1] = range_limit((int) DESCALE(tmp0 - tmp1, 3));
428 /* Row 1 */
429 outptr = p_byte + skip_line;
431 outptr[0] = range_limit((int) DESCALE(tmp2 + tmp3, 3));
432 outptr[1] = range_limit((int) DESCALE(tmp2 - tmp3, 3));
438 * Perform dequantization and inverse DCT on one block of coefficients,
439 * producing a reduced-size 4x4 output block.
441 void idct4x4(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
443 int tmp0, tmp2, tmp10, tmp12;
444 int z1, z2, z3;
445 int * wsptr;
446 unsigned char* outptr;
447 int ctr;
448 int workspace[4*4]; /* buffers data between passes */
450 /* Pass 1: process columns from input, store into work array. */
452 wsptr = workspace;
453 for (ctr = 0; ctr < 4; ctr++, inptr++, quantptr++, wsptr++)
455 /* Even part */
457 tmp0 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
458 tmp2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
460 tmp10 = (tmp0 + tmp2) << PASS1_BITS;
461 tmp12 = (tmp0 - tmp2) << PASS1_BITS;
463 /* Odd part */
464 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
466 z2 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
467 z3 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
469 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
470 tmp0 = DESCALE(z1 + MULTIPLY16(z3, - FIX_1_847759065), CONST_BITS-PASS1_BITS);
471 tmp2 = DESCALE(z1 + MULTIPLY16(z2, FIX_0_765366865), CONST_BITS-PASS1_BITS);
473 /* Final output stage */
475 wsptr[4*0] = (int) (tmp10 + tmp2);
476 wsptr[4*3] = (int) (tmp10 - tmp2);
477 wsptr[4*1] = (int) (tmp12 + tmp0);
478 wsptr[4*2] = (int) (tmp12 - tmp0);
481 /* Pass 2: process 4 rows from work array, store into output array. */
483 wsptr = workspace;
484 for (ctr = 0; ctr < 4; ctr++)
486 outptr = p_byte + (ctr*skip_line);
487 /* Even part */
489 tmp0 = (int) wsptr[0];
490 tmp2 = (int) wsptr[2];
492 tmp10 = (tmp0 + tmp2) << CONST_BITS;
493 tmp12 = (tmp0 - tmp2) << CONST_BITS;
495 /* Odd part */
496 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
498 z2 = (int) wsptr[1];
499 z3 = (int) wsptr[3];
501 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
502 tmp0 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
503 tmp2 = z1 + MULTIPLY16(z2, FIX_0_765366865);
505 /* Final output stage */
507 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp2,
508 CONST_BITS+PASS1_BITS+3));
509 outptr[3] = range_limit((int) DESCALE(tmp10 - tmp2,
510 CONST_BITS+PASS1_BITS+3));
511 outptr[1] = range_limit((int) DESCALE(tmp12 + tmp0,
512 CONST_BITS+PASS1_BITS+3));
513 outptr[2] = range_limit((int) DESCALE(tmp12 - tmp0,
514 CONST_BITS+PASS1_BITS+3));
516 wsptr += 4; /* advance pointer to next row */
523 * Perform dequantization and inverse DCT on one block of coefficients.
525 void idct8x8(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
527 long tmp0, tmp1, tmp2, tmp3;
528 long tmp10, tmp11, tmp12, tmp13;
529 long z1, z2, z3, z4, z5;
530 int * wsptr;
531 unsigned char* outptr;
532 int ctr;
533 int workspace[64]; /* buffers data between passes */
535 /* Pass 1: process columns from input, store into work array. */
536 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
537 /* furthermore, we scale the results by 2**PASS1_BITS. */
539 wsptr = workspace;
540 for (ctr = 8; ctr > 0; ctr--)
542 /* Due to quantization, we will usually find that many of the input
543 * coefficients are zero, especially the AC terms. We can exploit this
544 * by short-circuiting the IDCT calculation for any column in which all
545 * the AC terms are zero. In that case each output is equal to the
546 * DC coefficient (with scale factor as needed).
547 * With typical images and quantization tables, half or more of the
548 * column DCT calculations can be simplified this way.
551 if ((inptr[8*1] | inptr[8*2] | inptr[8*3]
552 | inptr[8*4] | inptr[8*5] | inptr[8*6] | inptr[8*7]) == 0)
554 /* AC terms all zero */
555 int dcval = DEQUANTIZE(inptr[8*0], quantptr[8*0]) << PASS1_BITS;
557 wsptr[8*0] = wsptr[8*1] = wsptr[8*2] = wsptr[8*3] = wsptr[8*4]
558 = wsptr[8*5] = wsptr[8*6] = wsptr[8*7] = dcval;
559 inptr++; /* advance pointers to next column */
560 quantptr++;
561 wsptr++;
562 continue;
565 /* Even part: reverse the even part of the forward DCT. */
566 /* The rotator is sqrt(2)*c(-6). */
568 z2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
569 z3 = DEQUANTIZE(inptr[8*6], quantptr[8*6]);
571 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
572 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
573 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
575 z2 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
576 z3 = DEQUANTIZE(inptr[8*4], quantptr[8*4]);
578 tmp0 = (z2 + z3) << CONST_BITS;
579 tmp1 = (z2 - z3) << CONST_BITS;
581 tmp10 = tmp0 + tmp3;
582 tmp13 = tmp0 - tmp3;
583 tmp11 = tmp1 + tmp2;
584 tmp12 = tmp1 - tmp2;
586 /* Odd part per figure 8; the matrix is unitary and hence its
587 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
589 tmp0 = DEQUANTIZE(inptr[8*7], quantptr[8*7]);
590 tmp1 = DEQUANTIZE(inptr[8*5], quantptr[8*5]);
591 tmp2 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
592 tmp3 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
594 z1 = tmp0 + tmp3;
595 z2 = tmp1 + tmp2;
596 z3 = tmp0 + tmp2;
597 z4 = tmp1 + tmp3;
598 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
600 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
601 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
602 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
603 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
604 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
605 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
606 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
607 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
609 z3 += z5;
610 z4 += z5;
612 tmp0 += z1 + z3;
613 tmp1 += z2 + z4;
614 tmp2 += z2 + z3;
615 tmp3 += z1 + z4;
617 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
619 wsptr[8*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
620 wsptr[8*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
621 wsptr[8*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
622 wsptr[8*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
623 wsptr[8*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
624 wsptr[8*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
625 wsptr[8*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
626 wsptr[8*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
628 inptr++; /* advance pointers to next column */
629 quantptr++;
630 wsptr++;
633 /* Pass 2: process rows from work array, store into output array. */
634 /* Note that we must descale the results by a factor of 8 == 2**3, */
635 /* and also undo the PASS1_BITS scaling. */
637 wsptr = workspace;
638 for (ctr = 0; ctr < 8; ctr++)
640 outptr = p_byte + (ctr*skip_line);
641 /* Rows of zeroes can be exploited in the same way as we did with columns.
642 * However, the column calculation has created many nonzero AC terms, so
643 * the simplification applies less often (typically 5% to 10% of the time).
644 * On machines with very fast multiplication, it's possible that the
645 * test takes more time than it's worth. In that case this section
646 * may be commented out.
649 #ifndef NO_ZERO_ROW_TEST
650 if ((wsptr[1] | wsptr[2] | wsptr[3]
651 | wsptr[4] | wsptr[5] | wsptr[6] | wsptr[7]) == 0)
653 /* AC terms all zero */
654 unsigned char dcval = range_limit((int) DESCALE((long) wsptr[0],
655 PASS1_BITS+3));
657 outptr[0] = dcval;
658 outptr[1] = dcval;
659 outptr[2] = dcval;
660 outptr[3] = dcval;
661 outptr[4] = dcval;
662 outptr[5] = dcval;
663 outptr[6] = dcval;
664 outptr[7] = dcval;
666 wsptr += 8; /* advance pointer to next row */
667 continue;
669 #endif
671 /* Even part: reverse the even part of the forward DCT. */
672 /* The rotator is sqrt(2)*c(-6). */
674 z2 = (long) wsptr[2];
675 z3 = (long) wsptr[6];
677 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
678 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
679 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
681 tmp0 = ((long) wsptr[0] + (long) wsptr[4]) << CONST_BITS;
682 tmp1 = ((long) wsptr[0] - (long) wsptr[4]) << CONST_BITS;
684 tmp10 = tmp0 + tmp3;
685 tmp13 = tmp0 - tmp3;
686 tmp11 = tmp1 + tmp2;
687 tmp12 = tmp1 - tmp2;
689 /* Odd part per figure 8; the matrix is unitary and hence its
690 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
692 tmp0 = (long) wsptr[7];
693 tmp1 = (long) wsptr[5];
694 tmp2 = (long) wsptr[3];
695 tmp3 = (long) wsptr[1];
697 z1 = tmp0 + tmp3;
698 z2 = tmp1 + tmp2;
699 z3 = tmp0 + tmp2;
700 z4 = tmp1 + tmp3;
701 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
703 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
704 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
705 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
706 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
707 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
708 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
709 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
710 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
712 z3 += z5;
713 z4 += z5;
715 tmp0 += z1 + z3;
716 tmp1 += z2 + z4;
717 tmp2 += z2 + z3;
718 tmp3 += z1 + z4;
720 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
722 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp3,
723 CONST_BITS+PASS1_BITS+3));
724 outptr[7] = range_limit((int) DESCALE(tmp10 - tmp3,
725 CONST_BITS+PASS1_BITS+3));
726 outptr[1] = range_limit((int) DESCALE(tmp11 + tmp2,
727 CONST_BITS+PASS1_BITS+3));
728 outptr[6] = range_limit((int) DESCALE(tmp11 - tmp2,
729 CONST_BITS+PASS1_BITS+3));
730 outptr[2] = range_limit((int) DESCALE(tmp12 + tmp1,
731 CONST_BITS+PASS1_BITS+3));
732 outptr[5] = range_limit((int) DESCALE(tmp12 - tmp1,
733 CONST_BITS+PASS1_BITS+3));
734 outptr[3] = range_limit((int) DESCALE(tmp13 + tmp0,
735 CONST_BITS+PASS1_BITS+3));
736 outptr[4] = range_limit((int) DESCALE(tmp13 - tmp0,
737 CONST_BITS+PASS1_BITS+3));
739 wsptr += 8; /* advance pointer to next row */
745 /* JPEG decoder implementation */
748 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
750 struct derived_tbl
752 /* Basic tables: (element [0] of each array is unused) */
753 long mincode[17]; /* smallest code of length k */
754 long maxcode[18]; /* largest code of length k (-1 if none) */
755 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
756 int valptr[17]; /* huffval[] index of 1st symbol of length k */
758 /* Back link to public Huffman table (needed only in slow_DECODE) */
759 int* pub;
761 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
762 the input data stream. If the next Huffman code is no more
763 than HUFF_LOOKAHEAD bits long, we can obtain its length and
764 the corresponding symbol directly from these tables. */
765 int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
766 unsigned char look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
769 #define QUANT_TABLE_LENGTH 64
771 /* for type of Huffman table */
772 #define DC_LEN 28
773 #define AC_LEN 178
775 struct huffman_table
776 { /* length and code according to JFIF format */
777 int huffmancodes_dc[DC_LEN];
778 int huffmancodes_ac[AC_LEN];
781 struct frame_component
783 int ID;
784 int horizontal_sampling;
785 int vertical_sampling;
786 int quanttable_select;
789 struct scan_component
791 int ID;
792 int DC_select;
793 int AC_select;
796 struct bitstream
798 unsigned long get_buffer; /* current bit-extraction buffer */
799 int bits_left; /* # of unused bits in it */
800 unsigned char* next_input_byte;
801 unsigned char* input_end; /* upper limit +1 */
804 struct jpeg
806 int x_size, y_size; /* size of image (can be less than block boundary) */
807 int x_phys, y_phys; /* physical size, block aligned */
808 int x_mbl; /* x dimension of MBL */
809 int y_mbl; /* y dimension of MBL */
810 int blocks; /* blocks per MB */
811 int restart_interval; /* number of MCUs between RSTm markers */
812 int store_pos[4]; /* for Y block ordering */
814 unsigned char* p_entropy_data;
815 unsigned char* p_entropy_end;
817 int quanttable[4][QUANT_TABLE_LENGTH]; /* raw quantization tables 0-3 */
818 int qt_idct[2][QUANT_TABLE_LENGTH]; /* quantization tables for IDCT */
820 struct huffman_table hufftable[2]; /* Huffman tables */
821 struct derived_tbl dc_derived_tbls[2]; /* Huffman-LUTs */
822 struct derived_tbl ac_derived_tbls[2];
824 struct frame_component frameheader[3]; /* Component descriptor */
825 struct scan_component scanheader[3]; /* currently not used */
827 int mcu_membership[6]; /* info per block */
828 int tab_membership[6];
829 int subsample_x[3]; /* info per component */
830 int subsample_y[3];
834 /* possible return flags for process_markers() */
835 #define HUFFTAB 0x0001 /* with huffman table */
836 #define QUANTTAB 0x0002 /* with quantization table */
837 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
838 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
839 #define SOF0 0x0010 /* with SOF0-Segment */
840 #define DHT 0x0020 /* with Definition of huffman tables */
841 #define SOS 0x0040 /* with Start-of-Scan segment */
842 #define DQT 0x0080 /* with definition of quantization table */
844 /* Preprocess the JPEG JFIF file */
845 int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
847 unsigned char* p_bytes = p_src;
848 int marker_size; /* variable length of marker segment */
849 int i, j, n;
850 int ret = 0; /* returned flags */
852 p_jpeg->p_entropy_end = p_src + size;
854 while (p_src < p_bytes + size)
856 if (*p_src++ != 0xFF) /* no marker? */
858 p_src--; /* it's image data, put it back */
859 p_jpeg->p_entropy_data = p_src;
860 break; /* exit marker processing */
863 switch (*p_src++)
865 case 0xFF: /* Fill byte */
866 ret |= FILL_FF;
867 case 0x00: /* Zero stuffed byte - entropy data */
868 p_src--; /* put it back */
869 continue;
871 case 0xC0: /* SOF Huff - Baseline DCT */
873 ret |= SOF0;
874 marker_size = *p_src++ << 8; /* Highbyte */
875 marker_size |= *p_src++; /* Lowbyte */
876 n = *p_src++; /* sample precision (= 8 or 12) */
877 if (n != 8)
879 return(-1); /* Unsupported sample precision */
881 p_jpeg->y_size = *p_src++ << 8; /* Highbyte */
882 p_jpeg->y_size |= *p_src++; /* Lowbyte */
883 p_jpeg->x_size = *p_src++ << 8; /* Highbyte */
884 p_jpeg->x_size |= *p_src++; /* Lowbyte */
886 n = (marker_size-2-6)/3;
887 if (*p_src++ != n || (n != 1 && n != 3))
889 return(-2); /* Unsupported SOF0 component specification */
891 for (i=0; i<n; i++)
893 p_jpeg->frameheader[i].ID = *p_src++; /* Component info */
894 p_jpeg->frameheader[i].horizontal_sampling = *p_src >> 4;
895 p_jpeg->frameheader[i].vertical_sampling = *p_src++ & 0x0F;
896 p_jpeg->frameheader[i].quanttable_select = *p_src++;
897 if (p_jpeg->frameheader[i].horizontal_sampling > 2
898 || p_jpeg->frameheader[i].vertical_sampling > 2)
899 return -3; /* Unsupported SOF0 subsampling */
901 p_jpeg->blocks = n;
903 break;
905 case 0xC1: /* SOF Huff - Extended sequential DCT*/
906 case 0xC2: /* SOF Huff - Progressive DCT*/
907 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
908 case 0xC5: /* SOF Huff - Differential sequential DCT*/
909 case 0xC6: /* SOF Huff - Differential progressive DCT*/
910 case 0xC7: /* SOF Huff - Differential spatial*/
911 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
912 case 0xC9: /* SOF Arith - Extended sequential DCT*/
913 case 0xCA: /* SOF Arith - Progressive DCT*/
914 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
915 case 0xCD: /* SOF Arith - Differential sequential DCT*/
916 case 0xCE: /* SOF Arith - Differential progressive DCT*/
917 case 0xCF: /* SOF Arith - Differential spatial*/
919 return (-4); /* other DCT model than baseline not implemented */
922 case 0xC4: /* Define Huffman Table(s) */
924 unsigned char* p_temp;
926 ret |= DHT;
927 marker_size = *p_src++ << 8; /* Highbyte */
928 marker_size |= *p_src++; /* Lowbyte */
930 p_temp = p_src;
931 while (p_src < p_temp+marker_size-2-17) /* another table */
933 int sum = 0;
934 i = *p_src & 0x0F; /* table index */
935 if (i > 1)
937 return (-5); /* Huffman table index out of range */
939 else if (*p_src++ & 0xF0) /* AC table */
941 for (j=0; j<16; j++)
943 sum += *p_src;
944 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
946 if(16 + sum > AC_LEN)
947 return -10; /* longer than allowed */
949 for (; j < 16 + sum; j++)
950 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
952 else /* DC table */
954 for (j=0; j<16; j++)
956 sum += *p_src;
957 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
959 if(16 + sum > DC_LEN)
960 return -11; /* longer than allowed */
962 for (; j < 16 + sum; j++)
963 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
965 } /* while */
966 p_src = p_temp+marker_size - 2; /* skip possible residue */
968 break;
970 case 0xCC: /* Define Arithmetic coding conditioning(s) */
971 return(-6); /* Arithmetic coding not supported */
973 case 0xD8: /* Start of Image */
974 case 0xD9: /* End of Image */
975 case 0x01: /* for temp private use arith code */
976 break; /* skip parameterless marker */
979 case 0xDA: /* Start of Scan */
981 ret |= SOS;
982 marker_size = *p_src++ << 8; /* Highbyte */
983 marker_size |= *p_src++; /* Lowbyte */
985 n = (marker_size-2-1-3)/2;
986 if (*p_src++ != n || (n != 1 && n != 3))
988 return (-7); /* Unsupported SOS component specification */
990 for (i=0; i<n; i++)
992 p_jpeg->scanheader[i].ID = *p_src++;
993 p_jpeg->scanheader[i].DC_select = *p_src >> 4;
994 p_jpeg->scanheader[i].AC_select = *p_src++ & 0x0F;
996 p_src += 3; /* skip spectral information */
998 break;
1000 case 0xDB: /* Define quantization Table(s) */
1002 ret |= DQT;
1003 marker_size = *p_src++ << 8; /* Highbyte */
1004 marker_size |= *p_src++; /* Lowbyte */
1005 n = (marker_size-2)/(QUANT_TABLE_LENGTH+1); /* # of tables */
1006 for (i=0; i<n; i++)
1008 int id = *p_src++; /* ID */
1009 if (id >= 4)
1011 return (-8); /* Unsupported quantization table */
1013 /* Read Quantisation table: */
1014 for (j=0; j<QUANT_TABLE_LENGTH; j++)
1015 p_jpeg->quanttable[id][j] = *p_src++;
1018 break;
1020 case 0xDD: /* Define Restart Interval */
1022 marker_size = *p_src++ << 8; /* Highbyte */
1023 marker_size |= *p_src++; /* Lowbyte */
1024 p_jpeg->restart_interval = *p_src++ << 8; /* Highbyte */
1025 p_jpeg->restart_interval |= *p_src++; /* Lowbyte */
1026 p_src += marker_size-4; /* skip segment */
1028 break;
1030 case 0xDC: /* Define Number of Lines */
1031 case 0xDE: /* Define Hierarchical progression */
1032 case 0xDF: /* Expand Reference Component(s) */
1033 case 0xE0: /* Application Field 0*/
1034 case 0xE1: /* Application Field 1*/
1035 case 0xE2: /* Application Field 2*/
1036 case 0xE3: /* Application Field 3*/
1037 case 0xE4: /* Application Field 4*/
1038 case 0xE5: /* Application Field 5*/
1039 case 0xE6: /* Application Field 6*/
1040 case 0xE7: /* Application Field 7*/
1041 case 0xE8: /* Application Field 8*/
1042 case 0xE9: /* Application Field 9*/
1043 case 0xEA: /* Application Field 10*/
1044 case 0xEB: /* Application Field 11*/
1045 case 0xEC: /* Application Field 12*/
1046 case 0xED: /* Application Field 13*/
1047 case 0xEE: /* Application Field 14*/
1048 case 0xEF: /* Application Field 15*/
1049 case 0xFE: /* Comment */
1051 marker_size = *p_src++ << 8; /* Highbyte */
1052 marker_size |= *p_src++; /* Lowbyte */
1053 p_src += marker_size-2; /* skip segment */
1055 break;
1057 case 0xF0: /* Reserved for JPEG extensions */
1058 case 0xF1: /* Reserved for JPEG extensions */
1059 case 0xF2: /* Reserved for JPEG extensions */
1060 case 0xF3: /* Reserved for JPEG extensions */
1061 case 0xF4: /* Reserved for JPEG extensions */
1062 case 0xF5: /* Reserved for JPEG extensions */
1063 case 0xF6: /* Reserved for JPEG extensions */
1064 case 0xF7: /* Reserved for JPEG extensions */
1065 case 0xF8: /* Reserved for JPEG extensions */
1066 case 0xF9: /* Reserved for JPEG extensions */
1067 case 0xFA: /* Reserved for JPEG extensions */
1068 case 0xFB: /* Reserved for JPEG extensions */
1069 case 0xFC: /* Reserved for JPEG extensions */
1070 case 0xFD: /* Reserved for JPEG extensions */
1071 case 0x02: /* Reserved */
1072 default:
1073 return (-9); /* Unknown marker */
1074 } /* switch */
1075 } /* while */
1077 return (ret); /* return flags with seen markers */
1081 void default_huff_tbl(struct jpeg* p_jpeg)
1083 static const struct huffman_table luma_table =
1086 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
1087 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1090 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
1091 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
1092 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
1093 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
1094 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
1095 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1096 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1097 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
1098 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
1099 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
1100 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1101 0xF9,0xFA
1105 static const struct huffman_table chroma_table =
1108 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
1109 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1112 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
1113 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
1114 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1115 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1116 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1117 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1118 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1119 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1120 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1121 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1122 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1123 0xF9,0xFA
1127 MEMCPY(&p_jpeg->hufftable[0], &luma_table, sizeof(luma_table));
1128 MEMCPY(&p_jpeg->hufftable[1], &chroma_table, sizeof(chroma_table));
1130 return;
1133 /* Compute the derived values for a Huffman table */
1134 void fix_huff_tbl(int* htbl, struct derived_tbl* dtbl)
1136 int p, i, l, si;
1137 int lookbits, ctr;
1138 char huffsize[257];
1139 unsigned int huffcode[257];
1140 unsigned int code;
1142 dtbl->pub = htbl; /* fill in back link */
1144 /* Figure C.1: make table of Huffman code length for each symbol */
1145 /* Note that this is in code-length order. */
1147 p = 0;
1148 for (l = 1; l <= 16; l++)
1149 { /* all possible code length */
1150 for (i = 1; i <= (int) htbl[l-1]; i++) /* all codes per length */
1151 huffsize[p++] = (char) l;
1153 huffsize[p] = 0;
1155 /* Figure C.2: generate the codes themselves */
1156 /* Note that this is in code-length order. */
1158 code = 0;
1159 si = huffsize[0];
1160 p = 0;
1161 while (huffsize[p])
1163 while (((int) huffsize[p]) == si)
1165 huffcode[p++] = code;
1166 code++;
1168 code <<= 1;
1169 si++;
1172 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1174 p = 0;
1175 for (l = 1; l <= 16; l++)
1177 if (htbl[l-1])
1179 dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */
1180 dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */
1181 p += htbl[l-1];
1182 dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
1184 else
1186 dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
1189 dtbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */
1191 /* Compute lookahead tables to speed up decoding.
1192 * First we set all the table entries to 0, indicating "too long";
1193 * then we iterate through the Huffman codes that are short enough and
1194 * fill in all the entries that correspond to bit sequences starting
1195 * with that code.
1198 MEMSET(dtbl->look_nbits, 0, sizeof(dtbl->look_nbits));
1200 p = 0;
1201 for (l = 1; l <= HUFF_LOOKAHEAD; l++)
1203 for (i = 1; i <= (int) htbl[l-1]; i++, p++)
1205 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1206 /* Generate left-justified code followed by all possible bit sequences */
1207 lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
1208 for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--)
1210 dtbl->look_nbits[lookbits] = l;
1211 dtbl->look_sym[lookbits] = htbl[16+p];
1212 lookbits++;
1219 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1220 * If the incoming data is corrupted, decode_mcu could attempt to
1221 * reference values beyond the end of the array. To avoid a wild store,
1222 * we put some extra zeroes after the real entries.
1224 static const int zag[] =
1226 0, 1, 8, 16, 9, 2, 3, 10,
1227 17, 24, 32, 25, 18, 11, 4, 5,
1228 12, 19, 26, 33, 40, 48, 41, 34,
1229 27, 20, 13, 6, 7, 14, 21, 28,
1230 35, 42, 49, 56, 57, 50, 43, 36,
1231 29, 22, 15, 23, 30, 37, 44, 51,
1232 58, 59, 52, 45, 38, 31, 39, 46,
1233 53, 60, 61, 54, 47, 55, 62, 63,
1234 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1235 0, 0, 0, 0, 0, 0, 0, 0
1238 void build_lut(struct jpeg* p_jpeg)
1240 int i;
1241 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_dc,
1242 &p_jpeg->dc_derived_tbls[0]);
1243 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_ac,
1244 &p_jpeg->ac_derived_tbls[0]);
1245 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_dc,
1246 &p_jpeg->dc_derived_tbls[1]);
1247 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_ac,
1248 &p_jpeg->ac_derived_tbls[1]);
1250 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1251 for (i=0; i<64; i++)
1253 p_jpeg->qt_idct[0][zag[i]] = p_jpeg->quanttable[0][i];
1254 p_jpeg->qt_idct[1][zag[i]] = p_jpeg->quanttable[1][i];
1257 for (i=0; i<4; i++)
1258 p_jpeg->store_pos[i] = i; /* default ordering */
1260 /* assignments for the decoding of blocks */
1261 if (p_jpeg->frameheader[0].horizontal_sampling == 2
1262 && p_jpeg->frameheader[0].vertical_sampling == 1)
1263 { /* 4:2:2 */
1264 p_jpeg->blocks = 4;
1265 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1266 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1267 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1268 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1269 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1270 p_jpeg->mcu_membership[1] = 0;
1271 p_jpeg->mcu_membership[2] = 1;
1272 p_jpeg->mcu_membership[3] = 2;
1273 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1274 p_jpeg->tab_membership[1] = 0;
1275 p_jpeg->tab_membership[2] = 1;
1276 p_jpeg->tab_membership[3] = 1;
1277 p_jpeg->subsample_x[0] = 1;
1278 p_jpeg->subsample_x[1] = 2;
1279 p_jpeg->subsample_x[2] = 2;
1280 p_jpeg->subsample_y[0] = 1;
1281 p_jpeg->subsample_y[1] = 1;
1282 p_jpeg->subsample_y[2] = 1;
1284 if (p_jpeg->frameheader[0].horizontal_sampling == 1
1285 && p_jpeg->frameheader[0].vertical_sampling == 2)
1286 { /* 4:2:2 vertically subsampled */
1287 p_jpeg->store_pos[1] = 2; /* block positions are mirrored */
1288 p_jpeg->store_pos[2] = 1;
1289 p_jpeg->blocks = 4;
1290 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1291 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1292 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1293 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1294 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1295 p_jpeg->mcu_membership[1] = 0;
1296 p_jpeg->mcu_membership[2] = 1;
1297 p_jpeg->mcu_membership[3] = 2;
1298 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1299 p_jpeg->tab_membership[1] = 0;
1300 p_jpeg->tab_membership[2] = 1;
1301 p_jpeg->tab_membership[3] = 1;
1302 p_jpeg->subsample_x[0] = 1;
1303 p_jpeg->subsample_x[1] = 1;
1304 p_jpeg->subsample_x[2] = 1;
1305 p_jpeg->subsample_y[0] = 1;
1306 p_jpeg->subsample_y[1] = 2;
1307 p_jpeg->subsample_y[2] = 2;
1309 else if (p_jpeg->frameheader[0].horizontal_sampling == 2
1310 && p_jpeg->frameheader[0].vertical_sampling == 2)
1311 { /* 4:2:0 */
1312 p_jpeg->blocks = 6;
1313 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1314 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1315 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1316 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1317 p_jpeg->mcu_membership[0] = 0;
1318 p_jpeg->mcu_membership[1] = 0;
1319 p_jpeg->mcu_membership[2] = 0;
1320 p_jpeg->mcu_membership[3] = 0;
1321 p_jpeg->mcu_membership[4] = 1;
1322 p_jpeg->mcu_membership[5] = 2;
1323 p_jpeg->tab_membership[0] = 0;
1324 p_jpeg->tab_membership[1] = 0;
1325 p_jpeg->tab_membership[2] = 0;
1326 p_jpeg->tab_membership[3] = 0;
1327 p_jpeg->tab_membership[4] = 1;
1328 p_jpeg->tab_membership[5] = 1;
1329 p_jpeg->subsample_x[0] = 1;
1330 p_jpeg->subsample_x[1] = 2;
1331 p_jpeg->subsample_x[2] = 2;
1332 p_jpeg->subsample_y[0] = 1;
1333 p_jpeg->subsample_y[1] = 2;
1334 p_jpeg->subsample_y[2] = 2;
1336 else if (p_jpeg->frameheader[0].horizontal_sampling == 1
1337 && p_jpeg->frameheader[0].vertical_sampling == 1)
1338 { /* 4:4:4 */
1339 /* don't overwrite p_jpeg->blocks */
1340 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1341 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1342 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1343 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1344 p_jpeg->mcu_membership[0] = 0;
1345 p_jpeg->mcu_membership[1] = 1;
1346 p_jpeg->mcu_membership[2] = 2;
1347 p_jpeg->tab_membership[0] = 0;
1348 p_jpeg->tab_membership[1] = 1;
1349 p_jpeg->tab_membership[2] = 1;
1350 p_jpeg->subsample_x[0] = 1;
1351 p_jpeg->subsample_x[1] = 1;
1352 p_jpeg->subsample_x[2] = 1;
1353 p_jpeg->subsample_y[0] = 1;
1354 p_jpeg->subsample_y[1] = 1;
1355 p_jpeg->subsample_y[2] = 1;
1357 else
1359 /* error */
1366 * These functions/macros provide the in-line portion of bit fetching.
1367 * Use check_bit_buffer to ensure there are N bits in get_buffer
1368 * before using get_bits, peek_bits, or drop_bits.
1369 * check_bit_buffer(state,n,action);
1370 * Ensure there are N bits in get_buffer; if suspend, take action.
1371 * val = get_bits(n);
1372 * Fetch next N bits.
1373 * val = peek_bits(n);
1374 * Fetch next N bits without removing them from the buffer.
1375 * drop_bits(n);
1376 * Discard next N bits.
1377 * The value N should be a simple variable, not an expression, because it
1378 * is evaluated multiple times.
1381 INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
1383 if (pb->bits_left < nbits)
1384 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1385 unsigned char byte;
1387 byte = *pb->next_input_byte++;
1388 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1389 { /* simplification: just skip the (one-byte) marker code */
1390 pb->next_input_byte++;
1392 pb->get_buffer = (pb->get_buffer << 8) | byte;
1394 byte = *pb->next_input_byte++;
1395 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1396 { /* simplification: just skip the (one-byte) marker code */
1397 pb->next_input_byte++;
1399 pb->get_buffer = (pb->get_buffer << 8) | byte;
1401 pb->bits_left += 16;
1405 INLINE int get_bits(struct bitstream* pb, int nbits)
1407 return ((int) (pb->get_buffer >> (pb->bits_left -= nbits))) & ((1<<nbits)-1);
1410 INLINE int peek_bits(struct bitstream* pb, int nbits)
1412 return ((int) (pb->get_buffer >> (pb->bits_left - nbits))) & ((1<<nbits)-1);
1415 INLINE void drop_bits(struct bitstream* pb, int nbits)
1417 pb->bits_left -= nbits;
1420 /* re-synchronize to entropy data (skip restart marker) */
1421 void search_restart(struct bitstream* pb)
1423 pb->next_input_byte--; /* we may have overread it, taking 2 bytes */
1424 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1425 while (pb->next_input_byte < pb->input_end &&
1426 (pb->next_input_byte[-2] != 0xFF || pb->next_input_byte[-1] == 0x00))
1428 pb->next_input_byte++;
1430 pb->bits_left = 0;
1433 /* Figure F.12: extend sign bit. */
1434 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1436 static const int extend_test[16] = /* entry n is 2**(n-1) */
1438 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1439 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1442 static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
1444 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1445 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1446 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1447 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1450 /* Decode a single value */
1451 INLINE int huff_decode_dc(struct bitstream* bs, struct derived_tbl* tbl)
1453 int nb, look, s, r;
1455 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1456 look = peek_bits(bs, HUFF_LOOKAHEAD);
1457 if ((nb = tbl->look_nbits[look]) != 0)
1459 drop_bits(bs, nb);
1460 s = tbl->look_sym[look];
1461 check_bit_buffer(bs, s);
1462 r = get_bits(bs, s);
1463 s = HUFF_EXTEND(r, s);
1465 else
1466 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1467 long code;
1468 nb=HUFF_LOOKAHEAD+1;
1469 check_bit_buffer(bs, nb);
1470 code = get_bits(bs, nb);
1471 while (code > tbl->maxcode[nb])
1473 code <<= 1;
1474 check_bit_buffer(bs, 1);
1475 code |= get_bits(bs, 1);
1476 nb++;
1478 if (nb > 16) /* error in Huffman */
1480 s=0; /* fake a zero, this is most safe */
1482 else
1484 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1485 check_bit_buffer(bs, s);
1486 r = get_bits(bs, s);
1487 s = HUFF_EXTEND(r, s);
1489 } /* end slow decode */
1490 return s;
1493 INLINE int huff_decode_ac(struct bitstream* bs, struct derived_tbl* tbl)
1495 int nb, look, s;
1497 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1498 look = peek_bits(bs, HUFF_LOOKAHEAD);
1499 if ((nb = tbl->look_nbits[look]) != 0)
1501 drop_bits(bs, nb);
1502 s = tbl->look_sym[look];
1504 else
1505 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1506 long code;
1507 nb=HUFF_LOOKAHEAD+1;
1508 check_bit_buffer(bs, nb);
1509 code = get_bits(bs, nb);
1510 while (code > tbl->maxcode[nb])
1512 code <<= 1;
1513 check_bit_buffer(bs, 1);
1514 code |= get_bits(bs, 1);
1515 nb++;
1517 if (nb > 16) /* error in Huffman */
1519 s=0; /* fake a zero, this is most safe */
1521 else
1523 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1525 } /* end slow decode */
1526 return s;
1530 #ifdef HAVE_LCD_COLOR
1532 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1533 /* Note: it keeps the original color subsampling, even if resized. */
1534 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1535 int downscale, void (*pf_progress)(int current, int total))
1537 struct bitstream bs; /* bitstream "object" */
1538 int block[64]; /* decoded DCT coefficients */
1540 int width, height;
1541 int skip_line[3]; /* bytes from one line to the next (skip_line) */
1542 int skip_strip[3], skip_mcu[3]; /* bytes to next DCT row / column */
1544 int i, x, y; /* loop counter */
1546 unsigned char* p_line[3] = {p_pixel[0], p_pixel[1], p_pixel[2]};
1547 unsigned char* p_byte[3]; /* bitmap pointer */
1549 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1550 int k_need; /* AC coefficients needed up to here */
1551 int zero_need; /* init the block with this many zeros */
1553 int last_dc_val[3] = {0, 0, 0}; /* or 128 for chroma? */
1554 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1555 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1557 /* pick the IDCT we want, determine how to work with coefs */
1558 if (downscale == 1)
1560 pf_idct = idct8x8;
1561 k_need = 64; /* all */
1562 zero_need = 63; /* all */
1564 else if (downscale == 2)
1566 pf_idct = idct4x4;
1567 k_need = 25; /* this far in zig-zag to cover 4*4 */
1568 zero_need = 27; /* clear this far in linear order */
1570 else if (downscale == 4)
1572 pf_idct = idct2x2;
1573 k_need = 5; /* this far in zig-zag to cover 2*2 */
1574 zero_need = 9; /* clear this far in linear order */
1576 else if (downscale == 8)
1578 pf_idct = idct1x1;
1579 k_need = 0; /* no AC, not needed */
1580 zero_need = 0; /* no AC, not needed */
1582 else return -1; /* not supported */
1584 /* init bitstream, fake a restart to make it start */
1585 bs.next_input_byte = p_jpeg->p_entropy_data;
1586 bs.bits_left = 0;
1587 bs.input_end = p_jpeg->p_entropy_end;
1589 width = p_jpeg->x_phys / downscale;
1590 height = p_jpeg->y_phys / downscale;
1591 for (i=0; i<3; i++) /* calculate some strides */
1593 skip_line[i] = width / p_jpeg->subsample_x[i];
1594 skip_strip[i] = skip_line[i]
1595 * (height / p_jpeg->y_mbl) / p_jpeg->subsample_y[i];
1596 skip_mcu[i] = width/p_jpeg->x_mbl / p_jpeg->subsample_x[i];
1599 /* prepare offsets about where to store the different blocks */
1600 store_offs[p_jpeg->store_pos[0]] = 0;
1601 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1602 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1603 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1605 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1607 for (i=0; i<3; i++) /* scan line init */
1609 p_byte[i] = p_line[i];
1610 p_line[i] += skip_strip[i];
1612 for (x=0; x<p_jpeg->x_mbl; x++)
1614 int blkn;
1616 /* Outer loop handles each block in the MCU */
1617 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1618 { /* Decode a single block's worth of coefficients */
1619 int k = 1; /* coefficient index */
1620 int s, r; /* huffman values */
1621 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1622 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1623 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1624 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1626 /* Section F.2.2.1: decode the DC coefficient difference */
1627 s = huff_decode_dc(&bs, dctbl);
1629 last_dc_val[ci] += s;
1630 block[0] = last_dc_val[ci]; /* output it (assumes zag[0] = 0) */
1632 /* coefficient buffer must be cleared */
1633 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1635 /* Section F.2.2.2: decode the AC coefficients */
1636 for (; k < k_need; k++)
1638 s = huff_decode_ac(&bs, actbl);
1639 r = s >> 4;
1640 s &= 15;
1642 if (s)
1644 k += r;
1645 check_bit_buffer(&bs, s);
1646 r = get_bits(&bs, s);
1647 block[zag[k]] = HUFF_EXTEND(r, s);
1649 else
1651 if (r != 15)
1653 k = 64;
1654 break;
1656 k += r;
1658 } /* for k */
1659 /* In this path we just discard the values */
1660 for (; k < 64; k++)
1662 s = huff_decode_ac(&bs, actbl);
1663 r = s >> 4;
1664 s &= 15;
1666 if (s)
1668 k += r;
1669 check_bit_buffer(&bs, s);
1670 drop_bits(&bs, s);
1672 else
1674 if (r != 15)
1675 break;
1676 k += r;
1678 } /* for k */
1680 if (ci == 0)
1681 { /* Y component needs to bother about block store */
1682 pf_idct(p_byte[0]+store_offs[blkn], block,
1683 p_jpeg->qt_idct[ti], skip_line[0]);
1685 else
1686 { /* chroma */
1687 pf_idct(p_byte[ci], block, p_jpeg->qt_idct[ti],
1688 skip_line[ci]);
1690 } /* for blkn */
1691 p_byte[0] += skip_mcu[0]; /* unrolled for (i=0; i<3; i++) loop */
1692 p_byte[1] += skip_mcu[1];
1693 p_byte[2] += skip_mcu[2];
1694 if (p_jpeg->restart_interval && --restart == 0)
1695 { /* if a restart marker is due: */
1696 restart = p_jpeg->restart_interval; /* count again */
1697 search_restart(&bs); /* align the bitstream */
1698 last_dc_val[0] = last_dc_val[1] =
1699 last_dc_val[2] = 0; /* reset decoder */
1701 } /* for x */
1702 if (pf_progress != NULL)
1703 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1704 } /* for y */
1706 return 0; /* success */
1708 #else /* !HAVE_LCD_COLOR */
1710 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1711 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[1], int downscale,
1712 void (*pf_progress)(int current, int total))
1714 struct bitstream bs; /* bitstream "object" */
1715 int block[64]; /* decoded DCT coefficients */
1717 int width, height;
1718 int skip_line; /* bytes from one line to the next (skip_line) */
1719 int skip_strip, skip_mcu; /* bytes to next DCT row / column */
1721 int x, y; /* loop counter */
1723 unsigned char* p_line = p_pixel[0];
1724 unsigned char* p_byte; /* bitmap pointer */
1726 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1727 int k_need; /* AC coefficients needed up to here */
1728 int zero_need; /* init the block with this many zeros */
1730 int last_dc_val = 0;
1731 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1732 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1734 /* pick the IDCT we want, determine how to work with coefs */
1735 if (downscale == 1)
1737 pf_idct = idct8x8;
1738 k_need = 64; /* all */
1739 zero_need = 63; /* all */
1741 else if (downscale == 2)
1743 pf_idct = idct4x4;
1744 k_need = 25; /* this far in zig-zag to cover 4*4 */
1745 zero_need = 27; /* clear this far in linear order */
1747 else if (downscale == 4)
1749 pf_idct = idct2x2;
1750 k_need = 5; /* this far in zig-zag to cover 2*2 */
1751 zero_need = 9; /* clear this far in linear order */
1753 else if (downscale == 8)
1755 pf_idct = idct1x1;
1756 k_need = 0; /* no AC, not needed */
1757 zero_need = 0; /* no AC, not needed */
1759 else return -1; /* not supported */
1761 /* init bitstream, fake a restart to make it start */
1762 bs.next_input_byte = p_jpeg->p_entropy_data;
1763 bs.bits_left = 0;
1764 bs.input_end = p_jpeg->p_entropy_end;
1766 width = p_jpeg->x_phys / downscale;
1767 height = p_jpeg->y_phys / downscale;
1768 skip_line = width;
1769 skip_strip = skip_line * (height / p_jpeg->y_mbl);
1770 skip_mcu = (width/p_jpeg->x_mbl);
1772 /* prepare offsets about where to store the different blocks */
1773 store_offs[p_jpeg->store_pos[0]] = 0;
1774 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1775 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1776 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1778 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1780 p_byte = p_line;
1781 p_line += skip_strip;
1782 for (x=0; x<p_jpeg->x_mbl; x++)
1784 int blkn;
1786 /* Outer loop handles each block in the MCU */
1787 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1788 { /* Decode a single block's worth of coefficients */
1789 int k = 1; /* coefficient index */
1790 int s, r; /* huffman values */
1791 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1792 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1793 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1794 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1796 /* Section F.2.2.1: decode the DC coefficient difference */
1797 s = huff_decode_dc(&bs, dctbl);
1799 if (ci == 0) /* only for Y component */
1801 last_dc_val += s;
1802 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
1804 /* coefficient buffer must be cleared */
1805 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1807 /* Section F.2.2.2: decode the AC coefficients */
1808 for (; k < k_need; k++)
1810 s = huff_decode_ac(&bs, actbl);
1811 r = s >> 4;
1812 s &= 15;
1814 if (s)
1816 k += r;
1817 check_bit_buffer(&bs, s);
1818 r = get_bits(&bs, s);
1819 block[zag[k]] = HUFF_EXTEND(r, s);
1821 else
1823 if (r != 15)
1825 k = 64;
1826 break;
1828 k += r;
1830 } /* for k */
1832 /* In this path we just discard the values */
1833 for (; k < 64; k++)
1835 s = huff_decode_ac(&bs, actbl);
1836 r = s >> 4;
1837 s &= 15;
1839 if (s)
1841 k += r;
1842 check_bit_buffer(&bs, s);
1843 drop_bits(&bs, s);
1845 else
1847 if (r != 15)
1848 break;
1849 k += r;
1851 } /* for k */
1853 if (ci == 0)
1854 { /* only for Y component */
1855 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
1856 skip_line);
1858 } /* for blkn */
1859 p_byte += skip_mcu;
1860 if (p_jpeg->restart_interval && --restart == 0)
1861 { /* if a restart marker is due: */
1862 restart = p_jpeg->restart_interval; /* count again */
1863 search_restart(&bs); /* align the bitstream */
1864 last_dc_val = 0; /* reset decoder */
1866 } /* for x */
1867 if (pf_progress != NULL)
1868 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1869 } /* for y */
1871 return 0; /* success */
1873 #endif /* !HAVE_LCD_COLOR */
1875 /**************** end JPEG code ********************/
1879 /**************** begin Application ********************/
1882 /************************* Types ***************************/
1884 struct t_disp
1886 #ifdef HAVE_LCD_COLOR
1887 unsigned char* bitmap[3]; /* Y, Cr, Cb */
1888 int csub_x, csub_y;
1889 #else
1890 unsigned char* bitmap[1]; /* Y only */
1891 #endif
1892 int width;
1893 int height;
1894 int stride;
1895 int x, y;
1898 /************************* Globals ***************************/
1900 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1901 struct t_disp disp[9];
1903 /* my memory pool (from the mp3 buffer) */
1904 char print[32]; /* use a common snprintf() buffer */
1905 unsigned char* buf; /* up to here currently used by image(s) */
1907 /* the remaining free part of the buffer for compressed+uncompressed images */
1908 unsigned char* buf_images;
1910 ssize_t buf_size, buf_images_size;
1911 /* the root of the images, hereafter are decompresed ones */
1912 unsigned char* buf_root;
1913 int root_size;
1915 int ds, ds_min, ds_max; /* downscaling and limits */
1916 static struct jpeg jpg; /* too large for stack */
1918 static struct tree_context *tree;
1920 /* the current full file name */
1921 static char np_file[MAX_PATH];
1922 int curfile = 0, direction = DIR_NONE, entries = 0;
1924 /* list of the jpeg files */
1925 char **file_pt;
1926 /* are we using the plugin buffer or the audio buffer? */
1927 bool plug_buf = false;
1930 /************************* Implementation ***************************/
1932 #ifdef HAVE_LCD_COLOR
1934 * Conversion of full 0-255 range YCrCb to RGB:
1935 * |R| |1.000000 -0.000001 1.402000| |Y'|
1936 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
1937 * |B| |1.000000 1.772000 0.000000| |Pr|
1938 * Scaled (yields s15-bit output):
1939 * |R| |128 0 179| |Y |
1940 * |G| = |128 -43 -91| |Cb - 128|
1941 * |B| |128 227 0| |Cr - 128|
1943 #define YFAC 128
1944 #define RVFAC 179
1945 #define GUFAC (-43)
1946 #define GVFAC (-91)
1947 #define BUFAC 227
1948 #define YUV_WHITE (255*YFAC)
1949 #define NODITHER_DELTA (127*YFAC)
1950 #define COMPONENT_SHIFT 15
1951 #define MATRIX_SHIFT 7
1953 static inline int clamp_component(int x)
1955 if ((unsigned)x > YUV_WHITE)
1956 x = x < 0 ? 0 : YUV_WHITE;
1957 return x;
1960 static inline int clamp_component_bits(int x, int bits)
1962 if ((unsigned)x > (1u << bits) - 1)
1963 x = x < 0 ? 0 : (1 << bits) - 1;
1964 return x;
1967 static inline int component_to_lcd(int x, int bits, int delta)
1969 /* Formula used in core bitmap loader. */
1970 return (((1 << bits) - 1)*x + (x >> (8 - bits)) + delta) >> COMPONENT_SHIFT;
1973 static inline int lcd_to_component(int x, int bits, int delta)
1975 /* Reasonable, approximate reversal to get a full range back from the
1976 quantized value. */
1977 return YUV_WHITE*x / ((1 << bits) - 1);
1978 (void)delta;
1981 #define RED 0
1982 #define GRN 1
1983 #define BLU 2
1985 struct rgb_err
1987 int16_t errbuf[LCD_WIDTH+2]; /* Error record for line below */
1988 } rgb_err_buffers[3];
1990 fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
1991 DITHER_DIFFUSION is set */
1993 struct rgb_pixel
1995 int r, g, b; /* Current pixel components in s16.0 */
1996 int inc; /* Current line increment (-1 or 1) */
1997 int row; /* Current row in source image */
1998 int col; /* Current column in source image */
1999 int ce[3]; /* Errors to apply to current pixel */
2000 struct rgb_err *e; /* RED, GRN, BLU */
2001 int epos; /* Current position in error record */
2004 struct rgb_pixel *pixel;
2006 /** round and truncate to lcd depth **/
2007 static fb_data pixel_to_lcd_colour(void)
2009 struct rgb_pixel *p = pixel;
2010 int r, g, b;
2012 r = component_to_lcd(p->r, LCD_RED_BITS, NODITHER_DELTA);
2013 r = clamp_component_bits(r, LCD_RED_BITS);
2015 g = component_to_lcd(p->g, LCD_GREEN_BITS, NODITHER_DELTA);
2016 g = clamp_component_bits(g, LCD_GREEN_BITS);
2018 b = component_to_lcd(p->b, LCD_BLUE_BITS, NODITHER_DELTA);
2019 b = clamp_component_bits(b, LCD_BLUE_BITS);
2021 return LCD_RGBPACK_LCD(r, g, b);
2024 /** write a monochrome pixel to the colour LCD **/
2025 static fb_data pixel_to_lcd_gray(void)
2027 int r, g, b;
2029 g = clamp_component(pixel->g);
2030 r = component_to_lcd(g, LCD_RED_BITS, NODITHER_DELTA);
2031 b = component_to_lcd(g, LCD_BLUE_BITS, NODITHER_DELTA);
2032 g = component_to_lcd(g, LCD_GREEN_BITS, NODITHER_DELTA);
2034 return LCD_RGBPACK_LCD(r, g, b);
2038 * Bayer ordered dithering - swiped from the core bitmap loader.
2040 static fb_data pixel_odither_to_lcd(void)
2042 /* canonical ordered dither matrix */
2043 static const unsigned char dither_matrix[16][16] = {
2044 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
2045 { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
2046 { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
2047 { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
2048 { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
2049 { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
2050 { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
2051 { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
2052 { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
2053 { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
2054 { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
2055 { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
2056 { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
2057 { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
2058 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
2059 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
2062 struct rgb_pixel *p = pixel;
2063 int r, g, b, delta;
2065 delta = dither_matrix[p->col & 15][p->row & 15] << MATRIX_SHIFT;
2067 r = component_to_lcd(p->r, LCD_RED_BITS, delta);
2068 r = clamp_component_bits(r, LCD_RED_BITS);
2070 g = component_to_lcd(p->g, LCD_GREEN_BITS, delta);
2071 g = clamp_component_bits(g, LCD_GREEN_BITS);
2073 b = component_to_lcd(p->b, LCD_BLUE_BITS, delta);
2074 b = clamp_component_bits(b, LCD_BLUE_BITS);
2076 p->col += p->inc;
2078 return LCD_RGBPACK_LCD(r, g, b);
2082 * Floyd/Steinberg dither to lcd depth.
2084 * Apply filter to each component in serpentine pattern. Kernel shown for
2085 * L->R scan. Kernel is reversed for R->L.
2086 * * 7
2087 * 3 5 1 (1/16)
2089 static inline void distribute_error(int *ce, struct rgb_err *e,
2090 int err, int epos, int inc)
2092 *ce = (7*err >> 4) + e->errbuf[epos+inc];
2093 e->errbuf[epos+inc] = err >> 4;
2094 e->errbuf[epos] += 5*err >> 4;
2095 e->errbuf[epos-inc] += 3*err >> 4;
2098 static fb_data pixel_fsdither_to_lcd(void)
2100 struct rgb_pixel *p = pixel;
2101 int rc, gc, bc, r, g, b;
2102 int inc, epos;
2104 /* Full components with error terms */
2105 rc = p->r + p->ce[RED];
2106 r = component_to_lcd(rc, LCD_RED_BITS, 0);
2107 r = clamp_component_bits(r, LCD_RED_BITS);
2109 gc = p->g + p->ce[GRN];
2110 g = component_to_lcd(gc, LCD_GREEN_BITS, 0);
2111 g = clamp_component_bits(g, LCD_GREEN_BITS);
2113 bc = p->b + p->ce[BLU];
2114 b = component_to_lcd(bc, LCD_BLUE_BITS, 0);
2115 b = clamp_component_bits(b, LCD_BLUE_BITS);
2117 /* Get pixel errors */
2118 rc -= lcd_to_component(r, LCD_RED_BITS, 0);
2119 gc -= lcd_to_component(g, LCD_GREEN_BITS, 0);
2120 bc -= lcd_to_component(b, LCD_BLUE_BITS, 0);
2122 /* Spead error to surrounding pixels. */
2123 inc = p->inc;
2124 epos = p->epos;
2125 p->epos += inc;
2127 distribute_error(&p->ce[RED], &p->e[RED], rc, epos, inc);
2128 distribute_error(&p->ce[GRN], &p->e[GRN], gc, epos, inc);
2129 distribute_error(&p->ce[BLU], &p->e[BLU], bc, epos, inc);
2131 /* Pack and return pixel */
2132 return LCD_RGBPACK_LCD(r, g, b);
2135 /* Functions for each output mode, colour then grayscale. */
2136 static fb_data (* const pixel_funcs[COLOUR_NUM_MODES][DITHER_NUM_MODES])(void) =
2138 [COLOURMODE_COLOUR] =
2140 [DITHER_NONE] = pixel_to_lcd_colour,
2141 [DITHER_ORDERED] = pixel_odither_to_lcd,
2142 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2144 [COLOURMODE_GRAY] =
2146 [DITHER_NONE] = pixel_to_lcd_gray,
2147 [DITHER_ORDERED] = pixel_odither_to_lcd,
2148 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2153 * Draw a partial YUV colour bitmap
2155 * Runs serpentine pattern when dithering is DITHER_DIFFUSION, else scan is
2156 * always L->R.
2158 void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
2159 int src_x, int src_y, int stride,
2160 int x, int y, int width, int height)
2162 fb_data *dst, *dst_end;
2163 fb_data (*pixel_func)(void);
2164 struct rgb_pixel px;
2166 if (x + width > LCD_WIDTH)
2167 width = LCD_WIDTH - x; /* Clip right */
2168 if (x < 0)
2169 width += x, x = 0; /* Clip left */
2170 if (width <= 0)
2171 return; /* nothing left to do */
2173 if (y + height > LCD_HEIGHT)
2174 height = LCD_HEIGHT - y; /* Clip bottom */
2175 if (y < 0)
2176 height += y, y = 0; /* Clip top */
2177 if (height <= 0)
2178 return; /* nothing left to do */
2180 pixel = &px;
2182 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
2183 dst_end = dst + LCD_WIDTH * height;
2185 if (jpeg_settings.colour_mode == COLOURMODE_GRAY)
2186 csub_y = 0; /* Ignore Cb, Cr */
2188 pixel_func = pixel_funcs[jpeg_settings.colour_mode]
2189 [jpeg_settings.dither_mode];
2191 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2193 /* Reset error terms. */
2194 px.e = rgb_err_buffers;
2195 px.ce[RED] = px.ce[GRN] = px.ce[BLU] = 0;
2196 rb->memset(px.e, 0, 3*sizeof (struct rgb_err));
2201 fb_data *dst_row, *row_end;
2202 const unsigned char *ysrc;
2203 px.inc = 1;
2205 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2207 /* Use R->L scan on odd lines */
2208 px.inc -= (src_y & 1) << 1;
2209 px.epos = x + 1;
2211 if (px.inc < 0)
2212 px.epos += width - 1;
2215 if (px.inc == 1)
2217 /* Scan is L->R */
2218 dst_row = dst;
2219 row_end = dst_row + width;
2220 px.col = src_x;
2222 else
2224 /* Scan is R->L */
2225 row_end = dst - 1;
2226 dst_row = row_end + width;
2227 px.col = src_x + width - 1;
2230 ysrc = src[0] + stride * src_y + px.col;
2231 px.row = src_y;
2233 /* Do one row of pixels */
2234 if (csub_y) /* colour */
2236 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
2237 const unsigned char *usrc, *vsrc;
2239 usrc = src[1] + (stride/csub_x) * (src_y/csub_y)
2240 + (px.col/csub_x);
2241 vsrc = src[2] + (stride/csub_x) * (src_y/csub_y)
2242 + (px.col/csub_x);
2243 int xphase = px.col % csub_x;
2244 int xphase_reset = px.inc * csub_x;
2245 int y, v, u, rv, guv, bu;
2247 v = *vsrc - 128;
2248 vsrc += px.inc;
2249 u = *usrc - 128;
2250 usrc += px.inc;
2251 rv = RVFAC*v;
2252 guv = GUFAC*u + GVFAC*v;
2253 bu = BUFAC*u;
2255 while (1)
2257 y = YFAC*(*ysrc);
2258 ysrc += px.inc;
2259 px.r = y + rv;
2260 px.g = y + guv;
2261 px.b = y + bu;
2263 *dst_row = pixel_func();
2264 dst_row += px.inc;
2266 if (dst_row == row_end)
2267 break;
2269 xphase += px.inc;
2270 if ((unsigned)xphase < (unsigned)csub_x)
2271 continue;
2273 /* fetch new chromas */
2274 v = *vsrc - 128;
2275 vsrc += px.inc;
2276 u = *usrc - 128;
2277 usrc += px.inc;
2278 rv = RVFAC*v;
2279 guv = GUFAC*u + GVFAC*v;
2280 bu = BUFAC*u;
2282 xphase -= xphase_reset;
2285 else /* monochrome */
2289 /* Set all components the same for dithering purposes */
2290 px.g = px.r = px.b = YFAC*(*ysrc);
2291 *dst_row = pixel_func();
2292 ysrc += px.inc;
2293 dst_row += px.inc;
2295 while (dst_row != row_end);
2298 src_y++;
2299 dst += LCD_WIDTH;
2301 while (dst < dst_end);
2304 #endif /* HAVE_LCD_COLOR */
2307 /* support function for qsort() */
2308 static int compare(const void* p1, const void* p2)
2310 return rb->strcasecmp(*((char **)p1), *((char **)p2));
2313 bool jpg_ext(const char ext[])
2315 if(!ext)
2316 return false;
2317 if(!rb->strcasecmp(ext,".jpg") ||
2318 !rb->strcasecmp(ext,".jpe") ||
2319 !rb->strcasecmp(ext,".jpeg"))
2320 return true;
2321 else
2322 return false;
2325 /*Read directory contents for scrolling. */
2326 void get_pic_list(void)
2328 int i;
2329 long int str_len = 0;
2330 char *pname;
2331 tree = rb->tree_get_context();
2333 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2334 file_pt = rb->plugin_get_buffer((size_t *)&buf_size);
2335 #else
2336 file_pt = rb->plugin_get_audio_buffer((size_t *)&buf_size);
2337 #endif
2339 for(i = 0; i < tree->filesindir; i++)
2341 if(jpg_ext(rb->strrchr(&tree->name_buffer[str_len],'.')))
2342 file_pt[entries++] = &tree->name_buffer[str_len];
2344 str_len += rb->strlen(&tree->name_buffer[str_len]) + 1;
2347 rb->qsort(file_pt, entries, sizeof(char**), compare);
2349 /* Remove path and leave only the name.*/
2350 pname = rb->strrchr(np_file,'/');
2351 pname++;
2353 /* Find Selected File. */
2354 for(i = 0; i < entries; i++)
2355 if(!rb->strcmp(file_pt[i], pname))
2356 curfile = i;
2359 int change_filename(int direct)
2361 int count = 0;
2362 direction = direct;
2364 if(direct == DIR_PREV)
2368 count++;
2369 if(curfile == 0)
2370 curfile = entries - 1;
2371 else
2372 curfile--;
2373 }while(file_pt[curfile] == '\0' && count < entries);
2374 /* we "erase" the file name if we encounter
2375 * a non-supported file, so skip it now */
2377 else /* DIR_NEXT/DIR_NONE */
2381 count++;
2382 if(curfile == entries - 1)
2383 curfile = 0;
2384 else
2385 curfile++;
2386 }while(file_pt[curfile] == '\0' && count < entries);
2389 if(count == entries && file_pt[curfile] == '\0')
2391 rb->splash(HZ, "No supported files");
2392 return PLUGIN_ERROR;
2394 if(rb->strlen(tree->currdir) > 1)
2396 rb->strcpy(np_file, tree->currdir);
2397 rb->strcat(np_file, "/");
2399 else
2400 rb->strcpy(np_file, tree->currdir);
2402 rb->strcat(np_file, file_pt[curfile]);
2404 return PLUGIN_OTHER;
2407 /* switch off overlay, for handling SYS_ events */
2408 void cleanup(void *parameter)
2410 (void)parameter;
2411 #ifdef USEGSLIB
2412 gray_show(false);
2413 #endif
2416 #define VSCROLL (LCD_HEIGHT/8)
2417 #define HSCROLL (LCD_WIDTH/10)
2419 #define ZOOM_IN 100 /* return codes for below function */
2420 #define ZOOM_OUT 101
2422 #ifdef HAVE_LCD_COLOR
2423 bool set_option_grayscale(void)
2425 bool gray = jpeg_settings.colour_mode == COLOURMODE_GRAY;
2426 rb->set_bool("Grayscale", &gray);
2427 jpeg_settings.colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
2428 return false;
2431 bool set_option_dithering(void)
2433 static const struct opt_items dithering[DITHER_NUM_MODES] = {
2434 [DITHER_NONE] = { "Off", -1 },
2435 [DITHER_ORDERED] = { "Ordered", -1 },
2436 [DITHER_DIFFUSION] = { "Diffusion", -1 },
2439 rb->set_option("Dithering", &jpeg_settings.dither_mode, INT,
2440 dithering, DITHER_NUM_MODES, NULL);
2441 return false;
2444 static void display_options(void)
2446 static const struct menu_item items[] = {
2447 { "Grayscale", set_option_grayscale },
2448 { "Dithering", set_option_dithering },
2451 int m = menu_init(rb, items, ARRAYLEN(items),
2452 NULL, NULL, NULL, NULL);
2453 menu_run(m);
2454 menu_exit(m);
2456 #endif /* HAVE_LCD_COLOR */
2458 int show_menu(void) /* return 1 to quit */
2460 #if LCD_DEPTH > 1
2461 rb->lcd_set_backdrop(old_backdrop);
2462 #ifdef HAVE_LCD_COLOR
2463 rb->lcd_set_foreground(rb->global_settings->fg_color);
2464 rb->lcd_set_background(rb->global_settings->bg_color);
2465 #else
2466 rb->lcd_set_foreground(LCD_BLACK);
2467 rb->lcd_set_background(LCD_WHITE);
2468 #endif
2469 #endif
2470 int m;
2471 int result;
2473 enum menu_id
2475 MIID_QUIT = 0,
2476 MIID_TOGGLE_SS_MODE,
2477 MIID_CHANGE_SS_MODE,
2478 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2479 MIID_SHOW_PLAYBACK_MENU,
2480 #endif
2481 #ifdef HAVE_LCD_COLOR
2482 MIID_DISPLAY_OPTIONS,
2483 #endif
2484 MIID_RETURN,
2487 static const struct menu_item items[] = {
2488 [MIID_QUIT] =
2489 { "Quit", NULL },
2490 [MIID_TOGGLE_SS_MODE] =
2491 { "Toggle Slideshow Mode", NULL },
2492 [MIID_CHANGE_SS_MODE] =
2493 { "Change Slideshow Time", NULL },
2494 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2495 [MIID_SHOW_PLAYBACK_MENU] =
2496 { "Show Playback Menu", NULL },
2497 #endif
2498 #ifdef HAVE_LCD_COLOR
2499 [MIID_DISPLAY_OPTIONS] =
2500 { "Display Options", NULL },
2501 #endif
2502 [MIID_RETURN] =
2503 { "Return", NULL },
2506 static const struct opt_items slideshow[2] = {
2507 { "Disable", -1 },
2508 { "Enable", -1 },
2511 static const struct opt_items timeout[12] = {
2512 { "1 second", -1 },
2513 { "2 seconds", -1 },
2514 { "3 seconds", -1 },
2515 { "4 seconds", -1 },
2516 { "5 seconds", -1 },
2517 { "6 seconds", -1 },
2518 { "7 seconds", -1 },
2519 { "8 seconds", -1 },
2520 { "9 seconds", -1 },
2521 { "10 seconds", -1 },
2522 { "15 seconds", -1 },
2523 { "20 seconds", -1 },
2526 m = menu_init(rb, items, sizeof(items) / sizeof(*items),
2527 NULL, NULL, NULL, NULL);
2528 result=menu_show(m);
2530 switch (result)
2532 case MIID_QUIT:
2533 menu_exit(m);
2534 return 1;
2535 break;
2536 case MIID_TOGGLE_SS_MODE:
2537 rb->set_option("Toggle Slideshow", &slideshow_enabled, INT,
2538 slideshow , 2, NULL);
2539 break;
2540 case MIID_CHANGE_SS_MODE:
2541 switch (button_timeout/HZ)
2543 case 10: result = 9; break;
2544 case 15: result = 10; break;
2545 case 20: result = 11; break;
2546 default: result = (button_timeout/HZ)-1; break;
2548 rb->set_option("Slideshow Time", &result, INT,
2549 timeout , 12, NULL);
2550 switch (result)
2552 case 9: button_timeout = 10*HZ; break;
2553 case 10: button_timeout = 15*HZ; break;
2554 case 11: button_timeout = 20*HZ; break;
2555 default: button_timeout = (result+1)*HZ; break;
2557 break;
2558 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2559 case MIID_SHOW_PLAYBACK_MENU:
2560 playback_control(rb);
2561 break;
2562 #endif
2563 #ifdef HAVE_LCD_COLOR
2564 case MIID_DISPLAY_OPTIONS:
2565 display_options();
2566 break;
2567 #endif
2568 case MIID_RETURN:
2569 break;
2572 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
2573 /* change ata spindown time based on slideshow time setting */
2574 immediate_ata_off = false;
2575 rb->ata_spindown(rb->global_settings->disk_spindown);
2577 if (slideshow_enabled)
2579 if(button_timeout/HZ < 10)
2581 /* slideshow times < 10s keep disk spinning */
2582 rb->ata_spindown(0);
2584 else if (!rb->mp3_is_playing())
2586 /* slideshow times > 10s and not playing: ata_off after load */
2587 immediate_ata_off = true;
2590 #endif
2591 #if LCD_DEPTH > 1
2592 rb->lcd_set_backdrop(NULL);
2593 rb->lcd_set_foreground(LCD_WHITE);
2594 rb->lcd_set_background(LCD_BLACK);
2595 #endif
2596 rb->lcd_clear_display();
2597 menu_exit(m);
2598 return 0;
2600 /* interactively scroll around the image */
2601 int scroll_bmp(struct t_disp* pdisp)
2603 int lastbutton = 0;
2605 while (true)
2607 int button;
2608 int move;
2610 if (slideshow_enabled)
2611 button = rb->button_get_w_tmo(button_timeout);
2612 else button = rb->button_get(true);
2614 running_slideshow = false;
2616 switch(button)
2618 case JPEG_LEFT:
2619 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2620 return change_filename(DIR_PREV);
2621 case JPEG_LEFT | BUTTON_REPEAT:
2622 move = MIN(HSCROLL, pdisp->x);
2623 if (move > 0)
2625 MYXLCD(scroll_right)(move); /* scroll right */
2626 pdisp->x -= move;
2627 #ifdef HAVE_LCD_COLOR
2628 yuv_bitmap_part(
2629 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2630 pdisp->x, pdisp->y, pdisp->stride,
2631 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2632 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2633 #else
2634 MYXLCD(gray_bitmap_part)(
2635 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2636 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2637 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2638 #endif
2639 MYLCD_UPDATE();
2641 break;
2643 case JPEG_RIGHT:
2644 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2645 return change_filename(DIR_NEXT);
2646 case JPEG_RIGHT | BUTTON_REPEAT:
2647 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
2648 if (move > 0)
2650 MYXLCD(scroll_left)(move); /* scroll left */
2651 pdisp->x += move;
2652 #ifdef HAVE_LCD_COLOR
2653 yuv_bitmap_part(
2654 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2655 pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride,
2656 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2657 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2658 #else
2659 MYXLCD(gray_bitmap_part)(
2660 pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move,
2661 pdisp->y, pdisp->stride,
2662 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2663 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2664 #endif
2665 MYLCD_UPDATE();
2667 break;
2669 case JPEG_UP:
2670 case JPEG_UP | BUTTON_REPEAT:
2671 move = MIN(VSCROLL, pdisp->y);
2672 if (move > 0)
2674 MYXLCD(scroll_down)(move); /* scroll down */
2675 pdisp->y -= move;
2676 #ifdef HAVE_LCD_COLOR
2677 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2679 /* Draw over the band at the top of the last update
2680 caused by lack of error history on line zero. */
2681 move = MIN(move + 1, pdisp->y + pdisp->height);
2684 yuv_bitmap_part(
2685 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2686 pdisp->x, pdisp->y, pdisp->stride,
2687 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2688 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2689 #else
2690 MYXLCD(gray_bitmap_part)(
2691 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2692 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2693 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2694 #endif
2695 MYLCD_UPDATE();
2697 break;
2699 case JPEG_DOWN:
2700 case JPEG_DOWN | BUTTON_REPEAT:
2701 move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT);
2702 if (move > 0)
2704 MYXLCD(scroll_up)(move); /* scroll up */
2705 pdisp->y += move;
2706 #ifdef HAVE_LCD_COLOR
2707 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2709 /* Save the line that was on the last line of the display
2710 and draw one extra line above then recover the line with
2711 image data that had an error history when it was drawn.
2713 move++, pdisp->y--;
2714 MEMCPY(rgb_linebuf,
2715 rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2716 LCD_WIDTH*sizeof (fb_data));
2719 yuv_bitmap_part(
2720 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x,
2721 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2722 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2723 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2725 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2727 /* Cover the first row drawn with previous image data. */
2728 MEMCPY(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2729 rgb_linebuf,
2730 LCD_WIDTH*sizeof (fb_data));
2731 pdisp->y++;
2733 #else
2734 MYXLCD(gray_bitmap_part)(
2735 pdisp->bitmap[0], pdisp->x,
2736 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2737 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2738 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2739 #endif
2740 MYLCD_UPDATE();
2742 break;
2743 case BUTTON_NONE:
2744 if (!slideshow_enabled)
2745 break;
2746 running_slideshow = true;
2747 if (entries > 0)
2748 return change_filename(DIR_NEXT);
2749 break;
2751 #ifdef JPEG_SLIDE_SHOW
2752 case JPEG_SLIDE_SHOW:
2753 slideshow_enabled = !slideshow_enabled;
2754 running_slideshow = slideshow_enabled;
2755 break;
2756 #endif
2758 #ifdef JPEG_NEXT_REPEAT
2759 case JPEG_NEXT_REPEAT:
2760 #endif
2761 case JPEG_NEXT:
2762 if (entries > 0)
2763 return change_filename(DIR_NEXT);
2764 break;
2766 #ifdef JPEG_PREVIOUS_REPEAT
2767 case JPEG_PREVIOUS_REPEAT:
2768 #endif
2769 case JPEG_PREVIOUS:
2770 if (entries > 0)
2771 return change_filename(DIR_PREV);
2772 break;
2774 case JPEG_ZOOM_IN:
2775 #ifdef JPEG_ZOOM_PRE
2776 if (lastbutton != JPEG_ZOOM_PRE)
2777 break;
2778 #endif
2779 return ZOOM_IN;
2780 break;
2782 case JPEG_ZOOM_OUT:
2783 #ifdef JPEG_ZOOM_PRE
2784 if (lastbutton != JPEG_ZOOM_PRE)
2785 break;
2786 #endif
2787 return ZOOM_OUT;
2788 break;
2789 #ifdef JPEG_RC_MENU
2790 case JPEG_RC_MENU:
2791 #endif
2792 case JPEG_MENU:
2793 #ifdef USEGSLIB
2794 gray_show(false); /* switch off grayscale overlay */
2795 #endif
2796 if (show_menu() == 1)
2797 return PLUGIN_OK;
2799 #ifdef USEGSLIB
2800 gray_show(true); /* switch on grayscale overlay */
2801 #else
2802 yuv_bitmap_part(
2803 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2804 pdisp->x, pdisp->y, pdisp->stride,
2805 MAX(0, (LCD_WIDTH - pdisp->width) / 2),
2806 MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
2807 MIN(LCD_WIDTH, pdisp->width),
2808 MIN(LCD_HEIGHT, pdisp->height));
2809 MYLCD_UPDATE();
2810 #endif
2811 break;
2812 default:
2813 if (rb->default_event_handler_ex(button, cleanup, NULL)
2814 == SYS_USB_CONNECTED)
2815 return PLUGIN_USB_CONNECTED;
2816 break;
2818 } /* switch */
2820 if (button != BUTTON_NONE)
2821 lastbutton = button;
2822 } /* while (true) */
2825 /********************* main function *************************/
2827 /* callback updating a progress meter while JPEG decoding */
2828 void cb_progess(int current, int total)
2830 rb->yield(); /* be nice to the other threads */
2831 if(!running_slideshow)
2833 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-8, LCD_WIDTH, 8, total, 0,
2834 current, HORIZONTAL);
2835 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
2837 #ifndef USEGSLIB
2838 else
2840 /* in slideshow mode, keep gui interference to a minimum */
2841 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-4, LCD_WIDTH, 4, total, 0,
2842 current, HORIZONTAL);
2843 rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4);
2845 #endif
2848 int jpegmem(struct jpeg *p_jpg, int ds)
2850 int size;
2852 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
2853 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
2854 #ifdef HAVE_LCD_COLOR
2855 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
2857 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
2858 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
2859 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
2860 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
2862 #endif
2863 return size;
2866 /* how far can we zoom in without running out of memory */
2867 int min_downscale(struct jpeg *p_jpg, int bufsize)
2869 int downscale = 8;
2871 if (jpegmem(p_jpg, 8) > bufsize)
2872 return 0; /* error, too large, even 1:8 doesn't fit */
2874 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
2875 downscale /= 2;
2877 return downscale;
2881 /* how far can we zoom out, to fit image into the LCD */
2882 int max_downscale(struct jpeg *p_jpg)
2884 int downscale = 1;
2886 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale
2887 || p_jpg->y_size > LCD_HEIGHT*downscale))
2889 downscale *= 2;
2892 return downscale;
2896 /* return decoded or cached image */
2897 struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2899 int w, h; /* used to center output */
2900 int size; /* decompressed image size */
2901 long time; /* measured ticks */
2902 int status;
2904 struct t_disp* p_disp = &disp[ds]; /* short cut */
2906 if (p_disp->bitmap[0] != NULL)
2908 return p_disp; /* we still have it */
2911 /* assign image buffer */
2913 /* physical size needed for decoding */
2914 size = jpegmem(p_jpg, ds);
2915 if (buf_size <= size)
2916 { /* have to discard the current */
2917 int i;
2918 for (i=1; i<=8; i++)
2919 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
2920 buf = buf_root; /* start again from the beginning of the buffer */
2921 buf_size = root_size;
2924 #ifdef HAVE_LCD_COLOR
2925 if (p_jpg->blocks > 1) /* colour jpeg */
2927 int i;
2929 for (i = 1; i < 3; i++)
2931 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
2932 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
2933 p_disp->bitmap[i] = buf;
2934 buf += size;
2935 buf_size -= size;
2937 p_disp->csub_x = p_jpg->subsample_x[1];
2938 p_disp->csub_y = p_jpg->subsample_y[1];
2940 else
2942 p_disp->csub_x = p_disp->csub_y = 0;
2943 p_disp->bitmap[1] = p_disp->bitmap[2] = buf;
2945 #endif
2946 /* size may be less when decoded (if height is not block aligned) */
2947 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
2948 p_disp->bitmap[0] = buf;
2949 buf += size;
2950 buf_size -= size;
2952 if(!running_slideshow)
2954 rb->snprintf(print, sizeof(print), "decoding %d*%d",
2955 p_jpg->x_size/ds, p_jpg->y_size/ds);
2956 rb->lcd_puts(0, 3, print);
2957 rb->lcd_update();
2960 /* update image properties */
2961 p_disp->width = p_jpg->x_size / ds;
2962 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
2963 p_disp->height = p_jpg->y_size / ds;
2965 /* the actual decoding */
2966 time = *rb->current_tick;
2967 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2968 rb->cpu_boost(true);
2969 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2970 rb->cpu_boost(false);
2971 #else
2972 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2973 #endif
2974 if (status)
2976 rb->splash(HZ, "decode error %d", status);
2977 file_pt[curfile] = '\0';
2978 return NULL;
2980 time = *rb->current_tick - time;
2982 if(!running_slideshow)
2984 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
2985 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
2986 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
2987 rb->lcd_update();
2990 return p_disp;
2994 /* set the view to the given center point, limit if necessary */
2995 void set_view (struct t_disp* p_disp, int cx, int cy)
2997 int x, y;
2999 /* plain center to available width/height */
3000 x = cx - MIN(LCD_WIDTH, p_disp->width) / 2;
3001 y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2;
3003 /* limit against upper image size */
3004 x = MIN(p_disp->width - LCD_WIDTH, x);
3005 y = MIN(p_disp->height - LCD_HEIGHT, y);
3007 /* limit against negative side */
3008 x = MAX(0, x);
3009 y = MAX(0, y);
3011 p_disp->x = x; /* set the values */
3012 p_disp->y = y;
3016 /* calculate the view center based on the bitmap position */
3017 void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
3019 *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2;
3020 *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2;
3024 /* load, decode, display the image */
3025 int load_and_show(char* filename)
3027 int fd;
3028 int filesize;
3029 unsigned char* buf_jpeg; /* compressed JPEG image */
3030 int status;
3031 struct t_disp* p_disp; /* currenly displayed image */
3032 int cx, cy; /* view center */
3034 fd = rb->open(filename, O_RDONLY);
3035 if (fd < 0)
3037 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
3038 rb->splash(HZ, print);
3039 return PLUGIN_ERROR;
3041 filesize = rb->filesize(fd);
3042 rb->memset(&disp, 0, sizeof(disp));
3044 buf = buf_images + filesize;
3045 buf_size = buf_images_size - filesize;
3046 /* allocate JPEG buffer */
3047 buf_jpeg = buf_images;
3049 buf_root = buf; /* we can start the decompressed images behind it */
3050 root_size = buf_size;
3052 if (buf_size <= 0)
3054 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
3055 if(plug_buf)
3057 rb->close(fd);
3058 rb->lcd_setfont(FONT_SYSFIXED);
3059 rb->lcd_clear_display();
3060 rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
3061 rb->lcd_puts(0,0,print);
3062 rb->lcd_puts(0,1,"Not enough plugin memory!");
3063 rb->lcd_puts(0,2,"Zoom In: Stop playback.");
3064 if(entries>1)
3065 rb->lcd_puts(0,3,"Left/Right: Skip File.");
3066 rb->lcd_puts(0,4,"Off: Quit.");
3067 rb->lcd_update();
3068 rb->lcd_setfont(FONT_UI);
3070 rb->button_clear_queue();
3072 while (1)
3074 int button = rb->button_get(true);
3075 switch(button)
3077 case JPEG_ZOOM_IN:
3078 plug_buf = false;
3079 buf_images = rb->plugin_get_audio_buffer(
3080 (size_t *)&buf_images_size);
3081 /*try again this file, now using the audio buffer */
3082 return PLUGIN_OTHER;
3083 #ifdef JPEG_RC_MENU
3084 case JPEG_RC_MENU:
3085 #endif
3086 case JPEG_MENU:
3087 return PLUGIN_OK;
3089 case JPEG_LEFT:
3090 if(entries>1)
3092 rb->lcd_clear_display();
3093 return change_filename(DIR_PREV);
3095 break;
3097 case JPEG_RIGHT:
3098 if(entries>1)
3100 rb->lcd_clear_display();
3101 return change_filename(DIR_NEXT);
3103 break;
3104 default:
3105 if(rb->default_event_handler_ex(button, cleanup, NULL)
3106 == SYS_USB_CONNECTED)
3107 return PLUGIN_USB_CONNECTED;
3112 else
3113 #endif
3115 rb->splash(HZ, "Out of Memory");
3116 rb->close(fd);
3117 return PLUGIN_ERROR;
3121 if(!running_slideshow)
3123 #if LCD_DEPTH > 1
3124 rb->lcd_set_foreground(LCD_WHITE);
3125 rb->lcd_set_background(LCD_BLACK);
3126 rb->lcd_set_backdrop(NULL);
3127 #endif
3129 rb->lcd_clear_display();
3130 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
3131 rb->lcd_puts(0, 0, print);
3132 rb->lcd_update();
3134 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
3135 rb->lcd_puts(0, 1, print);
3136 rb->lcd_update();
3139 rb->read(fd, buf_jpeg, filesize);
3140 rb->close(fd);
3142 if(!running_slideshow)
3144 rb->snprintf(print, sizeof(print), "decoding markers");
3145 rb->lcd_puts(0, 2, print);
3146 rb->lcd_update();
3148 #ifndef SIMULATOR
3149 else if(immediate_ata_off)
3151 /* running slideshow and time is long enough: power down disk */
3152 rb->ata_sleep();
3154 #endif
3156 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
3157 /* process markers, unstuffing */
3158 status = process_markers(buf_jpeg, filesize, &jpg);
3160 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
3161 { /* bad format or minimum components not contained */
3162 rb->splash(HZ, "unsupported %d", status);
3163 file_pt[curfile] = '\0';
3164 return change_filename(direction);
3167 if (!(status & DHT)) /* if no Huffman table present: */
3168 default_huff_tbl(&jpg); /* use default */
3169 build_lut(&jpg); /* derive Huffman and other lookup-tables */
3171 if(!running_slideshow)
3173 rb->snprintf(print, sizeof(print), "image %dx%d", jpg.x_size, jpg.y_size);
3174 rb->lcd_puts(0, 2, print);
3175 rb->lcd_update();
3177 ds_max = max_downscale(&jpg); /* check display constraint */
3178 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */
3179 if (ds_min == 0)
3181 rb->splash(HZ, "too large");
3182 file_pt[curfile] = '\0';
3183 return change_filename(direction);
3186 ds = ds_max; /* initials setting */
3187 cx = jpg.x_size/ds/2; /* center the view */
3188 cy = jpg.y_size/ds/2;
3190 do /* loop the image prepare and decoding when zoomed */
3192 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */
3193 if (p_disp == NULL)
3194 return change_filename(direction);
3196 set_view(p_disp, cx, cy);
3198 if(!running_slideshow)
3200 rb->snprintf(print, sizeof(print), "showing %dx%d",
3201 p_disp->width, p_disp->height);
3202 rb->lcd_puts(0, 3, print);
3203 rb->lcd_update();
3205 MYLCD(clear_display)();
3206 #ifdef HAVE_LCD_COLOR
3207 yuv_bitmap_part(
3208 p_disp->bitmap, p_disp->csub_x, p_disp->csub_y,
3209 p_disp->x, p_disp->y, p_disp->stride,
3210 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3211 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3212 MIN(LCD_WIDTH, p_disp->width),
3213 MIN(LCD_HEIGHT, p_disp->height));
3214 #else
3215 MYXLCD(gray_bitmap_part)(
3216 p_disp->bitmap[0], p_disp->x, p_disp->y, p_disp->stride,
3217 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3218 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3219 MIN(LCD_WIDTH, p_disp->width),
3220 MIN(LCD_HEIGHT, p_disp->height));
3221 #endif
3222 MYLCD_UPDATE();
3224 #ifdef USEGSLIB
3225 gray_show(true); /* switch on grayscale overlay */
3226 #endif
3228 /* drawing is now finished, play around with scrolling
3229 * until you press OFF or connect USB
3231 while (1)
3233 status = scroll_bmp(p_disp);
3234 if (status == ZOOM_IN)
3236 if (ds > ds_min)
3238 ds /= 2; /* reduce downscaling to zoom in */
3239 get_view(p_disp, &cx, &cy);
3240 cx *= 2; /* prepare the position in the new image */
3241 cy *= 2;
3243 else
3244 continue;
3247 if (status == ZOOM_OUT)
3249 if (ds < ds_max)
3251 ds *= 2; /* increase downscaling to zoom out */
3252 get_view(p_disp, &cx, &cy);
3253 cx /= 2; /* prepare the position in the new image */
3254 cy /= 2;
3256 else
3257 continue;
3259 break;
3262 #ifdef USEGSLIB
3263 gray_show(false); /* switch off overlay */
3264 #endif
3265 rb->lcd_clear_display();
3267 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
3268 && status != PLUGIN_OTHER);
3269 #ifdef USEGSLIB
3270 rb->lcd_update();
3271 #endif
3272 return status;
3275 /******************** Plugin entry point *********************/
3277 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
3279 rb = api;
3281 int condition;
3282 #ifdef USEGSLIB
3283 int grayscales;
3284 long graysize; /* helper */
3285 #endif
3286 #if LCD_DEPTH > 1
3287 old_backdrop = rb->lcd_get_backdrop();
3288 #endif
3290 if(!parameter) return PLUGIN_ERROR;
3292 rb->strcpy(np_file, parameter);
3293 get_pic_list();
3295 if(!entries) return PLUGIN_ERROR;
3297 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
3298 if(rb->audio_status())
3300 buf = rb->plugin_get_buffer((size_t *)&buf_size) +
3301 (entries * sizeof(char**));
3302 buf_size -= (entries * sizeof(char**));
3303 plug_buf = true;
3305 else
3306 buf = rb->plugin_get_audio_buffer((size_t *)&buf_size);
3307 #else
3308 buf = rb->plugin_get_audio_buffer(&buf_size) +
3309 (entries * sizeof(char**));
3310 buf_size -= (entries * sizeof(char**));
3311 #endif
3313 #ifdef USEGSLIB
3314 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */
3315 grayscales = gray_init(rb, buf, buf_size, false, LCD_WIDTH, LCD_HEIGHT,
3316 32, 2<<8, &graysize) + 1;
3317 buf += graysize;
3318 buf_size -= graysize;
3319 if (grayscales < 33 || buf_size <= 0)
3321 rb->splash(HZ, "gray buf error");
3322 return PLUGIN_ERROR;
3324 #else
3325 xlcd_init(rb);
3326 #endif
3328 #ifdef HAVE_LCD_COLOR
3329 /* should be ok to just load settings since a parameter is present
3330 here and the drive should be spinning */
3331 configfile_init(rb);
3332 configfile_load(JPEG_CONFIGFILE, jpeg_config,
3333 ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION);
3334 old_settings = jpeg_settings;
3335 #endif
3337 buf_images = buf; buf_images_size = buf_size;
3339 /* Turn off backlight timeout */
3340 backlight_force_on(rb); /* backlight control in lib/helper.c */
3344 condition = load_and_show(np_file);
3345 }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
3346 && condition != PLUGIN_ERROR);
3348 #ifdef HAVE_LCD_COLOR
3349 if (rb->memcmp(&jpeg_settings, &old_settings, sizeof (jpeg_settings)))
3351 /* Just in case drive has to spin, keep it from looking locked */
3352 rb->splash(0, "Saving Settings");
3353 configfile_save(JPEG_CONFIGFILE, jpeg_config,
3354 ARRAYLEN(jpeg_config), JPEG_SETTINGS_VERSION);
3356 #endif
3358 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
3359 /* set back ata spindown time in case we changed it */
3360 rb->ata_spindown(rb->global_settings->disk_spindown);
3361 #endif
3363 /* Turn on backlight timeout (revert to settings) */
3364 backlight_use_settings(rb); /* backlight control in lib/helper.c */
3366 #ifdef USEGSLIB
3367 gray_release(); /* deinitialize */
3368 #endif
3370 return condition;
3373 #endif /* HAVE_LCD_BITMAP */