Rename variables sectorbuf and verbose to avoid clashes in rbutil. Cleanup exports...
[Rockbox.git] / apps / plugins / jpeg.c
blob4daecd934ad2e7b17c88b2d32e2783afb457db55
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 #elif CONFIG_KEYPAD == MROBE100_PAD
191 #define JPEG_ZOOM_IN BUTTON_SELECT
192 #define JPEG_ZOOM_OUT BUTTON_PLAY
193 #define JPEG_UP BUTTON_UP
194 #define JPEG_DOWN BUTTON_DOWN
195 #define JPEG_LEFT BUTTON_LEFT
196 #define JPEG_RIGHT BUTTON_RIGHT
197 #define JPEG_MENU BUTTON_MENU
198 #define JPEG_NEXT (BUTTON_DISPLAY | BUTTON_RIGHT)
199 #define JPEG_PREVIOUS (BUTTON_DISPLAY | BUTTON_LEFT)
201 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
202 #define JPEG_ZOOM_PRE BUTTON_RC_PLAY
203 #define JPEG_ZOOM_IN (BUTTON_RC_PLAY|BUTTON_REL)
204 #define JPEG_ZOOM_OUT (BUTTON_RC_PLAY|BUTTON_REPEAT)
205 #define JPEG_UP BUTTON_RC_VOL_UP
206 #define JPEG_DOWN BUTTON_RC_VOL_DOWN
207 #define JPEG_LEFT BUTTON_RC_REW
208 #define JPEG_RIGHT BUTTON_RC_FF
209 #define JPEG_MENU BUTTON_RC_REC
210 #define JPEG_NEXT BUTTON_RC_MODE
211 #define JPEG_PREVIOUS BUTTON_RC_MENU
213 #elif CONFIG_KEYPAD == COWOND2_PAD
215 #else
216 #error No keymap defined!
217 #endif
219 #ifdef HAVE_TOUCHPAD
220 #ifndef JPEG_UP
221 #define JPEG_UP BUTTON_TOPMIDDLE
222 #endif
223 #ifndef JPEG_DOWN
224 #define JPEG_DOWN BUTTON_BOTTOMMIDDLE
225 #endif
226 #ifndef JPEG_LEFT
227 #define JPEG_LEFT BUTTON_MIDLEFT
228 #endif
229 #ifndef JPEG_RIGHT
230 #define JPEG_RIGHT BUTTON_MIDRIGHT
231 #endif
232 #ifndef JPEG_ZOOM_IN
233 #define JPEG_ZOOM_IN BUTTON_TOPRIGHT
234 #endif
235 #ifndef JPEG_ZOOM_OUT
236 #define JPEG_ZOOM_OUT BUTTON_TOPLEFT
237 #endif
238 #ifndef JPEG_MENU
239 #define JPEG_MENU (BUTTON_CENTER|BUTTON_REL)
240 #endif
241 #ifndef JPEG_NEXT
242 #define JPEG_NEXT BUTTON_BOTTOMRIGHT
243 #endif
244 #ifndef JPEG_PREVIOUS
245 #define JPEG_PREVIOUS BUTTON_BOTTOMLEFT
246 #endif
247 #endif
249 /* different graphics libraries */
250 #if LCD_DEPTH < 8
251 #define USEGSLIB
252 GREY_INFO_STRUCT
253 #define MYLCD(fn) grey_ub_ ## fn
254 #define MYLCD_UPDATE()
255 #define MYXLCD(fn) grey_ub_ ## fn
256 #else
257 #define MYLCD(fn) rb->lcd_ ## fn
258 #define MYLCD_UPDATE() rb->lcd_update();
259 #define MYXLCD(fn) xlcd_ ## fn
260 #endif
262 #define MAX_X_SIZE LCD_WIDTH*8
264 /* Min memory allowing us to use the plugin buffer
265 * and thus not stopping the music
266 * *Very* rough estimation:
267 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
268 * + 20k code size = 60 000
269 * + 50k min for jpeg = 120 000
271 #define MIN_MEM 120000
273 /* Headings */
274 #define DIR_PREV 1
275 #define DIR_NEXT -1
276 #define DIR_NONE 0
278 #define PLUGIN_OTHER 10 /* State code for output with return. */
280 /******************************* Globals ***********************************/
282 static const struct plugin_api* rb;
283 MEM_FUNCTION_WRAPPERS(rb);
285 /* for portability of below JPEG code */
286 #define MEMSET(p,v,c) rb->memset(p,v,c)
287 #define MEMCPY(d,s,c) rb->memcpy(d,s,c)
288 #define INLINE static inline
289 #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
291 static int slideshow_enabled = false; /* run slideshow */
292 static int running_slideshow = false; /* loading image because of slideshw */
293 #ifndef SIMULATOR
294 static int immediate_ata_off = false; /* power down disk after loading */
295 #endif
297 /* Persistent configuration */
298 #define JPEG_CONFIGFILE "jpeg.cfg"
299 #define JPEG_SETTINGS_MINVERSION 1
300 #define JPEG_SETTINGS_VERSION 2
302 /* Slideshow times */
303 #define SS_MIN_TIMEOUT 1
304 #define SS_MAX_TIMEOUT 20
305 #define SS_DEFAULT_TIMEOUT 5
307 enum color_modes
309 COLOURMODE_COLOUR = 0,
310 COLOURMODE_GRAY,
311 COLOUR_NUM_MODES
314 enum dither_modes
316 DITHER_NONE = 0, /* No dithering */
317 DITHER_ORDERED, /* Bayer ordered */
318 DITHER_DIFFUSION, /* Floyd/Steinberg error diffusion */
319 DITHER_NUM_MODES
322 struct jpeg_settings
324 int colour_mode;
325 int dither_mode;
326 int ss_timeout;
329 static struct jpeg_settings jpeg_settings =
330 { COLOURMODE_COLOUR, DITHER_NONE, SS_DEFAULT_TIMEOUT };
331 static struct jpeg_settings old_settings;
333 static struct configdata jpeg_config[] =
335 #ifdef HAVE_LCD_COLOR
336 { TYPE_ENUM, 0, COLOUR_NUM_MODES, &jpeg_settings.colour_mode,
337 "Colour Mode", (char *[]){ "Colour", "Grayscale" }, NULL },
338 { TYPE_ENUM, 0, DITHER_NUM_MODES, &jpeg_settings.dither_mode,
339 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" }, NULL },
340 #endif
341 { TYPE_INT, SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, &jpeg_settings.ss_timeout,
342 "Slideshow Time", NULL, NULL},
345 #if LCD_DEPTH > 1
346 fb_data* old_backdrop;
347 #endif
349 /**************** begin JPEG code ********************/
351 INLINE unsigned range_limit(int value)
353 #if CONFIG_CPU == SH7034
354 unsigned tmp;
355 asm ( /* Note: Uses knowledge that only low byte of result is used */
356 "mov #-128,%[t] \n"
357 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
358 "extu.b %[v],%[t] \n"
359 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
360 "bt 1f \n" /* yes: no overflow */
361 "cmp/pz %[v] \n" /* overflow: positive? */
362 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
363 "1: \n"
364 : /* outputs */
365 [v]"+r"(value),
366 [t]"=&r"(tmp)
368 return value;
369 #elif defined(CPU_COLDFIRE)
370 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
371 "add.l #128,%[v] \n" /* value += 128; */
372 "cmp.l #255,%[v] \n" /* overflow? */
373 "bls.b 1f \n" /* no: return value */
374 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
375 "1: \n"
376 : /* outputs */
377 [v]"+d"(value)
379 return value;
380 #elif defined(CPU_ARM)
381 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
382 "add %[v], %[v], #128 \n" /* value += 128 */
383 "cmp %[v], #255 \n" /* out of range 0..255? */
384 "mvnhi %[v], %[v], asr #31 \n" /* yes: set all bits to ~(sign_bit) */
385 : /* outputs */
386 [v]"+r"(value)
388 return value;
389 #else
390 value += 128;
392 if ((unsigned)value <= 255)
393 return value;
395 if (value < 0)
396 return 0;
398 return 255;
399 #endif
402 /* IDCT implementation */
405 #define CONST_BITS 13
406 #define PASS1_BITS 2
409 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
410 * causing a lot of useless floating-point operations at run time.
411 * To get around this we use the following pre-calculated constants.
412 * If you change CONST_BITS you may want to add appropriate values.
413 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
415 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
416 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
417 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
418 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
419 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
420 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
421 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
422 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
423 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
424 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
425 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
426 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
430 /* Multiply an long variable by an long constant to yield an long result.
431 * For 8-bit samples with the recommended scaling, all the variable
432 * and constant values involved are no more than 16 bits wide, so a
433 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
434 * For 12-bit samples, a full 32-bit multiplication will be needed.
436 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
439 /* Dequantize a coefficient by multiplying it by the multiplier-table
440 * entry; produce an int result. In this module, both inputs and result
441 * are 16 bits or less, so either int or short multiply will work.
443 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
444 #define DEQUANTIZE MULTIPLY16
446 /* Descale and correctly round an int value that's scaled by N bits.
447 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
448 * the fudge factor is correct for either sign of X.
450 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
455 * Perform dequantization and inverse DCT on one block of coefficients,
456 * producing a reduced-size 1x1 output block.
458 void idct1x1(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
460 (void)skip_line; /* unused */
461 *p_byte = range_limit(inptr[0] * quantptr[0] >> 3);
467 * Perform dequantization and inverse DCT on one block of coefficients,
468 * producing a reduced-size 2x2 output block.
470 void idct2x2(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
472 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
473 unsigned char* outptr;
475 /* Pass 1: process columns from input, store into work array. */
477 /* Column 0 */
478 tmp4 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
479 tmp5 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
481 tmp0 = tmp4 + tmp5;
482 tmp2 = tmp4 - tmp5;
484 /* Column 1 */
485 tmp4 = DEQUANTIZE(inptr[8*0+1], quantptr[8*0+1]);
486 tmp5 = DEQUANTIZE(inptr[8*1+1], quantptr[8*1+1]);
488 tmp1 = tmp4 + tmp5;
489 tmp3 = tmp4 - tmp5;
491 /* Pass 2: process 2 rows, store into output array. */
493 /* Row 0 */
494 outptr = p_byte;
496 outptr[0] = range_limit((int) DESCALE(tmp0 + tmp1, 3));
497 outptr[1] = range_limit((int) DESCALE(tmp0 - tmp1, 3));
499 /* Row 1 */
500 outptr = p_byte + skip_line;
502 outptr[0] = range_limit((int) DESCALE(tmp2 + tmp3, 3));
503 outptr[1] = range_limit((int) DESCALE(tmp2 - tmp3, 3));
509 * Perform dequantization and inverse DCT on one block of coefficients,
510 * producing a reduced-size 4x4 output block.
512 void idct4x4(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
514 int tmp0, tmp2, tmp10, tmp12;
515 int z1, z2, z3;
516 int * wsptr;
517 unsigned char* outptr;
518 int ctr;
519 int workspace[4*4]; /* buffers data between passes */
521 /* Pass 1: process columns from input, store into work array. */
523 wsptr = workspace;
524 for (ctr = 0; ctr < 4; ctr++, inptr++, quantptr++, wsptr++)
526 /* Even part */
528 tmp0 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
529 tmp2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
531 tmp10 = (tmp0 + tmp2) << PASS1_BITS;
532 tmp12 = (tmp0 - tmp2) << PASS1_BITS;
534 /* Odd part */
535 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
537 z2 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
538 z3 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
540 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
541 tmp0 = DESCALE(z1 + MULTIPLY16(z3, - FIX_1_847759065), CONST_BITS-PASS1_BITS);
542 tmp2 = DESCALE(z1 + MULTIPLY16(z2, FIX_0_765366865), CONST_BITS-PASS1_BITS);
544 /* Final output stage */
546 wsptr[4*0] = (int) (tmp10 + tmp2);
547 wsptr[4*3] = (int) (tmp10 - tmp2);
548 wsptr[4*1] = (int) (tmp12 + tmp0);
549 wsptr[4*2] = (int) (tmp12 - tmp0);
552 /* Pass 2: process 4 rows from work array, store into output array. */
554 wsptr = workspace;
555 for (ctr = 0; ctr < 4; ctr++)
557 outptr = p_byte + (ctr*skip_line);
558 /* Even part */
560 tmp0 = (int) wsptr[0];
561 tmp2 = (int) wsptr[2];
563 tmp10 = (tmp0 + tmp2) << CONST_BITS;
564 tmp12 = (tmp0 - tmp2) << CONST_BITS;
566 /* Odd part */
567 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
569 z2 = (int) wsptr[1];
570 z3 = (int) wsptr[3];
572 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
573 tmp0 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
574 tmp2 = z1 + MULTIPLY16(z2, FIX_0_765366865);
576 /* Final output stage */
578 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp2,
579 CONST_BITS+PASS1_BITS+3));
580 outptr[3] = range_limit((int) DESCALE(tmp10 - tmp2,
581 CONST_BITS+PASS1_BITS+3));
582 outptr[1] = range_limit((int) DESCALE(tmp12 + tmp0,
583 CONST_BITS+PASS1_BITS+3));
584 outptr[2] = range_limit((int) DESCALE(tmp12 - tmp0,
585 CONST_BITS+PASS1_BITS+3));
587 wsptr += 4; /* advance pointer to next row */
594 * Perform dequantization and inverse DCT on one block of coefficients.
596 void idct8x8(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
598 long tmp0, tmp1, tmp2, tmp3;
599 long tmp10, tmp11, tmp12, tmp13;
600 long z1, z2, z3, z4, z5;
601 int * wsptr;
602 unsigned char* outptr;
603 int ctr;
604 int workspace[64]; /* buffers data between passes */
606 /* Pass 1: process columns from input, store into work array. */
607 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
608 /* furthermore, we scale the results by 2**PASS1_BITS. */
610 wsptr = workspace;
611 for (ctr = 8; ctr > 0; ctr--)
613 /* Due to quantization, we will usually find that many of the input
614 * coefficients are zero, especially the AC terms. We can exploit this
615 * by short-circuiting the IDCT calculation for any column in which all
616 * the AC terms are zero. In that case each output is equal to the
617 * DC coefficient (with scale factor as needed).
618 * With typical images and quantization tables, half or more of the
619 * column DCT calculations can be simplified this way.
622 if ((inptr[8*1] | inptr[8*2] | inptr[8*3]
623 | inptr[8*4] | inptr[8*5] | inptr[8*6] | inptr[8*7]) == 0)
625 /* AC terms all zero */
626 int dcval = DEQUANTIZE(inptr[8*0], quantptr[8*0]) << PASS1_BITS;
628 wsptr[8*0] = wsptr[8*1] = wsptr[8*2] = wsptr[8*3] = wsptr[8*4]
629 = wsptr[8*5] = wsptr[8*6] = wsptr[8*7] = dcval;
630 inptr++; /* advance pointers to next column */
631 quantptr++;
632 wsptr++;
633 continue;
636 /* Even part: reverse the even part of the forward DCT. */
637 /* The rotator is sqrt(2)*c(-6). */
639 z2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
640 z3 = DEQUANTIZE(inptr[8*6], quantptr[8*6]);
642 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
643 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
644 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
646 z2 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
647 z3 = DEQUANTIZE(inptr[8*4], quantptr[8*4]);
649 tmp0 = (z2 + z3) << CONST_BITS;
650 tmp1 = (z2 - z3) << CONST_BITS;
652 tmp10 = tmp0 + tmp3;
653 tmp13 = tmp0 - tmp3;
654 tmp11 = tmp1 + tmp2;
655 tmp12 = tmp1 - tmp2;
657 /* Odd part per figure 8; the matrix is unitary and hence its
658 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
660 tmp0 = DEQUANTIZE(inptr[8*7], quantptr[8*7]);
661 tmp1 = DEQUANTIZE(inptr[8*5], quantptr[8*5]);
662 tmp2 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
663 tmp3 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
665 z1 = tmp0 + tmp3;
666 z2 = tmp1 + tmp2;
667 z3 = tmp0 + tmp2;
668 z4 = tmp1 + tmp3;
669 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
671 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
672 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
673 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
674 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
675 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
676 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
677 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
678 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
680 z3 += z5;
681 z4 += z5;
683 tmp0 += z1 + z3;
684 tmp1 += z2 + z4;
685 tmp2 += z2 + z3;
686 tmp3 += z1 + z4;
688 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
690 wsptr[8*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
691 wsptr[8*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
692 wsptr[8*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
693 wsptr[8*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
694 wsptr[8*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
695 wsptr[8*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
696 wsptr[8*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
697 wsptr[8*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
699 inptr++; /* advance pointers to next column */
700 quantptr++;
701 wsptr++;
704 /* Pass 2: process rows from work array, store into output array. */
705 /* Note that we must descale the results by a factor of 8 == 2**3, */
706 /* and also undo the PASS1_BITS scaling. */
708 wsptr = workspace;
709 for (ctr = 0; ctr < 8; ctr++)
711 outptr = p_byte + (ctr*skip_line);
712 /* Rows of zeroes can be exploited in the same way as we did with columns.
713 * However, the column calculation has created many nonzero AC terms, so
714 * the simplification applies less often (typically 5% to 10% of the time).
715 * On machines with very fast multiplication, it's possible that the
716 * test takes more time than it's worth. In that case this section
717 * may be commented out.
720 #ifndef NO_ZERO_ROW_TEST
721 if ((wsptr[1] | wsptr[2] | wsptr[3]
722 | wsptr[4] | wsptr[5] | wsptr[6] | wsptr[7]) == 0)
724 /* AC terms all zero */
725 unsigned char dcval = range_limit((int) DESCALE((long) wsptr[0],
726 PASS1_BITS+3));
728 outptr[0] = dcval;
729 outptr[1] = dcval;
730 outptr[2] = dcval;
731 outptr[3] = dcval;
732 outptr[4] = dcval;
733 outptr[5] = dcval;
734 outptr[6] = dcval;
735 outptr[7] = dcval;
737 wsptr += 8; /* advance pointer to next row */
738 continue;
740 #endif
742 /* Even part: reverse the even part of the forward DCT. */
743 /* The rotator is sqrt(2)*c(-6). */
745 z2 = (long) wsptr[2];
746 z3 = (long) wsptr[6];
748 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
749 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
750 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
752 tmp0 = ((long) wsptr[0] + (long) wsptr[4]) << CONST_BITS;
753 tmp1 = ((long) wsptr[0] - (long) wsptr[4]) << CONST_BITS;
755 tmp10 = tmp0 + tmp3;
756 tmp13 = tmp0 - tmp3;
757 tmp11 = tmp1 + tmp2;
758 tmp12 = tmp1 - tmp2;
760 /* Odd part per figure 8; the matrix is unitary and hence its
761 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
763 tmp0 = (long) wsptr[7];
764 tmp1 = (long) wsptr[5];
765 tmp2 = (long) wsptr[3];
766 tmp3 = (long) wsptr[1];
768 z1 = tmp0 + tmp3;
769 z2 = tmp1 + tmp2;
770 z3 = tmp0 + tmp2;
771 z4 = tmp1 + tmp3;
772 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
774 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
775 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
776 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
777 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
778 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
779 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
780 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
781 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
783 z3 += z5;
784 z4 += z5;
786 tmp0 += z1 + z3;
787 tmp1 += z2 + z4;
788 tmp2 += z2 + z3;
789 tmp3 += z1 + z4;
791 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
793 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp3,
794 CONST_BITS+PASS1_BITS+3));
795 outptr[7] = range_limit((int) DESCALE(tmp10 - tmp3,
796 CONST_BITS+PASS1_BITS+3));
797 outptr[1] = range_limit((int) DESCALE(tmp11 + tmp2,
798 CONST_BITS+PASS1_BITS+3));
799 outptr[6] = range_limit((int) DESCALE(tmp11 - tmp2,
800 CONST_BITS+PASS1_BITS+3));
801 outptr[2] = range_limit((int) DESCALE(tmp12 + tmp1,
802 CONST_BITS+PASS1_BITS+3));
803 outptr[5] = range_limit((int) DESCALE(tmp12 - tmp1,
804 CONST_BITS+PASS1_BITS+3));
805 outptr[3] = range_limit((int) DESCALE(tmp13 + tmp0,
806 CONST_BITS+PASS1_BITS+3));
807 outptr[4] = range_limit((int) DESCALE(tmp13 - tmp0,
808 CONST_BITS+PASS1_BITS+3));
810 wsptr += 8; /* advance pointer to next row */
816 /* JPEG decoder implementation */
819 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
821 struct derived_tbl
823 /* Basic tables: (element [0] of each array is unused) */
824 long mincode[17]; /* smallest code of length k */
825 long maxcode[18]; /* largest code of length k (-1 if none) */
826 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
827 int valptr[17]; /* huffval[] index of 1st symbol of length k */
829 /* Back link to public Huffman table (needed only in slow_DECODE) */
830 int* pub;
832 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
833 the input data stream. If the next Huffman code is no more
834 than HUFF_LOOKAHEAD bits long, we can obtain its length and
835 the corresponding symbol directly from these tables. */
836 int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
837 unsigned char look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
840 #define QUANT_TABLE_LENGTH 64
842 /* for type of Huffman table */
843 #define DC_LEN 28
844 #define AC_LEN 178
846 struct huffman_table
847 { /* length and code according to JFIF format */
848 int huffmancodes_dc[DC_LEN];
849 int huffmancodes_ac[AC_LEN];
852 struct frame_component
854 int ID;
855 int horizontal_sampling;
856 int vertical_sampling;
857 int quanttable_select;
860 struct scan_component
862 int ID;
863 int DC_select;
864 int AC_select;
867 struct bitstream
869 unsigned long get_buffer; /* current bit-extraction buffer */
870 int bits_left; /* # of unused bits in it */
871 unsigned char* next_input_byte;
872 unsigned char* input_end; /* upper limit +1 */
875 struct jpeg
877 int x_size, y_size; /* size of image (can be less than block boundary) */
878 int x_phys, y_phys; /* physical size, block aligned */
879 int x_mbl; /* x dimension of MBL */
880 int y_mbl; /* y dimension of MBL */
881 int blocks; /* blocks per MB */
882 int restart_interval; /* number of MCUs between RSTm markers */
883 int store_pos[4]; /* for Y block ordering */
885 unsigned char* p_entropy_data;
886 unsigned char* p_entropy_end;
888 int quanttable[4][QUANT_TABLE_LENGTH]; /* raw quantization tables 0-3 */
889 int qt_idct[2][QUANT_TABLE_LENGTH]; /* quantization tables for IDCT */
891 struct huffman_table hufftable[2]; /* Huffman tables */
892 struct derived_tbl dc_derived_tbls[2]; /* Huffman-LUTs */
893 struct derived_tbl ac_derived_tbls[2];
895 struct frame_component frameheader[3]; /* Component descriptor */
896 struct scan_component scanheader[3]; /* currently not used */
898 int mcu_membership[6]; /* info per block */
899 int tab_membership[6];
900 int subsample_x[3]; /* info per component */
901 int subsample_y[3];
905 /* possible return flags for process_markers() */
906 #define HUFFTAB 0x0001 /* with huffman table */
907 #define QUANTTAB 0x0002 /* with quantization table */
908 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
909 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
910 #define SOF0 0x0010 /* with SOF0-Segment */
911 #define DHT 0x0020 /* with Definition of huffman tables */
912 #define SOS 0x0040 /* with Start-of-Scan segment */
913 #define DQT 0x0080 /* with definition of quantization table */
915 /* Preprocess the JPEG JFIF file */
916 int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
918 unsigned char* p_bytes = p_src;
919 int marker_size; /* variable length of marker segment */
920 int i, j, n;
921 int ret = 0; /* returned flags */
923 p_jpeg->p_entropy_end = p_src + size;
925 while (p_src < p_bytes + size)
927 if (*p_src++ != 0xFF) /* no marker? */
929 p_src--; /* it's image data, put it back */
930 p_jpeg->p_entropy_data = p_src;
931 break; /* exit marker processing */
934 switch (*p_src++)
936 case 0xFF: /* Fill byte */
937 ret |= FILL_FF;
938 case 0x00: /* Zero stuffed byte - entropy data */
939 p_src--; /* put it back */
940 continue;
942 case 0xC0: /* SOF Huff - Baseline DCT */
944 ret |= SOF0;
945 marker_size = *p_src++ << 8; /* Highbyte */
946 marker_size |= *p_src++; /* Lowbyte */
947 n = *p_src++; /* sample precision (= 8 or 12) */
948 if (n != 8)
950 return(-1); /* Unsupported sample precision */
952 p_jpeg->y_size = *p_src++ << 8; /* Highbyte */
953 p_jpeg->y_size |= *p_src++; /* Lowbyte */
954 p_jpeg->x_size = *p_src++ << 8; /* Highbyte */
955 p_jpeg->x_size |= *p_src++; /* Lowbyte */
957 n = (marker_size-2-6)/3;
958 if (*p_src++ != n || (n != 1 && n != 3))
960 return(-2); /* Unsupported SOF0 component specification */
962 for (i=0; i<n; i++)
964 p_jpeg->frameheader[i].ID = *p_src++; /* Component info */
965 p_jpeg->frameheader[i].horizontal_sampling = *p_src >> 4;
966 p_jpeg->frameheader[i].vertical_sampling = *p_src++ & 0x0F;
967 p_jpeg->frameheader[i].quanttable_select = *p_src++;
968 if (p_jpeg->frameheader[i].horizontal_sampling > 2
969 || p_jpeg->frameheader[i].vertical_sampling > 2)
970 return -3; /* Unsupported SOF0 subsampling */
972 p_jpeg->blocks = n;
974 break;
976 case 0xC1: /* SOF Huff - Extended sequential DCT*/
977 case 0xC2: /* SOF Huff - Progressive DCT*/
978 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
979 case 0xC5: /* SOF Huff - Differential sequential DCT*/
980 case 0xC6: /* SOF Huff - Differential progressive DCT*/
981 case 0xC7: /* SOF Huff - Differential spatial*/
982 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
983 case 0xC9: /* SOF Arith - Extended sequential DCT*/
984 case 0xCA: /* SOF Arith - Progressive DCT*/
985 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
986 case 0xCD: /* SOF Arith - Differential sequential DCT*/
987 case 0xCE: /* SOF Arith - Differential progressive DCT*/
988 case 0xCF: /* SOF Arith - Differential spatial*/
990 return (-4); /* other DCT model than baseline not implemented */
993 case 0xC4: /* Define Huffman Table(s) */
995 unsigned char* p_temp;
997 ret |= DHT;
998 marker_size = *p_src++ << 8; /* Highbyte */
999 marker_size |= *p_src++; /* Lowbyte */
1001 p_temp = p_src;
1002 while (p_src < p_temp+marker_size-2-17) /* another table */
1004 int sum = 0;
1005 i = *p_src & 0x0F; /* table index */
1006 if (i > 1)
1008 return (-5); /* Huffman table index out of range */
1010 else if (*p_src++ & 0xF0) /* AC table */
1012 for (j=0; j<16; j++)
1014 sum += *p_src;
1015 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
1017 if(16 + sum > AC_LEN)
1018 return -10; /* longer than allowed */
1020 for (; j < 16 + sum; j++)
1021 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
1023 else /* DC table */
1025 for (j=0; j<16; j++)
1027 sum += *p_src;
1028 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
1030 if(16 + sum > DC_LEN)
1031 return -11; /* longer than allowed */
1033 for (; j < 16 + sum; j++)
1034 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
1036 } /* while */
1037 p_src = p_temp+marker_size - 2; /* skip possible residue */
1039 break;
1041 case 0xCC: /* Define Arithmetic coding conditioning(s) */
1042 return(-6); /* Arithmetic coding not supported */
1044 case 0xD8: /* Start of Image */
1045 case 0xD9: /* End of Image */
1046 case 0x01: /* for temp private use arith code */
1047 break; /* skip parameterless marker */
1050 case 0xDA: /* Start of Scan */
1052 ret |= SOS;
1053 marker_size = *p_src++ << 8; /* Highbyte */
1054 marker_size |= *p_src++; /* Lowbyte */
1056 n = (marker_size-2-1-3)/2;
1057 if (*p_src++ != n || (n != 1 && n != 3))
1059 return (-7); /* Unsupported SOS component specification */
1061 for (i=0; i<n; i++)
1063 p_jpeg->scanheader[i].ID = *p_src++;
1064 p_jpeg->scanheader[i].DC_select = *p_src >> 4;
1065 p_jpeg->scanheader[i].AC_select = *p_src++ & 0x0F;
1067 p_src += 3; /* skip spectral information */
1069 break;
1071 case 0xDB: /* Define quantization Table(s) */
1073 ret |= DQT;
1074 marker_size = *p_src++ << 8; /* Highbyte */
1075 marker_size |= *p_src++; /* Lowbyte */
1076 n = (marker_size-2)/(QUANT_TABLE_LENGTH+1); /* # of tables */
1077 for (i=0; i<n; i++)
1079 int id = *p_src++; /* ID */
1080 if (id >= 4)
1082 return (-8); /* Unsupported quantization table */
1084 /* Read Quantisation table: */
1085 for (j=0; j<QUANT_TABLE_LENGTH; j++)
1086 p_jpeg->quanttable[id][j] = *p_src++;
1089 break;
1091 case 0xDD: /* Define Restart Interval */
1093 marker_size = *p_src++ << 8; /* Highbyte */
1094 marker_size |= *p_src++; /* Lowbyte */
1095 p_jpeg->restart_interval = *p_src++ << 8; /* Highbyte */
1096 p_jpeg->restart_interval |= *p_src++; /* Lowbyte */
1097 p_src += marker_size-4; /* skip segment */
1099 break;
1101 case 0xDC: /* Define Number of Lines */
1102 case 0xDE: /* Define Hierarchical progression */
1103 case 0xDF: /* Expand Reference Component(s) */
1104 case 0xE0: /* Application Field 0*/
1105 case 0xE1: /* Application Field 1*/
1106 case 0xE2: /* Application Field 2*/
1107 case 0xE3: /* Application Field 3*/
1108 case 0xE4: /* Application Field 4*/
1109 case 0xE5: /* Application Field 5*/
1110 case 0xE6: /* Application Field 6*/
1111 case 0xE7: /* Application Field 7*/
1112 case 0xE8: /* Application Field 8*/
1113 case 0xE9: /* Application Field 9*/
1114 case 0xEA: /* Application Field 10*/
1115 case 0xEB: /* Application Field 11*/
1116 case 0xEC: /* Application Field 12*/
1117 case 0xED: /* Application Field 13*/
1118 case 0xEE: /* Application Field 14*/
1119 case 0xEF: /* Application Field 15*/
1120 case 0xFE: /* Comment */
1122 marker_size = *p_src++ << 8; /* Highbyte */
1123 marker_size |= *p_src++; /* Lowbyte */
1124 p_src += marker_size-2; /* skip segment */
1126 break;
1128 case 0xF0: /* Reserved for JPEG extensions */
1129 case 0xF1: /* Reserved for JPEG extensions */
1130 case 0xF2: /* Reserved for JPEG extensions */
1131 case 0xF3: /* Reserved for JPEG extensions */
1132 case 0xF4: /* Reserved for JPEG extensions */
1133 case 0xF5: /* Reserved for JPEG extensions */
1134 case 0xF6: /* Reserved for JPEG extensions */
1135 case 0xF7: /* Reserved for JPEG extensions */
1136 case 0xF8: /* Reserved for JPEG extensions */
1137 case 0xF9: /* Reserved for JPEG extensions */
1138 case 0xFA: /* Reserved for JPEG extensions */
1139 case 0xFB: /* Reserved for JPEG extensions */
1140 case 0xFC: /* Reserved for JPEG extensions */
1141 case 0xFD: /* Reserved for JPEG extensions */
1142 case 0x02: /* Reserved */
1143 default:
1144 return (-9); /* Unknown marker */
1145 } /* switch */
1146 } /* while */
1148 return (ret); /* return flags with seen markers */
1152 void default_huff_tbl(struct jpeg* p_jpeg)
1154 static const struct huffman_table luma_table =
1157 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
1158 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1161 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
1162 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
1163 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
1164 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
1165 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
1166 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1167 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1168 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
1169 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
1170 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
1171 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1172 0xF9,0xFA
1176 static const struct huffman_table chroma_table =
1179 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
1180 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1183 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
1184 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
1185 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1186 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1187 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1188 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1189 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1190 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1191 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1192 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1193 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1194 0xF9,0xFA
1198 MEMCPY(&p_jpeg->hufftable[0], &luma_table, sizeof(luma_table));
1199 MEMCPY(&p_jpeg->hufftable[1], &chroma_table, sizeof(chroma_table));
1201 return;
1204 /* Compute the derived values for a Huffman table */
1205 void fix_huff_tbl(int* htbl, struct derived_tbl* dtbl)
1207 int p, i, l, si;
1208 int lookbits, ctr;
1209 char huffsize[257];
1210 unsigned int huffcode[257];
1211 unsigned int code;
1213 dtbl->pub = htbl; /* fill in back link */
1215 /* Figure C.1: make table of Huffman code length for each symbol */
1216 /* Note that this is in code-length order. */
1218 p = 0;
1219 for (l = 1; l <= 16; l++)
1220 { /* all possible code length */
1221 for (i = 1; i <= (int) htbl[l-1]; i++) /* all codes per length */
1222 huffsize[p++] = (char) l;
1224 huffsize[p] = 0;
1226 /* Figure C.2: generate the codes themselves */
1227 /* Note that this is in code-length order. */
1229 code = 0;
1230 si = huffsize[0];
1231 p = 0;
1232 while (huffsize[p])
1234 while (((int) huffsize[p]) == si)
1236 huffcode[p++] = code;
1237 code++;
1239 code <<= 1;
1240 si++;
1243 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1245 p = 0;
1246 for (l = 1; l <= 16; l++)
1248 if (htbl[l-1])
1250 dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */
1251 dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */
1252 p += htbl[l-1];
1253 dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
1255 else
1257 dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
1260 dtbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */
1262 /* Compute lookahead tables to speed up decoding.
1263 * First we set all the table entries to 0, indicating "too long";
1264 * then we iterate through the Huffman codes that are short enough and
1265 * fill in all the entries that correspond to bit sequences starting
1266 * with that code.
1269 MEMSET(dtbl->look_nbits, 0, sizeof(dtbl->look_nbits));
1271 p = 0;
1272 for (l = 1; l <= HUFF_LOOKAHEAD; l++)
1274 for (i = 1; i <= (int) htbl[l-1]; i++, p++)
1276 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1277 /* Generate left-justified code followed by all possible bit sequences */
1278 lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
1279 for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--)
1281 dtbl->look_nbits[lookbits] = l;
1282 dtbl->look_sym[lookbits] = htbl[16+p];
1283 lookbits++;
1290 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1291 * If the incoming data is corrupted, decode_mcu could attempt to
1292 * reference values beyond the end of the array. To avoid a wild store,
1293 * we put some extra zeroes after the real entries.
1295 static const int zag[] =
1297 0, 1, 8, 16, 9, 2, 3, 10,
1298 17, 24, 32, 25, 18, 11, 4, 5,
1299 12, 19, 26, 33, 40, 48, 41, 34,
1300 27, 20, 13, 6, 7, 14, 21, 28,
1301 35, 42, 49, 56, 57, 50, 43, 36,
1302 29, 22, 15, 23, 30, 37, 44, 51,
1303 58, 59, 52, 45, 38, 31, 39, 46,
1304 53, 60, 61, 54, 47, 55, 62, 63,
1305 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1306 0, 0, 0, 0, 0, 0, 0, 0
1309 void build_lut(struct jpeg* p_jpeg)
1311 int i;
1312 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_dc,
1313 &p_jpeg->dc_derived_tbls[0]);
1314 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_ac,
1315 &p_jpeg->ac_derived_tbls[0]);
1316 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_dc,
1317 &p_jpeg->dc_derived_tbls[1]);
1318 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_ac,
1319 &p_jpeg->ac_derived_tbls[1]);
1321 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1322 for (i=0; i<64; i++)
1324 p_jpeg->qt_idct[0][zag[i]] = p_jpeg->quanttable[0][i];
1325 p_jpeg->qt_idct[1][zag[i]] = p_jpeg->quanttable[1][i];
1328 for (i=0; i<4; i++)
1329 p_jpeg->store_pos[i] = i; /* default ordering */
1331 /* assignments for the decoding of blocks */
1332 if (p_jpeg->frameheader[0].horizontal_sampling == 2
1333 && p_jpeg->frameheader[0].vertical_sampling == 1)
1334 { /* 4:2:2 */
1335 p_jpeg->blocks = 4;
1336 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1337 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1338 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1339 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1340 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1341 p_jpeg->mcu_membership[1] = 0;
1342 p_jpeg->mcu_membership[2] = 1;
1343 p_jpeg->mcu_membership[3] = 2;
1344 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1345 p_jpeg->tab_membership[1] = 0;
1346 p_jpeg->tab_membership[2] = 1;
1347 p_jpeg->tab_membership[3] = 1;
1348 p_jpeg->subsample_x[0] = 1;
1349 p_jpeg->subsample_x[1] = 2;
1350 p_jpeg->subsample_x[2] = 2;
1351 p_jpeg->subsample_y[0] = 1;
1352 p_jpeg->subsample_y[1] = 1;
1353 p_jpeg->subsample_y[2] = 1;
1355 if (p_jpeg->frameheader[0].horizontal_sampling == 1
1356 && p_jpeg->frameheader[0].vertical_sampling == 2)
1357 { /* 4:2:2 vertically subsampled */
1358 p_jpeg->store_pos[1] = 2; /* block positions are mirrored */
1359 p_jpeg->store_pos[2] = 1;
1360 p_jpeg->blocks = 4;
1361 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1362 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1363 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1364 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1365 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1366 p_jpeg->mcu_membership[1] = 0;
1367 p_jpeg->mcu_membership[2] = 1;
1368 p_jpeg->mcu_membership[3] = 2;
1369 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1370 p_jpeg->tab_membership[1] = 0;
1371 p_jpeg->tab_membership[2] = 1;
1372 p_jpeg->tab_membership[3] = 1;
1373 p_jpeg->subsample_x[0] = 1;
1374 p_jpeg->subsample_x[1] = 1;
1375 p_jpeg->subsample_x[2] = 1;
1376 p_jpeg->subsample_y[0] = 1;
1377 p_jpeg->subsample_y[1] = 2;
1378 p_jpeg->subsample_y[2] = 2;
1380 else if (p_jpeg->frameheader[0].horizontal_sampling == 2
1381 && p_jpeg->frameheader[0].vertical_sampling == 2)
1382 { /* 4:2:0 */
1383 p_jpeg->blocks = 6;
1384 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1385 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1386 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1387 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1388 p_jpeg->mcu_membership[0] = 0;
1389 p_jpeg->mcu_membership[1] = 0;
1390 p_jpeg->mcu_membership[2] = 0;
1391 p_jpeg->mcu_membership[3] = 0;
1392 p_jpeg->mcu_membership[4] = 1;
1393 p_jpeg->mcu_membership[5] = 2;
1394 p_jpeg->tab_membership[0] = 0;
1395 p_jpeg->tab_membership[1] = 0;
1396 p_jpeg->tab_membership[2] = 0;
1397 p_jpeg->tab_membership[3] = 0;
1398 p_jpeg->tab_membership[4] = 1;
1399 p_jpeg->tab_membership[5] = 1;
1400 p_jpeg->subsample_x[0] = 1;
1401 p_jpeg->subsample_x[1] = 2;
1402 p_jpeg->subsample_x[2] = 2;
1403 p_jpeg->subsample_y[0] = 1;
1404 p_jpeg->subsample_y[1] = 2;
1405 p_jpeg->subsample_y[2] = 2;
1407 else if (p_jpeg->frameheader[0].horizontal_sampling == 1
1408 && p_jpeg->frameheader[0].vertical_sampling == 1)
1409 { /* 4:4:4 */
1410 /* don't overwrite p_jpeg->blocks */
1411 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1412 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1413 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1414 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1415 p_jpeg->mcu_membership[0] = 0;
1416 p_jpeg->mcu_membership[1] = 1;
1417 p_jpeg->mcu_membership[2] = 2;
1418 p_jpeg->tab_membership[0] = 0;
1419 p_jpeg->tab_membership[1] = 1;
1420 p_jpeg->tab_membership[2] = 1;
1421 p_jpeg->subsample_x[0] = 1;
1422 p_jpeg->subsample_x[1] = 1;
1423 p_jpeg->subsample_x[2] = 1;
1424 p_jpeg->subsample_y[0] = 1;
1425 p_jpeg->subsample_y[1] = 1;
1426 p_jpeg->subsample_y[2] = 1;
1428 else
1430 /* error */
1437 * These functions/macros provide the in-line portion of bit fetching.
1438 * Use check_bit_buffer to ensure there are N bits in get_buffer
1439 * before using get_bits, peek_bits, or drop_bits.
1440 * check_bit_buffer(state,n,action);
1441 * Ensure there are N bits in get_buffer; if suspend, take action.
1442 * val = get_bits(n);
1443 * Fetch next N bits.
1444 * val = peek_bits(n);
1445 * Fetch next N bits without removing them from the buffer.
1446 * drop_bits(n);
1447 * Discard next N bits.
1448 * The value N should be a simple variable, not an expression, because it
1449 * is evaluated multiple times.
1452 INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
1454 if (pb->bits_left < nbits)
1455 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1456 unsigned char byte;
1458 byte = *pb->next_input_byte++;
1459 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1460 { /* simplification: just skip the (one-byte) marker code */
1461 pb->next_input_byte++;
1463 pb->get_buffer = (pb->get_buffer << 8) | byte;
1465 byte = *pb->next_input_byte++;
1466 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1467 { /* simplification: just skip the (one-byte) marker code */
1468 pb->next_input_byte++;
1470 pb->get_buffer = (pb->get_buffer << 8) | byte;
1472 pb->bits_left += 16;
1476 INLINE int get_bits(struct bitstream* pb, int nbits)
1478 return ((int) (pb->get_buffer >> (pb->bits_left -= nbits))) & ((1<<nbits)-1);
1481 INLINE int peek_bits(struct bitstream* pb, int nbits)
1483 return ((int) (pb->get_buffer >> (pb->bits_left - nbits))) & ((1<<nbits)-1);
1486 INLINE void drop_bits(struct bitstream* pb, int nbits)
1488 pb->bits_left -= nbits;
1491 /* re-synchronize to entropy data (skip restart marker) */
1492 void search_restart(struct bitstream* pb)
1494 pb->next_input_byte--; /* we may have overread it, taking 2 bytes */
1495 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1496 while (pb->next_input_byte < pb->input_end &&
1497 (pb->next_input_byte[-2] != 0xFF || pb->next_input_byte[-1] == 0x00))
1499 pb->next_input_byte++;
1501 pb->bits_left = 0;
1504 /* Figure F.12: extend sign bit. */
1505 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1507 static const int extend_test[16] = /* entry n is 2**(n-1) */
1509 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1510 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1513 static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
1515 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1516 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1517 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1518 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1521 /* Decode a single value */
1522 INLINE int huff_decode_dc(struct bitstream* bs, struct derived_tbl* tbl)
1524 int nb, look, s, r;
1526 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1527 look = peek_bits(bs, HUFF_LOOKAHEAD);
1528 if ((nb = tbl->look_nbits[look]) != 0)
1530 drop_bits(bs, nb);
1531 s = tbl->look_sym[look];
1532 check_bit_buffer(bs, s);
1533 r = get_bits(bs, s);
1534 s = HUFF_EXTEND(r, s);
1536 else
1537 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1538 long code;
1539 nb=HUFF_LOOKAHEAD+1;
1540 check_bit_buffer(bs, nb);
1541 code = get_bits(bs, nb);
1542 while (code > tbl->maxcode[nb])
1544 code <<= 1;
1545 check_bit_buffer(bs, 1);
1546 code |= get_bits(bs, 1);
1547 nb++;
1549 if (nb > 16) /* error in Huffman */
1551 s=0; /* fake a zero, this is most safe */
1553 else
1555 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1556 check_bit_buffer(bs, s);
1557 r = get_bits(bs, s);
1558 s = HUFF_EXTEND(r, s);
1560 } /* end slow decode */
1561 return s;
1564 INLINE int huff_decode_ac(struct bitstream* bs, struct derived_tbl* tbl)
1566 int nb, look, s;
1568 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1569 look = peek_bits(bs, HUFF_LOOKAHEAD);
1570 if ((nb = tbl->look_nbits[look]) != 0)
1572 drop_bits(bs, nb);
1573 s = tbl->look_sym[look];
1575 else
1576 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1577 long code;
1578 nb=HUFF_LOOKAHEAD+1;
1579 check_bit_buffer(bs, nb);
1580 code = get_bits(bs, nb);
1581 while (code > tbl->maxcode[nb])
1583 code <<= 1;
1584 check_bit_buffer(bs, 1);
1585 code |= get_bits(bs, 1);
1586 nb++;
1588 if (nb > 16) /* error in Huffman */
1590 s=0; /* fake a zero, this is most safe */
1592 else
1594 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1596 } /* end slow decode */
1597 return s;
1601 #ifdef HAVE_LCD_COLOR
1603 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1604 /* Note: it keeps the original color subsampling, even if resized. */
1605 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1606 int downscale, void (*pf_progress)(int current, int total))
1608 struct bitstream bs; /* bitstream "object" */
1609 int block[64]; /* decoded DCT coefficients */
1611 int width, height;
1612 int skip_line[3]; /* bytes from one line to the next (skip_line) */
1613 int skip_strip[3], skip_mcu[3]; /* bytes to next DCT row / column */
1615 int i, x, y; /* loop counter */
1617 unsigned char* p_line[3] = {p_pixel[0], p_pixel[1], p_pixel[2]};
1618 unsigned char* p_byte[3]; /* bitmap pointer */
1620 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1621 int k_need; /* AC coefficients needed up to here */
1622 int zero_need; /* init the block with this many zeros */
1624 int last_dc_val[3] = {0, 0, 0}; /* or 128 for chroma? */
1625 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1626 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1628 /* pick the IDCT we want, determine how to work with coefs */
1629 if (downscale == 1)
1631 pf_idct = idct8x8;
1632 k_need = 64; /* all */
1633 zero_need = 63; /* all */
1635 else if (downscale == 2)
1637 pf_idct = idct4x4;
1638 k_need = 25; /* this far in zig-zag to cover 4*4 */
1639 zero_need = 27; /* clear this far in linear order */
1641 else if (downscale == 4)
1643 pf_idct = idct2x2;
1644 k_need = 5; /* this far in zig-zag to cover 2*2 */
1645 zero_need = 9; /* clear this far in linear order */
1647 else if (downscale == 8)
1649 pf_idct = idct1x1;
1650 k_need = 0; /* no AC, not needed */
1651 zero_need = 0; /* no AC, not needed */
1653 else return -1; /* not supported */
1655 /* init bitstream, fake a restart to make it start */
1656 bs.next_input_byte = p_jpeg->p_entropy_data;
1657 bs.bits_left = 0;
1658 bs.input_end = p_jpeg->p_entropy_end;
1660 width = p_jpeg->x_phys / downscale;
1661 height = p_jpeg->y_phys / downscale;
1662 for (i=0; i<3; i++) /* calculate some strides */
1664 skip_line[i] = width / p_jpeg->subsample_x[i];
1665 skip_strip[i] = skip_line[i]
1666 * (height / p_jpeg->y_mbl) / p_jpeg->subsample_y[i];
1667 skip_mcu[i] = width/p_jpeg->x_mbl / p_jpeg->subsample_x[i];
1670 /* prepare offsets about where to store the different blocks */
1671 store_offs[p_jpeg->store_pos[0]] = 0;
1672 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1673 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1674 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1676 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1678 for (i=0; i<3; i++) /* scan line init */
1680 p_byte[i] = p_line[i];
1681 p_line[i] += skip_strip[i];
1683 for (x=0; x<p_jpeg->x_mbl; x++)
1685 int blkn;
1687 /* Outer loop handles each block in the MCU */
1688 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1689 { /* Decode a single block's worth of coefficients */
1690 int k = 1; /* coefficient index */
1691 int s, r; /* huffman values */
1692 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1693 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1694 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1695 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1697 /* Section F.2.2.1: decode the DC coefficient difference */
1698 s = huff_decode_dc(&bs, dctbl);
1700 last_dc_val[ci] += s;
1701 block[0] = last_dc_val[ci]; /* output it (assumes zag[0] = 0) */
1703 /* coefficient buffer must be cleared */
1704 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1706 /* Section F.2.2.2: decode the AC coefficients */
1707 for (; k < k_need; k++)
1709 s = huff_decode_ac(&bs, actbl);
1710 r = s >> 4;
1711 s &= 15;
1713 if (s)
1715 k += r;
1716 check_bit_buffer(&bs, s);
1717 r = get_bits(&bs, s);
1718 block[zag[k]] = HUFF_EXTEND(r, s);
1720 else
1722 if (r != 15)
1724 k = 64;
1725 break;
1727 k += r;
1729 } /* for k */
1730 /* In this path we just discard the values */
1731 for (; k < 64; k++)
1733 s = huff_decode_ac(&bs, actbl);
1734 r = s >> 4;
1735 s &= 15;
1737 if (s)
1739 k += r;
1740 check_bit_buffer(&bs, s);
1741 drop_bits(&bs, s);
1743 else
1745 if (r != 15)
1746 break;
1747 k += r;
1749 } /* for k */
1751 if (ci == 0)
1752 { /* Y component needs to bother about block store */
1753 pf_idct(p_byte[0]+store_offs[blkn], block,
1754 p_jpeg->qt_idct[ti], skip_line[0]);
1756 else
1757 { /* chroma */
1758 pf_idct(p_byte[ci], block, p_jpeg->qt_idct[ti],
1759 skip_line[ci]);
1761 } /* for blkn */
1762 p_byte[0] += skip_mcu[0]; /* unrolled for (i=0; i<3; i++) loop */
1763 p_byte[1] += skip_mcu[1];
1764 p_byte[2] += skip_mcu[2];
1765 if (p_jpeg->restart_interval && --restart == 0)
1766 { /* if a restart marker is due: */
1767 restart = p_jpeg->restart_interval; /* count again */
1768 search_restart(&bs); /* align the bitstream */
1769 last_dc_val[0] = last_dc_val[1] =
1770 last_dc_val[2] = 0; /* reset decoder */
1772 } /* for x */
1773 if (pf_progress != NULL)
1774 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1775 } /* for y */
1777 return 0; /* success */
1779 #else /* !HAVE_LCD_COLOR */
1781 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1782 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[1], int downscale,
1783 void (*pf_progress)(int current, int total))
1785 struct bitstream bs; /* bitstream "object" */
1786 int block[64]; /* decoded DCT coefficients */
1788 int width, height;
1789 int skip_line; /* bytes from one line to the next (skip_line) */
1790 int skip_strip, skip_mcu; /* bytes to next DCT row / column */
1792 int x, y; /* loop counter */
1794 unsigned char* p_line = p_pixel[0];
1795 unsigned char* p_byte; /* bitmap pointer */
1797 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1798 int k_need; /* AC coefficients needed up to here */
1799 int zero_need; /* init the block with this many zeros */
1801 int last_dc_val = 0;
1802 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1803 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1805 /* pick the IDCT we want, determine how to work with coefs */
1806 if (downscale == 1)
1808 pf_idct = idct8x8;
1809 k_need = 64; /* all */
1810 zero_need = 63; /* all */
1812 else if (downscale == 2)
1814 pf_idct = idct4x4;
1815 k_need = 25; /* this far in zig-zag to cover 4*4 */
1816 zero_need = 27; /* clear this far in linear order */
1818 else if (downscale == 4)
1820 pf_idct = idct2x2;
1821 k_need = 5; /* this far in zig-zag to cover 2*2 */
1822 zero_need = 9; /* clear this far in linear order */
1824 else if (downscale == 8)
1826 pf_idct = idct1x1;
1827 k_need = 0; /* no AC, not needed */
1828 zero_need = 0; /* no AC, not needed */
1830 else return -1; /* not supported */
1832 /* init bitstream, fake a restart to make it start */
1833 bs.next_input_byte = p_jpeg->p_entropy_data;
1834 bs.bits_left = 0;
1835 bs.input_end = p_jpeg->p_entropy_end;
1837 width = p_jpeg->x_phys / downscale;
1838 height = p_jpeg->y_phys / downscale;
1839 skip_line = width;
1840 skip_strip = skip_line * (height / p_jpeg->y_mbl);
1841 skip_mcu = (width/p_jpeg->x_mbl);
1843 /* prepare offsets about where to store the different blocks */
1844 store_offs[p_jpeg->store_pos[0]] = 0;
1845 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1846 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1847 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1849 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1851 p_byte = p_line;
1852 p_line += skip_strip;
1853 for (x=0; x<p_jpeg->x_mbl; x++)
1855 int blkn;
1857 /* Outer loop handles each block in the MCU */
1858 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1859 { /* Decode a single block's worth of coefficients */
1860 int k = 1; /* coefficient index */
1861 int s, r; /* huffman values */
1862 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1863 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1864 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1865 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1867 /* Section F.2.2.1: decode the DC coefficient difference */
1868 s = huff_decode_dc(&bs, dctbl);
1870 if (ci == 0) /* only for Y component */
1872 last_dc_val += s;
1873 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
1875 /* coefficient buffer must be cleared */
1876 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1878 /* Section F.2.2.2: decode the AC coefficients */
1879 for (; k < k_need; k++)
1881 s = huff_decode_ac(&bs, actbl);
1882 r = s >> 4;
1883 s &= 15;
1885 if (s)
1887 k += r;
1888 check_bit_buffer(&bs, s);
1889 r = get_bits(&bs, s);
1890 block[zag[k]] = HUFF_EXTEND(r, s);
1892 else
1894 if (r != 15)
1896 k = 64;
1897 break;
1899 k += r;
1901 } /* for k */
1903 /* In this path we just discard the values */
1904 for (; k < 64; k++)
1906 s = huff_decode_ac(&bs, actbl);
1907 r = s >> 4;
1908 s &= 15;
1910 if (s)
1912 k += r;
1913 check_bit_buffer(&bs, s);
1914 drop_bits(&bs, s);
1916 else
1918 if (r != 15)
1919 break;
1920 k += r;
1922 } /* for k */
1924 if (ci == 0)
1925 { /* only for Y component */
1926 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
1927 skip_line);
1929 } /* for blkn */
1930 p_byte += skip_mcu;
1931 if (p_jpeg->restart_interval && --restart == 0)
1932 { /* if a restart marker is due: */
1933 restart = p_jpeg->restart_interval; /* count again */
1934 search_restart(&bs); /* align the bitstream */
1935 last_dc_val = 0; /* reset decoder */
1937 } /* for x */
1938 if (pf_progress != NULL)
1939 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1940 } /* for y */
1942 return 0; /* success */
1944 #endif /* !HAVE_LCD_COLOR */
1946 /**************** end JPEG code ********************/
1950 /**************** begin Application ********************/
1953 /************************* Types ***************************/
1955 struct t_disp
1957 #ifdef HAVE_LCD_COLOR
1958 unsigned char* bitmap[3]; /* Y, Cr, Cb */
1959 int csub_x, csub_y;
1960 #else
1961 unsigned char* bitmap[1]; /* Y only */
1962 #endif
1963 int width;
1964 int height;
1965 int stride;
1966 int x, y;
1969 /************************* Globals ***************************/
1971 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1972 struct t_disp disp[9];
1974 /* my memory pool (from the mp3 buffer) */
1975 char print[32]; /* use a common snprintf() buffer */
1976 unsigned char* buf; /* up to here currently used by image(s) */
1978 /* the remaining free part of the buffer for compressed+uncompressed images */
1979 unsigned char* buf_images;
1981 ssize_t buf_size, buf_images_size;
1982 /* the root of the images, hereafter are decompresed ones */
1983 unsigned char* buf_root;
1984 int root_size;
1986 int ds, ds_min, ds_max; /* downscaling and limits */
1987 static struct jpeg jpg; /* too large for stack */
1989 static struct tree_context *tree;
1991 /* the current full file name */
1992 static char np_file[MAX_PATH];
1993 int curfile = 0, direction = DIR_NONE, entries = 0;
1995 /* list of the jpeg files */
1996 char **file_pt;
1997 /* are we using the plugin buffer or the audio buffer? */
1998 bool plug_buf = false;
2001 /************************* Implementation ***************************/
2003 #ifdef HAVE_LCD_COLOR
2005 * Conversion of full 0-255 range YCrCb to RGB:
2006 * |R| |1.000000 -0.000001 1.402000| |Y'|
2007 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
2008 * |B| |1.000000 1.772000 0.000000| |Pr|
2009 * Scaled (yields s15-bit output):
2010 * |R| |128 0 179| |Y |
2011 * |G| = |128 -43 -91| |Cb - 128|
2012 * |B| |128 227 0| |Cr - 128|
2014 #define YFAC 128
2015 #define RVFAC 179
2016 #define GUFAC (-43)
2017 #define GVFAC (-91)
2018 #define BUFAC 227
2019 #define YUV_WHITE (255*YFAC)
2020 #define NODITHER_DELTA (127*YFAC)
2021 #define COMPONENT_SHIFT 15
2022 #define MATRIX_SHIFT 7
2024 static inline int clamp_component(int x)
2026 if ((unsigned)x > YUV_WHITE)
2027 x = x < 0 ? 0 : YUV_WHITE;
2028 return x;
2031 static inline int clamp_component_bits(int x, int bits)
2033 if ((unsigned)x > (1u << bits) - 1)
2034 x = x < 0 ? 0 : (1 << bits) - 1;
2035 return x;
2038 static inline int component_to_lcd(int x, int bits, int delta)
2040 /* Formula used in core bitmap loader. */
2041 return (((1 << bits) - 1)*x + (x >> (8 - bits)) + delta) >> COMPONENT_SHIFT;
2044 static inline int lcd_to_component(int x, int bits, int delta)
2046 /* Reasonable, approximate reversal to get a full range back from the
2047 quantized value. */
2048 return YUV_WHITE*x / ((1 << bits) - 1);
2049 (void)delta;
2052 #define RED 0
2053 #define GRN 1
2054 #define BLU 2
2056 struct rgb_err
2058 int16_t errbuf[LCD_WIDTH+2]; /* Error record for line below */
2059 } rgb_err_buffers[3];
2061 fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
2062 DITHER_DIFFUSION is set */
2064 struct rgb_pixel
2066 int r, g, b; /* Current pixel components in s16.0 */
2067 int inc; /* Current line increment (-1 or 1) */
2068 int row; /* Current row in source image */
2069 int col; /* Current column in source image */
2070 int ce[3]; /* Errors to apply to current pixel */
2071 struct rgb_err *e; /* RED, GRN, BLU */
2072 int epos; /* Current position in error record */
2075 struct rgb_pixel *pixel;
2077 /** round and truncate to lcd depth **/
2078 static fb_data pixel_to_lcd_colour(void)
2080 struct rgb_pixel *p = pixel;
2081 int r, g, b;
2083 r = component_to_lcd(p->r, LCD_RED_BITS, NODITHER_DELTA);
2084 r = clamp_component_bits(r, LCD_RED_BITS);
2086 g = component_to_lcd(p->g, LCD_GREEN_BITS, NODITHER_DELTA);
2087 g = clamp_component_bits(g, LCD_GREEN_BITS);
2089 b = component_to_lcd(p->b, LCD_BLUE_BITS, NODITHER_DELTA);
2090 b = clamp_component_bits(b, LCD_BLUE_BITS);
2092 return LCD_RGBPACK_LCD(r, g, b);
2095 /** write a monochrome pixel to the colour LCD **/
2096 static fb_data pixel_to_lcd_gray(void)
2098 int r, g, b;
2100 g = clamp_component(pixel->g);
2101 r = component_to_lcd(g, LCD_RED_BITS, NODITHER_DELTA);
2102 b = component_to_lcd(g, LCD_BLUE_BITS, NODITHER_DELTA);
2103 g = component_to_lcd(g, LCD_GREEN_BITS, NODITHER_DELTA);
2105 return LCD_RGBPACK_LCD(r, g, b);
2109 * Bayer ordered dithering - swiped from the core bitmap loader.
2111 static fb_data pixel_odither_to_lcd(void)
2113 /* canonical ordered dither matrix */
2114 static const unsigned char dither_matrix[16][16] = {
2115 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
2116 { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
2117 { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
2118 { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
2119 { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
2120 { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
2121 { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
2122 { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
2123 { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
2124 { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
2125 { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
2126 { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
2127 { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
2128 { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
2129 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
2130 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
2133 struct rgb_pixel *p = pixel;
2134 int r, g, b, delta;
2136 delta = dither_matrix[p->col & 15][p->row & 15] << MATRIX_SHIFT;
2138 r = component_to_lcd(p->r, LCD_RED_BITS, delta);
2139 r = clamp_component_bits(r, LCD_RED_BITS);
2141 g = component_to_lcd(p->g, LCD_GREEN_BITS, delta);
2142 g = clamp_component_bits(g, LCD_GREEN_BITS);
2144 b = component_to_lcd(p->b, LCD_BLUE_BITS, delta);
2145 b = clamp_component_bits(b, LCD_BLUE_BITS);
2147 p->col += p->inc;
2149 return LCD_RGBPACK_LCD(r, g, b);
2153 * Floyd/Steinberg dither to lcd depth.
2155 * Apply filter to each component in serpentine pattern. Kernel shown for
2156 * L->R scan. Kernel is reversed for R->L.
2157 * * 7
2158 * 3 5 1 (1/16)
2160 static inline void distribute_error(int *ce, struct rgb_err *e,
2161 int err, int epos, int inc)
2163 *ce = (7*err >> 4) + e->errbuf[epos+inc];
2164 e->errbuf[epos+inc] = err >> 4;
2165 e->errbuf[epos] += 5*err >> 4;
2166 e->errbuf[epos-inc] += 3*err >> 4;
2169 static fb_data pixel_fsdither_to_lcd(void)
2171 struct rgb_pixel *p = pixel;
2172 int rc, gc, bc, r, g, b;
2173 int inc, epos;
2175 /* Full components with error terms */
2176 rc = p->r + p->ce[RED];
2177 r = component_to_lcd(rc, LCD_RED_BITS, 0);
2178 r = clamp_component_bits(r, LCD_RED_BITS);
2180 gc = p->g + p->ce[GRN];
2181 g = component_to_lcd(gc, LCD_GREEN_BITS, 0);
2182 g = clamp_component_bits(g, LCD_GREEN_BITS);
2184 bc = p->b + p->ce[BLU];
2185 b = component_to_lcd(bc, LCD_BLUE_BITS, 0);
2186 b = clamp_component_bits(b, LCD_BLUE_BITS);
2188 /* Get pixel errors */
2189 rc -= lcd_to_component(r, LCD_RED_BITS, 0);
2190 gc -= lcd_to_component(g, LCD_GREEN_BITS, 0);
2191 bc -= lcd_to_component(b, LCD_BLUE_BITS, 0);
2193 /* Spead error to surrounding pixels. */
2194 inc = p->inc;
2195 epos = p->epos;
2196 p->epos += inc;
2198 distribute_error(&p->ce[RED], &p->e[RED], rc, epos, inc);
2199 distribute_error(&p->ce[GRN], &p->e[GRN], gc, epos, inc);
2200 distribute_error(&p->ce[BLU], &p->e[BLU], bc, epos, inc);
2202 /* Pack and return pixel */
2203 return LCD_RGBPACK_LCD(r, g, b);
2206 /* Functions for each output mode, colour then grayscale. */
2207 static fb_data (* const pixel_funcs[COLOUR_NUM_MODES][DITHER_NUM_MODES])(void) =
2209 [COLOURMODE_COLOUR] =
2211 [DITHER_NONE] = pixel_to_lcd_colour,
2212 [DITHER_ORDERED] = pixel_odither_to_lcd,
2213 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2215 [COLOURMODE_GRAY] =
2217 [DITHER_NONE] = pixel_to_lcd_gray,
2218 [DITHER_ORDERED] = pixel_odither_to_lcd,
2219 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2224 * Draw a partial YUV colour bitmap
2226 * Runs serpentine pattern when dithering is DITHER_DIFFUSION, else scan is
2227 * always L->R.
2229 void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
2230 int src_x, int src_y, int stride,
2231 int x, int y, int width, int height)
2233 fb_data *dst, *dst_end;
2234 fb_data (*pixel_func)(void);
2235 struct rgb_pixel px;
2237 if (x + width > LCD_WIDTH)
2238 width = LCD_WIDTH - x; /* Clip right */
2239 if (x < 0)
2240 width += x, x = 0; /* Clip left */
2241 if (width <= 0)
2242 return; /* nothing left to do */
2244 if (y + height > LCD_HEIGHT)
2245 height = LCD_HEIGHT - y; /* Clip bottom */
2246 if (y < 0)
2247 height += y, y = 0; /* Clip top */
2248 if (height <= 0)
2249 return; /* nothing left to do */
2251 pixel = &px;
2253 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
2254 dst_end = dst + LCD_WIDTH * height;
2256 if (jpeg_settings.colour_mode == COLOURMODE_GRAY)
2257 csub_y = 0; /* Ignore Cb, Cr */
2259 pixel_func = pixel_funcs[jpeg_settings.colour_mode]
2260 [jpeg_settings.dither_mode];
2262 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2264 /* Reset error terms. */
2265 px.e = rgb_err_buffers;
2266 px.ce[RED] = px.ce[GRN] = px.ce[BLU] = 0;
2267 rb->memset(px.e, 0, 3*sizeof (struct rgb_err));
2272 fb_data *dst_row, *row_end;
2273 const unsigned char *ysrc;
2274 px.inc = 1;
2276 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2278 /* Use R->L scan on odd lines */
2279 px.inc -= (src_y & 1) << 1;
2280 px.epos = x + 1;
2282 if (px.inc < 0)
2283 px.epos += width - 1;
2286 if (px.inc == 1)
2288 /* Scan is L->R */
2289 dst_row = dst;
2290 row_end = dst_row + width;
2291 px.col = src_x;
2293 else
2295 /* Scan is R->L */
2296 row_end = dst - 1;
2297 dst_row = row_end + width;
2298 px.col = src_x + width - 1;
2301 ysrc = src[0] + stride * src_y + px.col;
2302 px.row = src_y;
2304 /* Do one row of pixels */
2305 if (csub_y) /* colour */
2307 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
2308 const unsigned char *usrc, *vsrc;
2310 usrc = src[1] + (stride/csub_x) * (src_y/csub_y)
2311 + (px.col/csub_x);
2312 vsrc = src[2] + (stride/csub_x) * (src_y/csub_y)
2313 + (px.col/csub_x);
2314 int xphase = px.col % csub_x;
2315 int xphase_reset = px.inc * csub_x;
2316 int y, v, u, rv, guv, bu;
2318 v = *vsrc - 128;
2319 vsrc += px.inc;
2320 u = *usrc - 128;
2321 usrc += px.inc;
2322 rv = RVFAC*v;
2323 guv = GUFAC*u + GVFAC*v;
2324 bu = BUFAC*u;
2326 while (1)
2328 y = YFAC*(*ysrc);
2329 ysrc += px.inc;
2330 px.r = y + rv;
2331 px.g = y + guv;
2332 px.b = y + bu;
2334 *dst_row = pixel_func();
2335 dst_row += px.inc;
2337 if (dst_row == row_end)
2338 break;
2340 xphase += px.inc;
2341 if ((unsigned)xphase < (unsigned)csub_x)
2342 continue;
2344 /* fetch new chromas */
2345 v = *vsrc - 128;
2346 vsrc += px.inc;
2347 u = *usrc - 128;
2348 usrc += px.inc;
2349 rv = RVFAC*v;
2350 guv = GUFAC*u + GVFAC*v;
2351 bu = BUFAC*u;
2353 xphase -= xphase_reset;
2356 else /* monochrome */
2360 /* Set all components the same for dithering purposes */
2361 px.g = px.r = px.b = YFAC*(*ysrc);
2362 *dst_row = pixel_func();
2363 ysrc += px.inc;
2364 dst_row += px.inc;
2366 while (dst_row != row_end);
2369 src_y++;
2370 dst += LCD_WIDTH;
2372 while (dst < dst_end);
2375 #endif /* HAVE_LCD_COLOR */
2378 /* support function for qsort() */
2379 static int compare(const void* p1, const void* p2)
2381 return rb->strcasecmp(*((char **)p1), *((char **)p2));
2384 bool jpg_ext(const char ext[])
2386 if(!ext)
2387 return false;
2388 if(!rb->strcasecmp(ext,".jpg") ||
2389 !rb->strcasecmp(ext,".jpe") ||
2390 !rb->strcasecmp(ext,".jpeg"))
2391 return true;
2392 else
2393 return false;
2396 /*Read directory contents for scrolling. */
2397 void get_pic_list(void)
2399 int i;
2400 long int str_len = 0;
2401 char *pname;
2402 tree = rb->tree_get_context();
2404 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2405 file_pt = rb->plugin_get_buffer((size_t *)&buf_size);
2406 #else
2407 file_pt = rb->plugin_get_audio_buffer((size_t *)&buf_size);
2408 #endif
2410 for(i = 0; i < tree->filesindir; i++)
2412 if(jpg_ext(rb->strrchr(&tree->name_buffer[str_len],'.')))
2413 file_pt[entries++] = &tree->name_buffer[str_len];
2415 str_len += rb->strlen(&tree->name_buffer[str_len]) + 1;
2418 rb->qsort(file_pt, entries, sizeof(char**), compare);
2420 /* Remove path and leave only the name.*/
2421 pname = rb->strrchr(np_file,'/');
2422 pname++;
2424 /* Find Selected File. */
2425 for(i = 0; i < entries; i++)
2426 if(!rb->strcmp(file_pt[i], pname))
2427 curfile = i;
2430 int change_filename(int direct)
2432 int count = 0;
2433 direction = direct;
2435 if(direct == DIR_PREV)
2439 count++;
2440 if(curfile == 0)
2441 curfile = entries - 1;
2442 else
2443 curfile--;
2444 }while(file_pt[curfile] == '\0' && count < entries);
2445 /* we "erase" the file name if we encounter
2446 * a non-supported file, so skip it now */
2448 else /* DIR_NEXT/DIR_NONE */
2452 count++;
2453 if(curfile == entries - 1)
2454 curfile = 0;
2455 else
2456 curfile++;
2457 }while(file_pt[curfile] == '\0' && count < entries);
2460 if(count == entries && file_pt[curfile] == '\0')
2462 rb->splash(HZ, "No supported files");
2463 return PLUGIN_ERROR;
2465 if(rb->strlen(tree->currdir) > 1)
2467 rb->strcpy(np_file, tree->currdir);
2468 rb->strcat(np_file, "/");
2470 else
2471 rb->strcpy(np_file, tree->currdir);
2473 rb->strcat(np_file, file_pt[curfile]);
2475 return PLUGIN_OTHER;
2478 /* switch off overlay, for handling SYS_ events */
2479 void cleanup(void *parameter)
2481 (void)parameter;
2482 #ifdef USEGSLIB
2483 grey_show(false);
2484 #endif
2487 #define VSCROLL (LCD_HEIGHT/8)
2488 #define HSCROLL (LCD_WIDTH/10)
2490 #define ZOOM_IN 100 /* return codes for below function */
2491 #define ZOOM_OUT 101
2493 #ifdef HAVE_LCD_COLOR
2494 bool set_option_grayscale(void)
2496 bool gray = jpeg_settings.colour_mode == COLOURMODE_GRAY;
2497 rb->set_bool("Grayscale", &gray);
2498 jpeg_settings.colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
2499 return false;
2502 bool set_option_dithering(void)
2504 static const struct opt_items dithering[DITHER_NUM_MODES] = {
2505 [DITHER_NONE] = { "Off", -1 },
2506 [DITHER_ORDERED] = { "Ordered", -1 },
2507 [DITHER_DIFFUSION] = { "Diffusion", -1 },
2510 rb->set_option("Dithering", &jpeg_settings.dither_mode, INT,
2511 dithering, DITHER_NUM_MODES, NULL);
2512 return false;
2515 static void display_options(void)
2517 static const struct menu_item items[] = {
2518 { "Grayscale", set_option_grayscale },
2519 { "Dithering", set_option_dithering },
2522 int m = menu_init(rb, items, ARRAYLEN(items),
2523 NULL, NULL, NULL, NULL);
2524 menu_run(m);
2525 menu_exit(m);
2527 #endif /* HAVE_LCD_COLOR */
2529 int show_menu(void) /* return 1 to quit */
2531 #if LCD_DEPTH > 1
2532 rb->lcd_set_backdrop(old_backdrop);
2533 #ifdef HAVE_LCD_COLOR
2534 rb->lcd_set_foreground(rb->global_settings->fg_color);
2535 rb->lcd_set_background(rb->global_settings->bg_color);
2536 #else
2537 rb->lcd_set_foreground(LCD_BLACK);
2538 rb->lcd_set_background(LCD_WHITE);
2539 #endif
2540 #endif
2541 int m;
2542 int result;
2544 enum menu_id
2546 MIID_QUIT = 0,
2547 MIID_TOGGLE_SS_MODE,
2548 MIID_CHANGE_SS_MODE,
2549 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2550 MIID_SHOW_PLAYBACK_MENU,
2551 #endif
2552 #ifdef HAVE_LCD_COLOR
2553 MIID_DISPLAY_OPTIONS,
2554 #endif
2555 MIID_RETURN,
2558 static const struct menu_item items[] = {
2559 [MIID_QUIT] =
2560 { "Quit", NULL },
2561 [MIID_TOGGLE_SS_MODE] =
2562 { "Toggle Slideshow Mode", NULL },
2563 [MIID_CHANGE_SS_MODE] =
2564 { "Change Slideshow Time", NULL },
2565 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2566 [MIID_SHOW_PLAYBACK_MENU] =
2567 { "Show Playback Menu", NULL },
2568 #endif
2569 #ifdef HAVE_LCD_COLOR
2570 [MIID_DISPLAY_OPTIONS] =
2571 { "Display Options", NULL },
2572 #endif
2573 [MIID_RETURN] =
2574 { "Return", NULL },
2577 static const struct opt_items slideshow[2] = {
2578 { "Disable", -1 },
2579 { "Enable", -1 },
2582 m = menu_init(rb, items, sizeof(items) / sizeof(*items),
2583 NULL, NULL, NULL, NULL);
2584 result=menu_show(m);
2586 switch (result)
2588 case MIID_QUIT:
2589 menu_exit(m);
2590 return 1;
2591 break;
2592 case MIID_TOGGLE_SS_MODE:
2593 rb->set_option("Toggle Slideshow", &slideshow_enabled, INT,
2594 slideshow , 2, NULL);
2595 break;
2596 case MIID_CHANGE_SS_MODE:
2597 rb->set_int("Slideshow Time", "s", UNIT_SEC,
2598 &jpeg_settings.ss_timeout, NULL, 1,
2599 SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, NULL);
2600 break;
2602 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2603 case MIID_SHOW_PLAYBACK_MENU:
2604 if (plug_buf)
2606 playback_control(rb, NULL);
2608 else
2610 rb->splash(HZ, "Cannot restart playback");
2612 break;
2613 #endif
2614 #ifdef HAVE_LCD_COLOR
2615 case MIID_DISPLAY_OPTIONS:
2616 display_options();
2617 break;
2618 #endif
2619 case MIID_RETURN:
2620 break;
2623 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
2624 /* change ata spindown time based on slideshow time setting */
2625 immediate_ata_off = false;
2626 rb->ata_spindown(rb->global_settings->disk_spindown);
2628 if (slideshow_enabled)
2630 if(jpeg_settings.ss_timeout < 10)
2632 /* slideshow times < 10s keep disk spinning */
2633 rb->ata_spindown(0);
2635 else if (!rb->mp3_is_playing())
2637 /* slideshow times > 10s and not playing: ata_off after load */
2638 immediate_ata_off = true;
2641 #endif
2642 #if LCD_DEPTH > 1
2643 rb->lcd_set_backdrop(NULL);
2644 rb->lcd_set_foreground(LCD_WHITE);
2645 rb->lcd_set_background(LCD_BLACK);
2646 #endif
2647 rb->lcd_clear_display();
2648 menu_exit(m);
2649 return 0;
2651 /* interactively scroll around the image */
2652 int scroll_bmp(struct t_disp* pdisp)
2654 int lastbutton = 0;
2656 while (true)
2658 int button;
2659 int move;
2661 if (slideshow_enabled)
2662 button = rb->button_get_w_tmo(jpeg_settings.ss_timeout * HZ);
2663 else button = rb->button_get(true);
2665 running_slideshow = false;
2667 switch(button)
2669 case JPEG_LEFT:
2670 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2671 return change_filename(DIR_PREV);
2672 case JPEG_LEFT | BUTTON_REPEAT:
2673 move = MIN(HSCROLL, pdisp->x);
2674 if (move > 0)
2676 MYXLCD(scroll_right)(move); /* scroll right */
2677 pdisp->x -= move;
2678 #ifdef HAVE_LCD_COLOR
2679 yuv_bitmap_part(
2680 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2681 pdisp->x, pdisp->y, pdisp->stride,
2682 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2683 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2684 #else
2685 MYXLCD(gray_bitmap_part)(
2686 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2687 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2688 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2689 #endif
2690 MYLCD_UPDATE();
2692 break;
2694 case JPEG_RIGHT:
2695 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2696 return change_filename(DIR_NEXT);
2697 case JPEG_RIGHT | BUTTON_REPEAT:
2698 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
2699 if (move > 0)
2701 MYXLCD(scroll_left)(move); /* scroll left */
2702 pdisp->x += move;
2703 #ifdef HAVE_LCD_COLOR
2704 yuv_bitmap_part(
2705 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2706 pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride,
2707 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2708 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2709 #else
2710 MYXLCD(gray_bitmap_part)(
2711 pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move,
2712 pdisp->y, pdisp->stride,
2713 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2714 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2715 #endif
2716 MYLCD_UPDATE();
2718 break;
2720 case JPEG_UP:
2721 case JPEG_UP | BUTTON_REPEAT:
2722 move = MIN(VSCROLL, pdisp->y);
2723 if (move > 0)
2725 MYXLCD(scroll_down)(move); /* scroll down */
2726 pdisp->y -= move;
2727 #ifdef HAVE_LCD_COLOR
2728 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2730 /* Draw over the band at the top of the last update
2731 caused by lack of error history on line zero. */
2732 move = MIN(move + 1, pdisp->y + pdisp->height);
2735 yuv_bitmap_part(
2736 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2737 pdisp->x, pdisp->y, pdisp->stride,
2738 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2739 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2740 #else
2741 MYXLCD(gray_bitmap_part)(
2742 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2743 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2744 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2745 #endif
2746 MYLCD_UPDATE();
2748 break;
2750 case JPEG_DOWN:
2751 case JPEG_DOWN | BUTTON_REPEAT:
2752 move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT);
2753 if (move > 0)
2755 MYXLCD(scroll_up)(move); /* scroll up */
2756 pdisp->y += move;
2757 #ifdef HAVE_LCD_COLOR
2758 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2760 /* Save the line that was on the last line of the display
2761 and draw one extra line above then recover the line with
2762 image data that had an error history when it was drawn.
2764 move++, pdisp->y--;
2765 MEMCPY(rgb_linebuf,
2766 rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2767 LCD_WIDTH*sizeof (fb_data));
2770 yuv_bitmap_part(
2771 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x,
2772 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2773 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2774 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2776 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2778 /* Cover the first row drawn with previous image data. */
2779 MEMCPY(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2780 rgb_linebuf,
2781 LCD_WIDTH*sizeof (fb_data));
2782 pdisp->y++;
2784 #else
2785 MYXLCD(gray_bitmap_part)(
2786 pdisp->bitmap[0], pdisp->x,
2787 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2788 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2789 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2790 #endif
2791 MYLCD_UPDATE();
2793 break;
2794 case BUTTON_NONE:
2795 if (!slideshow_enabled)
2796 break;
2797 running_slideshow = true;
2798 if (entries > 0)
2799 return change_filename(DIR_NEXT);
2800 break;
2802 #ifdef JPEG_SLIDE_SHOW
2803 case JPEG_SLIDE_SHOW:
2804 slideshow_enabled = !slideshow_enabled;
2805 running_slideshow = slideshow_enabled;
2806 break;
2807 #endif
2809 #ifdef JPEG_NEXT_REPEAT
2810 case JPEG_NEXT_REPEAT:
2811 #endif
2812 case JPEG_NEXT:
2813 if (entries > 0)
2814 return change_filename(DIR_NEXT);
2815 break;
2817 #ifdef JPEG_PREVIOUS_REPEAT
2818 case JPEG_PREVIOUS_REPEAT:
2819 #endif
2820 case JPEG_PREVIOUS:
2821 if (entries > 0)
2822 return change_filename(DIR_PREV);
2823 break;
2825 case JPEG_ZOOM_IN:
2826 #ifdef JPEG_ZOOM_PRE
2827 if (lastbutton != JPEG_ZOOM_PRE)
2828 break;
2829 #endif
2830 return ZOOM_IN;
2831 break;
2833 case JPEG_ZOOM_OUT:
2834 #ifdef JPEG_ZOOM_PRE
2835 if (lastbutton != JPEG_ZOOM_PRE)
2836 break;
2837 #endif
2838 return ZOOM_OUT;
2839 break;
2840 #ifdef JPEG_RC_MENU
2841 case JPEG_RC_MENU:
2842 #endif
2843 case JPEG_MENU:
2844 #ifdef USEGSLIB
2845 grey_show(false); /* switch off greyscale overlay */
2846 #endif
2847 if (show_menu() == 1)
2848 return PLUGIN_OK;
2850 #ifdef USEGSLIB
2851 grey_show(true); /* switch on greyscale overlay */
2852 #else
2853 yuv_bitmap_part(
2854 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2855 pdisp->x, pdisp->y, pdisp->stride,
2856 MAX(0, (LCD_WIDTH - pdisp->width) / 2),
2857 MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
2858 MIN(LCD_WIDTH, pdisp->width),
2859 MIN(LCD_HEIGHT, pdisp->height));
2860 MYLCD_UPDATE();
2861 #endif
2862 break;
2863 default:
2864 if (rb->default_event_handler_ex(button, cleanup, NULL)
2865 == SYS_USB_CONNECTED)
2866 return PLUGIN_USB_CONNECTED;
2867 break;
2869 } /* switch */
2871 if (button != BUTTON_NONE)
2872 lastbutton = button;
2873 } /* while (true) */
2876 /********************* main function *************************/
2878 /* callback updating a progress meter while JPEG decoding */
2879 void cb_progess(int current, int total)
2881 rb->yield(); /* be nice to the other threads */
2882 if(!running_slideshow)
2884 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-8, LCD_WIDTH, 8, total, 0,
2885 current, HORIZONTAL);
2886 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
2888 #ifndef USEGSLIB
2889 else
2891 /* in slideshow mode, keep gui interference to a minimum */
2892 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-4, LCD_WIDTH, 4, total, 0,
2893 current, HORIZONTAL);
2894 rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4);
2896 #endif
2899 int jpegmem(struct jpeg *p_jpg, int ds)
2901 int size;
2903 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
2904 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
2905 #ifdef HAVE_LCD_COLOR
2906 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
2908 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
2909 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
2910 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
2911 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
2913 #endif
2914 return size;
2917 /* how far can we zoom in without running out of memory */
2918 int min_downscale(struct jpeg *p_jpg, int bufsize)
2920 int downscale = 8;
2922 if (jpegmem(p_jpg, 8) > bufsize)
2923 return 0; /* error, too large, even 1:8 doesn't fit */
2925 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
2926 downscale /= 2;
2928 return downscale;
2932 /* how far can we zoom out, to fit image into the LCD */
2933 int max_downscale(struct jpeg *p_jpg)
2935 int downscale = 1;
2937 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale
2938 || p_jpg->y_size > LCD_HEIGHT*downscale))
2940 downscale *= 2;
2943 return downscale;
2947 /* return decoded or cached image */
2948 struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2950 int w, h; /* used to center output */
2951 int size; /* decompressed image size */
2952 long time; /* measured ticks */
2953 int status;
2955 struct t_disp* p_disp = &disp[ds]; /* short cut */
2957 if (p_disp->bitmap[0] != NULL)
2959 return p_disp; /* we still have it */
2962 /* assign image buffer */
2964 /* physical size needed for decoding */
2965 size = jpegmem(p_jpg, ds);
2966 if (buf_size <= size)
2967 { /* have to discard the current */
2968 int i;
2969 for (i=1; i<=8; i++)
2970 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
2971 buf = buf_root; /* start again from the beginning of the buffer */
2972 buf_size = root_size;
2975 #ifdef HAVE_LCD_COLOR
2976 if (p_jpg->blocks > 1) /* colour jpeg */
2978 int i;
2980 for (i = 1; i < 3; i++)
2982 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
2983 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
2984 p_disp->bitmap[i] = buf;
2985 buf += size;
2986 buf_size -= size;
2988 p_disp->csub_x = p_jpg->subsample_x[1];
2989 p_disp->csub_y = p_jpg->subsample_y[1];
2991 else
2993 p_disp->csub_x = p_disp->csub_y = 0;
2994 p_disp->bitmap[1] = p_disp->bitmap[2] = buf;
2996 #endif
2997 /* size may be less when decoded (if height is not block aligned) */
2998 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
2999 p_disp->bitmap[0] = buf;
3000 buf += size;
3001 buf_size -= size;
3003 if(!running_slideshow)
3005 rb->snprintf(print, sizeof(print), "decoding %d*%d",
3006 p_jpg->x_size/ds, p_jpg->y_size/ds);
3007 rb->lcd_puts(0, 3, print);
3008 rb->lcd_update();
3011 /* update image properties */
3012 p_disp->width = p_jpg->x_size / ds;
3013 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
3014 p_disp->height = p_jpg->y_size / ds;
3016 /* the actual decoding */
3017 time = *rb->current_tick;
3018 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
3019 rb->cpu_boost(true);
3020 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
3021 rb->cpu_boost(false);
3022 #else
3023 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
3024 #endif
3025 if (status)
3027 rb->splash(HZ, "decode error %d", status);
3028 file_pt[curfile] = '\0';
3029 return NULL;
3031 time = *rb->current_tick - time;
3033 if(!running_slideshow)
3035 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
3036 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
3037 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
3038 rb->lcd_update();
3041 return p_disp;
3045 /* set the view to the given center point, limit if necessary */
3046 void set_view (struct t_disp* p_disp, int cx, int cy)
3048 int x, y;
3050 /* plain center to available width/height */
3051 x = cx - MIN(LCD_WIDTH, p_disp->width) / 2;
3052 y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2;
3054 /* limit against upper image size */
3055 x = MIN(p_disp->width - LCD_WIDTH, x);
3056 y = MIN(p_disp->height - LCD_HEIGHT, y);
3058 /* limit against negative side */
3059 x = MAX(0, x);
3060 y = MAX(0, y);
3062 p_disp->x = x; /* set the values */
3063 p_disp->y = y;
3067 /* calculate the view center based on the bitmap position */
3068 void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
3070 *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2;
3071 *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2;
3075 /* load, decode, display the image */
3076 int load_and_show(char* filename)
3078 int fd;
3079 int filesize;
3080 unsigned char* buf_jpeg; /* compressed JPEG image */
3081 int status;
3082 struct t_disp* p_disp; /* currenly displayed image */
3083 int cx, cy; /* view center */
3085 fd = rb->open(filename, O_RDONLY);
3086 if (fd < 0)
3088 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
3089 rb->splash(HZ, print);
3090 return PLUGIN_ERROR;
3092 filesize = rb->filesize(fd);
3093 rb->memset(&disp, 0, sizeof(disp));
3095 buf = buf_images + filesize;
3096 buf_size = buf_images_size - filesize;
3097 /* allocate JPEG buffer */
3098 buf_jpeg = buf_images;
3100 buf_root = buf; /* we can start the decompressed images behind it */
3101 root_size = buf_size;
3103 if (buf_size <= 0)
3105 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
3106 if(plug_buf)
3108 rb->close(fd);
3109 rb->lcd_setfont(FONT_SYSFIXED);
3110 rb->lcd_clear_display();
3111 rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
3112 rb->lcd_puts(0,0,print);
3113 rb->lcd_puts(0,1,"Not enough plugin memory!");
3114 rb->lcd_puts(0,2,"Zoom In: Stop playback.");
3115 if(entries>1)
3116 rb->lcd_puts(0,3,"Left/Right: Skip File.");
3117 rb->lcd_puts(0,4,"Off: Quit.");
3118 rb->lcd_update();
3119 rb->lcd_setfont(FONT_UI);
3121 rb->button_clear_queue();
3123 while (1)
3125 int button = rb->button_get(true);
3126 switch(button)
3128 case JPEG_ZOOM_IN:
3129 plug_buf = false;
3130 buf_images = rb->plugin_get_audio_buffer(
3131 (size_t *)&buf_images_size);
3132 /*try again this file, now using the audio buffer */
3133 return PLUGIN_OTHER;
3134 #ifdef JPEG_RC_MENU
3135 case JPEG_RC_MENU:
3136 #endif
3137 case JPEG_MENU:
3138 return PLUGIN_OK;
3140 case JPEG_LEFT:
3141 if(entries>1)
3143 rb->lcd_clear_display();
3144 return change_filename(DIR_PREV);
3146 break;
3148 case JPEG_RIGHT:
3149 if(entries>1)
3151 rb->lcd_clear_display();
3152 return change_filename(DIR_NEXT);
3154 break;
3155 default:
3156 if(rb->default_event_handler_ex(button, cleanup, NULL)
3157 == SYS_USB_CONNECTED)
3158 return PLUGIN_USB_CONNECTED;
3163 else
3164 #endif
3166 rb->splash(HZ, "Out of Memory");
3167 rb->close(fd);
3168 return PLUGIN_ERROR;
3172 if(!running_slideshow)
3174 #if LCD_DEPTH > 1
3175 rb->lcd_set_foreground(LCD_WHITE);
3176 rb->lcd_set_background(LCD_BLACK);
3177 rb->lcd_set_backdrop(NULL);
3178 #endif
3180 rb->lcd_clear_display();
3181 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
3182 rb->lcd_puts(0, 0, print);
3183 rb->lcd_update();
3185 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
3186 rb->lcd_puts(0, 1, print);
3187 rb->lcd_update();
3190 rb->read(fd, buf_jpeg, filesize);
3191 rb->close(fd);
3193 if(!running_slideshow)
3195 rb->snprintf(print, sizeof(print), "decoding markers");
3196 rb->lcd_puts(0, 2, print);
3197 rb->lcd_update();
3199 #ifndef SIMULATOR
3200 else if(immediate_ata_off)
3202 /* running slideshow and time is long enough: power down disk */
3203 rb->ata_sleep();
3205 #endif
3207 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
3208 /* process markers, unstuffing */
3209 status = process_markers(buf_jpeg, filesize, &jpg);
3211 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
3212 { /* bad format or minimum components not contained */
3213 rb->splash(HZ, "unsupported %d", status);
3214 file_pt[curfile] = '\0';
3215 return change_filename(direction);
3218 if (!(status & DHT)) /* if no Huffman table present: */
3219 default_huff_tbl(&jpg); /* use default */
3220 build_lut(&jpg); /* derive Huffman and other lookup-tables */
3222 if(!running_slideshow)
3224 rb->snprintf(print, sizeof(print), "image %dx%d", jpg.x_size, jpg.y_size);
3225 rb->lcd_puts(0, 2, print);
3226 rb->lcd_update();
3228 ds_max = max_downscale(&jpg); /* check display constraint */
3229 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */
3230 if (ds_min == 0)
3232 rb->splash(HZ, "too large");
3233 file_pt[curfile] = '\0';
3234 return change_filename(direction);
3237 ds = ds_max; /* initials setting */
3238 cx = jpg.x_size/ds/2; /* center the view */
3239 cy = jpg.y_size/ds/2;
3241 do /* loop the image prepare and decoding when zoomed */
3243 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */
3244 if (p_disp == NULL)
3245 return change_filename(direction);
3247 set_view(p_disp, cx, cy);
3249 if(!running_slideshow)
3251 rb->snprintf(print, sizeof(print), "showing %dx%d",
3252 p_disp->width, p_disp->height);
3253 rb->lcd_puts(0, 3, print);
3254 rb->lcd_update();
3256 MYLCD(clear_display)();
3257 #ifdef HAVE_LCD_COLOR
3258 yuv_bitmap_part(
3259 p_disp->bitmap, p_disp->csub_x, p_disp->csub_y,
3260 p_disp->x, p_disp->y, p_disp->stride,
3261 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3262 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3263 MIN(LCD_WIDTH, p_disp->width),
3264 MIN(LCD_HEIGHT, p_disp->height));
3265 #else
3266 MYXLCD(gray_bitmap_part)(
3267 p_disp->bitmap[0], p_disp->x, p_disp->y, p_disp->stride,
3268 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3269 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3270 MIN(LCD_WIDTH, p_disp->width),
3271 MIN(LCD_HEIGHT, p_disp->height));
3272 #endif
3273 MYLCD_UPDATE();
3275 #ifdef USEGSLIB
3276 grey_show(true); /* switch on greyscale overlay */
3277 #endif
3279 /* drawing is now finished, play around with scrolling
3280 * until you press OFF or connect USB
3282 while (1)
3284 status = scroll_bmp(p_disp);
3285 if (status == ZOOM_IN)
3287 if (ds > ds_min)
3289 ds /= 2; /* reduce downscaling to zoom in */
3290 get_view(p_disp, &cx, &cy);
3291 cx *= 2; /* prepare the position in the new image */
3292 cy *= 2;
3294 else
3295 continue;
3298 if (status == ZOOM_OUT)
3300 if (ds < ds_max)
3302 ds *= 2; /* increase downscaling to zoom out */
3303 get_view(p_disp, &cx, &cy);
3304 cx /= 2; /* prepare the position in the new image */
3305 cy /= 2;
3307 else
3308 continue;
3310 break;
3313 #ifdef USEGSLIB
3314 grey_show(false); /* switch off overlay */
3315 #endif
3316 rb->lcd_clear_display();
3318 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
3319 && status != PLUGIN_OTHER);
3320 #ifdef USEGSLIB
3321 rb->lcd_update();
3322 #endif
3323 return status;
3326 /******************** Plugin entry point *********************/
3328 enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
3330 rb = api;
3332 int condition;
3333 #ifdef USEGSLIB
3334 long greysize; /* helper */
3335 #endif
3336 #if LCD_DEPTH > 1
3337 old_backdrop = rb->lcd_get_backdrop();
3338 #endif
3340 if(!parameter) return PLUGIN_ERROR;
3342 rb->strcpy(np_file, parameter);
3343 get_pic_list();
3345 if(!entries) return PLUGIN_ERROR;
3347 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
3348 if(rb->audio_status())
3350 buf = rb->plugin_get_buffer((size_t *)&buf_size) +
3351 (entries * sizeof(char**));
3352 buf_size -= (entries * sizeof(char**));
3353 plug_buf = true;
3355 else
3356 buf = rb->plugin_get_audio_buffer((size_t *)&buf_size);
3357 #else
3358 buf = rb->plugin_get_audio_buffer(&buf_size) +
3359 (entries * sizeof(char**));
3360 buf_size -= (entries * sizeof(char**));
3361 #endif
3363 #ifdef USEGSLIB
3364 if (!grey_init(rb, buf, buf_size, GREY_ON_COP,
3365 LCD_WIDTH, LCD_HEIGHT, &greysize))
3367 rb->splash(HZ, "grey buf error");
3368 return PLUGIN_ERROR;
3370 buf += greysize;
3371 buf_size -= greysize;
3372 #else
3373 xlcd_init(rb);
3374 #endif
3376 /* should be ok to just load settings since a parameter is present
3377 here and the drive should be spinning */
3378 configfile_init(rb);
3379 configfile_load(JPEG_CONFIGFILE, jpeg_config,
3380 ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION);
3381 old_settings = jpeg_settings;
3383 buf_images = buf; buf_images_size = buf_size;
3385 /* Turn off backlight timeout */
3386 backlight_force_on(rb); /* backlight control in lib/helper.c */
3390 condition = load_and_show(np_file);
3391 }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
3392 && condition != PLUGIN_ERROR);
3394 if (rb->memcmp(&jpeg_settings, &old_settings, sizeof (jpeg_settings)))
3396 /* Just in case drive has to spin, keep it from looking locked */
3397 rb->splash(0, "Saving Settings");
3398 configfile_save(JPEG_CONFIGFILE, jpeg_config,
3399 ARRAYLEN(jpeg_config), JPEG_SETTINGS_VERSION);
3402 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
3403 /* set back ata spindown time in case we changed it */
3404 rb->ata_spindown(rb->global_settings->disk_spindown);
3405 #endif
3407 /* Turn on backlight timeout (revert to settings) */
3408 backlight_use_settings(rb); /* backlight control in lib/helper.c */
3410 #ifdef USEGSLIB
3411 grey_release(); /* deinitialize */
3412 #endif
3414 return condition;
3417 #endif /* HAVE_LCD_BITMAP */