Add effective clockrate for realtime decoding to the displayed results of test_codec...
[kugel-rb.git] / apps / plugins / jpeg.c
bloba05eaa72dc3880e113866b3d2a93755b74d515a3
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 playback_control(rb, NULL);
2605 break;
2606 #endif
2607 #ifdef HAVE_LCD_COLOR
2608 case MIID_DISPLAY_OPTIONS:
2609 display_options();
2610 break;
2611 #endif
2612 case MIID_RETURN:
2613 break;
2616 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
2617 /* change ata spindown time based on slideshow time setting */
2618 immediate_ata_off = false;
2619 rb->ata_spindown(rb->global_settings->disk_spindown);
2621 if (slideshow_enabled)
2623 if(jpeg_settings.ss_timeout < 10)
2625 /* slideshow times < 10s keep disk spinning */
2626 rb->ata_spindown(0);
2628 else if (!rb->mp3_is_playing())
2630 /* slideshow times > 10s and not playing: ata_off after load */
2631 immediate_ata_off = true;
2634 #endif
2635 #if LCD_DEPTH > 1
2636 rb->lcd_set_backdrop(NULL);
2637 rb->lcd_set_foreground(LCD_WHITE);
2638 rb->lcd_set_background(LCD_BLACK);
2639 #endif
2640 rb->lcd_clear_display();
2641 menu_exit(m);
2642 return 0;
2644 /* interactively scroll around the image */
2645 int scroll_bmp(struct t_disp* pdisp)
2647 int lastbutton = 0;
2649 while (true)
2651 int button;
2652 int move;
2654 if (slideshow_enabled)
2655 button = rb->button_get_w_tmo(jpeg_settings.ss_timeout * HZ);
2656 else button = rb->button_get(true);
2658 running_slideshow = false;
2660 switch(button)
2662 case JPEG_LEFT:
2663 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2664 return change_filename(DIR_PREV);
2665 case JPEG_LEFT | BUTTON_REPEAT:
2666 move = MIN(HSCROLL, pdisp->x);
2667 if (move > 0)
2669 MYXLCD(scroll_right)(move); /* scroll right */
2670 pdisp->x -= move;
2671 #ifdef HAVE_LCD_COLOR
2672 yuv_bitmap_part(
2673 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2674 pdisp->x, pdisp->y, pdisp->stride,
2675 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2676 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2677 #else
2678 MYXLCD(gray_bitmap_part)(
2679 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2680 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2681 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2682 #endif
2683 MYLCD_UPDATE();
2685 break;
2687 case JPEG_RIGHT:
2688 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2689 return change_filename(DIR_NEXT);
2690 case JPEG_RIGHT | BUTTON_REPEAT:
2691 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
2692 if (move > 0)
2694 MYXLCD(scroll_left)(move); /* scroll left */
2695 pdisp->x += move;
2696 #ifdef HAVE_LCD_COLOR
2697 yuv_bitmap_part(
2698 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2699 pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride,
2700 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2701 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2702 #else
2703 MYXLCD(gray_bitmap_part)(
2704 pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move,
2705 pdisp->y, pdisp->stride,
2706 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2707 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2708 #endif
2709 MYLCD_UPDATE();
2711 break;
2713 case JPEG_UP:
2714 case JPEG_UP | BUTTON_REPEAT:
2715 move = MIN(VSCROLL, pdisp->y);
2716 if (move > 0)
2718 MYXLCD(scroll_down)(move); /* scroll down */
2719 pdisp->y -= move;
2720 #ifdef HAVE_LCD_COLOR
2721 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2723 /* Draw over the band at the top of the last update
2724 caused by lack of error history on line zero. */
2725 move = MIN(move + 1, pdisp->y + pdisp->height);
2728 yuv_bitmap_part(
2729 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2730 pdisp->x, pdisp->y, pdisp->stride,
2731 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2732 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2733 #else
2734 MYXLCD(gray_bitmap_part)(
2735 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2736 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2737 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2738 #endif
2739 MYLCD_UPDATE();
2741 break;
2743 case JPEG_DOWN:
2744 case JPEG_DOWN | BUTTON_REPEAT:
2745 move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT);
2746 if (move > 0)
2748 MYXLCD(scroll_up)(move); /* scroll up */
2749 pdisp->y += move;
2750 #ifdef HAVE_LCD_COLOR
2751 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2753 /* Save the line that was on the last line of the display
2754 and draw one extra line above then recover the line with
2755 image data that had an error history when it was drawn.
2757 move++, pdisp->y--;
2758 MEMCPY(rgb_linebuf,
2759 rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2760 LCD_WIDTH*sizeof (fb_data));
2763 yuv_bitmap_part(
2764 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x,
2765 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2766 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2767 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2769 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2771 /* Cover the first row drawn with previous image data. */
2772 MEMCPY(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2773 rgb_linebuf,
2774 LCD_WIDTH*sizeof (fb_data));
2775 pdisp->y++;
2777 #else
2778 MYXLCD(gray_bitmap_part)(
2779 pdisp->bitmap[0], pdisp->x,
2780 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2781 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2782 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2783 #endif
2784 MYLCD_UPDATE();
2786 break;
2787 case BUTTON_NONE:
2788 if (!slideshow_enabled)
2789 break;
2790 running_slideshow = true;
2791 if (entries > 0)
2792 return change_filename(DIR_NEXT);
2793 break;
2795 #ifdef JPEG_SLIDE_SHOW
2796 case JPEG_SLIDE_SHOW:
2797 slideshow_enabled = !slideshow_enabled;
2798 running_slideshow = slideshow_enabled;
2799 break;
2800 #endif
2802 #ifdef JPEG_NEXT_REPEAT
2803 case JPEG_NEXT_REPEAT:
2804 #endif
2805 case JPEG_NEXT:
2806 if (entries > 0)
2807 return change_filename(DIR_NEXT);
2808 break;
2810 #ifdef JPEG_PREVIOUS_REPEAT
2811 case JPEG_PREVIOUS_REPEAT:
2812 #endif
2813 case JPEG_PREVIOUS:
2814 if (entries > 0)
2815 return change_filename(DIR_PREV);
2816 break;
2818 case JPEG_ZOOM_IN:
2819 #ifdef JPEG_ZOOM_PRE
2820 if (lastbutton != JPEG_ZOOM_PRE)
2821 break;
2822 #endif
2823 return ZOOM_IN;
2824 break;
2826 case JPEG_ZOOM_OUT:
2827 #ifdef JPEG_ZOOM_PRE
2828 if (lastbutton != JPEG_ZOOM_PRE)
2829 break;
2830 #endif
2831 return ZOOM_OUT;
2832 break;
2833 #ifdef JPEG_RC_MENU
2834 case JPEG_RC_MENU:
2835 #endif
2836 case JPEG_MENU:
2837 #ifdef USEGSLIB
2838 grey_show(false); /* switch off greyscale overlay */
2839 #endif
2840 if (show_menu() == 1)
2841 return PLUGIN_OK;
2843 #ifdef USEGSLIB
2844 grey_show(true); /* switch on greyscale overlay */
2845 #else
2846 yuv_bitmap_part(
2847 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2848 pdisp->x, pdisp->y, pdisp->stride,
2849 MAX(0, (LCD_WIDTH - pdisp->width) / 2),
2850 MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
2851 MIN(LCD_WIDTH, pdisp->width),
2852 MIN(LCD_HEIGHT, pdisp->height));
2853 MYLCD_UPDATE();
2854 #endif
2855 break;
2856 default:
2857 if (rb->default_event_handler_ex(button, cleanup, NULL)
2858 == SYS_USB_CONNECTED)
2859 return PLUGIN_USB_CONNECTED;
2860 break;
2862 } /* switch */
2864 if (button != BUTTON_NONE)
2865 lastbutton = button;
2866 } /* while (true) */
2869 /********************* main function *************************/
2871 /* callback updating a progress meter while JPEG decoding */
2872 void cb_progess(int current, int total)
2874 rb->yield(); /* be nice to the other threads */
2875 if(!running_slideshow)
2877 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-8, LCD_WIDTH, 8, total, 0,
2878 current, HORIZONTAL);
2879 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
2881 #ifndef USEGSLIB
2882 else
2884 /* in slideshow mode, keep gui interference to a minimum */
2885 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-4, LCD_WIDTH, 4, total, 0,
2886 current, HORIZONTAL);
2887 rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4);
2889 #endif
2892 int jpegmem(struct jpeg *p_jpg, int ds)
2894 int size;
2896 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
2897 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
2898 #ifdef HAVE_LCD_COLOR
2899 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
2901 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
2902 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
2903 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
2904 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
2906 #endif
2907 return size;
2910 /* how far can we zoom in without running out of memory */
2911 int min_downscale(struct jpeg *p_jpg, int bufsize)
2913 int downscale = 8;
2915 if (jpegmem(p_jpg, 8) > bufsize)
2916 return 0; /* error, too large, even 1:8 doesn't fit */
2918 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
2919 downscale /= 2;
2921 return downscale;
2925 /* how far can we zoom out, to fit image into the LCD */
2926 int max_downscale(struct jpeg *p_jpg)
2928 int downscale = 1;
2930 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale
2931 || p_jpg->y_size > LCD_HEIGHT*downscale))
2933 downscale *= 2;
2936 return downscale;
2940 /* return decoded or cached image */
2941 struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2943 int w, h; /* used to center output */
2944 int size; /* decompressed image size */
2945 long time; /* measured ticks */
2946 int status;
2948 struct t_disp* p_disp = &disp[ds]; /* short cut */
2950 if (p_disp->bitmap[0] != NULL)
2952 return p_disp; /* we still have it */
2955 /* assign image buffer */
2957 /* physical size needed for decoding */
2958 size = jpegmem(p_jpg, ds);
2959 if (buf_size <= size)
2960 { /* have to discard the current */
2961 int i;
2962 for (i=1; i<=8; i++)
2963 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
2964 buf = buf_root; /* start again from the beginning of the buffer */
2965 buf_size = root_size;
2968 #ifdef HAVE_LCD_COLOR
2969 if (p_jpg->blocks > 1) /* colour jpeg */
2971 int i;
2973 for (i = 1; i < 3; i++)
2975 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
2976 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
2977 p_disp->bitmap[i] = buf;
2978 buf += size;
2979 buf_size -= size;
2981 p_disp->csub_x = p_jpg->subsample_x[1];
2982 p_disp->csub_y = p_jpg->subsample_y[1];
2984 else
2986 p_disp->csub_x = p_disp->csub_y = 0;
2987 p_disp->bitmap[1] = p_disp->bitmap[2] = buf;
2989 #endif
2990 /* size may be less when decoded (if height is not block aligned) */
2991 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
2992 p_disp->bitmap[0] = buf;
2993 buf += size;
2994 buf_size -= size;
2996 if(!running_slideshow)
2998 rb->snprintf(print, sizeof(print), "decoding %d*%d",
2999 p_jpg->x_size/ds, p_jpg->y_size/ds);
3000 rb->lcd_puts(0, 3, print);
3001 rb->lcd_update();
3004 /* update image properties */
3005 p_disp->width = p_jpg->x_size / ds;
3006 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
3007 p_disp->height = p_jpg->y_size / ds;
3009 /* the actual decoding */
3010 time = *rb->current_tick;
3011 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
3012 rb->cpu_boost(true);
3013 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
3014 rb->cpu_boost(false);
3015 #else
3016 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
3017 #endif
3018 if (status)
3020 rb->splash(HZ, "decode error %d", status);
3021 file_pt[curfile] = '\0';
3022 return NULL;
3024 time = *rb->current_tick - time;
3026 if(!running_slideshow)
3028 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
3029 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
3030 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
3031 rb->lcd_update();
3034 return p_disp;
3038 /* set the view to the given center point, limit if necessary */
3039 void set_view (struct t_disp* p_disp, int cx, int cy)
3041 int x, y;
3043 /* plain center to available width/height */
3044 x = cx - MIN(LCD_WIDTH, p_disp->width) / 2;
3045 y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2;
3047 /* limit against upper image size */
3048 x = MIN(p_disp->width - LCD_WIDTH, x);
3049 y = MIN(p_disp->height - LCD_HEIGHT, y);
3051 /* limit against negative side */
3052 x = MAX(0, x);
3053 y = MAX(0, y);
3055 p_disp->x = x; /* set the values */
3056 p_disp->y = y;
3060 /* calculate the view center based on the bitmap position */
3061 void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
3063 *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2;
3064 *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2;
3068 /* load, decode, display the image */
3069 int load_and_show(char* filename)
3071 int fd;
3072 int filesize;
3073 unsigned char* buf_jpeg; /* compressed JPEG image */
3074 int status;
3075 struct t_disp* p_disp; /* currenly displayed image */
3076 int cx, cy; /* view center */
3078 fd = rb->open(filename, O_RDONLY);
3079 if (fd < 0)
3081 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
3082 rb->splash(HZ, print);
3083 return PLUGIN_ERROR;
3085 filesize = rb->filesize(fd);
3086 rb->memset(&disp, 0, sizeof(disp));
3088 buf = buf_images + filesize;
3089 buf_size = buf_images_size - filesize;
3090 /* allocate JPEG buffer */
3091 buf_jpeg = buf_images;
3093 buf_root = buf; /* we can start the decompressed images behind it */
3094 root_size = buf_size;
3096 if (buf_size <= 0)
3098 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
3099 if(plug_buf)
3101 rb->close(fd);
3102 rb->lcd_setfont(FONT_SYSFIXED);
3103 rb->lcd_clear_display();
3104 rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
3105 rb->lcd_puts(0,0,print);
3106 rb->lcd_puts(0,1,"Not enough plugin memory!");
3107 rb->lcd_puts(0,2,"Zoom In: Stop playback.");
3108 if(entries>1)
3109 rb->lcd_puts(0,3,"Left/Right: Skip File.");
3110 rb->lcd_puts(0,4,"Off: Quit.");
3111 rb->lcd_update();
3112 rb->lcd_setfont(FONT_UI);
3114 rb->button_clear_queue();
3116 while (1)
3118 int button = rb->button_get(true);
3119 switch(button)
3121 case JPEG_ZOOM_IN:
3122 plug_buf = false;
3123 buf_images = rb->plugin_get_audio_buffer(
3124 (size_t *)&buf_images_size);
3125 /*try again this file, now using the audio buffer */
3126 return PLUGIN_OTHER;
3127 #ifdef JPEG_RC_MENU
3128 case JPEG_RC_MENU:
3129 #endif
3130 case JPEG_MENU:
3131 return PLUGIN_OK;
3133 case JPEG_LEFT:
3134 if(entries>1)
3136 rb->lcd_clear_display();
3137 return change_filename(DIR_PREV);
3139 break;
3141 case JPEG_RIGHT:
3142 if(entries>1)
3144 rb->lcd_clear_display();
3145 return change_filename(DIR_NEXT);
3147 break;
3148 default:
3149 if(rb->default_event_handler_ex(button, cleanup, NULL)
3150 == SYS_USB_CONNECTED)
3151 return PLUGIN_USB_CONNECTED;
3156 else
3157 #endif
3159 rb->splash(HZ, "Out of Memory");
3160 rb->close(fd);
3161 return PLUGIN_ERROR;
3165 if(!running_slideshow)
3167 #if LCD_DEPTH > 1
3168 rb->lcd_set_foreground(LCD_WHITE);
3169 rb->lcd_set_background(LCD_BLACK);
3170 rb->lcd_set_backdrop(NULL);
3171 #endif
3173 rb->lcd_clear_display();
3174 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
3175 rb->lcd_puts(0, 0, print);
3176 rb->lcd_update();
3178 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
3179 rb->lcd_puts(0, 1, print);
3180 rb->lcd_update();
3183 rb->read(fd, buf_jpeg, filesize);
3184 rb->close(fd);
3186 if(!running_slideshow)
3188 rb->snprintf(print, sizeof(print), "decoding markers");
3189 rb->lcd_puts(0, 2, print);
3190 rb->lcd_update();
3192 #ifndef SIMULATOR
3193 else if(immediate_ata_off)
3195 /* running slideshow and time is long enough: power down disk */
3196 rb->ata_sleep();
3198 #endif
3200 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
3201 /* process markers, unstuffing */
3202 status = process_markers(buf_jpeg, filesize, &jpg);
3204 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
3205 { /* bad format or minimum components not contained */
3206 rb->splash(HZ, "unsupported %d", status);
3207 file_pt[curfile] = '\0';
3208 return change_filename(direction);
3211 if (!(status & DHT)) /* if no Huffman table present: */
3212 default_huff_tbl(&jpg); /* use default */
3213 build_lut(&jpg); /* derive Huffman and other lookup-tables */
3215 if(!running_slideshow)
3217 rb->snprintf(print, sizeof(print), "image %dx%d", jpg.x_size, jpg.y_size);
3218 rb->lcd_puts(0, 2, print);
3219 rb->lcd_update();
3221 ds_max = max_downscale(&jpg); /* check display constraint */
3222 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */
3223 if (ds_min == 0)
3225 rb->splash(HZ, "too large");
3226 file_pt[curfile] = '\0';
3227 return change_filename(direction);
3230 ds = ds_max; /* initials setting */
3231 cx = jpg.x_size/ds/2; /* center the view */
3232 cy = jpg.y_size/ds/2;
3234 do /* loop the image prepare and decoding when zoomed */
3236 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */
3237 if (p_disp == NULL)
3238 return change_filename(direction);
3240 set_view(p_disp, cx, cy);
3242 if(!running_slideshow)
3244 rb->snprintf(print, sizeof(print), "showing %dx%d",
3245 p_disp->width, p_disp->height);
3246 rb->lcd_puts(0, 3, print);
3247 rb->lcd_update();
3249 MYLCD(clear_display)();
3250 #ifdef HAVE_LCD_COLOR
3251 yuv_bitmap_part(
3252 p_disp->bitmap, p_disp->csub_x, p_disp->csub_y,
3253 p_disp->x, p_disp->y, p_disp->stride,
3254 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3255 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3256 MIN(LCD_WIDTH, p_disp->width),
3257 MIN(LCD_HEIGHT, p_disp->height));
3258 #else
3259 MYXLCD(gray_bitmap_part)(
3260 p_disp->bitmap[0], 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 #endif
3266 MYLCD_UPDATE();
3268 #ifdef USEGSLIB
3269 grey_show(true); /* switch on greyscale overlay */
3270 #endif
3272 /* drawing is now finished, play around with scrolling
3273 * until you press OFF or connect USB
3275 while (1)
3277 status = scroll_bmp(p_disp);
3278 if (status == ZOOM_IN)
3280 if (ds > ds_min)
3282 ds /= 2; /* reduce downscaling to zoom in */
3283 get_view(p_disp, &cx, &cy);
3284 cx *= 2; /* prepare the position in the new image */
3285 cy *= 2;
3287 else
3288 continue;
3291 if (status == ZOOM_OUT)
3293 if (ds < ds_max)
3295 ds *= 2; /* increase downscaling to zoom out */
3296 get_view(p_disp, &cx, &cy);
3297 cx /= 2; /* prepare the position in the new image */
3298 cy /= 2;
3300 else
3301 continue;
3303 break;
3306 #ifdef USEGSLIB
3307 grey_show(false); /* switch off overlay */
3308 #endif
3309 rb->lcd_clear_display();
3311 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
3312 && status != PLUGIN_OTHER);
3313 #ifdef USEGSLIB
3314 rb->lcd_update();
3315 #endif
3316 return status;
3319 /******************** Plugin entry point *********************/
3321 enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
3323 rb = api;
3325 int condition;
3326 #ifdef USEGSLIB
3327 long greysize; /* helper */
3328 #endif
3329 #if LCD_DEPTH > 1
3330 old_backdrop = rb->lcd_get_backdrop();
3331 #endif
3333 if(!parameter) return PLUGIN_ERROR;
3335 rb->strcpy(np_file, parameter);
3336 get_pic_list();
3338 if(!entries) return PLUGIN_ERROR;
3340 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
3341 if(rb->audio_status())
3343 buf = rb->plugin_get_buffer((size_t *)&buf_size) +
3344 (entries * sizeof(char**));
3345 buf_size -= (entries * sizeof(char**));
3346 plug_buf = true;
3348 else
3349 buf = rb->plugin_get_audio_buffer((size_t *)&buf_size);
3350 #else
3351 buf = rb->plugin_get_audio_buffer(&buf_size) +
3352 (entries * sizeof(char**));
3353 buf_size -= (entries * sizeof(char**));
3354 #endif
3356 #ifdef USEGSLIB
3357 if (!grey_init(rb, buf, buf_size, GREY_ON_COP,
3358 LCD_WIDTH, LCD_HEIGHT, &greysize))
3360 rb->splash(HZ, "grey buf error");
3361 return PLUGIN_ERROR;
3363 buf += greysize;
3364 buf_size -= greysize;
3365 #else
3366 xlcd_init(rb);
3367 #endif
3369 /* should be ok to just load settings since a parameter is present
3370 here and the drive should be spinning */
3371 configfile_init(rb);
3372 configfile_load(JPEG_CONFIGFILE, jpeg_config,
3373 ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION);
3374 old_settings = jpeg_settings;
3376 buf_images = buf; buf_images_size = buf_size;
3378 /* Turn off backlight timeout */
3379 backlight_force_on(rb); /* backlight control in lib/helper.c */
3383 condition = load_and_show(np_file);
3384 }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
3385 && condition != PLUGIN_ERROR);
3387 if (rb->memcmp(&jpeg_settings, &old_settings, sizeof (jpeg_settings)))
3389 /* Just in case drive has to spin, keep it from looking locked */
3390 rb->splash(0, "Saving Settings");
3391 configfile_save(JPEG_CONFIGFILE, jpeg_config,
3392 ARRAYLEN(jpeg_config), JPEG_SETTINGS_VERSION);
3395 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
3396 /* set back ata spindown time in case we changed it */
3397 rb->ata_spindown(rb->global_settings->disk_spindown);
3398 #endif
3400 /* Turn on backlight timeout (revert to settings) */
3401 backlight_use_settings(rb); /* backlight control in lib/helper.c */
3403 #ifdef USEGSLIB
3404 grey_release(); /* deinitialize */
3405 #endif
3407 return condition;
3410 #endif /* HAVE_LCD_BITMAP */