Add 2008 to the copyright notice.
[Rockbox.git] / apps / plugins / jpeg.c
blob27c7c215c8ff26056dc0b2beca4d002fc7eb883a
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"
30 #include "lib/configfile.h"
32 #ifdef HAVE_LCD_BITMAP
33 #include "grey.h"
34 #include "xlcd.h"
36 PLUGIN_HEADER
38 /* variable button definitions */
39 #if CONFIG_KEYPAD == RECORDER_PAD
40 #define JPEG_ZOOM_IN BUTTON_PLAY
41 #define JPEG_ZOOM_OUT BUTTON_ON
42 #define JPEG_UP BUTTON_UP
43 #define JPEG_DOWN BUTTON_DOWN
44 #define JPEG_LEFT BUTTON_LEFT
45 #define JPEG_RIGHT BUTTON_RIGHT
46 #define JPEG_NEXT BUTTON_F3
47 #define JPEG_PREVIOUS BUTTON_F2
48 #define JPEG_MENU BUTTON_OFF
50 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
51 #define JPEG_ZOOM_IN BUTTON_SELECT
52 #define JPEG_ZOOM_OUT BUTTON_ON
53 #define JPEG_UP BUTTON_UP
54 #define JPEG_DOWN BUTTON_DOWN
55 #define JPEG_LEFT BUTTON_LEFT
56 #define JPEG_RIGHT BUTTON_RIGHT
57 #define JPEG_NEXT BUTTON_F3
58 #define JPEG_PREVIOUS BUTTON_F2
59 #define JPEG_MENU BUTTON_OFF
61 #elif CONFIG_KEYPAD == ONDIO_PAD
62 #define JPEG_ZOOM_PRE BUTTON_MENU
63 #define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
64 #define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
65 #define JPEG_UP BUTTON_UP
66 #define JPEG_DOWN BUTTON_DOWN
67 #define JPEG_LEFT BUTTON_LEFT
68 #define JPEG_RIGHT BUTTON_RIGHT
69 #define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
70 #define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
71 #define JPEG_MENU BUTTON_OFF
73 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
74 (CONFIG_KEYPAD == IRIVER_H300_PAD)
75 #define JPEG_ZOOM_IN BUTTON_SELECT
76 #define JPEG_ZOOM_OUT BUTTON_MODE
77 #define JPEG_UP BUTTON_UP
78 #define JPEG_DOWN BUTTON_DOWN
79 #define JPEG_LEFT BUTTON_LEFT
80 #define JPEG_RIGHT BUTTON_RIGHT
81 #if (CONFIG_KEYPAD == IRIVER_H100_PAD)
82 #define JPEG_NEXT BUTTON_ON
83 #define JPEG_PREVIOUS BUTTON_REC
84 #else
85 #define JPEG_NEXT BUTTON_REC
86 #define JPEG_PREVIOUS BUTTON_ON
87 #endif
88 #define JPEG_MENU BUTTON_OFF
89 #define JPEG_RC_MENU BUTTON_RC_STOP
91 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
92 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
93 #define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
94 #define JPEG_ZOOM_OUT BUTTON_SCROLL_BACK
95 #define JPEG_UP BUTTON_MENU
96 #define JPEG_DOWN BUTTON_PLAY
97 #define JPEG_LEFT BUTTON_LEFT
98 #define JPEG_RIGHT BUTTON_RIGHT
99 #define JPEG_MENU (BUTTON_SELECT | BUTTON_MENU)
100 #define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
101 #define JPEG_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
103 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
104 #define JPEG_ZOOM_PRE BUTTON_SELECT
105 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
106 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
107 #define JPEG_UP BUTTON_UP
108 #define JPEG_DOWN BUTTON_DOWN
109 #define JPEG_LEFT BUTTON_LEFT
110 #define JPEG_RIGHT BUTTON_RIGHT
111 #define JPEG_MENU BUTTON_POWER
112 #define JPEG_NEXT BUTTON_PLAY
113 #define JPEG_PREVIOUS BUTTON_REC
115 #elif CONFIG_KEYPAD == GIGABEAT_PAD
116 #define JPEG_ZOOM_IN BUTTON_VOL_UP
117 #define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
118 #define JPEG_UP BUTTON_UP
119 #define JPEG_DOWN BUTTON_DOWN
120 #define JPEG_LEFT BUTTON_LEFT
121 #define JPEG_RIGHT BUTTON_RIGHT
122 #define JPEG_MENU BUTTON_MENU
123 #define JPEG_NEXT (BUTTON_A | BUTTON_RIGHT)
124 #define JPEG_PREVIOUS (BUTTON_A | BUTTON_LEFT)
126 #elif CONFIG_KEYPAD == SANSA_E200_PAD
127 #define JPEG_ZOOM_PRE BUTTON_SELECT
128 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
129 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
130 #define JPEG_UP BUTTON_UP
131 #define JPEG_DOWN BUTTON_DOWN
132 #define JPEG_LEFT BUTTON_LEFT
133 #define JPEG_RIGHT BUTTON_RIGHT
134 #define JPEG_MENU BUTTON_POWER
135 #define JPEG_SLIDE_SHOW BUTTON_REC
136 #define JPEG_NEXT BUTTON_SCROLL_FWD
137 #define JPEG_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
138 #define JPEG_PREVIOUS BUTTON_SCROLL_BACK
139 #define JPEG_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
141 #elif CONFIG_KEYPAD == SANSA_C200_PAD
142 #define JPEG_ZOOM_PRE BUTTON_SELECT
143 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
144 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
145 #define JPEG_UP BUTTON_UP
146 #define JPEG_DOWN BUTTON_DOWN
147 #define JPEG_LEFT BUTTON_LEFT
148 #define JPEG_RIGHT BUTTON_RIGHT
149 #define JPEG_MENU BUTTON_POWER
150 #define JPEG_SLIDE_SHOW BUTTON_REC
151 #define JPEG_NEXT BUTTON_VOL_UP
152 #define JPEG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
153 #define JPEG_PREVIOUS BUTTON_VOL_DOWN
154 #define JPEG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
156 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
157 #define JPEG_ZOOM_PRE BUTTON_PLAY
158 #define JPEG_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
159 #define JPEG_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
160 #define JPEG_UP BUTTON_SCROLL_UP
161 #define JPEG_DOWN BUTTON_SCROLL_DOWN
162 #define JPEG_LEFT BUTTON_LEFT
163 #define JPEG_RIGHT BUTTON_RIGHT
164 #define JPEG_MENU BUTTON_POWER
165 #define JPEG_NEXT BUTTON_FF
166 #define JPEG_PREVIOUS BUTTON_REW
168 #elif CONFIG_KEYPAD == MROBE500_PAD
169 #define JPEG_ZOOM_IN BUTTON_RC_VOL_UP
170 #define JPEG_ZOOM_OUT BUTTON_RC_VOL_DOWN
171 #define JPEG_UP BUTTON_RC_PLAY
172 #define JPEG_DOWN BUTTON_RC_DOWN
173 #define JPEG_LEFT BUTTON_LEFT
174 #define JPEG_RIGHT BUTTON_RIGHT
175 #define JPEG_MENU BUTTON_POWER
176 #define JPEG_NEXT BUTTON_RC_HEART
177 #define JPEG_PREVIOUS BUTTON_RC_MODE
179 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
180 #define JPEG_ZOOM_IN BUTTON_VOL_UP
181 #define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
182 #define JPEG_UP BUTTON_UP
183 #define JPEG_DOWN BUTTON_DOWN
184 #define JPEG_LEFT BUTTON_LEFT
185 #define JPEG_RIGHT BUTTON_RIGHT
186 #define JPEG_MENU BUTTON_MENU
187 #define JPEG_NEXT BUTTON_NEXT
188 #define JPEG_PREVIOUS BUTTON_PREV
190 #endif
192 /* different graphics libraries */
193 #if LCD_DEPTH < 8
194 #define USEGSLIB
195 GREY_INFO_STRUCT
196 #define MYLCD(fn) grey_ub_ ## fn
197 #define MYLCD_UPDATE()
198 #define MYXLCD(fn) grey_ub_ ## fn
199 #else
200 #define MYLCD(fn) rb->lcd_ ## fn
201 #define MYLCD_UPDATE() rb->lcd_update();
202 #define MYXLCD(fn) xlcd_ ## fn
203 #endif
205 #define MAX_X_SIZE LCD_WIDTH*8
207 /* Min memory allowing us to use the plugin buffer
208 * and thus not stopping the music
209 * *Very* rough estimation:
210 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
211 * + 20k code size = 60 000
212 * + 50k min for jpeg = 120 000
214 #define MIN_MEM 120000
216 /* Headings */
217 #define DIR_PREV 1
218 #define DIR_NEXT -1
219 #define DIR_NONE 0
221 #define PLUGIN_OTHER 10 /* State code for output with return. */
223 /******************************* Globals ***********************************/
225 static struct plugin_api* rb;
226 MEM_FUNCTION_WRAPPERS(rb);
228 /* for portability of below JPEG code */
229 #define MEMSET(p,v,c) rb->memset(p,v,c)
230 #define MEMCPY(d,s,c) rb->memcpy(d,s,c)
231 #define INLINE static inline
232 #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
234 static int slideshow_enabled = false; /* run slideshow */
235 static int running_slideshow = false; /* loading image because of slideshw */
236 #ifndef SIMULATOR
237 static int immediate_ata_off = false; /* power down disk after loading */
238 #endif
240 /* Persistent configuration */
241 #define JPEG_CONFIGFILE "jpeg.cfg"
242 #define JPEG_SETTINGS_MINVERSION 1
243 #define JPEG_SETTINGS_VERSION 2
245 /* Slideshow times */
246 #define SS_MIN_TIMEOUT 1
247 #define SS_MAX_TIMEOUT 20
248 #define SS_DEFAULT_TIMEOUT 5
250 enum color_modes
252 COLOURMODE_COLOUR = 0,
253 COLOURMODE_GRAY,
254 COLOUR_NUM_MODES
257 enum dither_modes
259 DITHER_NONE = 0, /* No dithering */
260 DITHER_ORDERED, /* Bayer ordered */
261 DITHER_DIFFUSION, /* Floyd/Steinberg error diffusion */
262 DITHER_NUM_MODES
265 struct jpeg_settings
267 int colour_mode;
268 int dither_mode;
269 int ss_timeout;
272 static struct jpeg_settings jpeg_settings =
273 { COLOURMODE_COLOUR, DITHER_NONE, SS_DEFAULT_TIMEOUT };
274 static struct jpeg_settings old_settings;
276 static struct configdata jpeg_config[] =
278 #ifdef HAVE_LCD_COLOR
279 { TYPE_ENUM, 0, COLOUR_NUM_MODES, &jpeg_settings.colour_mode,
280 "Colour Mode", (char *[]){ "Colour", "Grayscale" }, NULL },
281 { TYPE_ENUM, 0, DITHER_NUM_MODES, &jpeg_settings.dither_mode,
282 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" }, NULL },
283 #endif
284 { TYPE_INT, SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, &jpeg_settings.ss_timeout,
285 "Slideshow Time", NULL, NULL},
288 #if LCD_DEPTH > 1
289 fb_data* old_backdrop;
290 #endif
292 /**************** begin JPEG code ********************/
294 INLINE unsigned range_limit(int value)
296 #if CONFIG_CPU == SH7034
297 unsigned tmp;
298 asm ( /* Note: Uses knowledge that only low byte of result is used */
299 "mov #-128,%[t] \n"
300 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
301 "extu.b %[v],%[t] \n"
302 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
303 "bt 1f \n" /* yes: no overflow */
304 "cmp/pz %[v] \n" /* overflow: positive? */
305 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
306 "1: \n"
307 : /* outputs */
308 [v]"+r"(value),
309 [t]"=&r"(tmp)
311 return value;
312 #elif defined(CPU_COLDFIRE)
313 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
314 "add.l #128,%[v] \n" /* value += 128; */
315 "cmp.l #255,%[v] \n" /* overflow? */
316 "bls.b 1f \n" /* no: return value */
317 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
318 "1: \n"
319 : /* outputs */
320 [v]"+d"(value)
322 return value;
323 #elif defined(CPU_ARM)
324 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
325 "add %[v], %[v], #128 \n" /* value += 128 */
326 "cmp %[v], #255 \n" /* out of range 0..255? */
327 "mvnhi %[v], %[v], asr #31 \n" /* yes: set all bits to ~(sign_bit) */
328 : /* outputs */
329 [v]"+r"(value)
331 return value;
332 #else
333 value += 128;
335 if ((unsigned)value <= 255)
336 return value;
338 if (value < 0)
339 return 0;
341 return 255;
342 #endif
345 /* IDCT implementation */
348 #define CONST_BITS 13
349 #define PASS1_BITS 2
352 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
353 * causing a lot of useless floating-point operations at run time.
354 * To get around this we use the following pre-calculated constants.
355 * If you change CONST_BITS you may want to add appropriate values.
356 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
358 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
359 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
360 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
361 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
362 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
363 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
364 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
365 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
366 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
367 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
368 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
369 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
373 /* Multiply an long variable by an long constant to yield an long result.
374 * For 8-bit samples with the recommended scaling, all the variable
375 * and constant values involved are no more than 16 bits wide, so a
376 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
377 * For 12-bit samples, a full 32-bit multiplication will be needed.
379 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
382 /* Dequantize a coefficient by multiplying it by the multiplier-table
383 * entry; produce an int result. In this module, both inputs and result
384 * are 16 bits or less, so either int or short multiply will work.
386 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
387 #define DEQUANTIZE MULTIPLY16
389 /* Descale and correctly round an int value that's scaled by N bits.
390 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
391 * the fudge factor is correct for either sign of X.
393 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
398 * Perform dequantization and inverse DCT on one block of coefficients,
399 * producing a reduced-size 1x1 output block.
401 void idct1x1(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
403 (void)skip_line; /* unused */
404 *p_byte = range_limit(inptr[0] * quantptr[0] >> 3);
410 * Perform dequantization and inverse DCT on one block of coefficients,
411 * producing a reduced-size 2x2 output block.
413 void idct2x2(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
415 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
416 unsigned char* outptr;
418 /* Pass 1: process columns from input, store into work array. */
420 /* Column 0 */
421 tmp4 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
422 tmp5 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
424 tmp0 = tmp4 + tmp5;
425 tmp2 = tmp4 - tmp5;
427 /* Column 1 */
428 tmp4 = DEQUANTIZE(inptr[8*0+1], quantptr[8*0+1]);
429 tmp5 = DEQUANTIZE(inptr[8*1+1], quantptr[8*1+1]);
431 tmp1 = tmp4 + tmp5;
432 tmp3 = tmp4 - tmp5;
434 /* Pass 2: process 2 rows, store into output array. */
436 /* Row 0 */
437 outptr = p_byte;
439 outptr[0] = range_limit((int) DESCALE(tmp0 + tmp1, 3));
440 outptr[1] = range_limit((int) DESCALE(tmp0 - tmp1, 3));
442 /* Row 1 */
443 outptr = p_byte + skip_line;
445 outptr[0] = range_limit((int) DESCALE(tmp2 + tmp3, 3));
446 outptr[1] = range_limit((int) DESCALE(tmp2 - tmp3, 3));
452 * Perform dequantization and inverse DCT on one block of coefficients,
453 * producing a reduced-size 4x4 output block.
455 void idct4x4(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
457 int tmp0, tmp2, tmp10, tmp12;
458 int z1, z2, z3;
459 int * wsptr;
460 unsigned char* outptr;
461 int ctr;
462 int workspace[4*4]; /* buffers data between passes */
464 /* Pass 1: process columns from input, store into work array. */
466 wsptr = workspace;
467 for (ctr = 0; ctr < 4; ctr++, inptr++, quantptr++, wsptr++)
469 /* Even part */
471 tmp0 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
472 tmp2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
474 tmp10 = (tmp0 + tmp2) << PASS1_BITS;
475 tmp12 = (tmp0 - tmp2) << PASS1_BITS;
477 /* Odd part */
478 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
480 z2 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
481 z3 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
483 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
484 tmp0 = DESCALE(z1 + MULTIPLY16(z3, - FIX_1_847759065), CONST_BITS-PASS1_BITS);
485 tmp2 = DESCALE(z1 + MULTIPLY16(z2, FIX_0_765366865), CONST_BITS-PASS1_BITS);
487 /* Final output stage */
489 wsptr[4*0] = (int) (tmp10 + tmp2);
490 wsptr[4*3] = (int) (tmp10 - tmp2);
491 wsptr[4*1] = (int) (tmp12 + tmp0);
492 wsptr[4*2] = (int) (tmp12 - tmp0);
495 /* Pass 2: process 4 rows from work array, store into output array. */
497 wsptr = workspace;
498 for (ctr = 0; ctr < 4; ctr++)
500 outptr = p_byte + (ctr*skip_line);
501 /* Even part */
503 tmp0 = (int) wsptr[0];
504 tmp2 = (int) wsptr[2];
506 tmp10 = (tmp0 + tmp2) << CONST_BITS;
507 tmp12 = (tmp0 - tmp2) << CONST_BITS;
509 /* Odd part */
510 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
512 z2 = (int) wsptr[1];
513 z3 = (int) wsptr[3];
515 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
516 tmp0 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
517 tmp2 = z1 + MULTIPLY16(z2, FIX_0_765366865);
519 /* Final output stage */
521 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp2,
522 CONST_BITS+PASS1_BITS+3));
523 outptr[3] = range_limit((int) DESCALE(tmp10 - tmp2,
524 CONST_BITS+PASS1_BITS+3));
525 outptr[1] = range_limit((int) DESCALE(tmp12 + tmp0,
526 CONST_BITS+PASS1_BITS+3));
527 outptr[2] = range_limit((int) DESCALE(tmp12 - tmp0,
528 CONST_BITS+PASS1_BITS+3));
530 wsptr += 4; /* advance pointer to next row */
537 * Perform dequantization and inverse DCT on one block of coefficients.
539 void idct8x8(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
541 long tmp0, tmp1, tmp2, tmp3;
542 long tmp10, tmp11, tmp12, tmp13;
543 long z1, z2, z3, z4, z5;
544 int * wsptr;
545 unsigned char* outptr;
546 int ctr;
547 int workspace[64]; /* buffers data between passes */
549 /* Pass 1: process columns from input, store into work array. */
550 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
551 /* furthermore, we scale the results by 2**PASS1_BITS. */
553 wsptr = workspace;
554 for (ctr = 8; ctr > 0; ctr--)
556 /* Due to quantization, we will usually find that many of the input
557 * coefficients are zero, especially the AC terms. We can exploit this
558 * by short-circuiting the IDCT calculation for any column in which all
559 * the AC terms are zero. In that case each output is equal to the
560 * DC coefficient (with scale factor as needed).
561 * With typical images and quantization tables, half or more of the
562 * column DCT calculations can be simplified this way.
565 if ((inptr[8*1] | inptr[8*2] | inptr[8*3]
566 | inptr[8*4] | inptr[8*5] | inptr[8*6] | inptr[8*7]) == 0)
568 /* AC terms all zero */
569 int dcval = DEQUANTIZE(inptr[8*0], quantptr[8*0]) << PASS1_BITS;
571 wsptr[8*0] = wsptr[8*1] = wsptr[8*2] = wsptr[8*3] = wsptr[8*4]
572 = wsptr[8*5] = wsptr[8*6] = wsptr[8*7] = dcval;
573 inptr++; /* advance pointers to next column */
574 quantptr++;
575 wsptr++;
576 continue;
579 /* Even part: reverse the even part of the forward DCT. */
580 /* The rotator is sqrt(2)*c(-6). */
582 z2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
583 z3 = DEQUANTIZE(inptr[8*6], quantptr[8*6]);
585 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
586 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
587 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
589 z2 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
590 z3 = DEQUANTIZE(inptr[8*4], quantptr[8*4]);
592 tmp0 = (z2 + z3) << CONST_BITS;
593 tmp1 = (z2 - z3) << CONST_BITS;
595 tmp10 = tmp0 + tmp3;
596 tmp13 = tmp0 - tmp3;
597 tmp11 = tmp1 + tmp2;
598 tmp12 = tmp1 - tmp2;
600 /* Odd part per figure 8; the matrix is unitary and hence its
601 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
603 tmp0 = DEQUANTIZE(inptr[8*7], quantptr[8*7]);
604 tmp1 = DEQUANTIZE(inptr[8*5], quantptr[8*5]);
605 tmp2 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
606 tmp3 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
608 z1 = tmp0 + tmp3;
609 z2 = tmp1 + tmp2;
610 z3 = tmp0 + tmp2;
611 z4 = tmp1 + tmp3;
612 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
614 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
615 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
616 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
617 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
618 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
619 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
620 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
621 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
623 z3 += z5;
624 z4 += z5;
626 tmp0 += z1 + z3;
627 tmp1 += z2 + z4;
628 tmp2 += z2 + z3;
629 tmp3 += z1 + z4;
631 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
633 wsptr[8*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
634 wsptr[8*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
635 wsptr[8*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
636 wsptr[8*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
637 wsptr[8*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
638 wsptr[8*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
639 wsptr[8*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
640 wsptr[8*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
642 inptr++; /* advance pointers to next column */
643 quantptr++;
644 wsptr++;
647 /* Pass 2: process rows from work array, store into output array. */
648 /* Note that we must descale the results by a factor of 8 == 2**3, */
649 /* and also undo the PASS1_BITS scaling. */
651 wsptr = workspace;
652 for (ctr = 0; ctr < 8; ctr++)
654 outptr = p_byte + (ctr*skip_line);
655 /* Rows of zeroes can be exploited in the same way as we did with columns.
656 * However, the column calculation has created many nonzero AC terms, so
657 * the simplification applies less often (typically 5% to 10% of the time).
658 * On machines with very fast multiplication, it's possible that the
659 * test takes more time than it's worth. In that case this section
660 * may be commented out.
663 #ifndef NO_ZERO_ROW_TEST
664 if ((wsptr[1] | wsptr[2] | wsptr[3]
665 | wsptr[4] | wsptr[5] | wsptr[6] | wsptr[7]) == 0)
667 /* AC terms all zero */
668 unsigned char dcval = range_limit((int) DESCALE((long) wsptr[0],
669 PASS1_BITS+3));
671 outptr[0] = dcval;
672 outptr[1] = dcval;
673 outptr[2] = dcval;
674 outptr[3] = dcval;
675 outptr[4] = dcval;
676 outptr[5] = dcval;
677 outptr[6] = dcval;
678 outptr[7] = dcval;
680 wsptr += 8; /* advance pointer to next row */
681 continue;
683 #endif
685 /* Even part: reverse the even part of the forward DCT. */
686 /* The rotator is sqrt(2)*c(-6). */
688 z2 = (long) wsptr[2];
689 z3 = (long) wsptr[6];
691 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
692 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
693 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
695 tmp0 = ((long) wsptr[0] + (long) wsptr[4]) << CONST_BITS;
696 tmp1 = ((long) wsptr[0] - (long) wsptr[4]) << CONST_BITS;
698 tmp10 = tmp0 + tmp3;
699 tmp13 = tmp0 - tmp3;
700 tmp11 = tmp1 + tmp2;
701 tmp12 = tmp1 - tmp2;
703 /* Odd part per figure 8; the matrix is unitary and hence its
704 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
706 tmp0 = (long) wsptr[7];
707 tmp1 = (long) wsptr[5];
708 tmp2 = (long) wsptr[3];
709 tmp3 = (long) wsptr[1];
711 z1 = tmp0 + tmp3;
712 z2 = tmp1 + tmp2;
713 z3 = tmp0 + tmp2;
714 z4 = tmp1 + tmp3;
715 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
717 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
718 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
719 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
720 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
721 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
722 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
723 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
724 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
726 z3 += z5;
727 z4 += z5;
729 tmp0 += z1 + z3;
730 tmp1 += z2 + z4;
731 tmp2 += z2 + z3;
732 tmp3 += z1 + z4;
734 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
736 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp3,
737 CONST_BITS+PASS1_BITS+3));
738 outptr[7] = range_limit((int) DESCALE(tmp10 - tmp3,
739 CONST_BITS+PASS1_BITS+3));
740 outptr[1] = range_limit((int) DESCALE(tmp11 + tmp2,
741 CONST_BITS+PASS1_BITS+3));
742 outptr[6] = range_limit((int) DESCALE(tmp11 - tmp2,
743 CONST_BITS+PASS1_BITS+3));
744 outptr[2] = range_limit((int) DESCALE(tmp12 + tmp1,
745 CONST_BITS+PASS1_BITS+3));
746 outptr[5] = range_limit((int) DESCALE(tmp12 - tmp1,
747 CONST_BITS+PASS1_BITS+3));
748 outptr[3] = range_limit((int) DESCALE(tmp13 + tmp0,
749 CONST_BITS+PASS1_BITS+3));
750 outptr[4] = range_limit((int) DESCALE(tmp13 - tmp0,
751 CONST_BITS+PASS1_BITS+3));
753 wsptr += 8; /* advance pointer to next row */
759 /* JPEG decoder implementation */
762 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
764 struct derived_tbl
766 /* Basic tables: (element [0] of each array is unused) */
767 long mincode[17]; /* smallest code of length k */
768 long maxcode[18]; /* largest code of length k (-1 if none) */
769 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
770 int valptr[17]; /* huffval[] index of 1st symbol of length k */
772 /* Back link to public Huffman table (needed only in slow_DECODE) */
773 int* pub;
775 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
776 the input data stream. If the next Huffman code is no more
777 than HUFF_LOOKAHEAD bits long, we can obtain its length and
778 the corresponding symbol directly from these tables. */
779 int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
780 unsigned char look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
783 #define QUANT_TABLE_LENGTH 64
785 /* for type of Huffman table */
786 #define DC_LEN 28
787 #define AC_LEN 178
789 struct huffman_table
790 { /* length and code according to JFIF format */
791 int huffmancodes_dc[DC_LEN];
792 int huffmancodes_ac[AC_LEN];
795 struct frame_component
797 int ID;
798 int horizontal_sampling;
799 int vertical_sampling;
800 int quanttable_select;
803 struct scan_component
805 int ID;
806 int DC_select;
807 int AC_select;
810 struct bitstream
812 unsigned long get_buffer; /* current bit-extraction buffer */
813 int bits_left; /* # of unused bits in it */
814 unsigned char* next_input_byte;
815 unsigned char* input_end; /* upper limit +1 */
818 struct jpeg
820 int x_size, y_size; /* size of image (can be less than block boundary) */
821 int x_phys, y_phys; /* physical size, block aligned */
822 int x_mbl; /* x dimension of MBL */
823 int y_mbl; /* y dimension of MBL */
824 int blocks; /* blocks per MB */
825 int restart_interval; /* number of MCUs between RSTm markers */
826 int store_pos[4]; /* for Y block ordering */
828 unsigned char* p_entropy_data;
829 unsigned char* p_entropy_end;
831 int quanttable[4][QUANT_TABLE_LENGTH]; /* raw quantization tables 0-3 */
832 int qt_idct[2][QUANT_TABLE_LENGTH]; /* quantization tables for IDCT */
834 struct huffman_table hufftable[2]; /* Huffman tables */
835 struct derived_tbl dc_derived_tbls[2]; /* Huffman-LUTs */
836 struct derived_tbl ac_derived_tbls[2];
838 struct frame_component frameheader[3]; /* Component descriptor */
839 struct scan_component scanheader[3]; /* currently not used */
841 int mcu_membership[6]; /* info per block */
842 int tab_membership[6];
843 int subsample_x[3]; /* info per component */
844 int subsample_y[3];
848 /* possible return flags for process_markers() */
849 #define HUFFTAB 0x0001 /* with huffman table */
850 #define QUANTTAB 0x0002 /* with quantization table */
851 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
852 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
853 #define SOF0 0x0010 /* with SOF0-Segment */
854 #define DHT 0x0020 /* with Definition of huffman tables */
855 #define SOS 0x0040 /* with Start-of-Scan segment */
856 #define DQT 0x0080 /* with definition of quantization table */
858 /* Preprocess the JPEG JFIF file */
859 int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
861 unsigned char* p_bytes = p_src;
862 int marker_size; /* variable length of marker segment */
863 int i, j, n;
864 int ret = 0; /* returned flags */
866 p_jpeg->p_entropy_end = p_src + size;
868 while (p_src < p_bytes + size)
870 if (*p_src++ != 0xFF) /* no marker? */
872 p_src--; /* it's image data, put it back */
873 p_jpeg->p_entropy_data = p_src;
874 break; /* exit marker processing */
877 switch (*p_src++)
879 case 0xFF: /* Fill byte */
880 ret |= FILL_FF;
881 case 0x00: /* Zero stuffed byte - entropy data */
882 p_src--; /* put it back */
883 continue;
885 case 0xC0: /* SOF Huff - Baseline DCT */
887 ret |= SOF0;
888 marker_size = *p_src++ << 8; /* Highbyte */
889 marker_size |= *p_src++; /* Lowbyte */
890 n = *p_src++; /* sample precision (= 8 or 12) */
891 if (n != 8)
893 return(-1); /* Unsupported sample precision */
895 p_jpeg->y_size = *p_src++ << 8; /* Highbyte */
896 p_jpeg->y_size |= *p_src++; /* Lowbyte */
897 p_jpeg->x_size = *p_src++ << 8; /* Highbyte */
898 p_jpeg->x_size |= *p_src++; /* Lowbyte */
900 n = (marker_size-2-6)/3;
901 if (*p_src++ != n || (n != 1 && n != 3))
903 return(-2); /* Unsupported SOF0 component specification */
905 for (i=0; i<n; i++)
907 p_jpeg->frameheader[i].ID = *p_src++; /* Component info */
908 p_jpeg->frameheader[i].horizontal_sampling = *p_src >> 4;
909 p_jpeg->frameheader[i].vertical_sampling = *p_src++ & 0x0F;
910 p_jpeg->frameheader[i].quanttable_select = *p_src++;
911 if (p_jpeg->frameheader[i].horizontal_sampling > 2
912 || p_jpeg->frameheader[i].vertical_sampling > 2)
913 return -3; /* Unsupported SOF0 subsampling */
915 p_jpeg->blocks = n;
917 break;
919 case 0xC1: /* SOF Huff - Extended sequential DCT*/
920 case 0xC2: /* SOF Huff - Progressive DCT*/
921 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
922 case 0xC5: /* SOF Huff - Differential sequential DCT*/
923 case 0xC6: /* SOF Huff - Differential progressive DCT*/
924 case 0xC7: /* SOF Huff - Differential spatial*/
925 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
926 case 0xC9: /* SOF Arith - Extended sequential DCT*/
927 case 0xCA: /* SOF Arith - Progressive DCT*/
928 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
929 case 0xCD: /* SOF Arith - Differential sequential DCT*/
930 case 0xCE: /* SOF Arith - Differential progressive DCT*/
931 case 0xCF: /* SOF Arith - Differential spatial*/
933 return (-4); /* other DCT model than baseline not implemented */
936 case 0xC4: /* Define Huffman Table(s) */
938 unsigned char* p_temp;
940 ret |= DHT;
941 marker_size = *p_src++ << 8; /* Highbyte */
942 marker_size |= *p_src++; /* Lowbyte */
944 p_temp = p_src;
945 while (p_src < p_temp+marker_size-2-17) /* another table */
947 int sum = 0;
948 i = *p_src & 0x0F; /* table index */
949 if (i > 1)
951 return (-5); /* Huffman table index out of range */
953 else if (*p_src++ & 0xF0) /* AC table */
955 for (j=0; j<16; j++)
957 sum += *p_src;
958 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
960 if(16 + sum > AC_LEN)
961 return -10; /* longer than allowed */
963 for (; j < 16 + sum; j++)
964 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
966 else /* DC table */
968 for (j=0; j<16; j++)
970 sum += *p_src;
971 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
973 if(16 + sum > DC_LEN)
974 return -11; /* longer than allowed */
976 for (; j < 16 + sum; j++)
977 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
979 } /* while */
980 p_src = p_temp+marker_size - 2; /* skip possible residue */
982 break;
984 case 0xCC: /* Define Arithmetic coding conditioning(s) */
985 return(-6); /* Arithmetic coding not supported */
987 case 0xD8: /* Start of Image */
988 case 0xD9: /* End of Image */
989 case 0x01: /* for temp private use arith code */
990 break; /* skip parameterless marker */
993 case 0xDA: /* Start of Scan */
995 ret |= SOS;
996 marker_size = *p_src++ << 8; /* Highbyte */
997 marker_size |= *p_src++; /* Lowbyte */
999 n = (marker_size-2-1-3)/2;
1000 if (*p_src++ != n || (n != 1 && n != 3))
1002 return (-7); /* Unsupported SOS component specification */
1004 for (i=0; i<n; i++)
1006 p_jpeg->scanheader[i].ID = *p_src++;
1007 p_jpeg->scanheader[i].DC_select = *p_src >> 4;
1008 p_jpeg->scanheader[i].AC_select = *p_src++ & 0x0F;
1010 p_src += 3; /* skip spectral information */
1012 break;
1014 case 0xDB: /* Define quantization Table(s) */
1016 ret |= DQT;
1017 marker_size = *p_src++ << 8; /* Highbyte */
1018 marker_size |= *p_src++; /* Lowbyte */
1019 n = (marker_size-2)/(QUANT_TABLE_LENGTH+1); /* # of tables */
1020 for (i=0; i<n; i++)
1022 int id = *p_src++; /* ID */
1023 if (id >= 4)
1025 return (-8); /* Unsupported quantization table */
1027 /* Read Quantisation table: */
1028 for (j=0; j<QUANT_TABLE_LENGTH; j++)
1029 p_jpeg->quanttable[id][j] = *p_src++;
1032 break;
1034 case 0xDD: /* Define Restart Interval */
1036 marker_size = *p_src++ << 8; /* Highbyte */
1037 marker_size |= *p_src++; /* Lowbyte */
1038 p_jpeg->restart_interval = *p_src++ << 8; /* Highbyte */
1039 p_jpeg->restart_interval |= *p_src++; /* Lowbyte */
1040 p_src += marker_size-4; /* skip segment */
1042 break;
1044 case 0xDC: /* Define Number of Lines */
1045 case 0xDE: /* Define Hierarchical progression */
1046 case 0xDF: /* Expand Reference Component(s) */
1047 case 0xE0: /* Application Field 0*/
1048 case 0xE1: /* Application Field 1*/
1049 case 0xE2: /* Application Field 2*/
1050 case 0xE3: /* Application Field 3*/
1051 case 0xE4: /* Application Field 4*/
1052 case 0xE5: /* Application Field 5*/
1053 case 0xE6: /* Application Field 6*/
1054 case 0xE7: /* Application Field 7*/
1055 case 0xE8: /* Application Field 8*/
1056 case 0xE9: /* Application Field 9*/
1057 case 0xEA: /* Application Field 10*/
1058 case 0xEB: /* Application Field 11*/
1059 case 0xEC: /* Application Field 12*/
1060 case 0xED: /* Application Field 13*/
1061 case 0xEE: /* Application Field 14*/
1062 case 0xEF: /* Application Field 15*/
1063 case 0xFE: /* Comment */
1065 marker_size = *p_src++ << 8; /* Highbyte */
1066 marker_size |= *p_src++; /* Lowbyte */
1067 p_src += marker_size-2; /* skip segment */
1069 break;
1071 case 0xF0: /* Reserved for JPEG extensions */
1072 case 0xF1: /* Reserved for JPEG extensions */
1073 case 0xF2: /* Reserved for JPEG extensions */
1074 case 0xF3: /* Reserved for JPEG extensions */
1075 case 0xF4: /* Reserved for JPEG extensions */
1076 case 0xF5: /* Reserved for JPEG extensions */
1077 case 0xF6: /* Reserved for JPEG extensions */
1078 case 0xF7: /* Reserved for JPEG extensions */
1079 case 0xF8: /* Reserved for JPEG extensions */
1080 case 0xF9: /* Reserved for JPEG extensions */
1081 case 0xFA: /* Reserved for JPEG extensions */
1082 case 0xFB: /* Reserved for JPEG extensions */
1083 case 0xFC: /* Reserved for JPEG extensions */
1084 case 0xFD: /* Reserved for JPEG extensions */
1085 case 0x02: /* Reserved */
1086 default:
1087 return (-9); /* Unknown marker */
1088 } /* switch */
1089 } /* while */
1091 return (ret); /* return flags with seen markers */
1095 void default_huff_tbl(struct jpeg* p_jpeg)
1097 static const struct huffman_table luma_table =
1100 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
1101 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1104 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
1105 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
1106 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
1107 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
1108 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
1109 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1110 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1111 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
1112 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
1113 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
1114 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1115 0xF9,0xFA
1119 static const struct huffman_table chroma_table =
1122 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
1123 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1126 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
1127 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
1128 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1129 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1130 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1131 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1132 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1133 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1134 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1135 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1136 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1137 0xF9,0xFA
1141 MEMCPY(&p_jpeg->hufftable[0], &luma_table, sizeof(luma_table));
1142 MEMCPY(&p_jpeg->hufftable[1], &chroma_table, sizeof(chroma_table));
1144 return;
1147 /* Compute the derived values for a Huffman table */
1148 void fix_huff_tbl(int* htbl, struct derived_tbl* dtbl)
1150 int p, i, l, si;
1151 int lookbits, ctr;
1152 char huffsize[257];
1153 unsigned int huffcode[257];
1154 unsigned int code;
1156 dtbl->pub = htbl; /* fill in back link */
1158 /* Figure C.1: make table of Huffman code length for each symbol */
1159 /* Note that this is in code-length order. */
1161 p = 0;
1162 for (l = 1; l <= 16; l++)
1163 { /* all possible code length */
1164 for (i = 1; i <= (int) htbl[l-1]; i++) /* all codes per length */
1165 huffsize[p++] = (char) l;
1167 huffsize[p] = 0;
1169 /* Figure C.2: generate the codes themselves */
1170 /* Note that this is in code-length order. */
1172 code = 0;
1173 si = huffsize[0];
1174 p = 0;
1175 while (huffsize[p])
1177 while (((int) huffsize[p]) == si)
1179 huffcode[p++] = code;
1180 code++;
1182 code <<= 1;
1183 si++;
1186 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1188 p = 0;
1189 for (l = 1; l <= 16; l++)
1191 if (htbl[l-1])
1193 dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */
1194 dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */
1195 p += htbl[l-1];
1196 dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
1198 else
1200 dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
1203 dtbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */
1205 /* Compute lookahead tables to speed up decoding.
1206 * First we set all the table entries to 0, indicating "too long";
1207 * then we iterate through the Huffman codes that are short enough and
1208 * fill in all the entries that correspond to bit sequences starting
1209 * with that code.
1212 MEMSET(dtbl->look_nbits, 0, sizeof(dtbl->look_nbits));
1214 p = 0;
1215 for (l = 1; l <= HUFF_LOOKAHEAD; l++)
1217 for (i = 1; i <= (int) htbl[l-1]; i++, p++)
1219 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1220 /* Generate left-justified code followed by all possible bit sequences */
1221 lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
1222 for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--)
1224 dtbl->look_nbits[lookbits] = l;
1225 dtbl->look_sym[lookbits] = htbl[16+p];
1226 lookbits++;
1233 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1234 * If the incoming data is corrupted, decode_mcu could attempt to
1235 * reference values beyond the end of the array. To avoid a wild store,
1236 * we put some extra zeroes after the real entries.
1238 static const int zag[] =
1240 0, 1, 8, 16, 9, 2, 3, 10,
1241 17, 24, 32, 25, 18, 11, 4, 5,
1242 12, 19, 26, 33, 40, 48, 41, 34,
1243 27, 20, 13, 6, 7, 14, 21, 28,
1244 35, 42, 49, 56, 57, 50, 43, 36,
1245 29, 22, 15, 23, 30, 37, 44, 51,
1246 58, 59, 52, 45, 38, 31, 39, 46,
1247 53, 60, 61, 54, 47, 55, 62, 63,
1248 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1249 0, 0, 0, 0, 0, 0, 0, 0
1252 void build_lut(struct jpeg* p_jpeg)
1254 int i;
1255 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_dc,
1256 &p_jpeg->dc_derived_tbls[0]);
1257 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_ac,
1258 &p_jpeg->ac_derived_tbls[0]);
1259 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_dc,
1260 &p_jpeg->dc_derived_tbls[1]);
1261 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_ac,
1262 &p_jpeg->ac_derived_tbls[1]);
1264 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1265 for (i=0; i<64; i++)
1267 p_jpeg->qt_idct[0][zag[i]] = p_jpeg->quanttable[0][i];
1268 p_jpeg->qt_idct[1][zag[i]] = p_jpeg->quanttable[1][i];
1271 for (i=0; i<4; i++)
1272 p_jpeg->store_pos[i] = i; /* default ordering */
1274 /* assignments for the decoding of blocks */
1275 if (p_jpeg->frameheader[0].horizontal_sampling == 2
1276 && p_jpeg->frameheader[0].vertical_sampling == 1)
1277 { /* 4:2:2 */
1278 p_jpeg->blocks = 4;
1279 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1280 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1281 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1282 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1283 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1284 p_jpeg->mcu_membership[1] = 0;
1285 p_jpeg->mcu_membership[2] = 1;
1286 p_jpeg->mcu_membership[3] = 2;
1287 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1288 p_jpeg->tab_membership[1] = 0;
1289 p_jpeg->tab_membership[2] = 1;
1290 p_jpeg->tab_membership[3] = 1;
1291 p_jpeg->subsample_x[0] = 1;
1292 p_jpeg->subsample_x[1] = 2;
1293 p_jpeg->subsample_x[2] = 2;
1294 p_jpeg->subsample_y[0] = 1;
1295 p_jpeg->subsample_y[1] = 1;
1296 p_jpeg->subsample_y[2] = 1;
1298 if (p_jpeg->frameheader[0].horizontal_sampling == 1
1299 && p_jpeg->frameheader[0].vertical_sampling == 2)
1300 { /* 4:2:2 vertically subsampled */
1301 p_jpeg->store_pos[1] = 2; /* block positions are mirrored */
1302 p_jpeg->store_pos[2] = 1;
1303 p_jpeg->blocks = 4;
1304 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1305 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1306 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1307 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1308 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1309 p_jpeg->mcu_membership[1] = 0;
1310 p_jpeg->mcu_membership[2] = 1;
1311 p_jpeg->mcu_membership[3] = 2;
1312 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1313 p_jpeg->tab_membership[1] = 0;
1314 p_jpeg->tab_membership[2] = 1;
1315 p_jpeg->tab_membership[3] = 1;
1316 p_jpeg->subsample_x[0] = 1;
1317 p_jpeg->subsample_x[1] = 1;
1318 p_jpeg->subsample_x[2] = 1;
1319 p_jpeg->subsample_y[0] = 1;
1320 p_jpeg->subsample_y[1] = 2;
1321 p_jpeg->subsample_y[2] = 2;
1323 else if (p_jpeg->frameheader[0].horizontal_sampling == 2
1324 && p_jpeg->frameheader[0].vertical_sampling == 2)
1325 { /* 4:2:0 */
1326 p_jpeg->blocks = 6;
1327 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1328 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1329 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1330 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1331 p_jpeg->mcu_membership[0] = 0;
1332 p_jpeg->mcu_membership[1] = 0;
1333 p_jpeg->mcu_membership[2] = 0;
1334 p_jpeg->mcu_membership[3] = 0;
1335 p_jpeg->mcu_membership[4] = 1;
1336 p_jpeg->mcu_membership[5] = 2;
1337 p_jpeg->tab_membership[0] = 0;
1338 p_jpeg->tab_membership[1] = 0;
1339 p_jpeg->tab_membership[2] = 0;
1340 p_jpeg->tab_membership[3] = 0;
1341 p_jpeg->tab_membership[4] = 1;
1342 p_jpeg->tab_membership[5] = 1;
1343 p_jpeg->subsample_x[0] = 1;
1344 p_jpeg->subsample_x[1] = 2;
1345 p_jpeg->subsample_x[2] = 2;
1346 p_jpeg->subsample_y[0] = 1;
1347 p_jpeg->subsample_y[1] = 2;
1348 p_jpeg->subsample_y[2] = 2;
1350 else if (p_jpeg->frameheader[0].horizontal_sampling == 1
1351 && p_jpeg->frameheader[0].vertical_sampling == 1)
1352 { /* 4:4:4 */
1353 /* don't overwrite p_jpeg->blocks */
1354 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1355 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1356 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1357 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1358 p_jpeg->mcu_membership[0] = 0;
1359 p_jpeg->mcu_membership[1] = 1;
1360 p_jpeg->mcu_membership[2] = 2;
1361 p_jpeg->tab_membership[0] = 0;
1362 p_jpeg->tab_membership[1] = 1;
1363 p_jpeg->tab_membership[2] = 1;
1364 p_jpeg->subsample_x[0] = 1;
1365 p_jpeg->subsample_x[1] = 1;
1366 p_jpeg->subsample_x[2] = 1;
1367 p_jpeg->subsample_y[0] = 1;
1368 p_jpeg->subsample_y[1] = 1;
1369 p_jpeg->subsample_y[2] = 1;
1371 else
1373 /* error */
1380 * These functions/macros provide the in-line portion of bit fetching.
1381 * Use check_bit_buffer to ensure there are N bits in get_buffer
1382 * before using get_bits, peek_bits, or drop_bits.
1383 * check_bit_buffer(state,n,action);
1384 * Ensure there are N bits in get_buffer; if suspend, take action.
1385 * val = get_bits(n);
1386 * Fetch next N bits.
1387 * val = peek_bits(n);
1388 * Fetch next N bits without removing them from the buffer.
1389 * drop_bits(n);
1390 * Discard next N bits.
1391 * The value N should be a simple variable, not an expression, because it
1392 * is evaluated multiple times.
1395 INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
1397 if (pb->bits_left < nbits)
1398 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1399 unsigned char 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 byte = *pb->next_input_byte++;
1409 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1410 { /* simplification: just skip the (one-byte) marker code */
1411 pb->next_input_byte++;
1413 pb->get_buffer = (pb->get_buffer << 8) | byte;
1415 pb->bits_left += 16;
1419 INLINE int get_bits(struct bitstream* pb, int nbits)
1421 return ((int) (pb->get_buffer >> (pb->bits_left -= nbits))) & ((1<<nbits)-1);
1424 INLINE int peek_bits(struct bitstream* pb, int nbits)
1426 return ((int) (pb->get_buffer >> (pb->bits_left - nbits))) & ((1<<nbits)-1);
1429 INLINE void drop_bits(struct bitstream* pb, int nbits)
1431 pb->bits_left -= nbits;
1434 /* re-synchronize to entropy data (skip restart marker) */
1435 void search_restart(struct bitstream* pb)
1437 pb->next_input_byte--; /* we may have overread it, taking 2 bytes */
1438 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1439 while (pb->next_input_byte < pb->input_end &&
1440 (pb->next_input_byte[-2] != 0xFF || pb->next_input_byte[-1] == 0x00))
1442 pb->next_input_byte++;
1444 pb->bits_left = 0;
1447 /* Figure F.12: extend sign bit. */
1448 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1450 static const int extend_test[16] = /* entry n is 2**(n-1) */
1452 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1453 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1456 static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
1458 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1459 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1460 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1461 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1464 /* Decode a single value */
1465 INLINE int huff_decode_dc(struct bitstream* bs, struct derived_tbl* tbl)
1467 int nb, look, s, r;
1469 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1470 look = peek_bits(bs, HUFF_LOOKAHEAD);
1471 if ((nb = tbl->look_nbits[look]) != 0)
1473 drop_bits(bs, nb);
1474 s = tbl->look_sym[look];
1475 check_bit_buffer(bs, s);
1476 r = get_bits(bs, s);
1477 s = HUFF_EXTEND(r, s);
1479 else
1480 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1481 long code;
1482 nb=HUFF_LOOKAHEAD+1;
1483 check_bit_buffer(bs, nb);
1484 code = get_bits(bs, nb);
1485 while (code > tbl->maxcode[nb])
1487 code <<= 1;
1488 check_bit_buffer(bs, 1);
1489 code |= get_bits(bs, 1);
1490 nb++;
1492 if (nb > 16) /* error in Huffman */
1494 s=0; /* fake a zero, this is most safe */
1496 else
1498 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1499 check_bit_buffer(bs, s);
1500 r = get_bits(bs, s);
1501 s = HUFF_EXTEND(r, s);
1503 } /* end slow decode */
1504 return s;
1507 INLINE int huff_decode_ac(struct bitstream* bs, struct derived_tbl* tbl)
1509 int nb, look, s;
1511 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1512 look = peek_bits(bs, HUFF_LOOKAHEAD);
1513 if ((nb = tbl->look_nbits[look]) != 0)
1515 drop_bits(bs, nb);
1516 s = tbl->look_sym[look];
1518 else
1519 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1520 long code;
1521 nb=HUFF_LOOKAHEAD+1;
1522 check_bit_buffer(bs, nb);
1523 code = get_bits(bs, nb);
1524 while (code > tbl->maxcode[nb])
1526 code <<= 1;
1527 check_bit_buffer(bs, 1);
1528 code |= get_bits(bs, 1);
1529 nb++;
1531 if (nb > 16) /* error in Huffman */
1533 s=0; /* fake a zero, this is most safe */
1535 else
1537 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1539 } /* end slow decode */
1540 return s;
1544 #ifdef HAVE_LCD_COLOR
1546 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1547 /* Note: it keeps the original color subsampling, even if resized. */
1548 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1549 int downscale, void (*pf_progress)(int current, int total))
1551 struct bitstream bs; /* bitstream "object" */
1552 int block[64]; /* decoded DCT coefficients */
1554 int width, height;
1555 int skip_line[3]; /* bytes from one line to the next (skip_line) */
1556 int skip_strip[3], skip_mcu[3]; /* bytes to next DCT row / column */
1558 int i, x, y; /* loop counter */
1560 unsigned char* p_line[3] = {p_pixel[0], p_pixel[1], p_pixel[2]};
1561 unsigned char* p_byte[3]; /* bitmap pointer */
1563 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1564 int k_need; /* AC coefficients needed up to here */
1565 int zero_need; /* init the block with this many zeros */
1567 int last_dc_val[3] = {0, 0, 0}; /* or 128 for chroma? */
1568 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1569 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1571 /* pick the IDCT we want, determine how to work with coefs */
1572 if (downscale == 1)
1574 pf_idct = idct8x8;
1575 k_need = 64; /* all */
1576 zero_need = 63; /* all */
1578 else if (downscale == 2)
1580 pf_idct = idct4x4;
1581 k_need = 25; /* this far in zig-zag to cover 4*4 */
1582 zero_need = 27; /* clear this far in linear order */
1584 else if (downscale == 4)
1586 pf_idct = idct2x2;
1587 k_need = 5; /* this far in zig-zag to cover 2*2 */
1588 zero_need = 9; /* clear this far in linear order */
1590 else if (downscale == 8)
1592 pf_idct = idct1x1;
1593 k_need = 0; /* no AC, not needed */
1594 zero_need = 0; /* no AC, not needed */
1596 else return -1; /* not supported */
1598 /* init bitstream, fake a restart to make it start */
1599 bs.next_input_byte = p_jpeg->p_entropy_data;
1600 bs.bits_left = 0;
1601 bs.input_end = p_jpeg->p_entropy_end;
1603 width = p_jpeg->x_phys / downscale;
1604 height = p_jpeg->y_phys / downscale;
1605 for (i=0; i<3; i++) /* calculate some strides */
1607 skip_line[i] = width / p_jpeg->subsample_x[i];
1608 skip_strip[i] = skip_line[i]
1609 * (height / p_jpeg->y_mbl) / p_jpeg->subsample_y[i];
1610 skip_mcu[i] = width/p_jpeg->x_mbl / p_jpeg->subsample_x[i];
1613 /* prepare offsets about where to store the different blocks */
1614 store_offs[p_jpeg->store_pos[0]] = 0;
1615 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1616 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1617 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1619 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1621 for (i=0; i<3; i++) /* scan line init */
1623 p_byte[i] = p_line[i];
1624 p_line[i] += skip_strip[i];
1626 for (x=0; x<p_jpeg->x_mbl; x++)
1628 int blkn;
1630 /* Outer loop handles each block in the MCU */
1631 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1632 { /* Decode a single block's worth of coefficients */
1633 int k = 1; /* coefficient index */
1634 int s, r; /* huffman values */
1635 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1636 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1637 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1638 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1640 /* Section F.2.2.1: decode the DC coefficient difference */
1641 s = huff_decode_dc(&bs, dctbl);
1643 last_dc_val[ci] += s;
1644 block[0] = last_dc_val[ci]; /* output it (assumes zag[0] = 0) */
1646 /* coefficient buffer must be cleared */
1647 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1649 /* Section F.2.2.2: decode the AC coefficients */
1650 for (; k < k_need; k++)
1652 s = huff_decode_ac(&bs, actbl);
1653 r = s >> 4;
1654 s &= 15;
1656 if (s)
1658 k += r;
1659 check_bit_buffer(&bs, s);
1660 r = get_bits(&bs, s);
1661 block[zag[k]] = HUFF_EXTEND(r, s);
1663 else
1665 if (r != 15)
1667 k = 64;
1668 break;
1670 k += r;
1672 } /* for k */
1673 /* In this path we just discard the values */
1674 for (; k < 64; k++)
1676 s = huff_decode_ac(&bs, actbl);
1677 r = s >> 4;
1678 s &= 15;
1680 if (s)
1682 k += r;
1683 check_bit_buffer(&bs, s);
1684 drop_bits(&bs, s);
1686 else
1688 if (r != 15)
1689 break;
1690 k += r;
1692 } /* for k */
1694 if (ci == 0)
1695 { /* Y component needs to bother about block store */
1696 pf_idct(p_byte[0]+store_offs[blkn], block,
1697 p_jpeg->qt_idct[ti], skip_line[0]);
1699 else
1700 { /* chroma */
1701 pf_idct(p_byte[ci], block, p_jpeg->qt_idct[ti],
1702 skip_line[ci]);
1704 } /* for blkn */
1705 p_byte[0] += skip_mcu[0]; /* unrolled for (i=0; i<3; i++) loop */
1706 p_byte[1] += skip_mcu[1];
1707 p_byte[2] += skip_mcu[2];
1708 if (p_jpeg->restart_interval && --restart == 0)
1709 { /* if a restart marker is due: */
1710 restart = p_jpeg->restart_interval; /* count again */
1711 search_restart(&bs); /* align the bitstream */
1712 last_dc_val[0] = last_dc_val[1] =
1713 last_dc_val[2] = 0; /* reset decoder */
1715 } /* for x */
1716 if (pf_progress != NULL)
1717 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1718 } /* for y */
1720 return 0; /* success */
1722 #else /* !HAVE_LCD_COLOR */
1724 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1725 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[1], int downscale,
1726 void (*pf_progress)(int current, int total))
1728 struct bitstream bs; /* bitstream "object" */
1729 int block[64]; /* decoded DCT coefficients */
1731 int width, height;
1732 int skip_line; /* bytes from one line to the next (skip_line) */
1733 int skip_strip, skip_mcu; /* bytes to next DCT row / column */
1735 int x, y; /* loop counter */
1737 unsigned char* p_line = p_pixel[0];
1738 unsigned char* p_byte; /* bitmap pointer */
1740 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1741 int k_need; /* AC coefficients needed up to here */
1742 int zero_need; /* init the block with this many zeros */
1744 int last_dc_val = 0;
1745 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1746 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1748 /* pick the IDCT we want, determine how to work with coefs */
1749 if (downscale == 1)
1751 pf_idct = idct8x8;
1752 k_need = 64; /* all */
1753 zero_need = 63; /* all */
1755 else if (downscale == 2)
1757 pf_idct = idct4x4;
1758 k_need = 25; /* this far in zig-zag to cover 4*4 */
1759 zero_need = 27; /* clear this far in linear order */
1761 else if (downscale == 4)
1763 pf_idct = idct2x2;
1764 k_need = 5; /* this far in zig-zag to cover 2*2 */
1765 zero_need = 9; /* clear this far in linear order */
1767 else if (downscale == 8)
1769 pf_idct = idct1x1;
1770 k_need = 0; /* no AC, not needed */
1771 zero_need = 0; /* no AC, not needed */
1773 else return -1; /* not supported */
1775 /* init bitstream, fake a restart to make it start */
1776 bs.next_input_byte = p_jpeg->p_entropy_data;
1777 bs.bits_left = 0;
1778 bs.input_end = p_jpeg->p_entropy_end;
1780 width = p_jpeg->x_phys / downscale;
1781 height = p_jpeg->y_phys / downscale;
1782 skip_line = width;
1783 skip_strip = skip_line * (height / p_jpeg->y_mbl);
1784 skip_mcu = (width/p_jpeg->x_mbl);
1786 /* prepare offsets about where to store the different blocks */
1787 store_offs[p_jpeg->store_pos[0]] = 0;
1788 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1789 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1790 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1792 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1794 p_byte = p_line;
1795 p_line += skip_strip;
1796 for (x=0; x<p_jpeg->x_mbl; x++)
1798 int blkn;
1800 /* Outer loop handles each block in the MCU */
1801 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1802 { /* Decode a single block's worth of coefficients */
1803 int k = 1; /* coefficient index */
1804 int s, r; /* huffman values */
1805 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1806 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1807 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1808 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1810 /* Section F.2.2.1: decode the DC coefficient difference */
1811 s = huff_decode_dc(&bs, dctbl);
1813 if (ci == 0) /* only for Y component */
1815 last_dc_val += s;
1816 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
1818 /* coefficient buffer must be cleared */
1819 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1821 /* Section F.2.2.2: decode the AC coefficients */
1822 for (; k < k_need; k++)
1824 s = huff_decode_ac(&bs, actbl);
1825 r = s >> 4;
1826 s &= 15;
1828 if (s)
1830 k += r;
1831 check_bit_buffer(&bs, s);
1832 r = get_bits(&bs, s);
1833 block[zag[k]] = HUFF_EXTEND(r, s);
1835 else
1837 if (r != 15)
1839 k = 64;
1840 break;
1842 k += r;
1844 } /* for k */
1846 /* In this path we just discard the values */
1847 for (; k < 64; k++)
1849 s = huff_decode_ac(&bs, actbl);
1850 r = s >> 4;
1851 s &= 15;
1853 if (s)
1855 k += r;
1856 check_bit_buffer(&bs, s);
1857 drop_bits(&bs, s);
1859 else
1861 if (r != 15)
1862 break;
1863 k += r;
1865 } /* for k */
1867 if (ci == 0)
1868 { /* only for Y component */
1869 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
1870 skip_line);
1872 } /* for blkn */
1873 p_byte += skip_mcu;
1874 if (p_jpeg->restart_interval && --restart == 0)
1875 { /* if a restart marker is due: */
1876 restart = p_jpeg->restart_interval; /* count again */
1877 search_restart(&bs); /* align the bitstream */
1878 last_dc_val = 0; /* reset decoder */
1880 } /* for x */
1881 if (pf_progress != NULL)
1882 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1883 } /* for y */
1885 return 0; /* success */
1887 #endif /* !HAVE_LCD_COLOR */
1889 /**************** end JPEG code ********************/
1893 /**************** begin Application ********************/
1896 /************************* Types ***************************/
1898 struct t_disp
1900 #ifdef HAVE_LCD_COLOR
1901 unsigned char* bitmap[3]; /* Y, Cr, Cb */
1902 int csub_x, csub_y;
1903 #else
1904 unsigned char* bitmap[1]; /* Y only */
1905 #endif
1906 int width;
1907 int height;
1908 int stride;
1909 int x, y;
1912 /************************* Globals ***************************/
1914 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1915 struct t_disp disp[9];
1917 /* my memory pool (from the mp3 buffer) */
1918 char print[32]; /* use a common snprintf() buffer */
1919 unsigned char* buf; /* up to here currently used by image(s) */
1921 /* the remaining free part of the buffer for compressed+uncompressed images */
1922 unsigned char* buf_images;
1924 ssize_t buf_size, buf_images_size;
1925 /* the root of the images, hereafter are decompresed ones */
1926 unsigned char* buf_root;
1927 int root_size;
1929 int ds, ds_min, ds_max; /* downscaling and limits */
1930 static struct jpeg jpg; /* too large for stack */
1932 static struct tree_context *tree;
1934 /* the current full file name */
1935 static char np_file[MAX_PATH];
1936 int curfile = 0, direction = DIR_NONE, entries = 0;
1938 /* list of the jpeg files */
1939 char **file_pt;
1940 /* are we using the plugin buffer or the audio buffer? */
1941 bool plug_buf = false;
1944 /************************* Implementation ***************************/
1946 #ifdef HAVE_LCD_COLOR
1948 * Conversion of full 0-255 range YCrCb to RGB:
1949 * |R| |1.000000 -0.000001 1.402000| |Y'|
1950 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
1951 * |B| |1.000000 1.772000 0.000000| |Pr|
1952 * Scaled (yields s15-bit output):
1953 * |R| |128 0 179| |Y |
1954 * |G| = |128 -43 -91| |Cb - 128|
1955 * |B| |128 227 0| |Cr - 128|
1957 #define YFAC 128
1958 #define RVFAC 179
1959 #define GUFAC (-43)
1960 #define GVFAC (-91)
1961 #define BUFAC 227
1962 #define YUV_WHITE (255*YFAC)
1963 #define NODITHER_DELTA (127*YFAC)
1964 #define COMPONENT_SHIFT 15
1965 #define MATRIX_SHIFT 7
1967 static inline int clamp_component(int x)
1969 if ((unsigned)x > YUV_WHITE)
1970 x = x < 0 ? 0 : YUV_WHITE;
1971 return x;
1974 static inline int clamp_component_bits(int x, int bits)
1976 if ((unsigned)x > (1u << bits) - 1)
1977 x = x < 0 ? 0 : (1 << bits) - 1;
1978 return x;
1981 static inline int component_to_lcd(int x, int bits, int delta)
1983 /* Formula used in core bitmap loader. */
1984 return (((1 << bits) - 1)*x + (x >> (8 - bits)) + delta) >> COMPONENT_SHIFT;
1987 static inline int lcd_to_component(int x, int bits, int delta)
1989 /* Reasonable, approximate reversal to get a full range back from the
1990 quantized value. */
1991 return YUV_WHITE*x / ((1 << bits) - 1);
1992 (void)delta;
1995 #define RED 0
1996 #define GRN 1
1997 #define BLU 2
1999 struct rgb_err
2001 int16_t errbuf[LCD_WIDTH+2]; /* Error record for line below */
2002 } rgb_err_buffers[3];
2004 fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
2005 DITHER_DIFFUSION is set */
2007 struct rgb_pixel
2009 int r, g, b; /* Current pixel components in s16.0 */
2010 int inc; /* Current line increment (-1 or 1) */
2011 int row; /* Current row in source image */
2012 int col; /* Current column in source image */
2013 int ce[3]; /* Errors to apply to current pixel */
2014 struct rgb_err *e; /* RED, GRN, BLU */
2015 int epos; /* Current position in error record */
2018 struct rgb_pixel *pixel;
2020 /** round and truncate to lcd depth **/
2021 static fb_data pixel_to_lcd_colour(void)
2023 struct rgb_pixel *p = pixel;
2024 int r, g, b;
2026 r = component_to_lcd(p->r, LCD_RED_BITS, NODITHER_DELTA);
2027 r = clamp_component_bits(r, LCD_RED_BITS);
2029 g = component_to_lcd(p->g, LCD_GREEN_BITS, NODITHER_DELTA);
2030 g = clamp_component_bits(g, LCD_GREEN_BITS);
2032 b = component_to_lcd(p->b, LCD_BLUE_BITS, NODITHER_DELTA);
2033 b = clamp_component_bits(b, LCD_BLUE_BITS);
2035 return LCD_RGBPACK_LCD(r, g, b);
2038 /** write a monochrome pixel to the colour LCD **/
2039 static fb_data pixel_to_lcd_gray(void)
2041 int r, g, b;
2043 g = clamp_component(pixel->g);
2044 r = component_to_lcd(g, LCD_RED_BITS, NODITHER_DELTA);
2045 b = component_to_lcd(g, LCD_BLUE_BITS, NODITHER_DELTA);
2046 g = component_to_lcd(g, LCD_GREEN_BITS, NODITHER_DELTA);
2048 return LCD_RGBPACK_LCD(r, g, b);
2052 * Bayer ordered dithering - swiped from the core bitmap loader.
2054 static fb_data pixel_odither_to_lcd(void)
2056 /* canonical ordered dither matrix */
2057 static const unsigned char dither_matrix[16][16] = {
2058 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
2059 { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
2060 { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
2061 { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
2062 { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
2063 { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
2064 { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
2065 { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
2066 { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
2067 { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
2068 { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
2069 { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
2070 { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
2071 { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
2072 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
2073 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
2076 struct rgb_pixel *p = pixel;
2077 int r, g, b, delta;
2079 delta = dither_matrix[p->col & 15][p->row & 15] << MATRIX_SHIFT;
2081 r = component_to_lcd(p->r, LCD_RED_BITS, delta);
2082 r = clamp_component_bits(r, LCD_RED_BITS);
2084 g = component_to_lcd(p->g, LCD_GREEN_BITS, delta);
2085 g = clamp_component_bits(g, LCD_GREEN_BITS);
2087 b = component_to_lcd(p->b, LCD_BLUE_BITS, delta);
2088 b = clamp_component_bits(b, LCD_BLUE_BITS);
2090 p->col += p->inc;
2092 return LCD_RGBPACK_LCD(r, g, b);
2096 * Floyd/Steinberg dither to lcd depth.
2098 * Apply filter to each component in serpentine pattern. Kernel shown for
2099 * L->R scan. Kernel is reversed for R->L.
2100 * * 7
2101 * 3 5 1 (1/16)
2103 static inline void distribute_error(int *ce, struct rgb_err *e,
2104 int err, int epos, int inc)
2106 *ce = (7*err >> 4) + e->errbuf[epos+inc];
2107 e->errbuf[epos+inc] = err >> 4;
2108 e->errbuf[epos] += 5*err >> 4;
2109 e->errbuf[epos-inc] += 3*err >> 4;
2112 static fb_data pixel_fsdither_to_lcd(void)
2114 struct rgb_pixel *p = pixel;
2115 int rc, gc, bc, r, g, b;
2116 int inc, epos;
2118 /* Full components with error terms */
2119 rc = p->r + p->ce[RED];
2120 r = component_to_lcd(rc, LCD_RED_BITS, 0);
2121 r = clamp_component_bits(r, LCD_RED_BITS);
2123 gc = p->g + p->ce[GRN];
2124 g = component_to_lcd(gc, LCD_GREEN_BITS, 0);
2125 g = clamp_component_bits(g, LCD_GREEN_BITS);
2127 bc = p->b + p->ce[BLU];
2128 b = component_to_lcd(bc, LCD_BLUE_BITS, 0);
2129 b = clamp_component_bits(b, LCD_BLUE_BITS);
2131 /* Get pixel errors */
2132 rc -= lcd_to_component(r, LCD_RED_BITS, 0);
2133 gc -= lcd_to_component(g, LCD_GREEN_BITS, 0);
2134 bc -= lcd_to_component(b, LCD_BLUE_BITS, 0);
2136 /* Spead error to surrounding pixels. */
2137 inc = p->inc;
2138 epos = p->epos;
2139 p->epos += inc;
2141 distribute_error(&p->ce[RED], &p->e[RED], rc, epos, inc);
2142 distribute_error(&p->ce[GRN], &p->e[GRN], gc, epos, inc);
2143 distribute_error(&p->ce[BLU], &p->e[BLU], bc, epos, inc);
2145 /* Pack and return pixel */
2146 return LCD_RGBPACK_LCD(r, g, b);
2149 /* Functions for each output mode, colour then grayscale. */
2150 static fb_data (* const pixel_funcs[COLOUR_NUM_MODES][DITHER_NUM_MODES])(void) =
2152 [COLOURMODE_COLOUR] =
2154 [DITHER_NONE] = pixel_to_lcd_colour,
2155 [DITHER_ORDERED] = pixel_odither_to_lcd,
2156 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2158 [COLOURMODE_GRAY] =
2160 [DITHER_NONE] = pixel_to_lcd_gray,
2161 [DITHER_ORDERED] = pixel_odither_to_lcd,
2162 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2167 * Draw a partial YUV colour bitmap
2169 * Runs serpentine pattern when dithering is DITHER_DIFFUSION, else scan is
2170 * always L->R.
2172 void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
2173 int src_x, int src_y, int stride,
2174 int x, int y, int width, int height)
2176 fb_data *dst, *dst_end;
2177 fb_data (*pixel_func)(void);
2178 struct rgb_pixel px;
2180 if (x + width > LCD_WIDTH)
2181 width = LCD_WIDTH - x; /* Clip right */
2182 if (x < 0)
2183 width += x, x = 0; /* Clip left */
2184 if (width <= 0)
2185 return; /* nothing left to do */
2187 if (y + height > LCD_HEIGHT)
2188 height = LCD_HEIGHT - y; /* Clip bottom */
2189 if (y < 0)
2190 height += y, y = 0; /* Clip top */
2191 if (height <= 0)
2192 return; /* nothing left to do */
2194 pixel = &px;
2196 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
2197 dst_end = dst + LCD_WIDTH * height;
2199 if (jpeg_settings.colour_mode == COLOURMODE_GRAY)
2200 csub_y = 0; /* Ignore Cb, Cr */
2202 pixel_func = pixel_funcs[jpeg_settings.colour_mode]
2203 [jpeg_settings.dither_mode];
2205 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2207 /* Reset error terms. */
2208 px.e = rgb_err_buffers;
2209 px.ce[RED] = px.ce[GRN] = px.ce[BLU] = 0;
2210 rb->memset(px.e, 0, 3*sizeof (struct rgb_err));
2215 fb_data *dst_row, *row_end;
2216 const unsigned char *ysrc;
2217 px.inc = 1;
2219 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2221 /* Use R->L scan on odd lines */
2222 px.inc -= (src_y & 1) << 1;
2223 px.epos = x + 1;
2225 if (px.inc < 0)
2226 px.epos += width - 1;
2229 if (px.inc == 1)
2231 /* Scan is L->R */
2232 dst_row = dst;
2233 row_end = dst_row + width;
2234 px.col = src_x;
2236 else
2238 /* Scan is R->L */
2239 row_end = dst - 1;
2240 dst_row = row_end + width;
2241 px.col = src_x + width - 1;
2244 ysrc = src[0] + stride * src_y + px.col;
2245 px.row = src_y;
2247 /* Do one row of pixels */
2248 if (csub_y) /* colour */
2250 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
2251 const unsigned char *usrc, *vsrc;
2253 usrc = src[1] + (stride/csub_x) * (src_y/csub_y)
2254 + (px.col/csub_x);
2255 vsrc = src[2] + (stride/csub_x) * (src_y/csub_y)
2256 + (px.col/csub_x);
2257 int xphase = px.col % csub_x;
2258 int xphase_reset = px.inc * csub_x;
2259 int y, v, u, rv, guv, bu;
2261 v = *vsrc - 128;
2262 vsrc += px.inc;
2263 u = *usrc - 128;
2264 usrc += px.inc;
2265 rv = RVFAC*v;
2266 guv = GUFAC*u + GVFAC*v;
2267 bu = BUFAC*u;
2269 while (1)
2271 y = YFAC*(*ysrc);
2272 ysrc += px.inc;
2273 px.r = y + rv;
2274 px.g = y + guv;
2275 px.b = y + bu;
2277 *dst_row = pixel_func();
2278 dst_row += px.inc;
2280 if (dst_row == row_end)
2281 break;
2283 xphase += px.inc;
2284 if ((unsigned)xphase < (unsigned)csub_x)
2285 continue;
2287 /* fetch new chromas */
2288 v = *vsrc - 128;
2289 vsrc += px.inc;
2290 u = *usrc - 128;
2291 usrc += px.inc;
2292 rv = RVFAC*v;
2293 guv = GUFAC*u + GVFAC*v;
2294 bu = BUFAC*u;
2296 xphase -= xphase_reset;
2299 else /* monochrome */
2303 /* Set all components the same for dithering purposes */
2304 px.g = px.r = px.b = YFAC*(*ysrc);
2305 *dst_row = pixel_func();
2306 ysrc += px.inc;
2307 dst_row += px.inc;
2309 while (dst_row != row_end);
2312 src_y++;
2313 dst += LCD_WIDTH;
2315 while (dst < dst_end);
2318 #endif /* HAVE_LCD_COLOR */
2321 /* support function for qsort() */
2322 static int compare(const void* p1, const void* p2)
2324 return rb->strcasecmp(*((char **)p1), *((char **)p2));
2327 bool jpg_ext(const char ext[])
2329 if(!ext)
2330 return false;
2331 if(!rb->strcasecmp(ext,".jpg") ||
2332 !rb->strcasecmp(ext,".jpe") ||
2333 !rb->strcasecmp(ext,".jpeg"))
2334 return true;
2335 else
2336 return false;
2339 /*Read directory contents for scrolling. */
2340 void get_pic_list(void)
2342 int i;
2343 long int str_len = 0;
2344 char *pname;
2345 tree = rb->tree_get_context();
2347 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2348 file_pt = rb->plugin_get_buffer((size_t *)&buf_size);
2349 #else
2350 file_pt = rb->plugin_get_audio_buffer((size_t *)&buf_size);
2351 #endif
2353 for(i = 0; i < tree->filesindir; i++)
2355 if(jpg_ext(rb->strrchr(&tree->name_buffer[str_len],'.')))
2356 file_pt[entries++] = &tree->name_buffer[str_len];
2358 str_len += rb->strlen(&tree->name_buffer[str_len]) + 1;
2361 rb->qsort(file_pt, entries, sizeof(char**), compare);
2363 /* Remove path and leave only the name.*/
2364 pname = rb->strrchr(np_file,'/');
2365 pname++;
2367 /* Find Selected File. */
2368 for(i = 0; i < entries; i++)
2369 if(!rb->strcmp(file_pt[i], pname))
2370 curfile = i;
2373 int change_filename(int direct)
2375 int count = 0;
2376 direction = direct;
2378 if(direct == DIR_PREV)
2382 count++;
2383 if(curfile == 0)
2384 curfile = entries - 1;
2385 else
2386 curfile--;
2387 }while(file_pt[curfile] == '\0' && count < entries);
2388 /* we "erase" the file name if we encounter
2389 * a non-supported file, so skip it now */
2391 else /* DIR_NEXT/DIR_NONE */
2395 count++;
2396 if(curfile == entries - 1)
2397 curfile = 0;
2398 else
2399 curfile++;
2400 }while(file_pt[curfile] == '\0' && count < entries);
2403 if(count == entries && file_pt[curfile] == '\0')
2405 rb->splash(HZ, "No supported files");
2406 return PLUGIN_ERROR;
2408 if(rb->strlen(tree->currdir) > 1)
2410 rb->strcpy(np_file, tree->currdir);
2411 rb->strcat(np_file, "/");
2413 else
2414 rb->strcpy(np_file, tree->currdir);
2416 rb->strcat(np_file, file_pt[curfile]);
2418 return PLUGIN_OTHER;
2421 /* switch off overlay, for handling SYS_ events */
2422 void cleanup(void *parameter)
2424 (void)parameter;
2425 #ifdef USEGSLIB
2426 grey_show(false);
2427 #endif
2430 #define VSCROLL (LCD_HEIGHT/8)
2431 #define HSCROLL (LCD_WIDTH/10)
2433 #define ZOOM_IN 100 /* return codes for below function */
2434 #define ZOOM_OUT 101
2436 #ifdef HAVE_LCD_COLOR
2437 bool set_option_grayscale(void)
2439 bool gray = jpeg_settings.colour_mode == COLOURMODE_GRAY;
2440 rb->set_bool("Grayscale", &gray);
2441 jpeg_settings.colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
2442 return false;
2445 bool set_option_dithering(void)
2447 static const struct opt_items dithering[DITHER_NUM_MODES] = {
2448 [DITHER_NONE] = { "Off", -1 },
2449 [DITHER_ORDERED] = { "Ordered", -1 },
2450 [DITHER_DIFFUSION] = { "Diffusion", -1 },
2453 rb->set_option("Dithering", &jpeg_settings.dither_mode, INT,
2454 dithering, DITHER_NUM_MODES, NULL);
2455 return false;
2458 static void display_options(void)
2460 static const struct menu_item items[] = {
2461 { "Grayscale", set_option_grayscale },
2462 { "Dithering", set_option_dithering },
2465 int m = menu_init(rb, items, ARRAYLEN(items),
2466 NULL, NULL, NULL, NULL);
2467 menu_run(m);
2468 menu_exit(m);
2470 #endif /* HAVE_LCD_COLOR */
2472 int show_menu(void) /* return 1 to quit */
2474 #if LCD_DEPTH > 1
2475 rb->lcd_set_backdrop(old_backdrop);
2476 #ifdef HAVE_LCD_COLOR
2477 rb->lcd_set_foreground(rb->global_settings->fg_color);
2478 rb->lcd_set_background(rb->global_settings->bg_color);
2479 #else
2480 rb->lcd_set_foreground(LCD_BLACK);
2481 rb->lcd_set_background(LCD_WHITE);
2482 #endif
2483 #endif
2484 int m;
2485 int result;
2487 enum menu_id
2489 MIID_QUIT = 0,
2490 MIID_TOGGLE_SS_MODE,
2491 MIID_CHANGE_SS_MODE,
2492 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2493 MIID_SHOW_PLAYBACK_MENU,
2494 #endif
2495 #ifdef HAVE_LCD_COLOR
2496 MIID_DISPLAY_OPTIONS,
2497 #endif
2498 MIID_RETURN,
2501 static const struct menu_item items[] = {
2502 [MIID_QUIT] =
2503 { "Quit", NULL },
2504 [MIID_TOGGLE_SS_MODE] =
2505 { "Toggle Slideshow Mode", NULL },
2506 [MIID_CHANGE_SS_MODE] =
2507 { "Change Slideshow Time", NULL },
2508 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2509 [MIID_SHOW_PLAYBACK_MENU] =
2510 { "Show Playback Menu", NULL },
2511 #endif
2512 #ifdef HAVE_LCD_COLOR
2513 [MIID_DISPLAY_OPTIONS] =
2514 { "Display Options", NULL },
2515 #endif
2516 [MIID_RETURN] =
2517 { "Return", NULL },
2520 static const struct opt_items slideshow[2] = {
2521 { "Disable", -1 },
2522 { "Enable", -1 },
2525 m = menu_init(rb, items, sizeof(items) / sizeof(*items),
2526 NULL, NULL, NULL, NULL);
2527 result=menu_show(m);
2529 switch (result)
2531 case MIID_QUIT:
2532 menu_exit(m);
2533 return 1;
2534 break;
2535 case MIID_TOGGLE_SS_MODE:
2536 rb->set_option("Toggle Slideshow", &slideshow_enabled, INT,
2537 slideshow , 2, NULL);
2538 break;
2539 case MIID_CHANGE_SS_MODE:
2540 rb->set_int("Slideshow Time", "s", UNIT_SEC,
2541 &jpeg_settings.ss_timeout, NULL, 1,
2542 SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, NULL);
2543 break;
2545 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2546 case MIID_SHOW_PLAYBACK_MENU:
2547 playback_control(rb);
2548 break;
2549 #endif
2550 #ifdef HAVE_LCD_COLOR
2551 case MIID_DISPLAY_OPTIONS:
2552 display_options();
2553 break;
2554 #endif
2555 case MIID_RETURN:
2556 break;
2559 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
2560 /* change ata spindown time based on slideshow time setting */
2561 immediate_ata_off = false;
2562 rb->ata_spindown(rb->global_settings->disk_spindown);
2564 if (slideshow_enabled)
2566 if(jpeg_settings.ss_timeout < 10)
2568 /* slideshow times < 10s keep disk spinning */
2569 rb->ata_spindown(0);
2571 else if (!rb->mp3_is_playing())
2573 /* slideshow times > 10s and not playing: ata_off after load */
2574 immediate_ata_off = true;
2577 #endif
2578 #if LCD_DEPTH > 1
2579 rb->lcd_set_backdrop(NULL);
2580 rb->lcd_set_foreground(LCD_WHITE);
2581 rb->lcd_set_background(LCD_BLACK);
2582 #endif
2583 rb->lcd_clear_display();
2584 menu_exit(m);
2585 return 0;
2587 /* interactively scroll around the image */
2588 int scroll_bmp(struct t_disp* pdisp)
2590 int lastbutton = 0;
2592 while (true)
2594 int button;
2595 int move;
2597 if (slideshow_enabled)
2598 button = rb->button_get_w_tmo(jpeg_settings.ss_timeout * HZ);
2599 else button = rb->button_get(true);
2601 running_slideshow = false;
2603 switch(button)
2605 case JPEG_LEFT:
2606 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2607 return change_filename(DIR_PREV);
2608 case JPEG_LEFT | BUTTON_REPEAT:
2609 move = MIN(HSCROLL, pdisp->x);
2610 if (move > 0)
2612 MYXLCD(scroll_right)(move); /* scroll right */
2613 pdisp->x -= move;
2614 #ifdef HAVE_LCD_COLOR
2615 yuv_bitmap_part(
2616 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2617 pdisp->x, pdisp->y, pdisp->stride,
2618 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2619 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2620 #else
2621 MYXLCD(gray_bitmap_part)(
2622 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2623 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2624 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2625 #endif
2626 MYLCD_UPDATE();
2628 break;
2630 case JPEG_RIGHT:
2631 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2632 return change_filename(DIR_NEXT);
2633 case JPEG_RIGHT | BUTTON_REPEAT:
2634 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
2635 if (move > 0)
2637 MYXLCD(scroll_left)(move); /* scroll left */
2638 pdisp->x += move;
2639 #ifdef HAVE_LCD_COLOR
2640 yuv_bitmap_part(
2641 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2642 pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride,
2643 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2644 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2645 #else
2646 MYXLCD(gray_bitmap_part)(
2647 pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move,
2648 pdisp->y, pdisp->stride,
2649 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2650 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2651 #endif
2652 MYLCD_UPDATE();
2654 break;
2656 case JPEG_UP:
2657 case JPEG_UP | BUTTON_REPEAT:
2658 move = MIN(VSCROLL, pdisp->y);
2659 if (move > 0)
2661 MYXLCD(scroll_down)(move); /* scroll down */
2662 pdisp->y -= move;
2663 #ifdef HAVE_LCD_COLOR
2664 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2666 /* Draw over the band at the top of the last update
2667 caused by lack of error history on line zero. */
2668 move = MIN(move + 1, pdisp->y + pdisp->height);
2671 yuv_bitmap_part(
2672 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2673 pdisp->x, pdisp->y, pdisp->stride,
2674 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2675 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2676 #else
2677 MYXLCD(gray_bitmap_part)(
2678 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2679 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2680 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2681 #endif
2682 MYLCD_UPDATE();
2684 break;
2686 case JPEG_DOWN:
2687 case JPEG_DOWN | BUTTON_REPEAT:
2688 move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT);
2689 if (move > 0)
2691 MYXLCD(scroll_up)(move); /* scroll up */
2692 pdisp->y += move;
2693 #ifdef HAVE_LCD_COLOR
2694 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2696 /* Save the line that was on the last line of the display
2697 and draw one extra line above then recover the line with
2698 image data that had an error history when it was drawn.
2700 move++, pdisp->y--;
2701 MEMCPY(rgb_linebuf,
2702 rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2703 LCD_WIDTH*sizeof (fb_data));
2706 yuv_bitmap_part(
2707 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x,
2708 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2709 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2710 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2712 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2714 /* Cover the first row drawn with previous image data. */
2715 MEMCPY(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2716 rgb_linebuf,
2717 LCD_WIDTH*sizeof (fb_data));
2718 pdisp->y++;
2720 #else
2721 MYXLCD(gray_bitmap_part)(
2722 pdisp->bitmap[0], pdisp->x,
2723 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2724 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2725 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2726 #endif
2727 MYLCD_UPDATE();
2729 break;
2730 case BUTTON_NONE:
2731 if (!slideshow_enabled)
2732 break;
2733 running_slideshow = true;
2734 if (entries > 0)
2735 return change_filename(DIR_NEXT);
2736 break;
2738 #ifdef JPEG_SLIDE_SHOW
2739 case JPEG_SLIDE_SHOW:
2740 slideshow_enabled = !slideshow_enabled;
2741 running_slideshow = slideshow_enabled;
2742 break;
2743 #endif
2745 #ifdef JPEG_NEXT_REPEAT
2746 case JPEG_NEXT_REPEAT:
2747 #endif
2748 case JPEG_NEXT:
2749 if (entries > 0)
2750 return change_filename(DIR_NEXT);
2751 break;
2753 #ifdef JPEG_PREVIOUS_REPEAT
2754 case JPEG_PREVIOUS_REPEAT:
2755 #endif
2756 case JPEG_PREVIOUS:
2757 if (entries > 0)
2758 return change_filename(DIR_PREV);
2759 break;
2761 case JPEG_ZOOM_IN:
2762 #ifdef JPEG_ZOOM_PRE
2763 if (lastbutton != JPEG_ZOOM_PRE)
2764 break;
2765 #endif
2766 return ZOOM_IN;
2767 break;
2769 case JPEG_ZOOM_OUT:
2770 #ifdef JPEG_ZOOM_PRE
2771 if (lastbutton != JPEG_ZOOM_PRE)
2772 break;
2773 #endif
2774 return ZOOM_OUT;
2775 break;
2776 #ifdef JPEG_RC_MENU
2777 case JPEG_RC_MENU:
2778 #endif
2779 case JPEG_MENU:
2780 #ifdef USEGSLIB
2781 grey_show(false); /* switch off greyscale overlay */
2782 #endif
2783 if (show_menu() == 1)
2784 return PLUGIN_OK;
2786 #ifdef USEGSLIB
2787 grey_show(true); /* switch on greyscale overlay */
2788 #else
2789 yuv_bitmap_part(
2790 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2791 pdisp->x, pdisp->y, pdisp->stride,
2792 MAX(0, (LCD_WIDTH - pdisp->width) / 2),
2793 MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
2794 MIN(LCD_WIDTH, pdisp->width),
2795 MIN(LCD_HEIGHT, pdisp->height));
2796 MYLCD_UPDATE();
2797 #endif
2798 break;
2799 default:
2800 if (rb->default_event_handler_ex(button, cleanup, NULL)
2801 == SYS_USB_CONNECTED)
2802 return PLUGIN_USB_CONNECTED;
2803 break;
2805 } /* switch */
2807 if (button != BUTTON_NONE)
2808 lastbutton = button;
2809 } /* while (true) */
2812 /********************* main function *************************/
2814 /* callback updating a progress meter while JPEG decoding */
2815 void cb_progess(int current, int total)
2817 rb->yield(); /* be nice to the other threads */
2818 if(!running_slideshow)
2820 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-8, LCD_WIDTH, 8, total, 0,
2821 current, HORIZONTAL);
2822 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
2824 #ifndef USEGSLIB
2825 else
2827 /* in slideshow mode, keep gui interference to a minimum */
2828 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-4, LCD_WIDTH, 4, total, 0,
2829 current, HORIZONTAL);
2830 rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4);
2832 #endif
2835 int jpegmem(struct jpeg *p_jpg, int ds)
2837 int size;
2839 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
2840 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
2841 #ifdef HAVE_LCD_COLOR
2842 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
2844 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
2845 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
2846 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
2847 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
2849 #endif
2850 return size;
2853 /* how far can we zoom in without running out of memory */
2854 int min_downscale(struct jpeg *p_jpg, int bufsize)
2856 int downscale = 8;
2858 if (jpegmem(p_jpg, 8) > bufsize)
2859 return 0; /* error, too large, even 1:8 doesn't fit */
2861 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
2862 downscale /= 2;
2864 return downscale;
2868 /* how far can we zoom out, to fit image into the LCD */
2869 int max_downscale(struct jpeg *p_jpg)
2871 int downscale = 1;
2873 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale
2874 || p_jpg->y_size > LCD_HEIGHT*downscale))
2876 downscale *= 2;
2879 return downscale;
2883 /* return decoded or cached image */
2884 struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2886 int w, h; /* used to center output */
2887 int size; /* decompressed image size */
2888 long time; /* measured ticks */
2889 int status;
2891 struct t_disp* p_disp = &disp[ds]; /* short cut */
2893 if (p_disp->bitmap[0] != NULL)
2895 return p_disp; /* we still have it */
2898 /* assign image buffer */
2900 /* physical size needed for decoding */
2901 size = jpegmem(p_jpg, ds);
2902 if (buf_size <= size)
2903 { /* have to discard the current */
2904 int i;
2905 for (i=1; i<=8; i++)
2906 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
2907 buf = buf_root; /* start again from the beginning of the buffer */
2908 buf_size = root_size;
2911 #ifdef HAVE_LCD_COLOR
2912 if (p_jpg->blocks > 1) /* colour jpeg */
2914 int i;
2916 for (i = 1; i < 3; i++)
2918 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
2919 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
2920 p_disp->bitmap[i] = buf;
2921 buf += size;
2922 buf_size -= size;
2924 p_disp->csub_x = p_jpg->subsample_x[1];
2925 p_disp->csub_y = p_jpg->subsample_y[1];
2927 else
2929 p_disp->csub_x = p_disp->csub_y = 0;
2930 p_disp->bitmap[1] = p_disp->bitmap[2] = buf;
2932 #endif
2933 /* size may be less when decoded (if height is not block aligned) */
2934 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
2935 p_disp->bitmap[0] = buf;
2936 buf += size;
2937 buf_size -= size;
2939 if(!running_slideshow)
2941 rb->snprintf(print, sizeof(print), "decoding %d*%d",
2942 p_jpg->x_size/ds, p_jpg->y_size/ds);
2943 rb->lcd_puts(0, 3, print);
2944 rb->lcd_update();
2947 /* update image properties */
2948 p_disp->width = p_jpg->x_size / ds;
2949 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
2950 p_disp->height = p_jpg->y_size / ds;
2952 /* the actual decoding */
2953 time = *rb->current_tick;
2954 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2955 rb->cpu_boost(true);
2956 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2957 rb->cpu_boost(false);
2958 #else
2959 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2960 #endif
2961 if (status)
2963 rb->splash(HZ, "decode error %d", status);
2964 file_pt[curfile] = '\0';
2965 return NULL;
2967 time = *rb->current_tick - time;
2969 if(!running_slideshow)
2971 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
2972 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
2973 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
2974 rb->lcd_update();
2977 return p_disp;
2981 /* set the view to the given center point, limit if necessary */
2982 void set_view (struct t_disp* p_disp, int cx, int cy)
2984 int x, y;
2986 /* plain center to available width/height */
2987 x = cx - MIN(LCD_WIDTH, p_disp->width) / 2;
2988 y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2;
2990 /* limit against upper image size */
2991 x = MIN(p_disp->width - LCD_WIDTH, x);
2992 y = MIN(p_disp->height - LCD_HEIGHT, y);
2994 /* limit against negative side */
2995 x = MAX(0, x);
2996 y = MAX(0, y);
2998 p_disp->x = x; /* set the values */
2999 p_disp->y = y;
3003 /* calculate the view center based on the bitmap position */
3004 void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
3006 *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2;
3007 *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2;
3011 /* load, decode, display the image */
3012 int load_and_show(char* filename)
3014 int fd;
3015 int filesize;
3016 unsigned char* buf_jpeg; /* compressed JPEG image */
3017 int status;
3018 struct t_disp* p_disp; /* currenly displayed image */
3019 int cx, cy; /* view center */
3021 fd = rb->open(filename, O_RDONLY);
3022 if (fd < 0)
3024 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
3025 rb->splash(HZ, print);
3026 return PLUGIN_ERROR;
3028 filesize = rb->filesize(fd);
3029 rb->memset(&disp, 0, sizeof(disp));
3031 buf = buf_images + filesize;
3032 buf_size = buf_images_size - filesize;
3033 /* allocate JPEG buffer */
3034 buf_jpeg = buf_images;
3036 buf_root = buf; /* we can start the decompressed images behind it */
3037 root_size = buf_size;
3039 if (buf_size <= 0)
3041 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
3042 if(plug_buf)
3044 rb->close(fd);
3045 rb->lcd_setfont(FONT_SYSFIXED);
3046 rb->lcd_clear_display();
3047 rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
3048 rb->lcd_puts(0,0,print);
3049 rb->lcd_puts(0,1,"Not enough plugin memory!");
3050 rb->lcd_puts(0,2,"Zoom In: Stop playback.");
3051 if(entries>1)
3052 rb->lcd_puts(0,3,"Left/Right: Skip File.");
3053 rb->lcd_puts(0,4,"Off: Quit.");
3054 rb->lcd_update();
3055 rb->lcd_setfont(FONT_UI);
3057 rb->button_clear_queue();
3059 while (1)
3061 int button = rb->button_get(true);
3062 switch(button)
3064 case JPEG_ZOOM_IN:
3065 plug_buf = false;
3066 buf_images = rb->plugin_get_audio_buffer(
3067 (size_t *)&buf_images_size);
3068 /*try again this file, now using the audio buffer */
3069 return PLUGIN_OTHER;
3070 #ifdef JPEG_RC_MENU
3071 case JPEG_RC_MENU:
3072 #endif
3073 case JPEG_MENU:
3074 return PLUGIN_OK;
3076 case JPEG_LEFT:
3077 if(entries>1)
3079 rb->lcd_clear_display();
3080 return change_filename(DIR_PREV);
3082 break;
3084 case JPEG_RIGHT:
3085 if(entries>1)
3087 rb->lcd_clear_display();
3088 return change_filename(DIR_NEXT);
3090 break;
3091 default:
3092 if(rb->default_event_handler_ex(button, cleanup, NULL)
3093 == SYS_USB_CONNECTED)
3094 return PLUGIN_USB_CONNECTED;
3099 else
3100 #endif
3102 rb->splash(HZ, "Out of Memory");
3103 rb->close(fd);
3104 return PLUGIN_ERROR;
3108 if(!running_slideshow)
3110 #if LCD_DEPTH > 1
3111 rb->lcd_set_foreground(LCD_WHITE);
3112 rb->lcd_set_background(LCD_BLACK);
3113 rb->lcd_set_backdrop(NULL);
3114 #endif
3116 rb->lcd_clear_display();
3117 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
3118 rb->lcd_puts(0, 0, print);
3119 rb->lcd_update();
3121 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
3122 rb->lcd_puts(0, 1, print);
3123 rb->lcd_update();
3126 rb->read(fd, buf_jpeg, filesize);
3127 rb->close(fd);
3129 if(!running_slideshow)
3131 rb->snprintf(print, sizeof(print), "decoding markers");
3132 rb->lcd_puts(0, 2, print);
3133 rb->lcd_update();
3135 #ifndef SIMULATOR
3136 else if(immediate_ata_off)
3138 /* running slideshow and time is long enough: power down disk */
3139 rb->ata_sleep();
3141 #endif
3143 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
3144 /* process markers, unstuffing */
3145 status = process_markers(buf_jpeg, filesize, &jpg);
3147 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
3148 { /* bad format or minimum components not contained */
3149 rb->splash(HZ, "unsupported %d", status);
3150 file_pt[curfile] = '\0';
3151 return change_filename(direction);
3154 if (!(status & DHT)) /* if no Huffman table present: */
3155 default_huff_tbl(&jpg); /* use default */
3156 build_lut(&jpg); /* derive Huffman and other lookup-tables */
3158 if(!running_slideshow)
3160 rb->snprintf(print, sizeof(print), "image %dx%d", jpg.x_size, jpg.y_size);
3161 rb->lcd_puts(0, 2, print);
3162 rb->lcd_update();
3164 ds_max = max_downscale(&jpg); /* check display constraint */
3165 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */
3166 if (ds_min == 0)
3168 rb->splash(HZ, "too large");
3169 file_pt[curfile] = '\0';
3170 return change_filename(direction);
3173 ds = ds_max; /* initials setting */
3174 cx = jpg.x_size/ds/2; /* center the view */
3175 cy = jpg.y_size/ds/2;
3177 do /* loop the image prepare and decoding when zoomed */
3179 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */
3180 if (p_disp == NULL)
3181 return change_filename(direction);
3183 set_view(p_disp, cx, cy);
3185 if(!running_slideshow)
3187 rb->snprintf(print, sizeof(print), "showing %dx%d",
3188 p_disp->width, p_disp->height);
3189 rb->lcd_puts(0, 3, print);
3190 rb->lcd_update();
3192 MYLCD(clear_display)();
3193 #ifdef HAVE_LCD_COLOR
3194 yuv_bitmap_part(
3195 p_disp->bitmap, p_disp->csub_x, p_disp->csub_y,
3196 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 #else
3202 MYXLCD(gray_bitmap_part)(
3203 p_disp->bitmap[0], p_disp->x, p_disp->y, p_disp->stride,
3204 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3205 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3206 MIN(LCD_WIDTH, p_disp->width),
3207 MIN(LCD_HEIGHT, p_disp->height));
3208 #endif
3209 MYLCD_UPDATE();
3211 #ifdef USEGSLIB
3212 grey_show(true); /* switch on greyscale overlay */
3213 #endif
3215 /* drawing is now finished, play around with scrolling
3216 * until you press OFF or connect USB
3218 while (1)
3220 status = scroll_bmp(p_disp);
3221 if (status == ZOOM_IN)
3223 if (ds > ds_min)
3225 ds /= 2; /* reduce downscaling to zoom in */
3226 get_view(p_disp, &cx, &cy);
3227 cx *= 2; /* prepare the position in the new image */
3228 cy *= 2;
3230 else
3231 continue;
3234 if (status == ZOOM_OUT)
3236 if (ds < ds_max)
3238 ds *= 2; /* increase downscaling to zoom out */
3239 get_view(p_disp, &cx, &cy);
3240 cx /= 2; /* prepare the position in the new image */
3241 cy /= 2;
3243 else
3244 continue;
3246 break;
3249 #ifdef USEGSLIB
3250 grey_show(false); /* switch off overlay */
3251 #endif
3252 rb->lcd_clear_display();
3254 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
3255 && status != PLUGIN_OTHER);
3256 #ifdef USEGSLIB
3257 rb->lcd_update();
3258 #endif
3259 return status;
3262 /******************** Plugin entry point *********************/
3264 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
3266 rb = api;
3268 int condition;
3269 #ifdef USEGSLIB
3270 long greysize; /* helper */
3271 #endif
3272 #if LCD_DEPTH > 1
3273 old_backdrop = rb->lcd_get_backdrop();
3274 #endif
3276 if(!parameter) return PLUGIN_ERROR;
3278 rb->strcpy(np_file, parameter);
3279 get_pic_list();
3281 if(!entries) return PLUGIN_ERROR;
3283 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
3284 if(rb->audio_status())
3286 buf = rb->plugin_get_buffer((size_t *)&buf_size) +
3287 (entries * sizeof(char**));
3288 buf_size -= (entries * sizeof(char**));
3289 plug_buf = true;
3291 else
3292 buf = rb->plugin_get_audio_buffer((size_t *)&buf_size);
3293 #else
3294 buf = rb->plugin_get_audio_buffer(&buf_size) +
3295 (entries * sizeof(char**));
3296 buf_size -= (entries * sizeof(char**));
3297 #endif
3299 #ifdef USEGSLIB
3300 if (!grey_init(rb, buf, buf_size, false, LCD_WIDTH, LCD_HEIGHT, &greysize))
3302 rb->splash(HZ, "grey buf error");
3303 return PLUGIN_ERROR;
3305 buf += greysize;
3306 buf_size -= greysize;
3307 #else
3308 xlcd_init(rb);
3309 #endif
3311 /* should be ok to just load settings since a parameter is present
3312 here and the drive should be spinning */
3313 configfile_init(rb);
3314 configfile_load(JPEG_CONFIGFILE, jpeg_config,
3315 ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION);
3316 old_settings = jpeg_settings;
3318 buf_images = buf; buf_images_size = buf_size;
3320 /* Turn off backlight timeout */
3321 backlight_force_on(rb); /* backlight control in lib/helper.c */
3325 condition = load_and_show(np_file);
3326 }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
3327 && condition != PLUGIN_ERROR);
3329 if (rb->memcmp(&jpeg_settings, &old_settings, sizeof (jpeg_settings)))
3331 /* Just in case drive has to spin, keep it from looking locked */
3332 rb->splash(0, "Saving Settings");
3333 configfile_save(JPEG_CONFIGFILE, jpeg_config,
3334 ARRAYLEN(jpeg_config), JPEG_SETTINGS_VERSION);
3337 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
3338 /* set back ata spindown time in case we changed it */
3339 rb->ata_spindown(rb->global_settings->disk_spindown);
3340 #endif
3342 /* Turn on backlight timeout (revert to settings) */
3343 backlight_use_settings(rb); /* backlight control in lib/helper.c */
3345 #ifdef USEGSLIB
3346 grey_release(); /* deinitialize */
3347 #endif
3349 return condition;
3352 #endif /* HAVE_LCD_BITMAP */