Make jpegviewer remember the slideshow timeout, fixes FS#8461, slight simplification...
[kugel-rb.git] / apps / plugins / jpeg.c
blob0eb94015225990e2691253041681d043b5fcbf94
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örg Hohensohn aka [IDC]Dragon
15 * Heavily borrowed from the IJG implementation (C) Thomas G. Lane
16 * Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
18 * All files in this archive are subject to the GNU General Public License.
19 * See the file COPYING in the source tree root for full license agreement.
21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22 * KIND, either express or implied.
24 ****************************************************************************/
26 #include "plugin.h"
27 #include "playback_control.h"
28 #include "oldmenuapi.h"
29 #include "helper.h"
31 #ifdef HAVE_LCD_BITMAP
32 #include "grey.h"
33 #include "xlcd.h"
35 #ifdef HAVE_LCD_COLOR
36 #include "lib/configfile.h"
37 #endif
39 PLUGIN_HEADER
41 /* variable button definitions */
42 #if CONFIG_KEYPAD == RECORDER_PAD
43 #define JPEG_ZOOM_IN BUTTON_PLAY
44 #define JPEG_ZOOM_OUT BUTTON_ON
45 #define JPEG_UP BUTTON_UP
46 #define JPEG_DOWN BUTTON_DOWN
47 #define JPEG_LEFT BUTTON_LEFT
48 #define JPEG_RIGHT BUTTON_RIGHT
49 #define JPEG_NEXT BUTTON_F3
50 #define JPEG_PREVIOUS BUTTON_F2
51 #define JPEG_MENU BUTTON_OFF
53 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
54 #define JPEG_ZOOM_IN BUTTON_SELECT
55 #define JPEG_ZOOM_OUT BUTTON_ON
56 #define JPEG_UP BUTTON_UP
57 #define JPEG_DOWN BUTTON_DOWN
58 #define JPEG_LEFT BUTTON_LEFT
59 #define JPEG_RIGHT BUTTON_RIGHT
60 #define JPEG_NEXT BUTTON_F3
61 #define JPEG_PREVIOUS BUTTON_F2
62 #define JPEG_MENU BUTTON_OFF
64 #elif CONFIG_KEYPAD == ONDIO_PAD
65 #define JPEG_ZOOM_PRE BUTTON_MENU
66 #define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
67 #define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
68 #define JPEG_UP BUTTON_UP
69 #define JPEG_DOWN BUTTON_DOWN
70 #define JPEG_LEFT BUTTON_LEFT
71 #define JPEG_RIGHT BUTTON_RIGHT
72 #define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
73 #define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
74 #define JPEG_MENU BUTTON_OFF
76 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
77 (CONFIG_KEYPAD == IRIVER_H300_PAD)
78 #define JPEG_ZOOM_IN BUTTON_SELECT
79 #define JPEG_ZOOM_OUT BUTTON_MODE
80 #define JPEG_UP BUTTON_UP
81 #define JPEG_DOWN BUTTON_DOWN
82 #define JPEG_LEFT BUTTON_LEFT
83 #define JPEG_RIGHT BUTTON_RIGHT
84 #if (CONFIG_KEYPAD == IRIVER_H100_PAD)
85 #define JPEG_NEXT BUTTON_ON
86 #define JPEG_PREVIOUS BUTTON_REC
87 #else
88 #define JPEG_NEXT BUTTON_REC
89 #define JPEG_PREVIOUS BUTTON_ON
90 #endif
91 #define JPEG_MENU BUTTON_OFF
92 #define JPEG_RC_MENU BUTTON_RC_STOP
94 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
95 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
96 #define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
97 #define JPEG_ZOOM_OUT BUTTON_SCROLL_BACK
98 #define JPEG_UP BUTTON_MENU
99 #define JPEG_DOWN BUTTON_PLAY
100 #define JPEG_LEFT BUTTON_LEFT
101 #define JPEG_RIGHT BUTTON_RIGHT
102 #define JPEG_MENU (BUTTON_SELECT | BUTTON_MENU)
103 #define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
104 #define JPEG_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
106 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
107 #define JPEG_ZOOM_PRE BUTTON_SELECT
108 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
109 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
110 #define JPEG_UP BUTTON_UP
111 #define JPEG_DOWN BUTTON_DOWN
112 #define JPEG_LEFT BUTTON_LEFT
113 #define JPEG_RIGHT BUTTON_RIGHT
114 #define JPEG_MENU BUTTON_POWER
115 #define JPEG_NEXT BUTTON_PLAY
116 #define JPEG_PREVIOUS BUTTON_REC
118 #elif CONFIG_KEYPAD == GIGABEAT_PAD
119 #define JPEG_ZOOM_IN BUTTON_VOL_UP
120 #define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
121 #define JPEG_UP BUTTON_UP
122 #define JPEG_DOWN BUTTON_DOWN
123 #define JPEG_LEFT BUTTON_LEFT
124 #define JPEG_RIGHT BUTTON_RIGHT
125 #define JPEG_MENU BUTTON_MENU
126 #define JPEG_NEXT (BUTTON_A | BUTTON_RIGHT)
127 #define JPEG_PREVIOUS (BUTTON_A | BUTTON_LEFT)
129 #elif CONFIG_KEYPAD == SANSA_E200_PAD
130 #define JPEG_ZOOM_PRE BUTTON_SELECT
131 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
132 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
133 #define JPEG_UP BUTTON_UP
134 #define JPEG_DOWN BUTTON_DOWN
135 #define JPEG_LEFT BUTTON_LEFT
136 #define JPEG_RIGHT BUTTON_RIGHT
137 #define JPEG_MENU BUTTON_POWER
138 #define JPEG_SLIDE_SHOW BUTTON_REC
139 #define JPEG_NEXT BUTTON_SCROLL_FWD
140 #define JPEG_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
141 #define JPEG_PREVIOUS BUTTON_SCROLL_BACK
142 #define JPEG_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
144 #elif CONFIG_KEYPAD == SANSA_C200_PAD
145 #define JPEG_ZOOM_PRE BUTTON_SELECT
146 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
147 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
148 #define JPEG_UP BUTTON_UP
149 #define JPEG_DOWN BUTTON_DOWN
150 #define JPEG_LEFT BUTTON_LEFT
151 #define JPEG_RIGHT BUTTON_RIGHT
152 #define JPEG_MENU BUTTON_POWER
153 #define JPEG_SLIDE_SHOW BUTTON_REC
154 #define JPEG_NEXT BUTTON_VOL_UP
155 #define JPEG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
156 #define JPEG_PREVIOUS BUTTON_VOL_DOWN
157 #define JPEG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
159 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
160 #define JPEG_ZOOM_PRE BUTTON_PLAY
161 #define JPEG_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
162 #define JPEG_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
163 #define JPEG_UP BUTTON_SCROLL_UP
164 #define JPEG_DOWN BUTTON_SCROLL_DOWN
165 #define JPEG_LEFT BUTTON_LEFT
166 #define JPEG_RIGHT BUTTON_RIGHT
167 #define JPEG_MENU BUTTON_POWER
168 #define JPEG_NEXT BUTTON_FF
169 #define JPEG_PREVIOUS BUTTON_REW
171 #elif CONFIG_KEYPAD == MROBE500_PAD
172 #define JPEG_ZOOM_IN BUTTON_RC_VOL_UP
173 #define JPEG_ZOOM_OUT BUTTON_RC_VOL_DOWN
174 #define JPEG_UP BUTTON_RC_PLAY
175 #define JPEG_DOWN BUTTON_RC_DOWN
176 #define JPEG_LEFT BUTTON_LEFT
177 #define JPEG_RIGHT BUTTON_RIGHT
178 #define JPEG_MENU BUTTON_POWER
179 #define JPEG_NEXT BUTTON_RC_HEART
180 #define JPEG_PREVIOUS BUTTON_RC_MODE
182 #endif
184 /* different graphics libraries */
185 #if LCD_DEPTH < 8
186 #define USEGSLIB
187 GREY_INFO_STRUCT
188 #define MYLCD(fn) grey_ub_ ## fn
189 #define MYLCD_UPDATE()
190 #define MYXLCD(fn) grey_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
232 #ifdef HAVE_LCD_COLOR
234 /* Persistent configuration - only needed for color displays atm */
235 #define JPEG_CONFIGFILE "jpeg.cfg"
236 #define JPEG_SETTINGS_MINVERSION 1
237 #define JPEG_SETTINGS_VERSION 2
239 /* Slideshow times */
240 #define SS_MIN_TIMEOUT 1
241 #define SS_MAX_TIMEOUT 20
242 #define SS_DEFAULT_TIMEOUT 5
244 enum color_modes
246 COLOURMODE_COLOUR = 0,
247 COLOURMODE_GRAY,
248 COLOUR_NUM_MODES
251 enum dither_modes
253 DITHER_NONE = 0, /* No dithering */
254 DITHER_ORDERED, /* Bayer ordered */
255 DITHER_DIFFUSION, /* Floyd/Steinberg error diffusion */
256 DITHER_NUM_MODES
259 struct jpeg_settings
261 int colour_mode;
262 int dither_mode;
263 int ss_timeout;
266 static struct jpeg_settings jpeg_settings =
267 { COLOURMODE_COLOUR, DITHER_NONE, SS_DEFAULT_TIMEOUT };
268 static struct jpeg_settings old_settings;
270 static struct configdata jpeg_config[] =
272 { TYPE_ENUM, 0, COLOUR_NUM_MODES, &jpeg_settings.colour_mode,
273 "Colour Mode", (char *[]){ "Colour", "Grayscale" }, NULL },
274 { TYPE_ENUM, 0, DITHER_NUM_MODES, &jpeg_settings.dither_mode,
275 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" }, NULL },
276 { TYPE_INT, SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, &jpeg_settings.ss_timeout,
277 "Slideshow Time", NULL, NULL},
280 #endif /* HAVE_LCD_COLOR */
281 #if LCD_DEPTH > 1
282 fb_data* old_backdrop;
283 #endif
285 /**************** begin JPEG code ********************/
287 INLINE unsigned range_limit(int value)
289 #if CONFIG_CPU == SH7034
290 unsigned tmp;
291 asm ( /* Note: Uses knowledge that only low byte of result is used */
292 "mov #-128,%[t] \n"
293 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
294 "extu.b %[v],%[t] \n"
295 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
296 "bt 1f \n" /* yes: no overflow */
297 "cmp/pz %[v] \n" /* overflow: positive? */
298 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
299 "1: \n"
300 : /* outputs */
301 [v]"+r"(value),
302 [t]"=&r"(tmp)
304 return value;
305 #elif defined(CPU_COLDFIRE)
306 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
307 "add.l #128,%[v] \n" /* value += 128; */
308 "cmp.l #255,%[v] \n" /* overflow? */
309 "bls.b 1f \n" /* no: return value */
310 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
311 "1: \n"
312 : /* outputs */
313 [v]"+d"(value)
315 return value;
316 #elif defined(CPU_ARM)
317 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
318 "add %[v], %[v], #128 \n" /* value += 128 */
319 "cmp %[v], #255 \n" /* out of range 0..255? */
320 "mvnhi %[v], %[v], asr #31 \n" /* yes: set all bits to ~(sign_bit) */
321 : /* outputs */
322 [v]"+r"(value)
324 return value;
325 #else
326 value += 128;
328 if ((unsigned)value <= 255)
329 return value;
331 if (value < 0)
332 return 0;
334 return 255;
335 #endif
338 /* IDCT implementation */
341 #define CONST_BITS 13
342 #define PASS1_BITS 2
345 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
346 * causing a lot of useless floating-point operations at run time.
347 * To get around this we use the following pre-calculated constants.
348 * If you change CONST_BITS you may want to add appropriate values.
349 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
351 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
352 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
353 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
354 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
355 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
356 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
357 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
358 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
359 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
360 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
361 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
362 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
366 /* Multiply an long variable by an long constant to yield an long result.
367 * For 8-bit samples with the recommended scaling, all the variable
368 * and constant values involved are no more than 16 bits wide, so a
369 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
370 * For 12-bit samples, a full 32-bit multiplication will be needed.
372 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
375 /* Dequantize a coefficient by multiplying it by the multiplier-table
376 * entry; produce an int result. In this module, both inputs and result
377 * are 16 bits or less, so either int or short multiply will work.
379 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
380 #define DEQUANTIZE MULTIPLY16
382 /* Descale and correctly round an int value that's scaled by N bits.
383 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
384 * the fudge factor is correct for either sign of X.
386 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
391 * Perform dequantization and inverse DCT on one block of coefficients,
392 * producing a reduced-size 1x1 output block.
394 void idct1x1(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
396 (void)skip_line; /* unused */
397 *p_byte = range_limit(inptr[0] * quantptr[0] >> 3);
403 * Perform dequantization and inverse DCT on one block of coefficients,
404 * producing a reduced-size 2x2 output block.
406 void idct2x2(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
408 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
409 unsigned char* outptr;
411 /* Pass 1: process columns from input, store into work array. */
413 /* Column 0 */
414 tmp4 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
415 tmp5 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
417 tmp0 = tmp4 + tmp5;
418 tmp2 = tmp4 - tmp5;
420 /* Column 1 */
421 tmp4 = DEQUANTIZE(inptr[8*0+1], quantptr[8*0+1]);
422 tmp5 = DEQUANTIZE(inptr[8*1+1], quantptr[8*1+1]);
424 tmp1 = tmp4 + tmp5;
425 tmp3 = tmp4 - tmp5;
427 /* Pass 2: process 2 rows, store into output array. */
429 /* Row 0 */
430 outptr = p_byte;
432 outptr[0] = range_limit((int) DESCALE(tmp0 + tmp1, 3));
433 outptr[1] = range_limit((int) DESCALE(tmp0 - tmp1, 3));
435 /* Row 1 */
436 outptr = p_byte + skip_line;
438 outptr[0] = range_limit((int) DESCALE(tmp2 + tmp3, 3));
439 outptr[1] = range_limit((int) DESCALE(tmp2 - tmp3, 3));
445 * Perform dequantization and inverse DCT on one block of coefficients,
446 * producing a reduced-size 4x4 output block.
448 void idct4x4(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
450 int tmp0, tmp2, tmp10, tmp12;
451 int z1, z2, z3;
452 int * wsptr;
453 unsigned char* outptr;
454 int ctr;
455 int workspace[4*4]; /* buffers data between passes */
457 /* Pass 1: process columns from input, store into work array. */
459 wsptr = workspace;
460 for (ctr = 0; ctr < 4; ctr++, inptr++, quantptr++, wsptr++)
462 /* Even part */
464 tmp0 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
465 tmp2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
467 tmp10 = (tmp0 + tmp2) << PASS1_BITS;
468 tmp12 = (tmp0 - tmp2) << PASS1_BITS;
470 /* Odd part */
471 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
473 z2 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
474 z3 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
476 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
477 tmp0 = DESCALE(z1 + MULTIPLY16(z3, - FIX_1_847759065), CONST_BITS-PASS1_BITS);
478 tmp2 = DESCALE(z1 + MULTIPLY16(z2, FIX_0_765366865), CONST_BITS-PASS1_BITS);
480 /* Final output stage */
482 wsptr[4*0] = (int) (tmp10 + tmp2);
483 wsptr[4*3] = (int) (tmp10 - tmp2);
484 wsptr[4*1] = (int) (tmp12 + tmp0);
485 wsptr[4*2] = (int) (tmp12 - tmp0);
488 /* Pass 2: process 4 rows from work array, store into output array. */
490 wsptr = workspace;
491 for (ctr = 0; ctr < 4; ctr++)
493 outptr = p_byte + (ctr*skip_line);
494 /* Even part */
496 tmp0 = (int) wsptr[0];
497 tmp2 = (int) wsptr[2];
499 tmp10 = (tmp0 + tmp2) << CONST_BITS;
500 tmp12 = (tmp0 - tmp2) << CONST_BITS;
502 /* Odd part */
503 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
505 z2 = (int) wsptr[1];
506 z3 = (int) wsptr[3];
508 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
509 tmp0 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
510 tmp2 = z1 + MULTIPLY16(z2, FIX_0_765366865);
512 /* Final output stage */
514 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp2,
515 CONST_BITS+PASS1_BITS+3));
516 outptr[3] = range_limit((int) DESCALE(tmp10 - tmp2,
517 CONST_BITS+PASS1_BITS+3));
518 outptr[1] = range_limit((int) DESCALE(tmp12 + tmp0,
519 CONST_BITS+PASS1_BITS+3));
520 outptr[2] = range_limit((int) DESCALE(tmp12 - tmp0,
521 CONST_BITS+PASS1_BITS+3));
523 wsptr += 4; /* advance pointer to next row */
530 * Perform dequantization and inverse DCT on one block of coefficients.
532 void idct8x8(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
534 long tmp0, tmp1, tmp2, tmp3;
535 long tmp10, tmp11, tmp12, tmp13;
536 long z1, z2, z3, z4, z5;
537 int * wsptr;
538 unsigned char* outptr;
539 int ctr;
540 int workspace[64]; /* buffers data between passes */
542 /* Pass 1: process columns from input, store into work array. */
543 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
544 /* furthermore, we scale the results by 2**PASS1_BITS. */
546 wsptr = workspace;
547 for (ctr = 8; ctr > 0; ctr--)
549 /* Due to quantization, we will usually find that many of the input
550 * coefficients are zero, especially the AC terms. We can exploit this
551 * by short-circuiting the IDCT calculation for any column in which all
552 * the AC terms are zero. In that case each output is equal to the
553 * DC coefficient (with scale factor as needed).
554 * With typical images and quantization tables, half or more of the
555 * column DCT calculations can be simplified this way.
558 if ((inptr[8*1] | inptr[8*2] | inptr[8*3]
559 | inptr[8*4] | inptr[8*5] | inptr[8*6] | inptr[8*7]) == 0)
561 /* AC terms all zero */
562 int dcval = DEQUANTIZE(inptr[8*0], quantptr[8*0]) << PASS1_BITS;
564 wsptr[8*0] = wsptr[8*1] = wsptr[8*2] = wsptr[8*3] = wsptr[8*4]
565 = wsptr[8*5] = wsptr[8*6] = wsptr[8*7] = dcval;
566 inptr++; /* advance pointers to next column */
567 quantptr++;
568 wsptr++;
569 continue;
572 /* Even part: reverse the even part of the forward DCT. */
573 /* The rotator is sqrt(2)*c(-6). */
575 z2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
576 z3 = DEQUANTIZE(inptr[8*6], quantptr[8*6]);
578 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
579 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
580 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
582 z2 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
583 z3 = DEQUANTIZE(inptr[8*4], quantptr[8*4]);
585 tmp0 = (z2 + z3) << CONST_BITS;
586 tmp1 = (z2 - z3) << CONST_BITS;
588 tmp10 = tmp0 + tmp3;
589 tmp13 = tmp0 - tmp3;
590 tmp11 = tmp1 + tmp2;
591 tmp12 = tmp1 - tmp2;
593 /* Odd part per figure 8; the matrix is unitary and hence its
594 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
596 tmp0 = DEQUANTIZE(inptr[8*7], quantptr[8*7]);
597 tmp1 = DEQUANTIZE(inptr[8*5], quantptr[8*5]);
598 tmp2 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
599 tmp3 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
601 z1 = tmp0 + tmp3;
602 z2 = tmp1 + tmp2;
603 z3 = tmp0 + tmp2;
604 z4 = tmp1 + tmp3;
605 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
607 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
608 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
609 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
610 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
611 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
612 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
613 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
614 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
616 z3 += z5;
617 z4 += z5;
619 tmp0 += z1 + z3;
620 tmp1 += z2 + z4;
621 tmp2 += z2 + z3;
622 tmp3 += z1 + z4;
624 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
626 wsptr[8*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
627 wsptr[8*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
628 wsptr[8*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
629 wsptr[8*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
630 wsptr[8*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
631 wsptr[8*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
632 wsptr[8*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
633 wsptr[8*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
635 inptr++; /* advance pointers to next column */
636 quantptr++;
637 wsptr++;
640 /* Pass 2: process rows from work array, store into output array. */
641 /* Note that we must descale the results by a factor of 8 == 2**3, */
642 /* and also undo the PASS1_BITS scaling. */
644 wsptr = workspace;
645 for (ctr = 0; ctr < 8; ctr++)
647 outptr = p_byte + (ctr*skip_line);
648 /* Rows of zeroes can be exploited in the same way as we did with columns.
649 * However, the column calculation has created many nonzero AC terms, so
650 * the simplification applies less often (typically 5% to 10% of the time).
651 * On machines with very fast multiplication, it's possible that the
652 * test takes more time than it's worth. In that case this section
653 * may be commented out.
656 #ifndef NO_ZERO_ROW_TEST
657 if ((wsptr[1] | wsptr[2] | wsptr[3]
658 | wsptr[4] | wsptr[5] | wsptr[6] | wsptr[7]) == 0)
660 /* AC terms all zero */
661 unsigned char dcval = range_limit((int) DESCALE((long) wsptr[0],
662 PASS1_BITS+3));
664 outptr[0] = dcval;
665 outptr[1] = dcval;
666 outptr[2] = dcval;
667 outptr[3] = dcval;
668 outptr[4] = dcval;
669 outptr[5] = dcval;
670 outptr[6] = dcval;
671 outptr[7] = dcval;
673 wsptr += 8; /* advance pointer to next row */
674 continue;
676 #endif
678 /* Even part: reverse the even part of the forward DCT. */
679 /* The rotator is sqrt(2)*c(-6). */
681 z2 = (long) wsptr[2];
682 z3 = (long) wsptr[6];
684 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
685 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
686 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
688 tmp0 = ((long) wsptr[0] + (long) wsptr[4]) << CONST_BITS;
689 tmp1 = ((long) wsptr[0] - (long) wsptr[4]) << CONST_BITS;
691 tmp10 = tmp0 + tmp3;
692 tmp13 = tmp0 - tmp3;
693 tmp11 = tmp1 + tmp2;
694 tmp12 = tmp1 - tmp2;
696 /* Odd part per figure 8; the matrix is unitary and hence its
697 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
699 tmp0 = (long) wsptr[7];
700 tmp1 = (long) wsptr[5];
701 tmp2 = (long) wsptr[3];
702 tmp3 = (long) wsptr[1];
704 z1 = tmp0 + tmp3;
705 z2 = tmp1 + tmp2;
706 z3 = tmp0 + tmp2;
707 z4 = tmp1 + tmp3;
708 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
710 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
711 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
712 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
713 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
714 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
715 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
716 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
717 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
719 z3 += z5;
720 z4 += z5;
722 tmp0 += z1 + z3;
723 tmp1 += z2 + z4;
724 tmp2 += z2 + z3;
725 tmp3 += z1 + z4;
727 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
729 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp3,
730 CONST_BITS+PASS1_BITS+3));
731 outptr[7] = range_limit((int) DESCALE(tmp10 - tmp3,
732 CONST_BITS+PASS1_BITS+3));
733 outptr[1] = range_limit((int) DESCALE(tmp11 + tmp2,
734 CONST_BITS+PASS1_BITS+3));
735 outptr[6] = range_limit((int) DESCALE(tmp11 - tmp2,
736 CONST_BITS+PASS1_BITS+3));
737 outptr[2] = range_limit((int) DESCALE(tmp12 + tmp1,
738 CONST_BITS+PASS1_BITS+3));
739 outptr[5] = range_limit((int) DESCALE(tmp12 - tmp1,
740 CONST_BITS+PASS1_BITS+3));
741 outptr[3] = range_limit((int) DESCALE(tmp13 + tmp0,
742 CONST_BITS+PASS1_BITS+3));
743 outptr[4] = range_limit((int) DESCALE(tmp13 - tmp0,
744 CONST_BITS+PASS1_BITS+3));
746 wsptr += 8; /* advance pointer to next row */
752 /* JPEG decoder implementation */
755 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
757 struct derived_tbl
759 /* Basic tables: (element [0] of each array is unused) */
760 long mincode[17]; /* smallest code of length k */
761 long maxcode[18]; /* largest code of length k (-1 if none) */
762 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
763 int valptr[17]; /* huffval[] index of 1st symbol of length k */
765 /* Back link to public Huffman table (needed only in slow_DECODE) */
766 int* pub;
768 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
769 the input data stream. If the next Huffman code is no more
770 than HUFF_LOOKAHEAD bits long, we can obtain its length and
771 the corresponding symbol directly from these tables. */
772 int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
773 unsigned char look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
776 #define QUANT_TABLE_LENGTH 64
778 /* for type of Huffman table */
779 #define DC_LEN 28
780 #define AC_LEN 178
782 struct huffman_table
783 { /* length and code according to JFIF format */
784 int huffmancodes_dc[DC_LEN];
785 int huffmancodes_ac[AC_LEN];
788 struct frame_component
790 int ID;
791 int horizontal_sampling;
792 int vertical_sampling;
793 int quanttable_select;
796 struct scan_component
798 int ID;
799 int DC_select;
800 int AC_select;
803 struct bitstream
805 unsigned long get_buffer; /* current bit-extraction buffer */
806 int bits_left; /* # of unused bits in it */
807 unsigned char* next_input_byte;
808 unsigned char* input_end; /* upper limit +1 */
811 struct jpeg
813 int x_size, y_size; /* size of image (can be less than block boundary) */
814 int x_phys, y_phys; /* physical size, block aligned */
815 int x_mbl; /* x dimension of MBL */
816 int y_mbl; /* y dimension of MBL */
817 int blocks; /* blocks per MB */
818 int restart_interval; /* number of MCUs between RSTm markers */
819 int store_pos[4]; /* for Y block ordering */
821 unsigned char* p_entropy_data;
822 unsigned char* p_entropy_end;
824 int quanttable[4][QUANT_TABLE_LENGTH]; /* raw quantization tables 0-3 */
825 int qt_idct[2][QUANT_TABLE_LENGTH]; /* quantization tables for IDCT */
827 struct huffman_table hufftable[2]; /* Huffman tables */
828 struct derived_tbl dc_derived_tbls[2]; /* Huffman-LUTs */
829 struct derived_tbl ac_derived_tbls[2];
831 struct frame_component frameheader[3]; /* Component descriptor */
832 struct scan_component scanheader[3]; /* currently not used */
834 int mcu_membership[6]; /* info per block */
835 int tab_membership[6];
836 int subsample_x[3]; /* info per component */
837 int subsample_y[3];
841 /* possible return flags for process_markers() */
842 #define HUFFTAB 0x0001 /* with huffman table */
843 #define QUANTTAB 0x0002 /* with quantization table */
844 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
845 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
846 #define SOF0 0x0010 /* with SOF0-Segment */
847 #define DHT 0x0020 /* with Definition of huffman tables */
848 #define SOS 0x0040 /* with Start-of-Scan segment */
849 #define DQT 0x0080 /* with definition of quantization table */
851 /* Preprocess the JPEG JFIF file */
852 int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
854 unsigned char* p_bytes = p_src;
855 int marker_size; /* variable length of marker segment */
856 int i, j, n;
857 int ret = 0; /* returned flags */
859 p_jpeg->p_entropy_end = p_src + size;
861 while (p_src < p_bytes + size)
863 if (*p_src++ != 0xFF) /* no marker? */
865 p_src--; /* it's image data, put it back */
866 p_jpeg->p_entropy_data = p_src;
867 break; /* exit marker processing */
870 switch (*p_src++)
872 case 0xFF: /* Fill byte */
873 ret |= FILL_FF;
874 case 0x00: /* Zero stuffed byte - entropy data */
875 p_src--; /* put it back */
876 continue;
878 case 0xC0: /* SOF Huff - Baseline DCT */
880 ret |= SOF0;
881 marker_size = *p_src++ << 8; /* Highbyte */
882 marker_size |= *p_src++; /* Lowbyte */
883 n = *p_src++; /* sample precision (= 8 or 12) */
884 if (n != 8)
886 return(-1); /* Unsupported sample precision */
888 p_jpeg->y_size = *p_src++ << 8; /* Highbyte */
889 p_jpeg->y_size |= *p_src++; /* Lowbyte */
890 p_jpeg->x_size = *p_src++ << 8; /* Highbyte */
891 p_jpeg->x_size |= *p_src++; /* Lowbyte */
893 n = (marker_size-2-6)/3;
894 if (*p_src++ != n || (n != 1 && n != 3))
896 return(-2); /* Unsupported SOF0 component specification */
898 for (i=0; i<n; i++)
900 p_jpeg->frameheader[i].ID = *p_src++; /* Component info */
901 p_jpeg->frameheader[i].horizontal_sampling = *p_src >> 4;
902 p_jpeg->frameheader[i].vertical_sampling = *p_src++ & 0x0F;
903 p_jpeg->frameheader[i].quanttable_select = *p_src++;
904 if (p_jpeg->frameheader[i].horizontal_sampling > 2
905 || p_jpeg->frameheader[i].vertical_sampling > 2)
906 return -3; /* Unsupported SOF0 subsampling */
908 p_jpeg->blocks = n;
910 break;
912 case 0xC1: /* SOF Huff - Extended sequential DCT*/
913 case 0xC2: /* SOF Huff - Progressive DCT*/
914 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
915 case 0xC5: /* SOF Huff - Differential sequential DCT*/
916 case 0xC6: /* SOF Huff - Differential progressive DCT*/
917 case 0xC7: /* SOF Huff - Differential spatial*/
918 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
919 case 0xC9: /* SOF Arith - Extended sequential DCT*/
920 case 0xCA: /* SOF Arith - Progressive DCT*/
921 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
922 case 0xCD: /* SOF Arith - Differential sequential DCT*/
923 case 0xCE: /* SOF Arith - Differential progressive DCT*/
924 case 0xCF: /* SOF Arith - Differential spatial*/
926 return (-4); /* other DCT model than baseline not implemented */
929 case 0xC4: /* Define Huffman Table(s) */
931 unsigned char* p_temp;
933 ret |= DHT;
934 marker_size = *p_src++ << 8; /* Highbyte */
935 marker_size |= *p_src++; /* Lowbyte */
937 p_temp = p_src;
938 while (p_src < p_temp+marker_size-2-17) /* another table */
940 int sum = 0;
941 i = *p_src & 0x0F; /* table index */
942 if (i > 1)
944 return (-5); /* Huffman table index out of range */
946 else if (*p_src++ & 0xF0) /* AC table */
948 for (j=0; j<16; j++)
950 sum += *p_src;
951 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
953 if(16 + sum > AC_LEN)
954 return -10; /* longer than allowed */
956 for (; j < 16 + sum; j++)
957 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
959 else /* DC table */
961 for (j=0; j<16; j++)
963 sum += *p_src;
964 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
966 if(16 + sum > DC_LEN)
967 return -11; /* longer than allowed */
969 for (; j < 16 + sum; j++)
970 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
972 } /* while */
973 p_src = p_temp+marker_size - 2; /* skip possible residue */
975 break;
977 case 0xCC: /* Define Arithmetic coding conditioning(s) */
978 return(-6); /* Arithmetic coding not supported */
980 case 0xD8: /* Start of Image */
981 case 0xD9: /* End of Image */
982 case 0x01: /* for temp private use arith code */
983 break; /* skip parameterless marker */
986 case 0xDA: /* Start of Scan */
988 ret |= SOS;
989 marker_size = *p_src++ << 8; /* Highbyte */
990 marker_size |= *p_src++; /* Lowbyte */
992 n = (marker_size-2-1-3)/2;
993 if (*p_src++ != n || (n != 1 && n != 3))
995 return (-7); /* Unsupported SOS component specification */
997 for (i=0; i<n; i++)
999 p_jpeg->scanheader[i].ID = *p_src++;
1000 p_jpeg->scanheader[i].DC_select = *p_src >> 4;
1001 p_jpeg->scanheader[i].AC_select = *p_src++ & 0x0F;
1003 p_src += 3; /* skip spectral information */
1005 break;
1007 case 0xDB: /* Define quantization Table(s) */
1009 ret |= DQT;
1010 marker_size = *p_src++ << 8; /* Highbyte */
1011 marker_size |= *p_src++; /* Lowbyte */
1012 n = (marker_size-2)/(QUANT_TABLE_LENGTH+1); /* # of tables */
1013 for (i=0; i<n; i++)
1015 int id = *p_src++; /* ID */
1016 if (id >= 4)
1018 return (-8); /* Unsupported quantization table */
1020 /* Read Quantisation table: */
1021 for (j=0; j<QUANT_TABLE_LENGTH; j++)
1022 p_jpeg->quanttable[id][j] = *p_src++;
1025 break;
1027 case 0xDD: /* Define Restart Interval */
1029 marker_size = *p_src++ << 8; /* Highbyte */
1030 marker_size |= *p_src++; /* Lowbyte */
1031 p_jpeg->restart_interval = *p_src++ << 8; /* Highbyte */
1032 p_jpeg->restart_interval |= *p_src++; /* Lowbyte */
1033 p_src += marker_size-4; /* skip segment */
1035 break;
1037 case 0xDC: /* Define Number of Lines */
1038 case 0xDE: /* Define Hierarchical progression */
1039 case 0xDF: /* Expand Reference Component(s) */
1040 case 0xE0: /* Application Field 0*/
1041 case 0xE1: /* Application Field 1*/
1042 case 0xE2: /* Application Field 2*/
1043 case 0xE3: /* Application Field 3*/
1044 case 0xE4: /* Application Field 4*/
1045 case 0xE5: /* Application Field 5*/
1046 case 0xE6: /* Application Field 6*/
1047 case 0xE7: /* Application Field 7*/
1048 case 0xE8: /* Application Field 8*/
1049 case 0xE9: /* Application Field 9*/
1050 case 0xEA: /* Application Field 10*/
1051 case 0xEB: /* Application Field 11*/
1052 case 0xEC: /* Application Field 12*/
1053 case 0xED: /* Application Field 13*/
1054 case 0xEE: /* Application Field 14*/
1055 case 0xEF: /* Application Field 15*/
1056 case 0xFE: /* Comment */
1058 marker_size = *p_src++ << 8; /* Highbyte */
1059 marker_size |= *p_src++; /* Lowbyte */
1060 p_src += marker_size-2; /* skip segment */
1062 break;
1064 case 0xF0: /* Reserved for JPEG extensions */
1065 case 0xF1: /* Reserved for JPEG extensions */
1066 case 0xF2: /* Reserved for JPEG extensions */
1067 case 0xF3: /* Reserved for JPEG extensions */
1068 case 0xF4: /* Reserved for JPEG extensions */
1069 case 0xF5: /* Reserved for JPEG extensions */
1070 case 0xF6: /* Reserved for JPEG extensions */
1071 case 0xF7: /* Reserved for JPEG extensions */
1072 case 0xF8: /* Reserved for JPEG extensions */
1073 case 0xF9: /* Reserved for JPEG extensions */
1074 case 0xFA: /* Reserved for JPEG extensions */
1075 case 0xFB: /* Reserved for JPEG extensions */
1076 case 0xFC: /* Reserved for JPEG extensions */
1077 case 0xFD: /* Reserved for JPEG extensions */
1078 case 0x02: /* Reserved */
1079 default:
1080 return (-9); /* Unknown marker */
1081 } /* switch */
1082 } /* while */
1084 return (ret); /* return flags with seen markers */
1088 void default_huff_tbl(struct jpeg* p_jpeg)
1090 static const struct huffman_table luma_table =
1093 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
1094 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1097 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
1098 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
1099 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
1100 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
1101 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
1102 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1103 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1104 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
1105 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
1106 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
1107 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1108 0xF9,0xFA
1112 static const struct huffman_table chroma_table =
1115 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
1116 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1119 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
1120 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
1121 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1122 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1123 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1124 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1125 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1126 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1127 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1128 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1129 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1130 0xF9,0xFA
1134 MEMCPY(&p_jpeg->hufftable[0], &luma_table, sizeof(luma_table));
1135 MEMCPY(&p_jpeg->hufftable[1], &chroma_table, sizeof(chroma_table));
1137 return;
1140 /* Compute the derived values for a Huffman table */
1141 void fix_huff_tbl(int* htbl, struct derived_tbl* dtbl)
1143 int p, i, l, si;
1144 int lookbits, ctr;
1145 char huffsize[257];
1146 unsigned int huffcode[257];
1147 unsigned int code;
1149 dtbl->pub = htbl; /* fill in back link */
1151 /* Figure C.1: make table of Huffman code length for each symbol */
1152 /* Note that this is in code-length order. */
1154 p = 0;
1155 for (l = 1; l <= 16; l++)
1156 { /* all possible code length */
1157 for (i = 1; i <= (int) htbl[l-1]; i++) /* all codes per length */
1158 huffsize[p++] = (char) l;
1160 huffsize[p] = 0;
1162 /* Figure C.2: generate the codes themselves */
1163 /* Note that this is in code-length order. */
1165 code = 0;
1166 si = huffsize[0];
1167 p = 0;
1168 while (huffsize[p])
1170 while (((int) huffsize[p]) == si)
1172 huffcode[p++] = code;
1173 code++;
1175 code <<= 1;
1176 si++;
1179 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1181 p = 0;
1182 for (l = 1; l <= 16; l++)
1184 if (htbl[l-1])
1186 dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */
1187 dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */
1188 p += htbl[l-1];
1189 dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
1191 else
1193 dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
1196 dtbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */
1198 /* Compute lookahead tables to speed up decoding.
1199 * First we set all the table entries to 0, indicating "too long";
1200 * then we iterate through the Huffman codes that are short enough and
1201 * fill in all the entries that correspond to bit sequences starting
1202 * with that code.
1205 MEMSET(dtbl->look_nbits, 0, sizeof(dtbl->look_nbits));
1207 p = 0;
1208 for (l = 1; l <= HUFF_LOOKAHEAD; l++)
1210 for (i = 1; i <= (int) htbl[l-1]; i++, p++)
1212 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1213 /* Generate left-justified code followed by all possible bit sequences */
1214 lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
1215 for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--)
1217 dtbl->look_nbits[lookbits] = l;
1218 dtbl->look_sym[lookbits] = htbl[16+p];
1219 lookbits++;
1226 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1227 * If the incoming data is corrupted, decode_mcu could attempt to
1228 * reference values beyond the end of the array. To avoid a wild store,
1229 * we put some extra zeroes after the real entries.
1231 static const int zag[] =
1233 0, 1, 8, 16, 9, 2, 3, 10,
1234 17, 24, 32, 25, 18, 11, 4, 5,
1235 12, 19, 26, 33, 40, 48, 41, 34,
1236 27, 20, 13, 6, 7, 14, 21, 28,
1237 35, 42, 49, 56, 57, 50, 43, 36,
1238 29, 22, 15, 23, 30, 37, 44, 51,
1239 58, 59, 52, 45, 38, 31, 39, 46,
1240 53, 60, 61, 54, 47, 55, 62, 63,
1241 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1242 0, 0, 0, 0, 0, 0, 0, 0
1245 void build_lut(struct jpeg* p_jpeg)
1247 int i;
1248 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_dc,
1249 &p_jpeg->dc_derived_tbls[0]);
1250 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_ac,
1251 &p_jpeg->ac_derived_tbls[0]);
1252 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_dc,
1253 &p_jpeg->dc_derived_tbls[1]);
1254 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_ac,
1255 &p_jpeg->ac_derived_tbls[1]);
1257 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1258 for (i=0; i<64; i++)
1260 p_jpeg->qt_idct[0][zag[i]] = p_jpeg->quanttable[0][i];
1261 p_jpeg->qt_idct[1][zag[i]] = p_jpeg->quanttable[1][i];
1264 for (i=0; i<4; i++)
1265 p_jpeg->store_pos[i] = i; /* default ordering */
1267 /* assignments for the decoding of blocks */
1268 if (p_jpeg->frameheader[0].horizontal_sampling == 2
1269 && p_jpeg->frameheader[0].vertical_sampling == 1)
1270 { /* 4:2:2 */
1271 p_jpeg->blocks = 4;
1272 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1273 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1274 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1275 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1276 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1277 p_jpeg->mcu_membership[1] = 0;
1278 p_jpeg->mcu_membership[2] = 1;
1279 p_jpeg->mcu_membership[3] = 2;
1280 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1281 p_jpeg->tab_membership[1] = 0;
1282 p_jpeg->tab_membership[2] = 1;
1283 p_jpeg->tab_membership[3] = 1;
1284 p_jpeg->subsample_x[0] = 1;
1285 p_jpeg->subsample_x[1] = 2;
1286 p_jpeg->subsample_x[2] = 2;
1287 p_jpeg->subsample_y[0] = 1;
1288 p_jpeg->subsample_y[1] = 1;
1289 p_jpeg->subsample_y[2] = 1;
1291 if (p_jpeg->frameheader[0].horizontal_sampling == 1
1292 && p_jpeg->frameheader[0].vertical_sampling == 2)
1293 { /* 4:2:2 vertically subsampled */
1294 p_jpeg->store_pos[1] = 2; /* block positions are mirrored */
1295 p_jpeg->store_pos[2] = 1;
1296 p_jpeg->blocks = 4;
1297 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1298 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1299 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1300 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1301 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1302 p_jpeg->mcu_membership[1] = 0;
1303 p_jpeg->mcu_membership[2] = 1;
1304 p_jpeg->mcu_membership[3] = 2;
1305 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1306 p_jpeg->tab_membership[1] = 0;
1307 p_jpeg->tab_membership[2] = 1;
1308 p_jpeg->tab_membership[3] = 1;
1309 p_jpeg->subsample_x[0] = 1;
1310 p_jpeg->subsample_x[1] = 1;
1311 p_jpeg->subsample_x[2] = 1;
1312 p_jpeg->subsample_y[0] = 1;
1313 p_jpeg->subsample_y[1] = 2;
1314 p_jpeg->subsample_y[2] = 2;
1316 else if (p_jpeg->frameheader[0].horizontal_sampling == 2
1317 && p_jpeg->frameheader[0].vertical_sampling == 2)
1318 { /* 4:2:0 */
1319 p_jpeg->blocks = 6;
1320 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1321 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1322 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1323 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1324 p_jpeg->mcu_membership[0] = 0;
1325 p_jpeg->mcu_membership[1] = 0;
1326 p_jpeg->mcu_membership[2] = 0;
1327 p_jpeg->mcu_membership[3] = 0;
1328 p_jpeg->mcu_membership[4] = 1;
1329 p_jpeg->mcu_membership[5] = 2;
1330 p_jpeg->tab_membership[0] = 0;
1331 p_jpeg->tab_membership[1] = 0;
1332 p_jpeg->tab_membership[2] = 0;
1333 p_jpeg->tab_membership[3] = 0;
1334 p_jpeg->tab_membership[4] = 1;
1335 p_jpeg->tab_membership[5] = 1;
1336 p_jpeg->subsample_x[0] = 1;
1337 p_jpeg->subsample_x[1] = 2;
1338 p_jpeg->subsample_x[2] = 2;
1339 p_jpeg->subsample_y[0] = 1;
1340 p_jpeg->subsample_y[1] = 2;
1341 p_jpeg->subsample_y[2] = 2;
1343 else if (p_jpeg->frameheader[0].horizontal_sampling == 1
1344 && p_jpeg->frameheader[0].vertical_sampling == 1)
1345 { /* 4:4:4 */
1346 /* don't overwrite p_jpeg->blocks */
1347 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1348 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1349 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1350 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1351 p_jpeg->mcu_membership[0] = 0;
1352 p_jpeg->mcu_membership[1] = 1;
1353 p_jpeg->mcu_membership[2] = 2;
1354 p_jpeg->tab_membership[0] = 0;
1355 p_jpeg->tab_membership[1] = 1;
1356 p_jpeg->tab_membership[2] = 1;
1357 p_jpeg->subsample_x[0] = 1;
1358 p_jpeg->subsample_x[1] = 1;
1359 p_jpeg->subsample_x[2] = 1;
1360 p_jpeg->subsample_y[0] = 1;
1361 p_jpeg->subsample_y[1] = 1;
1362 p_jpeg->subsample_y[2] = 1;
1364 else
1366 /* error */
1373 * These functions/macros provide the in-line portion of bit fetching.
1374 * Use check_bit_buffer to ensure there are N bits in get_buffer
1375 * before using get_bits, peek_bits, or drop_bits.
1376 * check_bit_buffer(state,n,action);
1377 * Ensure there are N bits in get_buffer; if suspend, take action.
1378 * val = get_bits(n);
1379 * Fetch next N bits.
1380 * val = peek_bits(n);
1381 * Fetch next N bits without removing them from the buffer.
1382 * drop_bits(n);
1383 * Discard next N bits.
1384 * The value N should be a simple variable, not an expression, because it
1385 * is evaluated multiple times.
1388 INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
1390 if (pb->bits_left < nbits)
1391 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1392 unsigned char 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 byte = *pb->next_input_byte++;
1402 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1403 { /* simplification: just skip the (one-byte) marker code */
1404 pb->next_input_byte++;
1406 pb->get_buffer = (pb->get_buffer << 8) | byte;
1408 pb->bits_left += 16;
1412 INLINE int get_bits(struct bitstream* pb, int nbits)
1414 return ((int) (pb->get_buffer >> (pb->bits_left -= nbits))) & ((1<<nbits)-1);
1417 INLINE int peek_bits(struct bitstream* pb, int nbits)
1419 return ((int) (pb->get_buffer >> (pb->bits_left - nbits))) & ((1<<nbits)-1);
1422 INLINE void drop_bits(struct bitstream* pb, int nbits)
1424 pb->bits_left -= nbits;
1427 /* re-synchronize to entropy data (skip restart marker) */
1428 void search_restart(struct bitstream* pb)
1430 pb->next_input_byte--; /* we may have overread it, taking 2 bytes */
1431 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1432 while (pb->next_input_byte < pb->input_end &&
1433 (pb->next_input_byte[-2] != 0xFF || pb->next_input_byte[-1] == 0x00))
1435 pb->next_input_byte++;
1437 pb->bits_left = 0;
1440 /* Figure F.12: extend sign bit. */
1441 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1443 static const int extend_test[16] = /* entry n is 2**(n-1) */
1445 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1446 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1449 static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
1451 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1452 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1453 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1454 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1457 /* Decode a single value */
1458 INLINE int huff_decode_dc(struct bitstream* bs, struct derived_tbl* tbl)
1460 int nb, look, s, r;
1462 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1463 look = peek_bits(bs, HUFF_LOOKAHEAD);
1464 if ((nb = tbl->look_nbits[look]) != 0)
1466 drop_bits(bs, nb);
1467 s = tbl->look_sym[look];
1468 check_bit_buffer(bs, s);
1469 r = get_bits(bs, s);
1470 s = HUFF_EXTEND(r, s);
1472 else
1473 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1474 long code;
1475 nb=HUFF_LOOKAHEAD+1;
1476 check_bit_buffer(bs, nb);
1477 code = get_bits(bs, nb);
1478 while (code > tbl->maxcode[nb])
1480 code <<= 1;
1481 check_bit_buffer(bs, 1);
1482 code |= get_bits(bs, 1);
1483 nb++;
1485 if (nb > 16) /* error in Huffman */
1487 s=0; /* fake a zero, this is most safe */
1489 else
1491 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1492 check_bit_buffer(bs, s);
1493 r = get_bits(bs, s);
1494 s = HUFF_EXTEND(r, s);
1496 } /* end slow decode */
1497 return s;
1500 INLINE int huff_decode_ac(struct bitstream* bs, struct derived_tbl* tbl)
1502 int nb, look, s;
1504 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1505 look = peek_bits(bs, HUFF_LOOKAHEAD);
1506 if ((nb = tbl->look_nbits[look]) != 0)
1508 drop_bits(bs, nb);
1509 s = tbl->look_sym[look];
1511 else
1512 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1513 long code;
1514 nb=HUFF_LOOKAHEAD+1;
1515 check_bit_buffer(bs, nb);
1516 code = get_bits(bs, nb);
1517 while (code > tbl->maxcode[nb])
1519 code <<= 1;
1520 check_bit_buffer(bs, 1);
1521 code |= get_bits(bs, 1);
1522 nb++;
1524 if (nb > 16) /* error in Huffman */
1526 s=0; /* fake a zero, this is most safe */
1528 else
1530 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1532 } /* end slow decode */
1533 return s;
1537 #ifdef HAVE_LCD_COLOR
1539 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1540 /* Note: it keeps the original color subsampling, even if resized. */
1541 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1542 int downscale, void (*pf_progress)(int current, int total))
1544 struct bitstream bs; /* bitstream "object" */
1545 int block[64]; /* decoded DCT coefficients */
1547 int width, height;
1548 int skip_line[3]; /* bytes from one line to the next (skip_line) */
1549 int skip_strip[3], skip_mcu[3]; /* bytes to next DCT row / column */
1551 int i, x, y; /* loop counter */
1553 unsigned char* p_line[3] = {p_pixel[0], p_pixel[1], p_pixel[2]};
1554 unsigned char* p_byte[3]; /* bitmap pointer */
1556 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1557 int k_need; /* AC coefficients needed up to here */
1558 int zero_need; /* init the block with this many zeros */
1560 int last_dc_val[3] = {0, 0, 0}; /* or 128 for chroma? */
1561 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1562 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1564 /* pick the IDCT we want, determine how to work with coefs */
1565 if (downscale == 1)
1567 pf_idct = idct8x8;
1568 k_need = 64; /* all */
1569 zero_need = 63; /* all */
1571 else if (downscale == 2)
1573 pf_idct = idct4x4;
1574 k_need = 25; /* this far in zig-zag to cover 4*4 */
1575 zero_need = 27; /* clear this far in linear order */
1577 else if (downscale == 4)
1579 pf_idct = idct2x2;
1580 k_need = 5; /* this far in zig-zag to cover 2*2 */
1581 zero_need = 9; /* clear this far in linear order */
1583 else if (downscale == 8)
1585 pf_idct = idct1x1;
1586 k_need = 0; /* no AC, not needed */
1587 zero_need = 0; /* no AC, not needed */
1589 else return -1; /* not supported */
1591 /* init bitstream, fake a restart to make it start */
1592 bs.next_input_byte = p_jpeg->p_entropy_data;
1593 bs.bits_left = 0;
1594 bs.input_end = p_jpeg->p_entropy_end;
1596 width = p_jpeg->x_phys / downscale;
1597 height = p_jpeg->y_phys / downscale;
1598 for (i=0; i<3; i++) /* calculate some strides */
1600 skip_line[i] = width / p_jpeg->subsample_x[i];
1601 skip_strip[i] = skip_line[i]
1602 * (height / p_jpeg->y_mbl) / p_jpeg->subsample_y[i];
1603 skip_mcu[i] = width/p_jpeg->x_mbl / p_jpeg->subsample_x[i];
1606 /* prepare offsets about where to store the different blocks */
1607 store_offs[p_jpeg->store_pos[0]] = 0;
1608 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1609 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1610 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1612 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1614 for (i=0; i<3; i++) /* scan line init */
1616 p_byte[i] = p_line[i];
1617 p_line[i] += skip_strip[i];
1619 for (x=0; x<p_jpeg->x_mbl; x++)
1621 int blkn;
1623 /* Outer loop handles each block in the MCU */
1624 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1625 { /* Decode a single block's worth of coefficients */
1626 int k = 1; /* coefficient index */
1627 int s, r; /* huffman values */
1628 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1629 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1630 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1631 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1633 /* Section F.2.2.1: decode the DC coefficient difference */
1634 s = huff_decode_dc(&bs, dctbl);
1636 last_dc_val[ci] += s;
1637 block[0] = last_dc_val[ci]; /* output it (assumes zag[0] = 0) */
1639 /* coefficient buffer must be cleared */
1640 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1642 /* Section F.2.2.2: decode the AC coefficients */
1643 for (; k < k_need; k++)
1645 s = huff_decode_ac(&bs, actbl);
1646 r = s >> 4;
1647 s &= 15;
1649 if (s)
1651 k += r;
1652 check_bit_buffer(&bs, s);
1653 r = get_bits(&bs, s);
1654 block[zag[k]] = HUFF_EXTEND(r, s);
1656 else
1658 if (r != 15)
1660 k = 64;
1661 break;
1663 k += r;
1665 } /* for k */
1666 /* In this path we just discard the values */
1667 for (; k < 64; k++)
1669 s = huff_decode_ac(&bs, actbl);
1670 r = s >> 4;
1671 s &= 15;
1673 if (s)
1675 k += r;
1676 check_bit_buffer(&bs, s);
1677 drop_bits(&bs, s);
1679 else
1681 if (r != 15)
1682 break;
1683 k += r;
1685 } /* for k */
1687 if (ci == 0)
1688 { /* Y component needs to bother about block store */
1689 pf_idct(p_byte[0]+store_offs[blkn], block,
1690 p_jpeg->qt_idct[ti], skip_line[0]);
1692 else
1693 { /* chroma */
1694 pf_idct(p_byte[ci], block, p_jpeg->qt_idct[ti],
1695 skip_line[ci]);
1697 } /* for blkn */
1698 p_byte[0] += skip_mcu[0]; /* unrolled for (i=0; i<3; i++) loop */
1699 p_byte[1] += skip_mcu[1];
1700 p_byte[2] += skip_mcu[2];
1701 if (p_jpeg->restart_interval && --restart == 0)
1702 { /* if a restart marker is due: */
1703 restart = p_jpeg->restart_interval; /* count again */
1704 search_restart(&bs); /* align the bitstream */
1705 last_dc_val[0] = last_dc_val[1] =
1706 last_dc_val[2] = 0; /* reset decoder */
1708 } /* for x */
1709 if (pf_progress != NULL)
1710 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1711 } /* for y */
1713 return 0; /* success */
1715 #else /* !HAVE_LCD_COLOR */
1717 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1718 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[1], int downscale,
1719 void (*pf_progress)(int current, int total))
1721 struct bitstream bs; /* bitstream "object" */
1722 int block[64]; /* decoded DCT coefficients */
1724 int width, height;
1725 int skip_line; /* bytes from one line to the next (skip_line) */
1726 int skip_strip, skip_mcu; /* bytes to next DCT row / column */
1728 int x, y; /* loop counter */
1730 unsigned char* p_line = p_pixel[0];
1731 unsigned char* p_byte; /* bitmap pointer */
1733 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1734 int k_need; /* AC coefficients needed up to here */
1735 int zero_need; /* init the block with this many zeros */
1737 int last_dc_val = 0;
1738 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1739 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1741 /* pick the IDCT we want, determine how to work with coefs */
1742 if (downscale == 1)
1744 pf_idct = idct8x8;
1745 k_need = 64; /* all */
1746 zero_need = 63; /* all */
1748 else if (downscale == 2)
1750 pf_idct = idct4x4;
1751 k_need = 25; /* this far in zig-zag to cover 4*4 */
1752 zero_need = 27; /* clear this far in linear order */
1754 else if (downscale == 4)
1756 pf_idct = idct2x2;
1757 k_need = 5; /* this far in zig-zag to cover 2*2 */
1758 zero_need = 9; /* clear this far in linear order */
1760 else if (downscale == 8)
1762 pf_idct = idct1x1;
1763 k_need = 0; /* no AC, not needed */
1764 zero_need = 0; /* no AC, not needed */
1766 else return -1; /* not supported */
1768 /* init bitstream, fake a restart to make it start */
1769 bs.next_input_byte = p_jpeg->p_entropy_data;
1770 bs.bits_left = 0;
1771 bs.input_end = p_jpeg->p_entropy_end;
1773 width = p_jpeg->x_phys / downscale;
1774 height = p_jpeg->y_phys / downscale;
1775 skip_line = width;
1776 skip_strip = skip_line * (height / p_jpeg->y_mbl);
1777 skip_mcu = (width/p_jpeg->x_mbl);
1779 /* prepare offsets about where to store the different blocks */
1780 store_offs[p_jpeg->store_pos[0]] = 0;
1781 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1782 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1783 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1785 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1787 p_byte = p_line;
1788 p_line += skip_strip;
1789 for (x=0; x<p_jpeg->x_mbl; x++)
1791 int blkn;
1793 /* Outer loop handles each block in the MCU */
1794 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1795 { /* Decode a single block's worth of coefficients */
1796 int k = 1; /* coefficient index */
1797 int s, r; /* huffman values */
1798 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1799 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1800 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1801 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1803 /* Section F.2.2.1: decode the DC coefficient difference */
1804 s = huff_decode_dc(&bs, dctbl);
1806 if (ci == 0) /* only for Y component */
1808 last_dc_val += s;
1809 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
1811 /* coefficient buffer must be cleared */
1812 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1814 /* Section F.2.2.2: decode the AC coefficients */
1815 for (; k < k_need; k++)
1817 s = huff_decode_ac(&bs, actbl);
1818 r = s >> 4;
1819 s &= 15;
1821 if (s)
1823 k += r;
1824 check_bit_buffer(&bs, s);
1825 r = get_bits(&bs, s);
1826 block[zag[k]] = HUFF_EXTEND(r, s);
1828 else
1830 if (r != 15)
1832 k = 64;
1833 break;
1835 k += r;
1837 } /* for k */
1839 /* In this path we just discard the values */
1840 for (; k < 64; k++)
1842 s = huff_decode_ac(&bs, actbl);
1843 r = s >> 4;
1844 s &= 15;
1846 if (s)
1848 k += r;
1849 check_bit_buffer(&bs, s);
1850 drop_bits(&bs, s);
1852 else
1854 if (r != 15)
1855 break;
1856 k += r;
1858 } /* for k */
1860 if (ci == 0)
1861 { /* only for Y component */
1862 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
1863 skip_line);
1865 } /* for blkn */
1866 p_byte += skip_mcu;
1867 if (p_jpeg->restart_interval && --restart == 0)
1868 { /* if a restart marker is due: */
1869 restart = p_jpeg->restart_interval; /* count again */
1870 search_restart(&bs); /* align the bitstream */
1871 last_dc_val = 0; /* reset decoder */
1873 } /* for x */
1874 if (pf_progress != NULL)
1875 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1876 } /* for y */
1878 return 0; /* success */
1880 #endif /* !HAVE_LCD_COLOR */
1882 /**************** end JPEG code ********************/
1886 /**************** begin Application ********************/
1889 /************************* Types ***************************/
1891 struct t_disp
1893 #ifdef HAVE_LCD_COLOR
1894 unsigned char* bitmap[3]; /* Y, Cr, Cb */
1895 int csub_x, csub_y;
1896 #else
1897 unsigned char* bitmap[1]; /* Y only */
1898 #endif
1899 int width;
1900 int height;
1901 int stride;
1902 int x, y;
1905 /************************* Globals ***************************/
1907 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1908 struct t_disp disp[9];
1910 /* my memory pool (from the mp3 buffer) */
1911 char print[32]; /* use a common snprintf() buffer */
1912 unsigned char* buf; /* up to here currently used by image(s) */
1914 /* the remaining free part of the buffer for compressed+uncompressed images */
1915 unsigned char* buf_images;
1917 ssize_t buf_size, buf_images_size;
1918 /* the root of the images, hereafter are decompresed ones */
1919 unsigned char* buf_root;
1920 int root_size;
1922 int ds, ds_min, ds_max; /* downscaling and limits */
1923 static struct jpeg jpg; /* too large for stack */
1925 static struct tree_context *tree;
1927 /* the current full file name */
1928 static char np_file[MAX_PATH];
1929 int curfile = 0, direction = DIR_NONE, entries = 0;
1931 /* list of the jpeg files */
1932 char **file_pt;
1933 /* are we using the plugin buffer or the audio buffer? */
1934 bool plug_buf = false;
1937 /************************* Implementation ***************************/
1939 #ifdef HAVE_LCD_COLOR
1941 * Conversion of full 0-255 range YCrCb to RGB:
1942 * |R| |1.000000 -0.000001 1.402000| |Y'|
1943 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
1944 * |B| |1.000000 1.772000 0.000000| |Pr|
1945 * Scaled (yields s15-bit output):
1946 * |R| |128 0 179| |Y |
1947 * |G| = |128 -43 -91| |Cb - 128|
1948 * |B| |128 227 0| |Cr - 128|
1950 #define YFAC 128
1951 #define RVFAC 179
1952 #define GUFAC (-43)
1953 #define GVFAC (-91)
1954 #define BUFAC 227
1955 #define YUV_WHITE (255*YFAC)
1956 #define NODITHER_DELTA (127*YFAC)
1957 #define COMPONENT_SHIFT 15
1958 #define MATRIX_SHIFT 7
1960 static inline int clamp_component(int x)
1962 if ((unsigned)x > YUV_WHITE)
1963 x = x < 0 ? 0 : YUV_WHITE;
1964 return x;
1967 static inline int clamp_component_bits(int x, int bits)
1969 if ((unsigned)x > (1u << bits) - 1)
1970 x = x < 0 ? 0 : (1 << bits) - 1;
1971 return x;
1974 static inline int component_to_lcd(int x, int bits, int delta)
1976 /* Formula used in core bitmap loader. */
1977 return (((1 << bits) - 1)*x + (x >> (8 - bits)) + delta) >> COMPONENT_SHIFT;
1980 static inline int lcd_to_component(int x, int bits, int delta)
1982 /* Reasonable, approximate reversal to get a full range back from the
1983 quantized value. */
1984 return YUV_WHITE*x / ((1 << bits) - 1);
1985 (void)delta;
1988 #define RED 0
1989 #define GRN 1
1990 #define BLU 2
1992 struct rgb_err
1994 int16_t errbuf[LCD_WIDTH+2]; /* Error record for line below */
1995 } rgb_err_buffers[3];
1997 fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
1998 DITHER_DIFFUSION is set */
2000 struct rgb_pixel
2002 int r, g, b; /* Current pixel components in s16.0 */
2003 int inc; /* Current line increment (-1 or 1) */
2004 int row; /* Current row in source image */
2005 int col; /* Current column in source image */
2006 int ce[3]; /* Errors to apply to current pixel */
2007 struct rgb_err *e; /* RED, GRN, BLU */
2008 int epos; /* Current position in error record */
2011 struct rgb_pixel *pixel;
2013 /** round and truncate to lcd depth **/
2014 static fb_data pixel_to_lcd_colour(void)
2016 struct rgb_pixel *p = pixel;
2017 int r, g, b;
2019 r = component_to_lcd(p->r, LCD_RED_BITS, NODITHER_DELTA);
2020 r = clamp_component_bits(r, LCD_RED_BITS);
2022 g = component_to_lcd(p->g, LCD_GREEN_BITS, NODITHER_DELTA);
2023 g = clamp_component_bits(g, LCD_GREEN_BITS);
2025 b = component_to_lcd(p->b, LCD_BLUE_BITS, NODITHER_DELTA);
2026 b = clamp_component_bits(b, LCD_BLUE_BITS);
2028 return LCD_RGBPACK_LCD(r, g, b);
2031 /** write a monochrome pixel to the colour LCD **/
2032 static fb_data pixel_to_lcd_gray(void)
2034 int r, g, b;
2036 g = clamp_component(pixel->g);
2037 r = component_to_lcd(g, LCD_RED_BITS, NODITHER_DELTA);
2038 b = component_to_lcd(g, LCD_BLUE_BITS, NODITHER_DELTA);
2039 g = component_to_lcd(g, LCD_GREEN_BITS, NODITHER_DELTA);
2041 return LCD_RGBPACK_LCD(r, g, b);
2045 * Bayer ordered dithering - swiped from the core bitmap loader.
2047 static fb_data pixel_odither_to_lcd(void)
2049 /* canonical ordered dither matrix */
2050 static const unsigned char dither_matrix[16][16] = {
2051 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
2052 { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
2053 { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
2054 { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
2055 { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
2056 { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
2057 { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
2058 { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
2059 { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
2060 { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
2061 { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
2062 { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
2063 { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
2064 { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
2065 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
2066 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
2069 struct rgb_pixel *p = pixel;
2070 int r, g, b, delta;
2072 delta = dither_matrix[p->col & 15][p->row & 15] << MATRIX_SHIFT;
2074 r = component_to_lcd(p->r, LCD_RED_BITS, delta);
2075 r = clamp_component_bits(r, LCD_RED_BITS);
2077 g = component_to_lcd(p->g, LCD_GREEN_BITS, delta);
2078 g = clamp_component_bits(g, LCD_GREEN_BITS);
2080 b = component_to_lcd(p->b, LCD_BLUE_BITS, delta);
2081 b = clamp_component_bits(b, LCD_BLUE_BITS);
2083 p->col += p->inc;
2085 return LCD_RGBPACK_LCD(r, g, b);
2089 * Floyd/Steinberg dither to lcd depth.
2091 * Apply filter to each component in serpentine pattern. Kernel shown for
2092 * L->R scan. Kernel is reversed for R->L.
2093 * * 7
2094 * 3 5 1 (1/16)
2096 static inline void distribute_error(int *ce, struct rgb_err *e,
2097 int err, int epos, int inc)
2099 *ce = (7*err >> 4) + e->errbuf[epos+inc];
2100 e->errbuf[epos+inc] = err >> 4;
2101 e->errbuf[epos] += 5*err >> 4;
2102 e->errbuf[epos-inc] += 3*err >> 4;
2105 static fb_data pixel_fsdither_to_lcd(void)
2107 struct rgb_pixel *p = pixel;
2108 int rc, gc, bc, r, g, b;
2109 int inc, epos;
2111 /* Full components with error terms */
2112 rc = p->r + p->ce[RED];
2113 r = component_to_lcd(rc, LCD_RED_BITS, 0);
2114 r = clamp_component_bits(r, LCD_RED_BITS);
2116 gc = p->g + p->ce[GRN];
2117 g = component_to_lcd(gc, LCD_GREEN_BITS, 0);
2118 g = clamp_component_bits(g, LCD_GREEN_BITS);
2120 bc = p->b + p->ce[BLU];
2121 b = component_to_lcd(bc, LCD_BLUE_BITS, 0);
2122 b = clamp_component_bits(b, LCD_BLUE_BITS);
2124 /* Get pixel errors */
2125 rc -= lcd_to_component(r, LCD_RED_BITS, 0);
2126 gc -= lcd_to_component(g, LCD_GREEN_BITS, 0);
2127 bc -= lcd_to_component(b, LCD_BLUE_BITS, 0);
2129 /* Spead error to surrounding pixels. */
2130 inc = p->inc;
2131 epos = p->epos;
2132 p->epos += inc;
2134 distribute_error(&p->ce[RED], &p->e[RED], rc, epos, inc);
2135 distribute_error(&p->ce[GRN], &p->e[GRN], gc, epos, inc);
2136 distribute_error(&p->ce[BLU], &p->e[BLU], bc, epos, inc);
2138 /* Pack and return pixel */
2139 return LCD_RGBPACK_LCD(r, g, b);
2142 /* Functions for each output mode, colour then grayscale. */
2143 static fb_data (* const pixel_funcs[COLOUR_NUM_MODES][DITHER_NUM_MODES])(void) =
2145 [COLOURMODE_COLOUR] =
2147 [DITHER_NONE] = pixel_to_lcd_colour,
2148 [DITHER_ORDERED] = pixel_odither_to_lcd,
2149 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2151 [COLOURMODE_GRAY] =
2153 [DITHER_NONE] = pixel_to_lcd_gray,
2154 [DITHER_ORDERED] = pixel_odither_to_lcd,
2155 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2160 * Draw a partial YUV colour bitmap
2162 * Runs serpentine pattern when dithering is DITHER_DIFFUSION, else scan is
2163 * always L->R.
2165 void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
2166 int src_x, int src_y, int stride,
2167 int x, int y, int width, int height)
2169 fb_data *dst, *dst_end;
2170 fb_data (*pixel_func)(void);
2171 struct rgb_pixel px;
2173 if (x + width > LCD_WIDTH)
2174 width = LCD_WIDTH - x; /* Clip right */
2175 if (x < 0)
2176 width += x, x = 0; /* Clip left */
2177 if (width <= 0)
2178 return; /* nothing left to do */
2180 if (y + height > LCD_HEIGHT)
2181 height = LCD_HEIGHT - y; /* Clip bottom */
2182 if (y < 0)
2183 height += y, y = 0; /* Clip top */
2184 if (height <= 0)
2185 return; /* nothing left to do */
2187 pixel = &px;
2189 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
2190 dst_end = dst + LCD_WIDTH * height;
2192 if (jpeg_settings.colour_mode == COLOURMODE_GRAY)
2193 csub_y = 0; /* Ignore Cb, Cr */
2195 pixel_func = pixel_funcs[jpeg_settings.colour_mode]
2196 [jpeg_settings.dither_mode];
2198 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2200 /* Reset error terms. */
2201 px.e = rgb_err_buffers;
2202 px.ce[RED] = px.ce[GRN] = px.ce[BLU] = 0;
2203 rb->memset(px.e, 0, 3*sizeof (struct rgb_err));
2208 fb_data *dst_row, *row_end;
2209 const unsigned char *ysrc;
2210 px.inc = 1;
2212 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2214 /* Use R->L scan on odd lines */
2215 px.inc -= (src_y & 1) << 1;
2216 px.epos = x + 1;
2218 if (px.inc < 0)
2219 px.epos += width - 1;
2222 if (px.inc == 1)
2224 /* Scan is L->R */
2225 dst_row = dst;
2226 row_end = dst_row + width;
2227 px.col = src_x;
2229 else
2231 /* Scan is R->L */
2232 row_end = dst - 1;
2233 dst_row = row_end + width;
2234 px.col = src_x + width - 1;
2237 ysrc = src[0] + stride * src_y + px.col;
2238 px.row = src_y;
2240 /* Do one row of pixels */
2241 if (csub_y) /* colour */
2243 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
2244 const unsigned char *usrc, *vsrc;
2246 usrc = src[1] + (stride/csub_x) * (src_y/csub_y)
2247 + (px.col/csub_x);
2248 vsrc = src[2] + (stride/csub_x) * (src_y/csub_y)
2249 + (px.col/csub_x);
2250 int xphase = px.col % csub_x;
2251 int xphase_reset = px.inc * csub_x;
2252 int y, v, u, rv, guv, bu;
2254 v = *vsrc - 128;
2255 vsrc += px.inc;
2256 u = *usrc - 128;
2257 usrc += px.inc;
2258 rv = RVFAC*v;
2259 guv = GUFAC*u + GVFAC*v;
2260 bu = BUFAC*u;
2262 while (1)
2264 y = YFAC*(*ysrc);
2265 ysrc += px.inc;
2266 px.r = y + rv;
2267 px.g = y + guv;
2268 px.b = y + bu;
2270 *dst_row = pixel_func();
2271 dst_row += px.inc;
2273 if (dst_row == row_end)
2274 break;
2276 xphase += px.inc;
2277 if ((unsigned)xphase < (unsigned)csub_x)
2278 continue;
2280 /* fetch new chromas */
2281 v = *vsrc - 128;
2282 vsrc += px.inc;
2283 u = *usrc - 128;
2284 usrc += px.inc;
2285 rv = RVFAC*v;
2286 guv = GUFAC*u + GVFAC*v;
2287 bu = BUFAC*u;
2289 xphase -= xphase_reset;
2292 else /* monochrome */
2296 /* Set all components the same for dithering purposes */
2297 px.g = px.r = px.b = YFAC*(*ysrc);
2298 *dst_row = pixel_func();
2299 ysrc += px.inc;
2300 dst_row += px.inc;
2302 while (dst_row != row_end);
2305 src_y++;
2306 dst += LCD_WIDTH;
2308 while (dst < dst_end);
2311 #endif /* HAVE_LCD_COLOR */
2314 /* support function for qsort() */
2315 static int compare(const void* p1, const void* p2)
2317 return rb->strcasecmp(*((char **)p1), *((char **)p2));
2320 bool jpg_ext(const char ext[])
2322 if(!ext)
2323 return false;
2324 if(!rb->strcasecmp(ext,".jpg") ||
2325 !rb->strcasecmp(ext,".jpe") ||
2326 !rb->strcasecmp(ext,".jpeg"))
2327 return true;
2328 else
2329 return false;
2332 /*Read directory contents for scrolling. */
2333 void get_pic_list(void)
2335 int i;
2336 long int str_len = 0;
2337 char *pname;
2338 tree = rb->tree_get_context();
2340 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2341 file_pt = rb->plugin_get_buffer((size_t *)&buf_size);
2342 #else
2343 file_pt = rb->plugin_get_audio_buffer((size_t *)&buf_size);
2344 #endif
2346 for(i = 0; i < tree->filesindir; i++)
2348 if(jpg_ext(rb->strrchr(&tree->name_buffer[str_len],'.')))
2349 file_pt[entries++] = &tree->name_buffer[str_len];
2351 str_len += rb->strlen(&tree->name_buffer[str_len]) + 1;
2354 rb->qsort(file_pt, entries, sizeof(char**), compare);
2356 /* Remove path and leave only the name.*/
2357 pname = rb->strrchr(np_file,'/');
2358 pname++;
2360 /* Find Selected File. */
2361 for(i = 0; i < entries; i++)
2362 if(!rb->strcmp(file_pt[i], pname))
2363 curfile = i;
2366 int change_filename(int direct)
2368 int count = 0;
2369 direction = direct;
2371 if(direct == DIR_PREV)
2375 count++;
2376 if(curfile == 0)
2377 curfile = entries - 1;
2378 else
2379 curfile--;
2380 }while(file_pt[curfile] == '\0' && count < entries);
2381 /* we "erase" the file name if we encounter
2382 * a non-supported file, so skip it now */
2384 else /* DIR_NEXT/DIR_NONE */
2388 count++;
2389 if(curfile == entries - 1)
2390 curfile = 0;
2391 else
2392 curfile++;
2393 }while(file_pt[curfile] == '\0' && count < entries);
2396 if(count == entries && file_pt[curfile] == '\0')
2398 rb->splash(HZ, "No supported files");
2399 return PLUGIN_ERROR;
2401 if(rb->strlen(tree->currdir) > 1)
2403 rb->strcpy(np_file, tree->currdir);
2404 rb->strcat(np_file, "/");
2406 else
2407 rb->strcpy(np_file, tree->currdir);
2409 rb->strcat(np_file, file_pt[curfile]);
2411 return PLUGIN_OTHER;
2414 /* switch off overlay, for handling SYS_ events */
2415 void cleanup(void *parameter)
2417 (void)parameter;
2418 #ifdef USEGSLIB
2419 grey_show(false);
2420 #endif
2423 #define VSCROLL (LCD_HEIGHT/8)
2424 #define HSCROLL (LCD_WIDTH/10)
2426 #define ZOOM_IN 100 /* return codes for below function */
2427 #define ZOOM_OUT 101
2429 #ifdef HAVE_LCD_COLOR
2430 bool set_option_grayscale(void)
2432 bool gray = jpeg_settings.colour_mode == COLOURMODE_GRAY;
2433 rb->set_bool("Grayscale", &gray);
2434 jpeg_settings.colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
2435 return false;
2438 bool set_option_dithering(void)
2440 static const struct opt_items dithering[DITHER_NUM_MODES] = {
2441 [DITHER_NONE] = { "Off", -1 },
2442 [DITHER_ORDERED] = { "Ordered", -1 },
2443 [DITHER_DIFFUSION] = { "Diffusion", -1 },
2446 rb->set_option("Dithering", &jpeg_settings.dither_mode, INT,
2447 dithering, DITHER_NUM_MODES, NULL);
2448 return false;
2451 static void display_options(void)
2453 static const struct menu_item items[] = {
2454 { "Grayscale", set_option_grayscale },
2455 { "Dithering", set_option_dithering },
2458 int m = menu_init(rb, items, ARRAYLEN(items),
2459 NULL, NULL, NULL, NULL);
2460 menu_run(m);
2461 menu_exit(m);
2463 #endif /* HAVE_LCD_COLOR */
2465 int show_menu(void) /* return 1 to quit */
2467 #if LCD_DEPTH > 1
2468 rb->lcd_set_backdrop(old_backdrop);
2469 #ifdef HAVE_LCD_COLOR
2470 rb->lcd_set_foreground(rb->global_settings->fg_color);
2471 rb->lcd_set_background(rb->global_settings->bg_color);
2472 #else
2473 rb->lcd_set_foreground(LCD_BLACK);
2474 rb->lcd_set_background(LCD_WHITE);
2475 #endif
2476 #endif
2477 int m;
2478 int result;
2480 enum menu_id
2482 MIID_QUIT = 0,
2483 MIID_TOGGLE_SS_MODE,
2484 MIID_CHANGE_SS_MODE,
2485 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2486 MIID_SHOW_PLAYBACK_MENU,
2487 #endif
2488 #ifdef HAVE_LCD_COLOR
2489 MIID_DISPLAY_OPTIONS,
2490 #endif
2491 MIID_RETURN,
2494 static const struct menu_item items[] = {
2495 [MIID_QUIT] =
2496 { "Quit", NULL },
2497 [MIID_TOGGLE_SS_MODE] =
2498 { "Toggle Slideshow Mode", NULL },
2499 [MIID_CHANGE_SS_MODE] =
2500 { "Change Slideshow Time", NULL },
2501 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2502 [MIID_SHOW_PLAYBACK_MENU] =
2503 { "Show Playback Menu", NULL },
2504 #endif
2505 #ifdef HAVE_LCD_COLOR
2506 [MIID_DISPLAY_OPTIONS] =
2507 { "Display Options", NULL },
2508 #endif
2509 [MIID_RETURN] =
2510 { "Return", NULL },
2513 static const struct opt_items slideshow[2] = {
2514 { "Disable", -1 },
2515 { "Enable", -1 },
2518 m = menu_init(rb, items, sizeof(items) / sizeof(*items),
2519 NULL, NULL, NULL, NULL);
2520 result=menu_show(m);
2522 switch (result)
2524 case MIID_QUIT:
2525 menu_exit(m);
2526 return 1;
2527 break;
2528 case MIID_TOGGLE_SS_MODE:
2529 rb->set_option("Toggle Slideshow", &slideshow_enabled, INT,
2530 slideshow , 2, NULL);
2531 break;
2532 case MIID_CHANGE_SS_MODE:
2533 rb->set_int("Slideshow Time", "s", UNIT_SEC,
2534 &jpeg_settings.ss_timeout, NULL, 1,
2535 SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, NULL);
2536 break;
2538 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2539 case MIID_SHOW_PLAYBACK_MENU:
2540 playback_control(rb);
2541 break;
2542 #endif
2543 #ifdef HAVE_LCD_COLOR
2544 case MIID_DISPLAY_OPTIONS:
2545 display_options();
2546 break;
2547 #endif
2548 case MIID_RETURN:
2549 break;
2552 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
2553 /* change ata spindown time based on slideshow time setting */
2554 immediate_ata_off = false;
2555 rb->ata_spindown(rb->global_settings->disk_spindown);
2557 if (slideshow_enabled)
2559 if(jpeg_settings.ss_timeout < 10)
2561 /* slideshow times < 10s keep disk spinning */
2562 rb->ata_spindown(0);
2564 else if (!rb->mp3_is_playing())
2566 /* slideshow times > 10s and not playing: ata_off after load */
2567 immediate_ata_off = true;
2570 #endif
2571 #if LCD_DEPTH > 1
2572 rb->lcd_set_backdrop(NULL);
2573 rb->lcd_set_foreground(LCD_WHITE);
2574 rb->lcd_set_background(LCD_BLACK);
2575 #endif
2576 rb->lcd_clear_display();
2577 menu_exit(m);
2578 return 0;
2580 /* interactively scroll around the image */
2581 int scroll_bmp(struct t_disp* pdisp)
2583 int lastbutton = 0;
2585 while (true)
2587 int button;
2588 int move;
2590 if (slideshow_enabled)
2591 button = rb->button_get_w_tmo(jpeg_settings.ss_timeout * HZ);
2592 else button = rb->button_get(true);
2594 running_slideshow = false;
2596 switch(button)
2598 case JPEG_LEFT:
2599 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2600 return change_filename(DIR_PREV);
2601 case JPEG_LEFT | BUTTON_REPEAT:
2602 move = MIN(HSCROLL, pdisp->x);
2603 if (move > 0)
2605 MYXLCD(scroll_right)(move); /* scroll right */
2606 pdisp->x -= move;
2607 #ifdef HAVE_LCD_COLOR
2608 yuv_bitmap_part(
2609 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2610 pdisp->x, pdisp->y, pdisp->stride,
2611 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2612 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2613 #else
2614 MYXLCD(gray_bitmap_part)(
2615 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2616 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2617 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2618 #endif
2619 MYLCD_UPDATE();
2621 break;
2623 case JPEG_RIGHT:
2624 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2625 return change_filename(DIR_NEXT);
2626 case JPEG_RIGHT | BUTTON_REPEAT:
2627 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
2628 if (move > 0)
2630 MYXLCD(scroll_left)(move); /* scroll left */
2631 pdisp->x += move;
2632 #ifdef HAVE_LCD_COLOR
2633 yuv_bitmap_part(
2634 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2635 pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride,
2636 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2637 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2638 #else
2639 MYXLCD(gray_bitmap_part)(
2640 pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move,
2641 pdisp->y, pdisp->stride,
2642 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2643 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2644 #endif
2645 MYLCD_UPDATE();
2647 break;
2649 case JPEG_UP:
2650 case JPEG_UP | BUTTON_REPEAT:
2651 move = MIN(VSCROLL, pdisp->y);
2652 if (move > 0)
2654 MYXLCD(scroll_down)(move); /* scroll down */
2655 pdisp->y -= move;
2656 #ifdef HAVE_LCD_COLOR
2657 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2659 /* Draw over the band at the top of the last update
2660 caused by lack of error history on line zero. */
2661 move = MIN(move + 1, pdisp->y + pdisp->height);
2664 yuv_bitmap_part(
2665 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2666 pdisp->x, pdisp->y, pdisp->stride,
2667 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2668 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2669 #else
2670 MYXLCD(gray_bitmap_part)(
2671 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2672 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2673 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2674 #endif
2675 MYLCD_UPDATE();
2677 break;
2679 case JPEG_DOWN:
2680 case JPEG_DOWN | BUTTON_REPEAT:
2681 move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT);
2682 if (move > 0)
2684 MYXLCD(scroll_up)(move); /* scroll up */
2685 pdisp->y += move;
2686 #ifdef HAVE_LCD_COLOR
2687 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2689 /* Save the line that was on the last line of the display
2690 and draw one extra line above then recover the line with
2691 image data that had an error history when it was drawn.
2693 move++, pdisp->y--;
2694 MEMCPY(rgb_linebuf,
2695 rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2696 LCD_WIDTH*sizeof (fb_data));
2699 yuv_bitmap_part(
2700 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x,
2701 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2702 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2703 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2705 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2707 /* Cover the first row drawn with previous image data. */
2708 MEMCPY(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2709 rgb_linebuf,
2710 LCD_WIDTH*sizeof (fb_data));
2711 pdisp->y++;
2713 #else
2714 MYXLCD(gray_bitmap_part)(
2715 pdisp->bitmap[0], pdisp->x,
2716 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2717 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2718 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2719 #endif
2720 MYLCD_UPDATE();
2722 break;
2723 case BUTTON_NONE:
2724 if (!slideshow_enabled)
2725 break;
2726 running_slideshow = true;
2727 if (entries > 0)
2728 return change_filename(DIR_NEXT);
2729 break;
2731 #ifdef JPEG_SLIDE_SHOW
2732 case JPEG_SLIDE_SHOW:
2733 slideshow_enabled = !slideshow_enabled;
2734 running_slideshow = slideshow_enabled;
2735 break;
2736 #endif
2738 #ifdef JPEG_NEXT_REPEAT
2739 case JPEG_NEXT_REPEAT:
2740 #endif
2741 case JPEG_NEXT:
2742 if (entries > 0)
2743 return change_filename(DIR_NEXT);
2744 break;
2746 #ifdef JPEG_PREVIOUS_REPEAT
2747 case JPEG_PREVIOUS_REPEAT:
2748 #endif
2749 case JPEG_PREVIOUS:
2750 if (entries > 0)
2751 return change_filename(DIR_PREV);
2752 break;
2754 case JPEG_ZOOM_IN:
2755 #ifdef JPEG_ZOOM_PRE
2756 if (lastbutton != JPEG_ZOOM_PRE)
2757 break;
2758 #endif
2759 return ZOOM_IN;
2760 break;
2762 case JPEG_ZOOM_OUT:
2763 #ifdef JPEG_ZOOM_PRE
2764 if (lastbutton != JPEG_ZOOM_PRE)
2765 break;
2766 #endif
2767 return ZOOM_OUT;
2768 break;
2769 #ifdef JPEG_RC_MENU
2770 case JPEG_RC_MENU:
2771 #endif
2772 case JPEG_MENU:
2773 #ifdef USEGSLIB
2774 grey_show(false); /* switch off greyscale overlay */
2775 #endif
2776 if (show_menu() == 1)
2777 return PLUGIN_OK;
2779 #ifdef USEGSLIB
2780 grey_show(true); /* switch on greyscale overlay */
2781 #else
2782 yuv_bitmap_part(
2783 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2784 pdisp->x, pdisp->y, pdisp->stride,
2785 MAX(0, (LCD_WIDTH - pdisp->width) / 2),
2786 MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
2787 MIN(LCD_WIDTH, pdisp->width),
2788 MIN(LCD_HEIGHT, pdisp->height));
2789 MYLCD_UPDATE();
2790 #endif
2791 break;
2792 default:
2793 if (rb->default_event_handler_ex(button, cleanup, NULL)
2794 == SYS_USB_CONNECTED)
2795 return PLUGIN_USB_CONNECTED;
2796 break;
2798 } /* switch */
2800 if (button != BUTTON_NONE)
2801 lastbutton = button;
2802 } /* while (true) */
2805 /********************* main function *************************/
2807 /* callback updating a progress meter while JPEG decoding */
2808 void cb_progess(int current, int total)
2810 rb->yield(); /* be nice to the other threads */
2811 if(!running_slideshow)
2813 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-8, LCD_WIDTH, 8, total, 0,
2814 current, HORIZONTAL);
2815 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
2817 #ifndef USEGSLIB
2818 else
2820 /* in slideshow mode, keep gui interference to a minimum */
2821 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-4, LCD_WIDTH, 4, total, 0,
2822 current, HORIZONTAL);
2823 rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4);
2825 #endif
2828 int jpegmem(struct jpeg *p_jpg, int ds)
2830 int size;
2832 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
2833 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
2834 #ifdef HAVE_LCD_COLOR
2835 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
2837 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
2838 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
2839 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
2840 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
2842 #endif
2843 return size;
2846 /* how far can we zoom in without running out of memory */
2847 int min_downscale(struct jpeg *p_jpg, int bufsize)
2849 int downscale = 8;
2851 if (jpegmem(p_jpg, 8) > bufsize)
2852 return 0; /* error, too large, even 1:8 doesn't fit */
2854 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
2855 downscale /= 2;
2857 return downscale;
2861 /* how far can we zoom out, to fit image into the LCD */
2862 int max_downscale(struct jpeg *p_jpg)
2864 int downscale = 1;
2866 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale
2867 || p_jpg->y_size > LCD_HEIGHT*downscale))
2869 downscale *= 2;
2872 return downscale;
2876 /* return decoded or cached image */
2877 struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2879 int w, h; /* used to center output */
2880 int size; /* decompressed image size */
2881 long time; /* measured ticks */
2882 int status;
2884 struct t_disp* p_disp = &disp[ds]; /* short cut */
2886 if (p_disp->bitmap[0] != NULL)
2888 return p_disp; /* we still have it */
2891 /* assign image buffer */
2893 /* physical size needed for decoding */
2894 size = jpegmem(p_jpg, ds);
2895 if (buf_size <= size)
2896 { /* have to discard the current */
2897 int i;
2898 for (i=1; i<=8; i++)
2899 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
2900 buf = buf_root; /* start again from the beginning of the buffer */
2901 buf_size = root_size;
2904 #ifdef HAVE_LCD_COLOR
2905 if (p_jpg->blocks > 1) /* colour jpeg */
2907 int i;
2909 for (i = 1; i < 3; i++)
2911 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
2912 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
2913 p_disp->bitmap[i] = buf;
2914 buf += size;
2915 buf_size -= size;
2917 p_disp->csub_x = p_jpg->subsample_x[1];
2918 p_disp->csub_y = p_jpg->subsample_y[1];
2920 else
2922 p_disp->csub_x = p_disp->csub_y = 0;
2923 p_disp->bitmap[1] = p_disp->bitmap[2] = buf;
2925 #endif
2926 /* size may be less when decoded (if height is not block aligned) */
2927 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
2928 p_disp->bitmap[0] = buf;
2929 buf += size;
2930 buf_size -= size;
2932 if(!running_slideshow)
2934 rb->snprintf(print, sizeof(print), "decoding %d*%d",
2935 p_jpg->x_size/ds, p_jpg->y_size/ds);
2936 rb->lcd_puts(0, 3, print);
2937 rb->lcd_update();
2940 /* update image properties */
2941 p_disp->width = p_jpg->x_size / ds;
2942 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
2943 p_disp->height = p_jpg->y_size / ds;
2945 /* the actual decoding */
2946 time = *rb->current_tick;
2947 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2948 rb->cpu_boost(true);
2949 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2950 rb->cpu_boost(false);
2951 #else
2952 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2953 #endif
2954 if (status)
2956 rb->splash(HZ, "decode error %d", status);
2957 file_pt[curfile] = '\0';
2958 return NULL;
2960 time = *rb->current_tick - time;
2962 if(!running_slideshow)
2964 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
2965 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
2966 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
2967 rb->lcd_update();
2970 return p_disp;
2974 /* set the view to the given center point, limit if necessary */
2975 void set_view (struct t_disp* p_disp, int cx, int cy)
2977 int x, y;
2979 /* plain center to available width/height */
2980 x = cx - MIN(LCD_WIDTH, p_disp->width) / 2;
2981 y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2;
2983 /* limit against upper image size */
2984 x = MIN(p_disp->width - LCD_WIDTH, x);
2985 y = MIN(p_disp->height - LCD_HEIGHT, y);
2987 /* limit against negative side */
2988 x = MAX(0, x);
2989 y = MAX(0, y);
2991 p_disp->x = x; /* set the values */
2992 p_disp->y = y;
2996 /* calculate the view center based on the bitmap position */
2997 void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
2999 *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2;
3000 *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2;
3004 /* load, decode, display the image */
3005 int load_and_show(char* filename)
3007 int fd;
3008 int filesize;
3009 unsigned char* buf_jpeg; /* compressed JPEG image */
3010 int status;
3011 struct t_disp* p_disp; /* currenly displayed image */
3012 int cx, cy; /* view center */
3014 fd = rb->open(filename, O_RDONLY);
3015 if (fd < 0)
3017 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
3018 rb->splash(HZ, print);
3019 return PLUGIN_ERROR;
3021 filesize = rb->filesize(fd);
3022 rb->memset(&disp, 0, sizeof(disp));
3024 buf = buf_images + filesize;
3025 buf_size = buf_images_size - filesize;
3026 /* allocate JPEG buffer */
3027 buf_jpeg = buf_images;
3029 buf_root = buf; /* we can start the decompressed images behind it */
3030 root_size = buf_size;
3032 if (buf_size <= 0)
3034 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
3035 if(plug_buf)
3037 rb->close(fd);
3038 rb->lcd_setfont(FONT_SYSFIXED);
3039 rb->lcd_clear_display();
3040 rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
3041 rb->lcd_puts(0,0,print);
3042 rb->lcd_puts(0,1,"Not enough plugin memory!");
3043 rb->lcd_puts(0,2,"Zoom In: Stop playback.");
3044 if(entries>1)
3045 rb->lcd_puts(0,3,"Left/Right: Skip File.");
3046 rb->lcd_puts(0,4,"Off: Quit.");
3047 rb->lcd_update();
3048 rb->lcd_setfont(FONT_UI);
3050 rb->button_clear_queue();
3052 while (1)
3054 int button = rb->button_get(true);
3055 switch(button)
3057 case JPEG_ZOOM_IN:
3058 plug_buf = false;
3059 buf_images = rb->plugin_get_audio_buffer(
3060 (size_t *)&buf_images_size);
3061 /*try again this file, now using the audio buffer */
3062 return PLUGIN_OTHER;
3063 #ifdef JPEG_RC_MENU
3064 case JPEG_RC_MENU:
3065 #endif
3066 case JPEG_MENU:
3067 return PLUGIN_OK;
3069 case JPEG_LEFT:
3070 if(entries>1)
3072 rb->lcd_clear_display();
3073 return change_filename(DIR_PREV);
3075 break;
3077 case JPEG_RIGHT:
3078 if(entries>1)
3080 rb->lcd_clear_display();
3081 return change_filename(DIR_NEXT);
3083 break;
3084 default:
3085 if(rb->default_event_handler_ex(button, cleanup, NULL)
3086 == SYS_USB_CONNECTED)
3087 return PLUGIN_USB_CONNECTED;
3092 else
3093 #endif
3095 rb->splash(HZ, "Out of Memory");
3096 rb->close(fd);
3097 return PLUGIN_ERROR;
3101 if(!running_slideshow)
3103 #if LCD_DEPTH > 1
3104 rb->lcd_set_foreground(LCD_WHITE);
3105 rb->lcd_set_background(LCD_BLACK);
3106 rb->lcd_set_backdrop(NULL);
3107 #endif
3109 rb->lcd_clear_display();
3110 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
3111 rb->lcd_puts(0, 0, print);
3112 rb->lcd_update();
3114 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
3115 rb->lcd_puts(0, 1, print);
3116 rb->lcd_update();
3119 rb->read(fd, buf_jpeg, filesize);
3120 rb->close(fd);
3122 if(!running_slideshow)
3124 rb->snprintf(print, sizeof(print), "decoding markers");
3125 rb->lcd_puts(0, 2, print);
3126 rb->lcd_update();
3128 #ifndef SIMULATOR
3129 else if(immediate_ata_off)
3131 /* running slideshow and time is long enough: power down disk */
3132 rb->ata_sleep();
3134 #endif
3136 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
3137 /* process markers, unstuffing */
3138 status = process_markers(buf_jpeg, filesize, &jpg);
3140 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
3141 { /* bad format or minimum components not contained */
3142 rb->splash(HZ, "unsupported %d", status);
3143 file_pt[curfile] = '\0';
3144 return change_filename(direction);
3147 if (!(status & DHT)) /* if no Huffman table present: */
3148 default_huff_tbl(&jpg); /* use default */
3149 build_lut(&jpg); /* derive Huffman and other lookup-tables */
3151 if(!running_slideshow)
3153 rb->snprintf(print, sizeof(print), "image %dx%d", jpg.x_size, jpg.y_size);
3154 rb->lcd_puts(0, 2, print);
3155 rb->lcd_update();
3157 ds_max = max_downscale(&jpg); /* check display constraint */
3158 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */
3159 if (ds_min == 0)
3161 rb->splash(HZ, "too large");
3162 file_pt[curfile] = '\0';
3163 return change_filename(direction);
3166 ds = ds_max; /* initials setting */
3167 cx = jpg.x_size/ds/2; /* center the view */
3168 cy = jpg.y_size/ds/2;
3170 do /* loop the image prepare and decoding when zoomed */
3172 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */
3173 if (p_disp == NULL)
3174 return change_filename(direction);
3176 set_view(p_disp, cx, cy);
3178 if(!running_slideshow)
3180 rb->snprintf(print, sizeof(print), "showing %dx%d",
3181 p_disp->width, p_disp->height);
3182 rb->lcd_puts(0, 3, print);
3183 rb->lcd_update();
3185 MYLCD(clear_display)();
3186 #ifdef HAVE_LCD_COLOR
3187 yuv_bitmap_part(
3188 p_disp->bitmap, p_disp->csub_x, p_disp->csub_y,
3189 p_disp->x, p_disp->y, p_disp->stride,
3190 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3191 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3192 MIN(LCD_WIDTH, p_disp->width),
3193 MIN(LCD_HEIGHT, p_disp->height));
3194 #else
3195 MYXLCD(gray_bitmap_part)(
3196 p_disp->bitmap[0], p_disp->x, p_disp->y, p_disp->stride,
3197 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3198 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3199 MIN(LCD_WIDTH, p_disp->width),
3200 MIN(LCD_HEIGHT, p_disp->height));
3201 #endif
3202 MYLCD_UPDATE();
3204 #ifdef USEGSLIB
3205 grey_show(true); /* switch on greyscale overlay */
3206 #endif
3208 /* drawing is now finished, play around with scrolling
3209 * until you press OFF or connect USB
3211 while (1)
3213 status = scroll_bmp(p_disp);
3214 if (status == ZOOM_IN)
3216 if (ds > ds_min)
3218 ds /= 2; /* reduce downscaling to zoom in */
3219 get_view(p_disp, &cx, &cy);
3220 cx *= 2; /* prepare the position in the new image */
3221 cy *= 2;
3223 else
3224 continue;
3227 if (status == ZOOM_OUT)
3229 if (ds < ds_max)
3231 ds *= 2; /* increase downscaling to zoom out */
3232 get_view(p_disp, &cx, &cy);
3233 cx /= 2; /* prepare the position in the new image */
3234 cy /= 2;
3236 else
3237 continue;
3239 break;
3242 #ifdef USEGSLIB
3243 grey_show(false); /* switch off overlay */
3244 #endif
3245 rb->lcd_clear_display();
3247 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
3248 && status != PLUGIN_OTHER);
3249 #ifdef USEGSLIB
3250 rb->lcd_update();
3251 #endif
3252 return status;
3255 /******************** Plugin entry point *********************/
3257 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
3259 rb = api;
3261 int condition;
3262 #ifdef USEGSLIB
3263 long greysize; /* helper */
3264 #endif
3265 #if LCD_DEPTH > 1
3266 old_backdrop = rb->lcd_get_backdrop();
3267 #endif
3269 if(!parameter) return PLUGIN_ERROR;
3271 rb->strcpy(np_file, parameter);
3272 get_pic_list();
3274 if(!entries) return PLUGIN_ERROR;
3276 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
3277 if(rb->audio_status())
3279 buf = rb->plugin_get_buffer((size_t *)&buf_size) +
3280 (entries * sizeof(char**));
3281 buf_size -= (entries * sizeof(char**));
3282 plug_buf = true;
3284 else
3285 buf = rb->plugin_get_audio_buffer((size_t *)&buf_size);
3286 #else
3287 buf = rb->plugin_get_audio_buffer(&buf_size) +
3288 (entries * sizeof(char**));
3289 buf_size -= (entries * sizeof(char**));
3290 #endif
3292 #ifdef USEGSLIB
3293 if (!grey_init(rb, buf, buf_size, false, LCD_WIDTH, LCD_HEIGHT, &greysize))
3295 rb->splash(HZ, "grey buf error");
3296 return PLUGIN_ERROR;
3298 buf += greysize;
3299 buf_size -= greysize;
3300 #else
3301 xlcd_init(rb);
3302 #endif
3304 #ifdef HAVE_LCD_COLOR
3305 /* should be ok to just load settings since a parameter is present
3306 here and the drive should be spinning */
3307 configfile_init(rb);
3308 configfile_load(JPEG_CONFIGFILE, jpeg_config,
3309 ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION);
3310 old_settings = jpeg_settings;
3311 #endif
3313 buf_images = buf; buf_images_size = buf_size;
3315 /* Turn off backlight timeout */
3316 backlight_force_on(rb); /* backlight control in lib/helper.c */
3320 condition = load_and_show(np_file);
3321 }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
3322 && condition != PLUGIN_ERROR);
3324 #ifdef HAVE_LCD_COLOR
3325 if (rb->memcmp(&jpeg_settings, &old_settings, sizeof (jpeg_settings)))
3327 /* Just in case drive has to spin, keep it from looking locked */
3328 rb->splash(0, "Saving Settings");
3329 configfile_save(JPEG_CONFIGFILE, jpeg_config,
3330 ARRAYLEN(jpeg_config), JPEG_SETTINGS_VERSION);
3332 #endif
3334 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
3335 /* set back ata spindown time in case we changed it */
3336 rb->ata_spindown(rb->global_settings->disk_spindown);
3337 #endif
3339 /* Turn on backlight timeout (revert to settings) */
3340 backlight_use_settings(rb); /* backlight control in lib/helper.c */
3342 #ifdef USEGSLIB
3343 grey_release(); /* deinitialize */
3344 #endif
3346 return condition;
3349 #endif /* HAVE_LCD_BITMAP */