add HAVE_DISK_STORAGE, and use that instead of HAVE_FLASH_STORAGE when checking for...
[kugel-rb.git] / apps / plugins / jpeg.c
blob397fab7bd63ae0d2521e455e2ddde76d64b1b39e
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 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
26 ****************************************************************************/
28 #include "plugin.h"
29 #include "playback_control.h"
30 #include "oldmenuapi.h"
31 #include "helper.h"
32 #include "lib/configfile.h"
34 #ifdef HAVE_LCD_BITMAP
35 #include "grey.h"
36 #include "xlcd.h"
38 PLUGIN_HEADER
40 /* variable button definitions */
41 #if CONFIG_KEYPAD == RECORDER_PAD
42 #define JPEG_ZOOM_IN BUTTON_PLAY
43 #define JPEG_ZOOM_OUT BUTTON_ON
44 #define JPEG_UP BUTTON_UP
45 #define JPEG_DOWN BUTTON_DOWN
46 #define JPEG_LEFT BUTTON_LEFT
47 #define JPEG_RIGHT BUTTON_RIGHT
48 #define JPEG_NEXT BUTTON_F3
49 #define JPEG_PREVIOUS BUTTON_F2
50 #define JPEG_MENU BUTTON_OFF
52 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
53 #define JPEG_ZOOM_IN BUTTON_SELECT
54 #define JPEG_ZOOM_OUT BUTTON_ON
55 #define JPEG_UP BUTTON_UP
56 #define JPEG_DOWN BUTTON_DOWN
57 #define JPEG_LEFT BUTTON_LEFT
58 #define JPEG_RIGHT BUTTON_RIGHT
59 #define JPEG_NEXT BUTTON_F3
60 #define JPEG_PREVIOUS BUTTON_F2
61 #define JPEG_MENU BUTTON_OFF
63 #elif CONFIG_KEYPAD == ONDIO_PAD
64 #define JPEG_ZOOM_PRE BUTTON_MENU
65 #define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
66 #define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
67 #define JPEG_UP BUTTON_UP
68 #define JPEG_DOWN BUTTON_DOWN
69 #define JPEG_LEFT BUTTON_LEFT
70 #define JPEG_RIGHT BUTTON_RIGHT
71 #define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
72 #define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
73 #define JPEG_MENU BUTTON_OFF
75 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
76 (CONFIG_KEYPAD == IRIVER_H300_PAD)
77 #define JPEG_ZOOM_IN BUTTON_SELECT
78 #define JPEG_ZOOM_OUT BUTTON_MODE
79 #define JPEG_UP BUTTON_UP
80 #define JPEG_DOWN BUTTON_DOWN
81 #define JPEG_LEFT BUTTON_LEFT
82 #define JPEG_RIGHT BUTTON_RIGHT
83 #if (CONFIG_KEYPAD == IRIVER_H100_PAD)
84 #define JPEG_NEXT BUTTON_ON
85 #define JPEG_PREVIOUS BUTTON_REC
86 #else
87 #define JPEG_NEXT BUTTON_REC
88 #define JPEG_PREVIOUS BUTTON_ON
89 #endif
90 #define JPEG_MENU BUTTON_OFF
91 #define JPEG_RC_MENU BUTTON_RC_STOP
93 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
94 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
95 #define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
96 #define JPEG_ZOOM_OUT BUTTON_SCROLL_BACK
97 #define JPEG_UP BUTTON_MENU
98 #define JPEG_DOWN BUTTON_PLAY
99 #define JPEG_LEFT BUTTON_LEFT
100 #define JPEG_RIGHT BUTTON_RIGHT
101 #define JPEG_MENU (BUTTON_SELECT | BUTTON_MENU)
102 #define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
103 #define JPEG_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
105 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
106 #define JPEG_ZOOM_PRE BUTTON_SELECT
107 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
108 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
109 #define JPEG_UP BUTTON_UP
110 #define JPEG_DOWN BUTTON_DOWN
111 #define JPEG_LEFT BUTTON_LEFT
112 #define JPEG_RIGHT BUTTON_RIGHT
113 #define JPEG_MENU BUTTON_POWER
114 #define JPEG_NEXT BUTTON_PLAY
115 #define JPEG_PREVIOUS BUTTON_REC
117 #elif CONFIG_KEYPAD == GIGABEAT_PAD
118 #define JPEG_ZOOM_IN BUTTON_VOL_UP
119 #define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
120 #define JPEG_UP BUTTON_UP
121 #define JPEG_DOWN BUTTON_DOWN
122 #define JPEG_LEFT BUTTON_LEFT
123 #define JPEG_RIGHT BUTTON_RIGHT
124 #define JPEG_MENU BUTTON_MENU
125 #define JPEG_NEXT (BUTTON_A | BUTTON_RIGHT)
126 #define JPEG_PREVIOUS (BUTTON_A | BUTTON_LEFT)
128 #elif CONFIG_KEYPAD == SANSA_E200_PAD
129 #define JPEG_ZOOM_PRE BUTTON_SELECT
130 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
131 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
132 #define JPEG_UP BUTTON_UP
133 #define JPEG_DOWN BUTTON_DOWN
134 #define JPEG_LEFT BUTTON_LEFT
135 #define JPEG_RIGHT BUTTON_RIGHT
136 #define JPEG_MENU BUTTON_POWER
137 #define JPEG_SLIDE_SHOW BUTTON_REC
138 #define JPEG_NEXT BUTTON_SCROLL_FWD
139 #define JPEG_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
140 #define JPEG_PREVIOUS BUTTON_SCROLL_BACK
141 #define JPEG_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
143 #elif CONFIG_KEYPAD == SANSA_C200_PAD
144 #define JPEG_ZOOM_PRE BUTTON_SELECT
145 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
146 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
147 #define JPEG_UP BUTTON_UP
148 #define JPEG_DOWN BUTTON_DOWN
149 #define JPEG_LEFT BUTTON_LEFT
150 #define JPEG_RIGHT BUTTON_RIGHT
151 #define JPEG_MENU BUTTON_POWER
152 #define JPEG_SLIDE_SHOW BUTTON_REC
153 #define JPEG_NEXT BUTTON_VOL_UP
154 #define JPEG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
155 #define JPEG_PREVIOUS BUTTON_VOL_DOWN
156 #define JPEG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
158 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
159 #define JPEG_ZOOM_PRE BUTTON_PLAY
160 #define JPEG_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
161 #define JPEG_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
162 #define JPEG_UP BUTTON_SCROLL_UP
163 #define JPEG_DOWN BUTTON_SCROLL_DOWN
164 #define JPEG_LEFT BUTTON_LEFT
165 #define JPEG_RIGHT BUTTON_RIGHT
166 #define JPEG_MENU BUTTON_POWER
167 #define JPEG_NEXT BUTTON_FF
168 #define JPEG_PREVIOUS BUTTON_REW
170 #elif CONFIG_KEYPAD == MROBE500_PAD
171 #define JPEG_ZOOM_IN BUTTON_RC_VOL_UP
172 #define JPEG_ZOOM_OUT BUTTON_RC_VOL_DOWN
173 #define JPEG_UP BUTTON_RC_PLAY
174 #define JPEG_DOWN BUTTON_RC_DOWN
175 #define JPEG_LEFT BUTTON_LEFT
176 #define JPEG_RIGHT BUTTON_RIGHT
177 #define JPEG_MENU BUTTON_POWER
178 #define JPEG_NEXT BUTTON_RC_HEART
179 #define JPEG_PREVIOUS BUTTON_RC_MODE
181 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
182 #define JPEG_ZOOM_IN BUTTON_VOL_UP
183 #define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
184 #define JPEG_UP BUTTON_UP
185 #define JPEG_DOWN BUTTON_DOWN
186 #define JPEG_LEFT BUTTON_LEFT
187 #define JPEG_RIGHT BUTTON_RIGHT
188 #define JPEG_MENU BUTTON_MENU
189 #define JPEG_NEXT BUTTON_NEXT
190 #define JPEG_PREVIOUS BUTTON_PREV
192 #elif CONFIG_KEYPAD == MROBE100_PAD
193 #define JPEG_ZOOM_IN BUTTON_SELECT
194 #define JPEG_ZOOM_OUT BUTTON_PLAY
195 #define JPEG_UP BUTTON_UP
196 #define JPEG_DOWN BUTTON_DOWN
197 #define JPEG_LEFT BUTTON_LEFT
198 #define JPEG_RIGHT BUTTON_RIGHT
199 #define JPEG_MENU BUTTON_MENU
200 #define JPEG_NEXT (BUTTON_DISPLAY | BUTTON_RIGHT)
201 #define JPEG_PREVIOUS (BUTTON_DISPLAY | BUTTON_LEFT)
203 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
204 #define JPEG_ZOOM_PRE BUTTON_RC_PLAY
205 #define JPEG_ZOOM_IN (BUTTON_RC_PLAY|BUTTON_REL)
206 #define JPEG_ZOOM_OUT (BUTTON_RC_PLAY|BUTTON_REPEAT)
207 #define JPEG_UP BUTTON_RC_VOL_UP
208 #define JPEG_DOWN BUTTON_RC_VOL_DOWN
209 #define JPEG_LEFT BUTTON_RC_REW
210 #define JPEG_RIGHT BUTTON_RC_FF
211 #define JPEG_MENU BUTTON_RC_REC
212 #define JPEG_NEXT BUTTON_RC_MODE
213 #define JPEG_PREVIOUS BUTTON_RC_MENU
215 #elif CONFIG_KEYPAD == COWOND2_PAD
217 #elif CONFIG_KEYPAD == IAUDIO67_PAD
218 #define JPEG_ZOOM_IN BUTTON_VOLUP
219 #define JPEG_ZOOM_OUT BUTTON_VOLDOWN
220 #define JPEG_UP BUTTON_STOP
221 #define JPEG_DOWN BUTTON_PLAY
222 #define JPEG_LEFT BUTTON_LEFT
223 #define JPEG_RIGHT BUTTON_RIGHT
224 #define JPEG_MENU BUTTON_MENU
225 #define JPEG_NEXT (BUTTON_PLAY|BUTTON_VOLUP)
226 #define JPEG_PREVIOUS (BUTTON_PLAY|BUTTON_VOLDOWN)
228 #else
229 #error No keymap defined!
230 #endif
232 #ifdef HAVE_TOUCHSCREEN
233 #ifndef JPEG_UP
234 #define JPEG_UP BUTTON_TOPMIDDLE
235 #endif
236 #ifndef JPEG_DOWN
237 #define JPEG_DOWN BUTTON_BOTTOMMIDDLE
238 #endif
239 #ifndef JPEG_LEFT
240 #define JPEG_LEFT BUTTON_MIDLEFT
241 #endif
242 #ifndef JPEG_RIGHT
243 #define JPEG_RIGHT BUTTON_MIDRIGHT
244 #endif
245 #ifndef JPEG_ZOOM_IN
246 #define JPEG_ZOOM_IN BUTTON_TOPRIGHT
247 #endif
248 #ifndef JPEG_ZOOM_OUT
249 #define JPEG_ZOOM_OUT BUTTON_TOPLEFT
250 #endif
251 #ifndef JPEG_MENU
252 #define JPEG_MENU (BUTTON_CENTER|BUTTON_REL)
253 #endif
254 #ifndef JPEG_NEXT
255 #define JPEG_NEXT BUTTON_BOTTOMRIGHT
256 #endif
257 #ifndef JPEG_PREVIOUS
258 #define JPEG_PREVIOUS BUTTON_BOTTOMLEFT
259 #endif
260 #endif
262 /* different graphics libraries */
263 #if LCD_DEPTH < 8
264 #define USEGSLIB
265 GREY_INFO_STRUCT
266 #define MYLCD(fn) grey_ub_ ## fn
267 #define MYLCD_UPDATE()
268 #define MYXLCD(fn) grey_ub_ ## fn
269 #else
270 #define MYLCD(fn) rb->lcd_ ## fn
271 #define MYLCD_UPDATE() rb->lcd_update();
272 #define MYXLCD(fn) xlcd_ ## fn
273 #endif
275 #define MAX_X_SIZE LCD_WIDTH*8
277 /* Min memory allowing us to use the plugin buffer
278 * and thus not stopping the music
279 * *Very* rough estimation:
280 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
281 * + 20k code size = 60 000
282 * + 50k min for jpeg = 120 000
284 #define MIN_MEM 120000
286 /* Headings */
287 #define DIR_PREV 1
288 #define DIR_NEXT -1
289 #define DIR_NONE 0
291 #define PLUGIN_OTHER 10 /* State code for output with return. */
293 /******************************* Globals ***********************************/
295 static const struct plugin_api* rb;
296 MEM_FUNCTION_WRAPPERS(rb);
298 /* for portability of below JPEG code */
299 #define MEMSET(p,v,c) rb->memset(p,v,c)
300 #define MEMCPY(d,s,c) rb->memcpy(d,s,c)
301 #define INLINE static inline
302 #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
304 static int slideshow_enabled = false; /* run slideshow */
305 static int running_slideshow = false; /* loading image because of slideshw */
306 #ifndef SIMULATOR
307 static int immediate_ata_off = false; /* power down disk after loading */
308 #endif
310 /* Persistent configuration */
311 #define JPEG_CONFIGFILE "jpeg.cfg"
312 #define JPEG_SETTINGS_MINVERSION 1
313 #define JPEG_SETTINGS_VERSION 2
315 /* Slideshow times */
316 #define SS_MIN_TIMEOUT 1
317 #define SS_MAX_TIMEOUT 20
318 #define SS_DEFAULT_TIMEOUT 5
320 enum color_modes
322 COLOURMODE_COLOUR = 0,
323 COLOURMODE_GRAY,
324 COLOUR_NUM_MODES
327 enum dither_modes
329 DITHER_NONE = 0, /* No dithering */
330 DITHER_ORDERED, /* Bayer ordered */
331 DITHER_DIFFUSION, /* Floyd/Steinberg error diffusion */
332 DITHER_NUM_MODES
335 struct jpeg_settings
337 int colour_mode;
338 int dither_mode;
339 int ss_timeout;
342 static struct jpeg_settings jpeg_settings =
343 { COLOURMODE_COLOUR, DITHER_NONE, SS_DEFAULT_TIMEOUT };
344 static struct jpeg_settings old_settings;
346 static struct configdata jpeg_config[] =
348 #ifdef HAVE_LCD_COLOR
349 { TYPE_ENUM, 0, COLOUR_NUM_MODES, &jpeg_settings.colour_mode,
350 "Colour Mode", (char *[]){ "Colour", "Grayscale" }, NULL },
351 { TYPE_ENUM, 0, DITHER_NUM_MODES, &jpeg_settings.dither_mode,
352 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" }, NULL },
353 #endif
354 { TYPE_INT, SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, &jpeg_settings.ss_timeout,
355 "Slideshow Time", NULL, NULL},
358 #if LCD_DEPTH > 1
359 fb_data* old_backdrop;
360 #endif
362 /**************** begin JPEG code ********************/
364 INLINE unsigned range_limit(int value)
366 #if CONFIG_CPU == SH7034
367 unsigned tmp;
368 asm ( /* Note: Uses knowledge that only low byte of result is used */
369 "mov #-128,%[t] \n"
370 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
371 "extu.b %[v],%[t] \n"
372 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
373 "bt 1f \n" /* yes: no overflow */
374 "cmp/pz %[v] \n" /* overflow: positive? */
375 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
376 "1: \n"
377 : /* outputs */
378 [v]"+r"(value),
379 [t]"=&r"(tmp)
381 return value;
382 #elif defined(CPU_COLDFIRE)
383 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
384 "add.l #128,%[v] \n" /* value += 128; */
385 "cmp.l #255,%[v] \n" /* overflow? */
386 "bls.b 1f \n" /* no: return value */
387 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
388 "1: \n"
389 : /* outputs */
390 [v]"+d"(value)
392 return value;
393 #elif defined(CPU_ARM)
394 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
395 "add %[v], %[v], #128 \n" /* value += 128 */
396 "cmp %[v], #255 \n" /* out of range 0..255? */
397 "mvnhi %[v], %[v], asr #31 \n" /* yes: set all bits to ~(sign_bit) */
398 : /* outputs */
399 [v]"+r"(value)
401 return value;
402 #else
403 value += 128;
405 if ((unsigned)value <= 255)
406 return value;
408 if (value < 0)
409 return 0;
411 return 255;
412 #endif
415 /* IDCT implementation */
418 #define CONST_BITS 13
419 #define PASS1_BITS 2
422 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
423 * causing a lot of useless floating-point operations at run time.
424 * To get around this we use the following pre-calculated constants.
425 * If you change CONST_BITS you may want to add appropriate values.
426 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
428 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
429 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
430 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
431 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
432 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
433 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
434 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
435 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
436 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
437 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
438 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
439 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
443 /* Multiply an long variable by an long constant to yield an long result.
444 * For 8-bit samples with the recommended scaling, all the variable
445 * and constant values involved are no more than 16 bits wide, so a
446 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
447 * For 12-bit samples, a full 32-bit multiplication will be needed.
449 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
452 /* Dequantize a coefficient by multiplying it by the multiplier-table
453 * entry; produce an int result. In this module, both inputs and result
454 * are 16 bits or less, so either int or short multiply will work.
456 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
457 #define DEQUANTIZE MULTIPLY16
459 /* Descale and correctly round an int value that's scaled by N bits.
460 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
461 * the fudge factor is correct for either sign of X.
463 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
468 * Perform dequantization and inverse DCT on one block of coefficients,
469 * producing a reduced-size 1x1 output block.
471 void idct1x1(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
473 (void)skip_line; /* unused */
474 *p_byte = range_limit(inptr[0] * quantptr[0] >> 3);
480 * Perform dequantization and inverse DCT on one block of coefficients,
481 * producing a reduced-size 2x2 output block.
483 void idct2x2(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
485 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
486 unsigned char* outptr;
488 /* Pass 1: process columns from input, store into work array. */
490 /* Column 0 */
491 tmp4 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
492 tmp5 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
494 tmp0 = tmp4 + tmp5;
495 tmp2 = tmp4 - tmp5;
497 /* Column 1 */
498 tmp4 = DEQUANTIZE(inptr[8*0+1], quantptr[8*0+1]);
499 tmp5 = DEQUANTIZE(inptr[8*1+1], quantptr[8*1+1]);
501 tmp1 = tmp4 + tmp5;
502 tmp3 = tmp4 - tmp5;
504 /* Pass 2: process 2 rows, store into output array. */
506 /* Row 0 */
507 outptr = p_byte;
509 outptr[0] = range_limit((int) DESCALE(tmp0 + tmp1, 3));
510 outptr[1] = range_limit((int) DESCALE(tmp0 - tmp1, 3));
512 /* Row 1 */
513 outptr = p_byte + skip_line;
515 outptr[0] = range_limit((int) DESCALE(tmp2 + tmp3, 3));
516 outptr[1] = range_limit((int) DESCALE(tmp2 - tmp3, 3));
522 * Perform dequantization and inverse DCT on one block of coefficients,
523 * producing a reduced-size 4x4 output block.
525 void idct4x4(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
527 int tmp0, tmp2, tmp10, tmp12;
528 int z1, z2, z3;
529 int * wsptr;
530 unsigned char* outptr;
531 int ctr;
532 int workspace[4*4]; /* buffers data between passes */
534 /* Pass 1: process columns from input, store into work array. */
536 wsptr = workspace;
537 for (ctr = 0; ctr < 4; ctr++, inptr++, quantptr++, wsptr++)
539 /* Even part */
541 tmp0 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
542 tmp2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
544 tmp10 = (tmp0 + tmp2) << PASS1_BITS;
545 tmp12 = (tmp0 - tmp2) << PASS1_BITS;
547 /* Odd part */
548 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
550 z2 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
551 z3 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
553 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
554 tmp0 = DESCALE(z1 + MULTIPLY16(z3, - FIX_1_847759065), CONST_BITS-PASS1_BITS);
555 tmp2 = DESCALE(z1 + MULTIPLY16(z2, FIX_0_765366865), CONST_BITS-PASS1_BITS);
557 /* Final output stage */
559 wsptr[4*0] = (int) (tmp10 + tmp2);
560 wsptr[4*3] = (int) (tmp10 - tmp2);
561 wsptr[4*1] = (int) (tmp12 + tmp0);
562 wsptr[4*2] = (int) (tmp12 - tmp0);
565 /* Pass 2: process 4 rows from work array, store into output array. */
567 wsptr = workspace;
568 for (ctr = 0; ctr < 4; ctr++)
570 outptr = p_byte + (ctr*skip_line);
571 /* Even part */
573 tmp0 = (int) wsptr[0];
574 tmp2 = (int) wsptr[2];
576 tmp10 = (tmp0 + tmp2) << CONST_BITS;
577 tmp12 = (tmp0 - tmp2) << CONST_BITS;
579 /* Odd part */
580 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
582 z2 = (int) wsptr[1];
583 z3 = (int) wsptr[3];
585 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
586 tmp0 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
587 tmp2 = z1 + MULTIPLY16(z2, FIX_0_765366865);
589 /* Final output stage */
591 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp2,
592 CONST_BITS+PASS1_BITS+3));
593 outptr[3] = range_limit((int) DESCALE(tmp10 - tmp2,
594 CONST_BITS+PASS1_BITS+3));
595 outptr[1] = range_limit((int) DESCALE(tmp12 + tmp0,
596 CONST_BITS+PASS1_BITS+3));
597 outptr[2] = range_limit((int) DESCALE(tmp12 - tmp0,
598 CONST_BITS+PASS1_BITS+3));
600 wsptr += 4; /* advance pointer to next row */
607 * Perform dequantization and inverse DCT on one block of coefficients.
609 void idct8x8(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
611 long tmp0, tmp1, tmp2, tmp3;
612 long tmp10, tmp11, tmp12, tmp13;
613 long z1, z2, z3, z4, z5;
614 int * wsptr;
615 unsigned char* outptr;
616 int ctr;
617 int workspace[64]; /* buffers data between passes */
619 /* Pass 1: process columns from input, store into work array. */
620 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
621 /* furthermore, we scale the results by 2**PASS1_BITS. */
623 wsptr = workspace;
624 for (ctr = 8; ctr > 0; ctr--)
626 /* Due to quantization, we will usually find that many of the input
627 * coefficients are zero, especially the AC terms. We can exploit this
628 * by short-circuiting the IDCT calculation for any column in which all
629 * the AC terms are zero. In that case each output is equal to the
630 * DC coefficient (with scale factor as needed).
631 * With typical images and quantization tables, half or more of the
632 * column DCT calculations can be simplified this way.
635 if ((inptr[8*1] | inptr[8*2] | inptr[8*3]
636 | inptr[8*4] | inptr[8*5] | inptr[8*6] | inptr[8*7]) == 0)
638 /* AC terms all zero */
639 int dcval = DEQUANTIZE(inptr[8*0], quantptr[8*0]) << PASS1_BITS;
641 wsptr[8*0] = wsptr[8*1] = wsptr[8*2] = wsptr[8*3] = wsptr[8*4]
642 = wsptr[8*5] = wsptr[8*6] = wsptr[8*7] = dcval;
643 inptr++; /* advance pointers to next column */
644 quantptr++;
645 wsptr++;
646 continue;
649 /* Even part: reverse the even part of the forward DCT. */
650 /* The rotator is sqrt(2)*c(-6). */
652 z2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
653 z3 = DEQUANTIZE(inptr[8*6], quantptr[8*6]);
655 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
656 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
657 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
659 z2 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
660 z3 = DEQUANTIZE(inptr[8*4], quantptr[8*4]);
662 tmp0 = (z2 + z3) << CONST_BITS;
663 tmp1 = (z2 - z3) << CONST_BITS;
665 tmp10 = tmp0 + tmp3;
666 tmp13 = tmp0 - tmp3;
667 tmp11 = tmp1 + tmp2;
668 tmp12 = tmp1 - tmp2;
670 /* Odd part per figure 8; the matrix is unitary and hence its
671 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
673 tmp0 = DEQUANTIZE(inptr[8*7], quantptr[8*7]);
674 tmp1 = DEQUANTIZE(inptr[8*5], quantptr[8*5]);
675 tmp2 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
676 tmp3 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
678 z1 = tmp0 + tmp3;
679 z2 = tmp1 + tmp2;
680 z3 = tmp0 + tmp2;
681 z4 = tmp1 + tmp3;
682 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
684 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
685 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
686 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
687 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
688 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
689 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
690 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
691 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
693 z3 += z5;
694 z4 += z5;
696 tmp0 += z1 + z3;
697 tmp1 += z2 + z4;
698 tmp2 += z2 + z3;
699 tmp3 += z1 + z4;
701 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
703 wsptr[8*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
704 wsptr[8*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
705 wsptr[8*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
706 wsptr[8*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
707 wsptr[8*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
708 wsptr[8*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
709 wsptr[8*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
710 wsptr[8*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
712 inptr++; /* advance pointers to next column */
713 quantptr++;
714 wsptr++;
717 /* Pass 2: process rows from work array, store into output array. */
718 /* Note that we must descale the results by a factor of 8 == 2**3, */
719 /* and also undo the PASS1_BITS scaling. */
721 wsptr = workspace;
722 for (ctr = 0; ctr < 8; ctr++)
724 outptr = p_byte + (ctr*skip_line);
725 /* Rows of zeroes can be exploited in the same way as we did with columns.
726 * However, the column calculation has created many nonzero AC terms, so
727 * the simplification applies less often (typically 5% to 10% of the time).
728 * On machines with very fast multiplication, it's possible that the
729 * test takes more time than it's worth. In that case this section
730 * may be commented out.
733 #ifndef NO_ZERO_ROW_TEST
734 if ((wsptr[1] | wsptr[2] | wsptr[3]
735 | wsptr[4] | wsptr[5] | wsptr[6] | wsptr[7]) == 0)
737 /* AC terms all zero */
738 unsigned char dcval = range_limit((int) DESCALE((long) wsptr[0],
739 PASS1_BITS+3));
741 outptr[0] = dcval;
742 outptr[1] = dcval;
743 outptr[2] = dcval;
744 outptr[3] = dcval;
745 outptr[4] = dcval;
746 outptr[5] = dcval;
747 outptr[6] = dcval;
748 outptr[7] = dcval;
750 wsptr += 8; /* advance pointer to next row */
751 continue;
753 #endif
755 /* Even part: reverse the even part of the forward DCT. */
756 /* The rotator is sqrt(2)*c(-6). */
758 z2 = (long) wsptr[2];
759 z3 = (long) wsptr[6];
761 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
762 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
763 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
765 tmp0 = ((long) wsptr[0] + (long) wsptr[4]) << CONST_BITS;
766 tmp1 = ((long) wsptr[0] - (long) wsptr[4]) << CONST_BITS;
768 tmp10 = tmp0 + tmp3;
769 tmp13 = tmp0 - tmp3;
770 tmp11 = tmp1 + tmp2;
771 tmp12 = tmp1 - tmp2;
773 /* Odd part per figure 8; the matrix is unitary and hence its
774 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
776 tmp0 = (long) wsptr[7];
777 tmp1 = (long) wsptr[5];
778 tmp2 = (long) wsptr[3];
779 tmp3 = (long) wsptr[1];
781 z1 = tmp0 + tmp3;
782 z2 = tmp1 + tmp2;
783 z3 = tmp0 + tmp2;
784 z4 = tmp1 + tmp3;
785 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
787 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
788 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
789 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
790 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
791 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
792 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
793 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
794 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
796 z3 += z5;
797 z4 += z5;
799 tmp0 += z1 + z3;
800 tmp1 += z2 + z4;
801 tmp2 += z2 + z3;
802 tmp3 += z1 + z4;
804 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
806 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp3,
807 CONST_BITS+PASS1_BITS+3));
808 outptr[7] = range_limit((int) DESCALE(tmp10 - tmp3,
809 CONST_BITS+PASS1_BITS+3));
810 outptr[1] = range_limit((int) DESCALE(tmp11 + tmp2,
811 CONST_BITS+PASS1_BITS+3));
812 outptr[6] = range_limit((int) DESCALE(tmp11 - tmp2,
813 CONST_BITS+PASS1_BITS+3));
814 outptr[2] = range_limit((int) DESCALE(tmp12 + tmp1,
815 CONST_BITS+PASS1_BITS+3));
816 outptr[5] = range_limit((int) DESCALE(tmp12 - tmp1,
817 CONST_BITS+PASS1_BITS+3));
818 outptr[3] = range_limit((int) DESCALE(tmp13 + tmp0,
819 CONST_BITS+PASS1_BITS+3));
820 outptr[4] = range_limit((int) DESCALE(tmp13 - tmp0,
821 CONST_BITS+PASS1_BITS+3));
823 wsptr += 8; /* advance pointer to next row */
829 /* JPEG decoder implementation */
832 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
834 struct derived_tbl
836 /* Basic tables: (element [0] of each array is unused) */
837 long mincode[17]; /* smallest code of length k */
838 long maxcode[18]; /* largest code of length k (-1 if none) */
839 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
840 int valptr[17]; /* huffval[] index of 1st symbol of length k */
842 /* Back link to public Huffman table (needed only in slow_DECODE) */
843 int* pub;
845 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
846 the input data stream. If the next Huffman code is no more
847 than HUFF_LOOKAHEAD bits long, we can obtain its length and
848 the corresponding symbol directly from these tables. */
849 int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
850 unsigned char look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
853 #define QUANT_TABLE_LENGTH 64
855 /* for type of Huffman table */
856 #define DC_LEN 28
857 #define AC_LEN 178
859 struct huffman_table
860 { /* length and code according to JFIF format */
861 int huffmancodes_dc[DC_LEN];
862 int huffmancodes_ac[AC_LEN];
865 struct frame_component
867 int ID;
868 int horizontal_sampling;
869 int vertical_sampling;
870 int quanttable_select;
873 struct scan_component
875 int ID;
876 int DC_select;
877 int AC_select;
880 struct bitstream
882 unsigned long get_buffer; /* current bit-extraction buffer */
883 int bits_left; /* # of unused bits in it */
884 unsigned char* next_input_byte;
885 unsigned char* input_end; /* upper limit +1 */
888 struct jpeg
890 int x_size, y_size; /* size of image (can be less than block boundary) */
891 int x_phys, y_phys; /* physical size, block aligned */
892 int x_mbl; /* x dimension of MBL */
893 int y_mbl; /* y dimension of MBL */
894 int blocks; /* blocks per MB */
895 int restart_interval; /* number of MCUs between RSTm markers */
896 int store_pos[4]; /* for Y block ordering */
898 unsigned char* p_entropy_data;
899 unsigned char* p_entropy_end;
901 int quanttable[4][QUANT_TABLE_LENGTH]; /* raw quantization tables 0-3 */
902 int qt_idct[2][QUANT_TABLE_LENGTH]; /* quantization tables for IDCT */
904 struct huffman_table hufftable[2]; /* Huffman tables */
905 struct derived_tbl dc_derived_tbls[2]; /* Huffman-LUTs */
906 struct derived_tbl ac_derived_tbls[2];
908 struct frame_component frameheader[3]; /* Component descriptor */
909 struct scan_component scanheader[3]; /* currently not used */
911 int mcu_membership[6]; /* info per block */
912 int tab_membership[6];
913 int subsample_x[3]; /* info per component */
914 int subsample_y[3];
918 /* possible return flags for process_markers() */
919 #define HUFFTAB 0x0001 /* with huffman table */
920 #define QUANTTAB 0x0002 /* with quantization table */
921 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
922 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
923 #define SOF0 0x0010 /* with SOF0-Segment */
924 #define DHT 0x0020 /* with Definition of huffman tables */
925 #define SOS 0x0040 /* with Start-of-Scan segment */
926 #define DQT 0x0080 /* with definition of quantization table */
928 /* Preprocess the JPEG JFIF file */
929 int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
931 unsigned char* p_bytes = p_src;
932 int marker_size; /* variable length of marker segment */
933 int i, j, n;
934 int ret = 0; /* returned flags */
936 p_jpeg->p_entropy_end = p_src + size;
938 while (p_src < p_bytes + size)
940 if (*p_src++ != 0xFF) /* no marker? */
942 p_src--; /* it's image data, put it back */
943 p_jpeg->p_entropy_data = p_src;
944 break; /* exit marker processing */
947 switch (*p_src++)
949 case 0xFF: /* Fill byte */
950 ret |= FILL_FF;
951 case 0x00: /* Zero stuffed byte - entropy data */
952 p_src--; /* put it back */
953 continue;
955 case 0xC0: /* SOF Huff - Baseline DCT */
957 ret |= SOF0;
958 marker_size = *p_src++ << 8; /* Highbyte */
959 marker_size |= *p_src++; /* Lowbyte */
960 n = *p_src++; /* sample precision (= 8 or 12) */
961 if (n != 8)
963 return(-1); /* Unsupported sample precision */
965 p_jpeg->y_size = *p_src++ << 8; /* Highbyte */
966 p_jpeg->y_size |= *p_src++; /* Lowbyte */
967 p_jpeg->x_size = *p_src++ << 8; /* Highbyte */
968 p_jpeg->x_size |= *p_src++; /* Lowbyte */
970 n = (marker_size-2-6)/3;
971 if (*p_src++ != n || (n != 1 && n != 3))
973 return(-2); /* Unsupported SOF0 component specification */
975 for (i=0; i<n; i++)
977 p_jpeg->frameheader[i].ID = *p_src++; /* Component info */
978 p_jpeg->frameheader[i].horizontal_sampling = *p_src >> 4;
979 p_jpeg->frameheader[i].vertical_sampling = *p_src++ & 0x0F;
980 p_jpeg->frameheader[i].quanttable_select = *p_src++;
981 if (p_jpeg->frameheader[i].horizontal_sampling > 2
982 || p_jpeg->frameheader[i].vertical_sampling > 2)
983 return -3; /* Unsupported SOF0 subsampling */
985 p_jpeg->blocks = n;
987 break;
989 case 0xC1: /* SOF Huff - Extended sequential DCT*/
990 case 0xC2: /* SOF Huff - Progressive DCT*/
991 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
992 case 0xC5: /* SOF Huff - Differential sequential DCT*/
993 case 0xC6: /* SOF Huff - Differential progressive DCT*/
994 case 0xC7: /* SOF Huff - Differential spatial*/
995 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
996 case 0xC9: /* SOF Arith - Extended sequential DCT*/
997 case 0xCA: /* SOF Arith - Progressive DCT*/
998 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
999 case 0xCD: /* SOF Arith - Differential sequential DCT*/
1000 case 0xCE: /* SOF Arith - Differential progressive DCT*/
1001 case 0xCF: /* SOF Arith - Differential spatial*/
1003 return (-4); /* other DCT model than baseline not implemented */
1006 case 0xC4: /* Define Huffman Table(s) */
1008 unsigned char* p_temp;
1010 ret |= DHT;
1011 marker_size = *p_src++ << 8; /* Highbyte */
1012 marker_size |= *p_src++; /* Lowbyte */
1014 p_temp = p_src;
1015 while (p_src < p_temp+marker_size-2-17) /* another table */
1017 int sum = 0;
1018 i = *p_src & 0x0F; /* table index */
1019 if (i > 1)
1021 return (-5); /* Huffman table index out of range */
1023 else if (*p_src++ & 0xF0) /* AC table */
1025 for (j=0; j<16; j++)
1027 sum += *p_src;
1028 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
1030 if(16 + sum > AC_LEN)
1031 return -10; /* longer than allowed */
1033 for (; j < 16 + sum; j++)
1034 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
1036 else /* DC table */
1038 for (j=0; j<16; j++)
1040 sum += *p_src;
1041 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
1043 if(16 + sum > DC_LEN)
1044 return -11; /* longer than allowed */
1046 for (; j < 16 + sum; j++)
1047 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
1049 } /* while */
1050 p_src = p_temp+marker_size - 2; /* skip possible residue */
1052 break;
1054 case 0xCC: /* Define Arithmetic coding conditioning(s) */
1055 return(-6); /* Arithmetic coding not supported */
1057 case 0xD8: /* Start of Image */
1058 case 0xD9: /* End of Image */
1059 case 0x01: /* for temp private use arith code */
1060 break; /* skip parameterless marker */
1063 case 0xDA: /* Start of Scan */
1065 ret |= SOS;
1066 marker_size = *p_src++ << 8; /* Highbyte */
1067 marker_size |= *p_src++; /* Lowbyte */
1069 n = (marker_size-2-1-3)/2;
1070 if (*p_src++ != n || (n != 1 && n != 3))
1072 return (-7); /* Unsupported SOS component specification */
1074 for (i=0; i<n; i++)
1076 p_jpeg->scanheader[i].ID = *p_src++;
1077 p_jpeg->scanheader[i].DC_select = *p_src >> 4;
1078 p_jpeg->scanheader[i].AC_select = *p_src++ & 0x0F;
1080 p_src += 3; /* skip spectral information */
1082 break;
1084 case 0xDB: /* Define quantization Table(s) */
1086 ret |= DQT;
1087 marker_size = *p_src++ << 8; /* Highbyte */
1088 marker_size |= *p_src++; /* Lowbyte */
1089 n = (marker_size-2)/(QUANT_TABLE_LENGTH+1); /* # of tables */
1090 for (i=0; i<n; i++)
1092 int id = *p_src++; /* ID */
1093 if (id >= 4)
1095 return (-8); /* Unsupported quantization table */
1097 /* Read Quantisation table: */
1098 for (j=0; j<QUANT_TABLE_LENGTH; j++)
1099 p_jpeg->quanttable[id][j] = *p_src++;
1102 break;
1104 case 0xDD: /* Define Restart Interval */
1106 marker_size = *p_src++ << 8; /* Highbyte */
1107 marker_size |= *p_src++; /* Lowbyte */
1108 p_jpeg->restart_interval = *p_src++ << 8; /* Highbyte */
1109 p_jpeg->restart_interval |= *p_src++; /* Lowbyte */
1110 p_src += marker_size-4; /* skip segment */
1112 break;
1114 case 0xDC: /* Define Number of Lines */
1115 case 0xDE: /* Define Hierarchical progression */
1116 case 0xDF: /* Expand Reference Component(s) */
1117 case 0xE0: /* Application Field 0*/
1118 case 0xE1: /* Application Field 1*/
1119 case 0xE2: /* Application Field 2*/
1120 case 0xE3: /* Application Field 3*/
1121 case 0xE4: /* Application Field 4*/
1122 case 0xE5: /* Application Field 5*/
1123 case 0xE6: /* Application Field 6*/
1124 case 0xE7: /* Application Field 7*/
1125 case 0xE8: /* Application Field 8*/
1126 case 0xE9: /* Application Field 9*/
1127 case 0xEA: /* Application Field 10*/
1128 case 0xEB: /* Application Field 11*/
1129 case 0xEC: /* Application Field 12*/
1130 case 0xED: /* Application Field 13*/
1131 case 0xEE: /* Application Field 14*/
1132 case 0xEF: /* Application Field 15*/
1133 case 0xFE: /* Comment */
1135 marker_size = *p_src++ << 8; /* Highbyte */
1136 marker_size |= *p_src++; /* Lowbyte */
1137 p_src += marker_size-2; /* skip segment */
1139 break;
1141 case 0xF0: /* Reserved for JPEG extensions */
1142 case 0xF1: /* Reserved for JPEG extensions */
1143 case 0xF2: /* Reserved for JPEG extensions */
1144 case 0xF3: /* Reserved for JPEG extensions */
1145 case 0xF4: /* Reserved for JPEG extensions */
1146 case 0xF5: /* Reserved for JPEG extensions */
1147 case 0xF6: /* Reserved for JPEG extensions */
1148 case 0xF7: /* Reserved for JPEG extensions */
1149 case 0xF8: /* Reserved for JPEG extensions */
1150 case 0xF9: /* Reserved for JPEG extensions */
1151 case 0xFA: /* Reserved for JPEG extensions */
1152 case 0xFB: /* Reserved for JPEG extensions */
1153 case 0xFC: /* Reserved for JPEG extensions */
1154 case 0xFD: /* Reserved for JPEG extensions */
1155 case 0x02: /* Reserved */
1156 default:
1157 return (-9); /* Unknown marker */
1158 } /* switch */
1159 } /* while */
1161 return (ret); /* return flags with seen markers */
1165 void default_huff_tbl(struct jpeg* p_jpeg)
1167 static const struct huffman_table luma_table =
1170 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
1171 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1174 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
1175 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
1176 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
1177 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
1178 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
1179 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1180 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1181 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
1182 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
1183 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
1184 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1185 0xF9,0xFA
1189 static const struct huffman_table chroma_table =
1192 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
1193 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1196 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
1197 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
1198 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1199 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1200 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1201 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1202 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1203 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1204 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1205 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1206 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1207 0xF9,0xFA
1211 MEMCPY(&p_jpeg->hufftable[0], &luma_table, sizeof(luma_table));
1212 MEMCPY(&p_jpeg->hufftable[1], &chroma_table, sizeof(chroma_table));
1214 return;
1217 /* Compute the derived values for a Huffman table */
1218 void fix_huff_tbl(int* htbl, struct derived_tbl* dtbl)
1220 int p, i, l, si;
1221 int lookbits, ctr;
1222 char huffsize[257];
1223 unsigned int huffcode[257];
1224 unsigned int code;
1226 dtbl->pub = htbl; /* fill in back link */
1228 /* Figure C.1: make table of Huffman code length for each symbol */
1229 /* Note that this is in code-length order. */
1231 p = 0;
1232 for (l = 1; l <= 16; l++)
1233 { /* all possible code length */
1234 for (i = 1; i <= (int) htbl[l-1]; i++) /* all codes per length */
1235 huffsize[p++] = (char) l;
1237 huffsize[p] = 0;
1239 /* Figure C.2: generate the codes themselves */
1240 /* Note that this is in code-length order. */
1242 code = 0;
1243 si = huffsize[0];
1244 p = 0;
1245 while (huffsize[p])
1247 while (((int) huffsize[p]) == si)
1249 huffcode[p++] = code;
1250 code++;
1252 code <<= 1;
1253 si++;
1256 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1258 p = 0;
1259 for (l = 1; l <= 16; l++)
1261 if (htbl[l-1])
1263 dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */
1264 dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */
1265 p += htbl[l-1];
1266 dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
1268 else
1270 dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
1273 dtbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */
1275 /* Compute lookahead tables to speed up decoding.
1276 * First we set all the table entries to 0, indicating "too long";
1277 * then we iterate through the Huffman codes that are short enough and
1278 * fill in all the entries that correspond to bit sequences starting
1279 * with that code.
1282 MEMSET(dtbl->look_nbits, 0, sizeof(dtbl->look_nbits));
1284 p = 0;
1285 for (l = 1; l <= HUFF_LOOKAHEAD; l++)
1287 for (i = 1; i <= (int) htbl[l-1]; i++, p++)
1289 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1290 /* Generate left-justified code followed by all possible bit sequences */
1291 lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
1292 for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--)
1294 dtbl->look_nbits[lookbits] = l;
1295 dtbl->look_sym[lookbits] = htbl[16+p];
1296 lookbits++;
1303 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1304 * If the incoming data is corrupted, decode_mcu could attempt to
1305 * reference values beyond the end of the array. To avoid a wild store,
1306 * we put some extra zeroes after the real entries.
1308 static const int zag[] =
1310 0, 1, 8, 16, 9, 2, 3, 10,
1311 17, 24, 32, 25, 18, 11, 4, 5,
1312 12, 19, 26, 33, 40, 48, 41, 34,
1313 27, 20, 13, 6, 7, 14, 21, 28,
1314 35, 42, 49, 56, 57, 50, 43, 36,
1315 29, 22, 15, 23, 30, 37, 44, 51,
1316 58, 59, 52, 45, 38, 31, 39, 46,
1317 53, 60, 61, 54, 47, 55, 62, 63,
1318 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1319 0, 0, 0, 0, 0, 0, 0, 0
1322 void build_lut(struct jpeg* p_jpeg)
1324 int i;
1325 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_dc,
1326 &p_jpeg->dc_derived_tbls[0]);
1327 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_ac,
1328 &p_jpeg->ac_derived_tbls[0]);
1329 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_dc,
1330 &p_jpeg->dc_derived_tbls[1]);
1331 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_ac,
1332 &p_jpeg->ac_derived_tbls[1]);
1334 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1335 for (i=0; i<64; i++)
1337 p_jpeg->qt_idct[0][zag[i]] = p_jpeg->quanttable[0][i];
1338 p_jpeg->qt_idct[1][zag[i]] = p_jpeg->quanttable[1][i];
1341 for (i=0; i<4; i++)
1342 p_jpeg->store_pos[i] = i; /* default ordering */
1344 /* assignments for the decoding of blocks */
1345 if (p_jpeg->frameheader[0].horizontal_sampling == 2
1346 && p_jpeg->frameheader[0].vertical_sampling == 1)
1347 { /* 4:2:2 */
1348 p_jpeg->blocks = 4;
1349 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1350 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1351 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1352 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1353 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1354 p_jpeg->mcu_membership[1] = 0;
1355 p_jpeg->mcu_membership[2] = 1;
1356 p_jpeg->mcu_membership[3] = 2;
1357 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1358 p_jpeg->tab_membership[1] = 0;
1359 p_jpeg->tab_membership[2] = 1;
1360 p_jpeg->tab_membership[3] = 1;
1361 p_jpeg->subsample_x[0] = 1;
1362 p_jpeg->subsample_x[1] = 2;
1363 p_jpeg->subsample_x[2] = 2;
1364 p_jpeg->subsample_y[0] = 1;
1365 p_jpeg->subsample_y[1] = 1;
1366 p_jpeg->subsample_y[2] = 1;
1368 if (p_jpeg->frameheader[0].horizontal_sampling == 1
1369 && p_jpeg->frameheader[0].vertical_sampling == 2)
1370 { /* 4:2:2 vertically subsampled */
1371 p_jpeg->store_pos[1] = 2; /* block positions are mirrored */
1372 p_jpeg->store_pos[2] = 1;
1373 p_jpeg->blocks = 4;
1374 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1375 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1376 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1377 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1378 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1379 p_jpeg->mcu_membership[1] = 0;
1380 p_jpeg->mcu_membership[2] = 1;
1381 p_jpeg->mcu_membership[3] = 2;
1382 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1383 p_jpeg->tab_membership[1] = 0;
1384 p_jpeg->tab_membership[2] = 1;
1385 p_jpeg->tab_membership[3] = 1;
1386 p_jpeg->subsample_x[0] = 1;
1387 p_jpeg->subsample_x[1] = 1;
1388 p_jpeg->subsample_x[2] = 1;
1389 p_jpeg->subsample_y[0] = 1;
1390 p_jpeg->subsample_y[1] = 2;
1391 p_jpeg->subsample_y[2] = 2;
1393 else if (p_jpeg->frameheader[0].horizontal_sampling == 2
1394 && p_jpeg->frameheader[0].vertical_sampling == 2)
1395 { /* 4:2:0 */
1396 p_jpeg->blocks = 6;
1397 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1398 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1399 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1400 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1401 p_jpeg->mcu_membership[0] = 0;
1402 p_jpeg->mcu_membership[1] = 0;
1403 p_jpeg->mcu_membership[2] = 0;
1404 p_jpeg->mcu_membership[3] = 0;
1405 p_jpeg->mcu_membership[4] = 1;
1406 p_jpeg->mcu_membership[5] = 2;
1407 p_jpeg->tab_membership[0] = 0;
1408 p_jpeg->tab_membership[1] = 0;
1409 p_jpeg->tab_membership[2] = 0;
1410 p_jpeg->tab_membership[3] = 0;
1411 p_jpeg->tab_membership[4] = 1;
1412 p_jpeg->tab_membership[5] = 1;
1413 p_jpeg->subsample_x[0] = 1;
1414 p_jpeg->subsample_x[1] = 2;
1415 p_jpeg->subsample_x[2] = 2;
1416 p_jpeg->subsample_y[0] = 1;
1417 p_jpeg->subsample_y[1] = 2;
1418 p_jpeg->subsample_y[2] = 2;
1420 else if (p_jpeg->frameheader[0].horizontal_sampling == 1
1421 && p_jpeg->frameheader[0].vertical_sampling == 1)
1422 { /* 4:4:4 */
1423 /* don't overwrite p_jpeg->blocks */
1424 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1425 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1426 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1427 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1428 p_jpeg->mcu_membership[0] = 0;
1429 p_jpeg->mcu_membership[1] = 1;
1430 p_jpeg->mcu_membership[2] = 2;
1431 p_jpeg->tab_membership[0] = 0;
1432 p_jpeg->tab_membership[1] = 1;
1433 p_jpeg->tab_membership[2] = 1;
1434 p_jpeg->subsample_x[0] = 1;
1435 p_jpeg->subsample_x[1] = 1;
1436 p_jpeg->subsample_x[2] = 1;
1437 p_jpeg->subsample_y[0] = 1;
1438 p_jpeg->subsample_y[1] = 1;
1439 p_jpeg->subsample_y[2] = 1;
1441 else
1443 /* error */
1450 * These functions/macros provide the in-line portion of bit fetching.
1451 * Use check_bit_buffer to ensure there are N bits in get_buffer
1452 * before using get_bits, peek_bits, or drop_bits.
1453 * check_bit_buffer(state,n,action);
1454 * Ensure there are N bits in get_buffer; if suspend, take action.
1455 * val = get_bits(n);
1456 * Fetch next N bits.
1457 * val = peek_bits(n);
1458 * Fetch next N bits without removing them from the buffer.
1459 * drop_bits(n);
1460 * Discard next N bits.
1461 * The value N should be a simple variable, not an expression, because it
1462 * is evaluated multiple times.
1465 INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
1467 if (pb->bits_left < nbits)
1468 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1469 unsigned char byte;
1471 byte = *pb->next_input_byte++;
1472 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1473 { /* simplification: just skip the (one-byte) marker code */
1474 pb->next_input_byte++;
1476 pb->get_buffer = (pb->get_buffer << 8) | byte;
1478 byte = *pb->next_input_byte++;
1479 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1480 { /* simplification: just skip the (one-byte) marker code */
1481 pb->next_input_byte++;
1483 pb->get_buffer = (pb->get_buffer << 8) | byte;
1485 pb->bits_left += 16;
1489 INLINE int get_bits(struct bitstream* pb, int nbits)
1491 return ((int) (pb->get_buffer >> (pb->bits_left -= nbits))) & ((1<<nbits)-1);
1494 INLINE int peek_bits(struct bitstream* pb, int nbits)
1496 return ((int) (pb->get_buffer >> (pb->bits_left - nbits))) & ((1<<nbits)-1);
1499 INLINE void drop_bits(struct bitstream* pb, int nbits)
1501 pb->bits_left -= nbits;
1504 /* re-synchronize to entropy data (skip restart marker) */
1505 void search_restart(struct bitstream* pb)
1507 pb->next_input_byte--; /* we may have overread it, taking 2 bytes */
1508 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1509 while (pb->next_input_byte < pb->input_end &&
1510 (pb->next_input_byte[-2] != 0xFF || pb->next_input_byte[-1] == 0x00))
1512 pb->next_input_byte++;
1514 pb->bits_left = 0;
1517 /* Figure F.12: extend sign bit. */
1518 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1520 static const int extend_test[16] = /* entry n is 2**(n-1) */
1522 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1523 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1526 static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
1528 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1529 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1530 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1531 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1534 /* Decode a single value */
1535 INLINE int huff_decode_dc(struct bitstream* bs, struct derived_tbl* tbl)
1537 int nb, look, s, r;
1539 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1540 look = peek_bits(bs, HUFF_LOOKAHEAD);
1541 if ((nb = tbl->look_nbits[look]) != 0)
1543 drop_bits(bs, nb);
1544 s = tbl->look_sym[look];
1545 check_bit_buffer(bs, s);
1546 r = get_bits(bs, s);
1547 s = HUFF_EXTEND(r, s);
1549 else
1550 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1551 long code;
1552 nb=HUFF_LOOKAHEAD+1;
1553 check_bit_buffer(bs, nb);
1554 code = get_bits(bs, nb);
1555 while (code > tbl->maxcode[nb])
1557 code <<= 1;
1558 check_bit_buffer(bs, 1);
1559 code |= get_bits(bs, 1);
1560 nb++;
1562 if (nb > 16) /* error in Huffman */
1564 s=0; /* fake a zero, this is most safe */
1566 else
1568 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1569 check_bit_buffer(bs, s);
1570 r = get_bits(bs, s);
1571 s = HUFF_EXTEND(r, s);
1573 } /* end slow decode */
1574 return s;
1577 INLINE int huff_decode_ac(struct bitstream* bs, struct derived_tbl* tbl)
1579 int nb, look, s;
1581 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1582 look = peek_bits(bs, HUFF_LOOKAHEAD);
1583 if ((nb = tbl->look_nbits[look]) != 0)
1585 drop_bits(bs, nb);
1586 s = tbl->look_sym[look];
1588 else
1589 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1590 long code;
1591 nb=HUFF_LOOKAHEAD+1;
1592 check_bit_buffer(bs, nb);
1593 code = get_bits(bs, nb);
1594 while (code > tbl->maxcode[nb])
1596 code <<= 1;
1597 check_bit_buffer(bs, 1);
1598 code |= get_bits(bs, 1);
1599 nb++;
1601 if (nb > 16) /* error in Huffman */
1603 s=0; /* fake a zero, this is most safe */
1605 else
1607 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1609 } /* end slow decode */
1610 return s;
1614 #ifdef HAVE_LCD_COLOR
1616 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1617 /* Note: it keeps the original color subsampling, even if resized. */
1618 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1619 int downscale, void (*pf_progress)(int current, int total))
1621 struct bitstream bs; /* bitstream "object" */
1622 int block[64]; /* decoded DCT coefficients */
1624 int width, height;
1625 int skip_line[3]; /* bytes from one line to the next (skip_line) */
1626 int skip_strip[3], skip_mcu[3]; /* bytes to next DCT row / column */
1628 int i, x, y; /* loop counter */
1630 unsigned char* p_line[3] = {p_pixel[0], p_pixel[1], p_pixel[2]};
1631 unsigned char* p_byte[3]; /* bitmap pointer */
1633 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1634 int k_need; /* AC coefficients needed up to here */
1635 int zero_need; /* init the block with this many zeros */
1637 int last_dc_val[3] = {0, 0, 0}; /* or 128 for chroma? */
1638 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1639 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1641 /* pick the IDCT we want, determine how to work with coefs */
1642 if (downscale == 1)
1644 pf_idct = idct8x8;
1645 k_need = 64; /* all */
1646 zero_need = 63; /* all */
1648 else if (downscale == 2)
1650 pf_idct = idct4x4;
1651 k_need = 25; /* this far in zig-zag to cover 4*4 */
1652 zero_need = 27; /* clear this far in linear order */
1654 else if (downscale == 4)
1656 pf_idct = idct2x2;
1657 k_need = 5; /* this far in zig-zag to cover 2*2 */
1658 zero_need = 9; /* clear this far in linear order */
1660 else if (downscale == 8)
1662 pf_idct = idct1x1;
1663 k_need = 0; /* no AC, not needed */
1664 zero_need = 0; /* no AC, not needed */
1666 else return -1; /* not supported */
1668 /* init bitstream, fake a restart to make it start */
1669 bs.next_input_byte = p_jpeg->p_entropy_data;
1670 bs.bits_left = 0;
1671 bs.input_end = p_jpeg->p_entropy_end;
1673 width = p_jpeg->x_phys / downscale;
1674 height = p_jpeg->y_phys / downscale;
1675 for (i=0; i<3; i++) /* calculate some strides */
1677 skip_line[i] = width / p_jpeg->subsample_x[i];
1678 skip_strip[i] = skip_line[i]
1679 * (height / p_jpeg->y_mbl) / p_jpeg->subsample_y[i];
1680 skip_mcu[i] = width/p_jpeg->x_mbl / p_jpeg->subsample_x[i];
1683 /* prepare offsets about where to store the different blocks */
1684 store_offs[p_jpeg->store_pos[0]] = 0;
1685 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1686 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1687 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1689 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1691 for (i=0; i<3; i++) /* scan line init */
1693 p_byte[i] = p_line[i];
1694 p_line[i] += skip_strip[i];
1696 for (x=0; x<p_jpeg->x_mbl; x++)
1698 int blkn;
1700 /* Outer loop handles each block in the MCU */
1701 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1702 { /* Decode a single block's worth of coefficients */
1703 int k = 1; /* coefficient index */
1704 int s, r; /* huffman values */
1705 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1706 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1707 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1708 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1710 /* Section F.2.2.1: decode the DC coefficient difference */
1711 s = huff_decode_dc(&bs, dctbl);
1713 last_dc_val[ci] += s;
1714 block[0] = last_dc_val[ci]; /* output it (assumes zag[0] = 0) */
1716 /* coefficient buffer must be cleared */
1717 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1719 /* Section F.2.2.2: decode the AC coefficients */
1720 for (; k < k_need; k++)
1722 s = huff_decode_ac(&bs, actbl);
1723 r = s >> 4;
1724 s &= 15;
1726 if (s)
1728 k += r;
1729 check_bit_buffer(&bs, s);
1730 r = get_bits(&bs, s);
1731 block[zag[k]] = HUFF_EXTEND(r, s);
1733 else
1735 if (r != 15)
1737 k = 64;
1738 break;
1740 k += r;
1742 } /* for k */
1743 /* In this path we just discard the values */
1744 for (; k < 64; k++)
1746 s = huff_decode_ac(&bs, actbl);
1747 r = s >> 4;
1748 s &= 15;
1750 if (s)
1752 k += r;
1753 check_bit_buffer(&bs, s);
1754 drop_bits(&bs, s);
1756 else
1758 if (r != 15)
1759 break;
1760 k += r;
1762 } /* for k */
1764 if (ci == 0)
1765 { /* Y component needs to bother about block store */
1766 pf_idct(p_byte[0]+store_offs[blkn], block,
1767 p_jpeg->qt_idct[ti], skip_line[0]);
1769 else
1770 { /* chroma */
1771 pf_idct(p_byte[ci], block, p_jpeg->qt_idct[ti],
1772 skip_line[ci]);
1774 } /* for blkn */
1775 p_byte[0] += skip_mcu[0]; /* unrolled for (i=0; i<3; i++) loop */
1776 p_byte[1] += skip_mcu[1];
1777 p_byte[2] += skip_mcu[2];
1778 if (p_jpeg->restart_interval && --restart == 0)
1779 { /* if a restart marker is due: */
1780 restart = p_jpeg->restart_interval; /* count again */
1781 search_restart(&bs); /* align the bitstream */
1782 last_dc_val[0] = last_dc_val[1] =
1783 last_dc_val[2] = 0; /* reset decoder */
1785 } /* for x */
1786 if (pf_progress != NULL)
1787 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1788 } /* for y */
1790 return 0; /* success */
1792 #else /* !HAVE_LCD_COLOR */
1794 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1795 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[1], int downscale,
1796 void (*pf_progress)(int current, int total))
1798 struct bitstream bs; /* bitstream "object" */
1799 int block[64]; /* decoded DCT coefficients */
1801 int width, height;
1802 int skip_line; /* bytes from one line to the next (skip_line) */
1803 int skip_strip, skip_mcu; /* bytes to next DCT row / column */
1805 int x, y; /* loop counter */
1807 unsigned char* p_line = p_pixel[0];
1808 unsigned char* p_byte; /* bitmap pointer */
1810 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1811 int k_need; /* AC coefficients needed up to here */
1812 int zero_need; /* init the block with this many zeros */
1814 int last_dc_val = 0;
1815 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1816 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1818 /* pick the IDCT we want, determine how to work with coefs */
1819 if (downscale == 1)
1821 pf_idct = idct8x8;
1822 k_need = 64; /* all */
1823 zero_need = 63; /* all */
1825 else if (downscale == 2)
1827 pf_idct = idct4x4;
1828 k_need = 25; /* this far in zig-zag to cover 4*4 */
1829 zero_need = 27; /* clear this far in linear order */
1831 else if (downscale == 4)
1833 pf_idct = idct2x2;
1834 k_need = 5; /* this far in zig-zag to cover 2*2 */
1835 zero_need = 9; /* clear this far in linear order */
1837 else if (downscale == 8)
1839 pf_idct = idct1x1;
1840 k_need = 0; /* no AC, not needed */
1841 zero_need = 0; /* no AC, not needed */
1843 else return -1; /* not supported */
1845 /* init bitstream, fake a restart to make it start */
1846 bs.next_input_byte = p_jpeg->p_entropy_data;
1847 bs.bits_left = 0;
1848 bs.input_end = p_jpeg->p_entropy_end;
1850 width = p_jpeg->x_phys / downscale;
1851 height = p_jpeg->y_phys / downscale;
1852 skip_line = width;
1853 skip_strip = skip_line * (height / p_jpeg->y_mbl);
1854 skip_mcu = (width/p_jpeg->x_mbl);
1856 /* prepare offsets about where to store the different blocks */
1857 store_offs[p_jpeg->store_pos[0]] = 0;
1858 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1859 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1860 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1862 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1864 p_byte = p_line;
1865 p_line += skip_strip;
1866 for (x=0; x<p_jpeg->x_mbl; x++)
1868 int blkn;
1870 /* Outer loop handles each block in the MCU */
1871 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1872 { /* Decode a single block's worth of coefficients */
1873 int k = 1; /* coefficient index */
1874 int s, r; /* huffman values */
1875 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1876 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1877 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1878 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1880 /* Section F.2.2.1: decode the DC coefficient difference */
1881 s = huff_decode_dc(&bs, dctbl);
1883 if (ci == 0) /* only for Y component */
1885 last_dc_val += s;
1886 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
1888 /* coefficient buffer must be cleared */
1889 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1891 /* Section F.2.2.2: decode the AC coefficients */
1892 for (; k < k_need; k++)
1894 s = huff_decode_ac(&bs, actbl);
1895 r = s >> 4;
1896 s &= 15;
1898 if (s)
1900 k += r;
1901 check_bit_buffer(&bs, s);
1902 r = get_bits(&bs, s);
1903 block[zag[k]] = HUFF_EXTEND(r, s);
1905 else
1907 if (r != 15)
1909 k = 64;
1910 break;
1912 k += r;
1914 } /* for k */
1916 /* In this path we just discard the values */
1917 for (; k < 64; k++)
1919 s = huff_decode_ac(&bs, actbl);
1920 r = s >> 4;
1921 s &= 15;
1923 if (s)
1925 k += r;
1926 check_bit_buffer(&bs, s);
1927 drop_bits(&bs, s);
1929 else
1931 if (r != 15)
1932 break;
1933 k += r;
1935 } /* for k */
1937 if (ci == 0)
1938 { /* only for Y component */
1939 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
1940 skip_line);
1942 } /* for blkn */
1943 p_byte += skip_mcu;
1944 if (p_jpeg->restart_interval && --restart == 0)
1945 { /* if a restart marker is due: */
1946 restart = p_jpeg->restart_interval; /* count again */
1947 search_restart(&bs); /* align the bitstream */
1948 last_dc_val = 0; /* reset decoder */
1950 } /* for x */
1951 if (pf_progress != NULL)
1952 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1953 } /* for y */
1955 return 0; /* success */
1957 #endif /* !HAVE_LCD_COLOR */
1959 /**************** end JPEG code ********************/
1963 /**************** begin Application ********************/
1966 /************************* Types ***************************/
1968 struct t_disp
1970 #ifdef HAVE_LCD_COLOR
1971 unsigned char* bitmap[3]; /* Y, Cr, Cb */
1972 int csub_x, csub_y;
1973 #else
1974 unsigned char* bitmap[1]; /* Y only */
1975 #endif
1976 int width;
1977 int height;
1978 int stride;
1979 int x, y;
1982 /************************* Globals ***************************/
1984 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1985 struct t_disp disp[9];
1987 /* my memory pool (from the mp3 buffer) */
1988 char print[32]; /* use a common snprintf() buffer */
1989 unsigned char* buf; /* up to here currently used by image(s) */
1991 /* the remaining free part of the buffer for compressed+uncompressed images */
1992 unsigned char* buf_images;
1994 ssize_t buf_size, buf_images_size;
1995 /* the root of the images, hereafter are decompresed ones */
1996 unsigned char* buf_root;
1997 int root_size;
1999 int ds, ds_min, ds_max; /* downscaling and limits */
2000 static struct jpeg jpg; /* too large for stack */
2002 static struct tree_context *tree;
2004 /* the current full file name */
2005 static char np_file[MAX_PATH];
2006 int curfile = 0, direction = DIR_NONE, entries = 0;
2008 /* list of the jpeg files */
2009 char **file_pt;
2010 /* are we using the plugin buffer or the audio buffer? */
2011 bool plug_buf = false;
2014 /************************* Implementation ***************************/
2016 #ifdef HAVE_LCD_COLOR
2018 * Conversion of full 0-255 range YCrCb to RGB:
2019 * |R| |1.000000 -0.000001 1.402000| |Y'|
2020 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
2021 * |B| |1.000000 1.772000 0.000000| |Pr|
2022 * Scaled (yields s15-bit output):
2023 * |R| |128 0 179| |Y |
2024 * |G| = |128 -43 -91| |Cb - 128|
2025 * |B| |128 227 0| |Cr - 128|
2027 #define YFAC 128
2028 #define RVFAC 179
2029 #define GUFAC (-43)
2030 #define GVFAC (-91)
2031 #define BUFAC 227
2032 #define YUV_WHITE (255*YFAC)
2033 #define NODITHER_DELTA (127*YFAC)
2034 #define COMPONENT_SHIFT 15
2035 #define MATRIX_SHIFT 7
2037 static inline int clamp_component(int x)
2039 if ((unsigned)x > YUV_WHITE)
2040 x = x < 0 ? 0 : YUV_WHITE;
2041 return x;
2044 static inline int clamp_component_bits(int x, int bits)
2046 if ((unsigned)x > (1u << bits) - 1)
2047 x = x < 0 ? 0 : (1 << bits) - 1;
2048 return x;
2051 static inline int component_to_lcd(int x, int bits, int delta)
2053 /* Formula used in core bitmap loader. */
2054 return (((1 << bits) - 1)*x + (x >> (8 - bits)) + delta) >> COMPONENT_SHIFT;
2057 static inline int lcd_to_component(int x, int bits, int delta)
2059 /* Reasonable, approximate reversal to get a full range back from the
2060 quantized value. */
2061 return YUV_WHITE*x / ((1 << bits) - 1);
2062 (void)delta;
2065 #define RED 0
2066 #define GRN 1
2067 #define BLU 2
2069 struct rgb_err
2071 int16_t errbuf[LCD_WIDTH+2]; /* Error record for line below */
2072 } rgb_err_buffers[3];
2074 fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
2075 DITHER_DIFFUSION is set */
2077 struct rgb_pixel
2079 int r, g, b; /* Current pixel components in s16.0 */
2080 int inc; /* Current line increment (-1 or 1) */
2081 int row; /* Current row in source image */
2082 int col; /* Current column in source image */
2083 int ce[3]; /* Errors to apply to current pixel */
2084 struct rgb_err *e; /* RED, GRN, BLU */
2085 int epos; /* Current position in error record */
2088 struct rgb_pixel *pixel;
2090 /** round and truncate to lcd depth **/
2091 static fb_data pixel_to_lcd_colour(void)
2093 struct rgb_pixel *p = pixel;
2094 int r, g, b;
2096 r = component_to_lcd(p->r, LCD_RED_BITS, NODITHER_DELTA);
2097 r = clamp_component_bits(r, LCD_RED_BITS);
2099 g = component_to_lcd(p->g, LCD_GREEN_BITS, NODITHER_DELTA);
2100 g = clamp_component_bits(g, LCD_GREEN_BITS);
2102 b = component_to_lcd(p->b, LCD_BLUE_BITS, NODITHER_DELTA);
2103 b = clamp_component_bits(b, LCD_BLUE_BITS);
2105 return LCD_RGBPACK_LCD(r, g, b);
2108 /** write a monochrome pixel to the colour LCD **/
2109 static fb_data pixel_to_lcd_gray(void)
2111 int r, g, b;
2113 g = clamp_component(pixel->g);
2114 r = component_to_lcd(g, LCD_RED_BITS, NODITHER_DELTA);
2115 b = component_to_lcd(g, LCD_BLUE_BITS, NODITHER_DELTA);
2116 g = component_to_lcd(g, LCD_GREEN_BITS, NODITHER_DELTA);
2118 return LCD_RGBPACK_LCD(r, g, b);
2122 * Bayer ordered dithering - swiped from the core bitmap loader.
2124 static fb_data pixel_odither_to_lcd(void)
2126 /* canonical ordered dither matrix */
2127 static const unsigned char dither_matrix[16][16] = {
2128 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
2129 { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
2130 { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
2131 { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
2132 { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
2133 { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
2134 { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
2135 { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
2136 { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
2137 { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
2138 { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
2139 { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
2140 { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
2141 { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
2142 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
2143 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
2146 struct rgb_pixel *p = pixel;
2147 int r, g, b, delta;
2149 delta = dither_matrix[p->col & 15][p->row & 15] << MATRIX_SHIFT;
2151 r = component_to_lcd(p->r, LCD_RED_BITS, delta);
2152 r = clamp_component_bits(r, LCD_RED_BITS);
2154 g = component_to_lcd(p->g, LCD_GREEN_BITS, delta);
2155 g = clamp_component_bits(g, LCD_GREEN_BITS);
2157 b = component_to_lcd(p->b, LCD_BLUE_BITS, delta);
2158 b = clamp_component_bits(b, LCD_BLUE_BITS);
2160 p->col += p->inc;
2162 return LCD_RGBPACK_LCD(r, g, b);
2166 * Floyd/Steinberg dither to lcd depth.
2168 * Apply filter to each component in serpentine pattern. Kernel shown for
2169 * L->R scan. Kernel is reversed for R->L.
2170 * * 7
2171 * 3 5 1 (1/16)
2173 static inline void distribute_error(int *ce, struct rgb_err *e,
2174 int err, int epos, int inc)
2176 *ce = (7*err >> 4) + e->errbuf[epos+inc];
2177 e->errbuf[epos+inc] = err >> 4;
2178 e->errbuf[epos] += 5*err >> 4;
2179 e->errbuf[epos-inc] += 3*err >> 4;
2182 static fb_data pixel_fsdither_to_lcd(void)
2184 struct rgb_pixel *p = pixel;
2185 int rc, gc, bc, r, g, b;
2186 int inc, epos;
2188 /* Full components with error terms */
2189 rc = p->r + p->ce[RED];
2190 r = component_to_lcd(rc, LCD_RED_BITS, 0);
2191 r = clamp_component_bits(r, LCD_RED_BITS);
2193 gc = p->g + p->ce[GRN];
2194 g = component_to_lcd(gc, LCD_GREEN_BITS, 0);
2195 g = clamp_component_bits(g, LCD_GREEN_BITS);
2197 bc = p->b + p->ce[BLU];
2198 b = component_to_lcd(bc, LCD_BLUE_BITS, 0);
2199 b = clamp_component_bits(b, LCD_BLUE_BITS);
2201 /* Get pixel errors */
2202 rc -= lcd_to_component(r, LCD_RED_BITS, 0);
2203 gc -= lcd_to_component(g, LCD_GREEN_BITS, 0);
2204 bc -= lcd_to_component(b, LCD_BLUE_BITS, 0);
2206 /* Spead error to surrounding pixels. */
2207 inc = p->inc;
2208 epos = p->epos;
2209 p->epos += inc;
2211 distribute_error(&p->ce[RED], &p->e[RED], rc, epos, inc);
2212 distribute_error(&p->ce[GRN], &p->e[GRN], gc, epos, inc);
2213 distribute_error(&p->ce[BLU], &p->e[BLU], bc, epos, inc);
2215 /* Pack and return pixel */
2216 return LCD_RGBPACK_LCD(r, g, b);
2219 /* Functions for each output mode, colour then grayscale. */
2220 static fb_data (* const pixel_funcs[COLOUR_NUM_MODES][DITHER_NUM_MODES])(void) =
2222 [COLOURMODE_COLOUR] =
2224 [DITHER_NONE] = pixel_to_lcd_colour,
2225 [DITHER_ORDERED] = pixel_odither_to_lcd,
2226 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2228 [COLOURMODE_GRAY] =
2230 [DITHER_NONE] = pixel_to_lcd_gray,
2231 [DITHER_ORDERED] = pixel_odither_to_lcd,
2232 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2237 * Draw a partial YUV colour bitmap
2239 * Runs serpentine pattern when dithering is DITHER_DIFFUSION, else scan is
2240 * always L->R.
2242 void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
2243 int src_x, int src_y, int stride,
2244 int x, int y, int width, int height)
2246 fb_data *dst, *dst_end;
2247 fb_data (*pixel_func)(void);
2248 struct rgb_pixel px;
2250 if (x + width > LCD_WIDTH)
2251 width = LCD_WIDTH - x; /* Clip right */
2252 if (x < 0)
2253 width += x, x = 0; /* Clip left */
2254 if (width <= 0)
2255 return; /* nothing left to do */
2257 if (y + height > LCD_HEIGHT)
2258 height = LCD_HEIGHT - y; /* Clip bottom */
2259 if (y < 0)
2260 height += y, y = 0; /* Clip top */
2261 if (height <= 0)
2262 return; /* nothing left to do */
2264 pixel = &px;
2266 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
2267 dst_end = dst + LCD_WIDTH * height;
2269 if (jpeg_settings.colour_mode == COLOURMODE_GRAY)
2270 csub_y = 0; /* Ignore Cb, Cr */
2272 pixel_func = pixel_funcs[jpeg_settings.colour_mode]
2273 [jpeg_settings.dither_mode];
2275 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2277 /* Reset error terms. */
2278 px.e = rgb_err_buffers;
2279 px.ce[RED] = px.ce[GRN] = px.ce[BLU] = 0;
2280 rb->memset(px.e, 0, 3*sizeof (struct rgb_err));
2285 fb_data *dst_row, *row_end;
2286 const unsigned char *ysrc;
2287 px.inc = 1;
2289 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2291 /* Use R->L scan on odd lines */
2292 px.inc -= (src_y & 1) << 1;
2293 px.epos = x + 1;
2295 if (px.inc < 0)
2296 px.epos += width - 1;
2299 if (px.inc == 1)
2301 /* Scan is L->R */
2302 dst_row = dst;
2303 row_end = dst_row + width;
2304 px.col = src_x;
2306 else
2308 /* Scan is R->L */
2309 row_end = dst - 1;
2310 dst_row = row_end + width;
2311 px.col = src_x + width - 1;
2314 ysrc = src[0] + stride * src_y + px.col;
2315 px.row = src_y;
2317 /* Do one row of pixels */
2318 if (csub_y) /* colour */
2320 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
2321 const unsigned char *usrc, *vsrc;
2323 usrc = src[1] + (stride/csub_x) * (src_y/csub_y)
2324 + (px.col/csub_x);
2325 vsrc = src[2] + (stride/csub_x) * (src_y/csub_y)
2326 + (px.col/csub_x);
2327 int xphase = px.col % csub_x;
2328 int xphase_reset = px.inc * csub_x;
2329 int y, v, u, rv, guv, bu;
2331 v = *vsrc - 128;
2332 vsrc += px.inc;
2333 u = *usrc - 128;
2334 usrc += px.inc;
2335 rv = RVFAC*v;
2336 guv = GUFAC*u + GVFAC*v;
2337 bu = BUFAC*u;
2339 while (1)
2341 y = YFAC*(*ysrc);
2342 ysrc += px.inc;
2343 px.r = y + rv;
2344 px.g = y + guv;
2345 px.b = y + bu;
2347 *dst_row = pixel_func();
2348 dst_row += px.inc;
2350 if (dst_row == row_end)
2351 break;
2353 xphase += px.inc;
2354 if ((unsigned)xphase < (unsigned)csub_x)
2355 continue;
2357 /* fetch new chromas */
2358 v = *vsrc - 128;
2359 vsrc += px.inc;
2360 u = *usrc - 128;
2361 usrc += px.inc;
2362 rv = RVFAC*v;
2363 guv = GUFAC*u + GVFAC*v;
2364 bu = BUFAC*u;
2366 xphase -= xphase_reset;
2369 else /* monochrome */
2373 /* Set all components the same for dithering purposes */
2374 px.g = px.r = px.b = YFAC*(*ysrc);
2375 *dst_row = pixel_func();
2376 ysrc += px.inc;
2377 dst_row += px.inc;
2379 while (dst_row != row_end);
2382 src_y++;
2383 dst += LCD_WIDTH;
2385 while (dst < dst_end);
2388 #endif /* HAVE_LCD_COLOR */
2391 /* support function for qsort() */
2392 static int compare(const void* p1, const void* p2)
2394 return rb->strcasecmp(*((char **)p1), *((char **)p2));
2397 bool jpg_ext(const char ext[])
2399 if(!ext)
2400 return false;
2401 if(!rb->strcasecmp(ext,".jpg") ||
2402 !rb->strcasecmp(ext,".jpe") ||
2403 !rb->strcasecmp(ext,".jpeg"))
2404 return true;
2405 else
2406 return false;
2409 /*Read directory contents for scrolling. */
2410 void get_pic_list(void)
2412 int i;
2413 long int str_len = 0;
2414 char *pname;
2415 tree = rb->tree_get_context();
2417 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2418 file_pt = rb->plugin_get_buffer((size_t *)&buf_size);
2419 #else
2420 file_pt = rb->plugin_get_audio_buffer((size_t *)&buf_size);
2421 #endif
2423 for(i = 0; i < tree->filesindir; i++)
2425 if(jpg_ext(rb->strrchr(&tree->name_buffer[str_len],'.')))
2426 file_pt[entries++] = &tree->name_buffer[str_len];
2428 str_len += rb->strlen(&tree->name_buffer[str_len]) + 1;
2431 rb->qsort(file_pt, entries, sizeof(char**), compare);
2433 /* Remove path and leave only the name.*/
2434 pname = rb->strrchr(np_file,'/');
2435 pname++;
2437 /* Find Selected File. */
2438 for(i = 0; i < entries; i++)
2439 if(!rb->strcmp(file_pt[i], pname))
2440 curfile = i;
2443 int change_filename(int direct)
2445 int count = 0;
2446 direction = direct;
2448 if(direct == DIR_PREV)
2452 count++;
2453 if(curfile == 0)
2454 curfile = entries - 1;
2455 else
2456 curfile--;
2457 }while(file_pt[curfile] == '\0' && count < entries);
2458 /* we "erase" the file name if we encounter
2459 * a non-supported file, so skip it now */
2461 else /* DIR_NEXT/DIR_NONE */
2465 count++;
2466 if(curfile == entries - 1)
2467 curfile = 0;
2468 else
2469 curfile++;
2470 }while(file_pt[curfile] == '\0' && count < entries);
2473 if(count == entries && file_pt[curfile] == '\0')
2475 rb->splash(HZ, "No supported files");
2476 return PLUGIN_ERROR;
2478 if(rb->strlen(tree->currdir) > 1)
2480 rb->strcpy(np_file, tree->currdir);
2481 rb->strcat(np_file, "/");
2483 else
2484 rb->strcpy(np_file, tree->currdir);
2486 rb->strcat(np_file, file_pt[curfile]);
2488 return PLUGIN_OTHER;
2491 /* switch off overlay, for handling SYS_ events */
2492 void cleanup(void *parameter)
2494 (void)parameter;
2495 #ifdef USEGSLIB
2496 grey_show(false);
2497 #endif
2500 #define VSCROLL (LCD_HEIGHT/8)
2501 #define HSCROLL (LCD_WIDTH/10)
2503 #define ZOOM_IN 100 /* return codes for below function */
2504 #define ZOOM_OUT 101
2506 #ifdef HAVE_LCD_COLOR
2507 bool set_option_grayscale(void)
2509 bool gray = jpeg_settings.colour_mode == COLOURMODE_GRAY;
2510 rb->set_bool("Grayscale", &gray);
2511 jpeg_settings.colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
2512 return false;
2515 bool set_option_dithering(void)
2517 static const struct opt_items dithering[DITHER_NUM_MODES] = {
2518 [DITHER_NONE] = { "Off", -1 },
2519 [DITHER_ORDERED] = { "Ordered", -1 },
2520 [DITHER_DIFFUSION] = { "Diffusion", -1 },
2523 rb->set_option("Dithering", &jpeg_settings.dither_mode, INT,
2524 dithering, DITHER_NUM_MODES, NULL);
2525 return false;
2528 static void display_options(void)
2530 static const struct menu_item items[] = {
2531 { "Grayscale", set_option_grayscale },
2532 { "Dithering", set_option_dithering },
2535 int m = menu_init(rb, items, ARRAYLEN(items),
2536 NULL, NULL, NULL, NULL);
2537 menu_run(m);
2538 menu_exit(m);
2540 #endif /* HAVE_LCD_COLOR */
2542 int show_menu(void) /* return 1 to quit */
2544 #if LCD_DEPTH > 1
2545 rb->lcd_set_backdrop(old_backdrop);
2546 #ifdef HAVE_LCD_COLOR
2547 rb->lcd_set_foreground(rb->global_settings->fg_color);
2548 rb->lcd_set_background(rb->global_settings->bg_color);
2549 #else
2550 rb->lcd_set_foreground(LCD_BLACK);
2551 rb->lcd_set_background(LCD_WHITE);
2552 #endif
2553 #endif
2554 int m;
2555 int result;
2557 enum menu_id
2559 MIID_QUIT = 0,
2560 MIID_TOGGLE_SS_MODE,
2561 MIID_CHANGE_SS_MODE,
2562 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2563 MIID_SHOW_PLAYBACK_MENU,
2564 #endif
2565 #ifdef HAVE_LCD_COLOR
2566 MIID_DISPLAY_OPTIONS,
2567 #endif
2568 MIID_RETURN,
2571 static const struct menu_item items[] = {
2572 [MIID_QUIT] =
2573 { "Quit", NULL },
2574 [MIID_TOGGLE_SS_MODE] =
2575 { "Toggle Slideshow Mode", NULL },
2576 [MIID_CHANGE_SS_MODE] =
2577 { "Change Slideshow Time", NULL },
2578 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2579 [MIID_SHOW_PLAYBACK_MENU] =
2580 { "Show Playback Menu", NULL },
2581 #endif
2582 #ifdef HAVE_LCD_COLOR
2583 [MIID_DISPLAY_OPTIONS] =
2584 { "Display Options", NULL },
2585 #endif
2586 [MIID_RETURN] =
2587 { "Return", NULL },
2590 static const struct opt_items slideshow[2] = {
2591 { "Disable", -1 },
2592 { "Enable", -1 },
2595 m = menu_init(rb, items, sizeof(items) / sizeof(*items),
2596 NULL, NULL, NULL, NULL);
2597 result=menu_show(m);
2599 switch (result)
2601 case MIID_QUIT:
2602 menu_exit(m);
2603 return 1;
2604 break;
2605 case MIID_TOGGLE_SS_MODE:
2606 rb->set_option("Toggle Slideshow", &slideshow_enabled, INT,
2607 slideshow , 2, NULL);
2608 break;
2609 case MIID_CHANGE_SS_MODE:
2610 rb->set_int("Slideshow Time", "s", UNIT_SEC,
2611 &jpeg_settings.ss_timeout, NULL, 1,
2612 SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, NULL);
2613 break;
2615 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2616 case MIID_SHOW_PLAYBACK_MENU:
2617 if (plug_buf)
2619 playback_control(rb, NULL);
2621 else
2623 rb->splash(HZ, "Cannot restart playback");
2625 break;
2626 #endif
2627 #ifdef HAVE_LCD_COLOR
2628 case MIID_DISPLAY_OPTIONS:
2629 display_options();
2630 break;
2631 #endif
2632 case MIID_RETURN:
2633 break;
2636 #if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
2637 /* change ata spindown time based on slideshow time setting */
2638 immediate_ata_off = false;
2639 rb->ata_spindown(rb->global_settings->disk_spindown);
2641 if (slideshow_enabled)
2643 if(jpeg_settings.ss_timeout < 10)
2645 /* slideshow times < 10s keep disk spinning */
2646 rb->ata_spindown(0);
2648 else if (!rb->mp3_is_playing())
2650 /* slideshow times > 10s and not playing: ata_off after load */
2651 immediate_ata_off = true;
2654 #endif
2655 #if LCD_DEPTH > 1
2656 rb->lcd_set_backdrop(NULL);
2657 rb->lcd_set_foreground(LCD_WHITE);
2658 rb->lcd_set_background(LCD_BLACK);
2659 #endif
2660 rb->lcd_clear_display();
2661 menu_exit(m);
2662 return 0;
2664 /* interactively scroll around the image */
2665 int scroll_bmp(struct t_disp* pdisp)
2667 int lastbutton = 0;
2669 while (true)
2671 int button;
2672 int move;
2674 if (slideshow_enabled)
2675 button = rb->button_get_w_tmo(jpeg_settings.ss_timeout * HZ);
2676 else button = rb->button_get(true);
2678 running_slideshow = false;
2680 switch(button)
2682 case JPEG_LEFT:
2683 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2684 return change_filename(DIR_PREV);
2685 case JPEG_LEFT | BUTTON_REPEAT:
2686 move = MIN(HSCROLL, pdisp->x);
2687 if (move > 0)
2689 MYXLCD(scroll_right)(move); /* scroll right */
2690 pdisp->x -= move;
2691 #ifdef HAVE_LCD_COLOR
2692 yuv_bitmap_part(
2693 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2694 pdisp->x, pdisp->y, pdisp->stride,
2695 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2696 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2697 #else
2698 MYXLCD(gray_bitmap_part)(
2699 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2700 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2701 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2702 #endif
2703 MYLCD_UPDATE();
2705 break;
2707 case JPEG_RIGHT:
2708 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2709 return change_filename(DIR_NEXT);
2710 case JPEG_RIGHT | BUTTON_REPEAT:
2711 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
2712 if (move > 0)
2714 MYXLCD(scroll_left)(move); /* scroll left */
2715 pdisp->x += move;
2716 #ifdef HAVE_LCD_COLOR
2717 yuv_bitmap_part(
2718 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2719 pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride,
2720 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2721 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2722 #else
2723 MYXLCD(gray_bitmap_part)(
2724 pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move,
2725 pdisp->y, pdisp->stride,
2726 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2727 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2728 #endif
2729 MYLCD_UPDATE();
2731 break;
2733 case JPEG_UP:
2734 case JPEG_UP | BUTTON_REPEAT:
2735 move = MIN(VSCROLL, pdisp->y);
2736 if (move > 0)
2738 MYXLCD(scroll_down)(move); /* scroll down */
2739 pdisp->y -= move;
2740 #ifdef HAVE_LCD_COLOR
2741 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2743 /* Draw over the band at the top of the last update
2744 caused by lack of error history on line zero. */
2745 move = MIN(move + 1, pdisp->y + pdisp->height);
2748 yuv_bitmap_part(
2749 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2750 pdisp->x, pdisp->y, pdisp->stride,
2751 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2752 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2753 #else
2754 MYXLCD(gray_bitmap_part)(
2755 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2756 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2757 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2758 #endif
2759 MYLCD_UPDATE();
2761 break;
2763 case JPEG_DOWN:
2764 case JPEG_DOWN | BUTTON_REPEAT:
2765 move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT);
2766 if (move > 0)
2768 MYXLCD(scroll_up)(move); /* scroll up */
2769 pdisp->y += move;
2770 #ifdef HAVE_LCD_COLOR
2771 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2773 /* Save the line that was on the last line of the display
2774 and draw one extra line above then recover the line with
2775 image data that had an error history when it was drawn.
2777 move++, pdisp->y--;
2778 MEMCPY(rgb_linebuf,
2779 rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2780 LCD_WIDTH*sizeof (fb_data));
2783 yuv_bitmap_part(
2784 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x,
2785 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2786 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2787 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2789 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2791 /* Cover the first row drawn with previous image data. */
2792 MEMCPY(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2793 rgb_linebuf,
2794 LCD_WIDTH*sizeof (fb_data));
2795 pdisp->y++;
2797 #else
2798 MYXLCD(gray_bitmap_part)(
2799 pdisp->bitmap[0], pdisp->x,
2800 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2801 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2802 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2803 #endif
2804 MYLCD_UPDATE();
2806 break;
2807 case BUTTON_NONE:
2808 if (!slideshow_enabled)
2809 break;
2810 running_slideshow = true;
2811 if (entries > 0)
2812 return change_filename(DIR_NEXT);
2813 break;
2815 #ifdef JPEG_SLIDE_SHOW
2816 case JPEG_SLIDE_SHOW:
2817 slideshow_enabled = !slideshow_enabled;
2818 running_slideshow = slideshow_enabled;
2819 break;
2820 #endif
2822 #ifdef JPEG_NEXT_REPEAT
2823 case JPEG_NEXT_REPEAT:
2824 #endif
2825 case JPEG_NEXT:
2826 if (entries > 0)
2827 return change_filename(DIR_NEXT);
2828 break;
2830 #ifdef JPEG_PREVIOUS_REPEAT
2831 case JPEG_PREVIOUS_REPEAT:
2832 #endif
2833 case JPEG_PREVIOUS:
2834 if (entries > 0)
2835 return change_filename(DIR_PREV);
2836 break;
2838 case JPEG_ZOOM_IN:
2839 #ifdef JPEG_ZOOM_PRE
2840 if (lastbutton != JPEG_ZOOM_PRE)
2841 break;
2842 #endif
2843 return ZOOM_IN;
2844 break;
2846 case JPEG_ZOOM_OUT:
2847 #ifdef JPEG_ZOOM_PRE
2848 if (lastbutton != JPEG_ZOOM_PRE)
2849 break;
2850 #endif
2851 return ZOOM_OUT;
2852 break;
2853 #ifdef JPEG_RC_MENU
2854 case JPEG_RC_MENU:
2855 #endif
2856 case JPEG_MENU:
2857 #ifdef USEGSLIB
2858 grey_show(false); /* switch off greyscale overlay */
2859 #endif
2860 if (show_menu() == 1)
2861 return PLUGIN_OK;
2863 #ifdef USEGSLIB
2864 grey_show(true); /* switch on greyscale overlay */
2865 #else
2866 yuv_bitmap_part(
2867 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2868 pdisp->x, pdisp->y, pdisp->stride,
2869 MAX(0, (LCD_WIDTH - pdisp->width) / 2),
2870 MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
2871 MIN(LCD_WIDTH, pdisp->width),
2872 MIN(LCD_HEIGHT, pdisp->height));
2873 MYLCD_UPDATE();
2874 #endif
2875 break;
2876 default:
2877 if (rb->default_event_handler_ex(button, cleanup, NULL)
2878 == SYS_USB_CONNECTED)
2879 return PLUGIN_USB_CONNECTED;
2880 break;
2882 } /* switch */
2884 if (button != BUTTON_NONE)
2885 lastbutton = button;
2886 } /* while (true) */
2889 /********************* main function *************************/
2891 /* callback updating a progress meter while JPEG decoding */
2892 void cb_progess(int current, int total)
2894 rb->yield(); /* be nice to the other threads */
2895 if(!running_slideshow)
2897 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-8, LCD_WIDTH, 8, total, 0,
2898 current, HORIZONTAL);
2899 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
2901 #ifndef USEGSLIB
2902 else
2904 /* in slideshow mode, keep gui interference to a minimum */
2905 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-4, LCD_WIDTH, 4, total, 0,
2906 current, HORIZONTAL);
2907 rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4);
2909 #endif
2912 int jpegmem(struct jpeg *p_jpg, int ds)
2914 int size;
2916 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
2917 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
2918 #ifdef HAVE_LCD_COLOR
2919 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
2921 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
2922 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
2923 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
2924 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
2926 #endif
2927 return size;
2930 /* how far can we zoom in without running out of memory */
2931 int min_downscale(struct jpeg *p_jpg, int bufsize)
2933 int downscale = 8;
2935 if (jpegmem(p_jpg, 8) > bufsize)
2936 return 0; /* error, too large, even 1:8 doesn't fit */
2938 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
2939 downscale /= 2;
2941 return downscale;
2945 /* how far can we zoom out, to fit image into the LCD */
2946 int max_downscale(struct jpeg *p_jpg)
2948 int downscale = 1;
2950 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale
2951 || p_jpg->y_size > LCD_HEIGHT*downscale))
2953 downscale *= 2;
2956 return downscale;
2960 /* return decoded or cached image */
2961 struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2963 int w, h; /* used to center output */
2964 int size; /* decompressed image size */
2965 long time; /* measured ticks */
2966 int status;
2968 struct t_disp* p_disp = &disp[ds]; /* short cut */
2970 if (p_disp->bitmap[0] != NULL)
2972 return p_disp; /* we still have it */
2975 /* assign image buffer */
2977 /* physical size needed for decoding */
2978 size = jpegmem(p_jpg, ds);
2979 if (buf_size <= size)
2980 { /* have to discard the current */
2981 int i;
2982 for (i=1; i<=8; i++)
2983 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
2984 buf = buf_root; /* start again from the beginning of the buffer */
2985 buf_size = root_size;
2988 #ifdef HAVE_LCD_COLOR
2989 if (p_jpg->blocks > 1) /* colour jpeg */
2991 int i;
2993 for (i = 1; i < 3; i++)
2995 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
2996 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
2997 p_disp->bitmap[i] = buf;
2998 buf += size;
2999 buf_size -= size;
3001 p_disp->csub_x = p_jpg->subsample_x[1];
3002 p_disp->csub_y = p_jpg->subsample_y[1];
3004 else
3006 p_disp->csub_x = p_disp->csub_y = 0;
3007 p_disp->bitmap[1] = p_disp->bitmap[2] = buf;
3009 #endif
3010 /* size may be less when decoded (if height is not block aligned) */
3011 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
3012 p_disp->bitmap[0] = buf;
3013 buf += size;
3014 buf_size -= size;
3016 if(!running_slideshow)
3018 rb->snprintf(print, sizeof(print), "decoding %d*%d",
3019 p_jpg->x_size/ds, p_jpg->y_size/ds);
3020 rb->lcd_puts(0, 3, print);
3021 rb->lcd_update();
3024 /* update image properties */
3025 p_disp->width = p_jpg->x_size / ds;
3026 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
3027 p_disp->height = p_jpg->y_size / ds;
3029 /* the actual decoding */
3030 time = *rb->current_tick;
3031 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
3032 rb->cpu_boost(true);
3033 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
3034 rb->cpu_boost(false);
3035 #else
3036 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
3037 #endif
3038 if (status)
3040 rb->splashf(HZ, "decode error %d", status);
3041 file_pt[curfile] = '\0';
3042 return NULL;
3044 time = *rb->current_tick - time;
3046 if(!running_slideshow)
3048 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
3049 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
3050 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
3051 rb->lcd_update();
3054 return p_disp;
3058 /* set the view to the given center point, limit if necessary */
3059 void set_view (struct t_disp* p_disp, int cx, int cy)
3061 int x, y;
3063 /* plain center to available width/height */
3064 x = cx - MIN(LCD_WIDTH, p_disp->width) / 2;
3065 y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2;
3067 /* limit against upper image size */
3068 x = MIN(p_disp->width - LCD_WIDTH, x);
3069 y = MIN(p_disp->height - LCD_HEIGHT, y);
3071 /* limit against negative side */
3072 x = MAX(0, x);
3073 y = MAX(0, y);
3075 p_disp->x = x; /* set the values */
3076 p_disp->y = y;
3080 /* calculate the view center based on the bitmap position */
3081 void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
3083 *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2;
3084 *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2;
3088 /* load, decode, display the image */
3089 int load_and_show(char* filename)
3091 int fd;
3092 int filesize;
3093 unsigned char* buf_jpeg; /* compressed JPEG image */
3094 int status;
3095 struct t_disp* p_disp; /* currenly displayed image */
3096 int cx, cy; /* view center */
3098 fd = rb->open(filename, O_RDONLY);
3099 if (fd < 0)
3101 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
3102 rb->splash(HZ, print);
3103 return PLUGIN_ERROR;
3105 filesize = rb->filesize(fd);
3106 rb->memset(&disp, 0, sizeof(disp));
3108 buf = buf_images + filesize;
3109 buf_size = buf_images_size - filesize;
3110 /* allocate JPEG buffer */
3111 buf_jpeg = buf_images;
3113 buf_root = buf; /* we can start the decompressed images behind it */
3114 root_size = buf_size;
3116 if (buf_size <= 0)
3118 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
3119 if(plug_buf)
3121 rb->close(fd);
3122 rb->lcd_setfont(FONT_SYSFIXED);
3123 rb->lcd_clear_display();
3124 rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
3125 rb->lcd_puts(0,0,print);
3126 rb->lcd_puts(0,1,"Not enough plugin memory!");
3127 rb->lcd_puts(0,2,"Zoom In: Stop playback.");
3128 if(entries>1)
3129 rb->lcd_puts(0,3,"Left/Right: Skip File.");
3130 rb->lcd_puts(0,4,"Off: Quit.");
3131 rb->lcd_update();
3132 rb->lcd_setfont(FONT_UI);
3134 rb->button_clear_queue();
3136 while (1)
3138 int button = rb->button_get(true);
3139 switch(button)
3141 case JPEG_ZOOM_IN:
3142 plug_buf = false;
3143 buf_images = rb->plugin_get_audio_buffer(
3144 (size_t *)&buf_images_size);
3145 /*try again this file, now using the audio buffer */
3146 return PLUGIN_OTHER;
3147 #ifdef JPEG_RC_MENU
3148 case JPEG_RC_MENU:
3149 #endif
3150 case JPEG_MENU:
3151 return PLUGIN_OK;
3153 case JPEG_LEFT:
3154 if(entries>1)
3156 rb->lcd_clear_display();
3157 return change_filename(DIR_PREV);
3159 break;
3161 case JPEG_RIGHT:
3162 if(entries>1)
3164 rb->lcd_clear_display();
3165 return change_filename(DIR_NEXT);
3167 break;
3168 default:
3169 if(rb->default_event_handler_ex(button, cleanup, NULL)
3170 == SYS_USB_CONNECTED)
3171 return PLUGIN_USB_CONNECTED;
3176 else
3177 #endif
3179 rb->splash(HZ, "Out of Memory");
3180 rb->close(fd);
3181 return PLUGIN_ERROR;
3185 if(!running_slideshow)
3187 #if LCD_DEPTH > 1
3188 rb->lcd_set_foreground(LCD_WHITE);
3189 rb->lcd_set_background(LCD_BLACK);
3190 rb->lcd_set_backdrop(NULL);
3191 #endif
3193 rb->lcd_clear_display();
3194 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
3195 rb->lcd_puts(0, 0, print);
3196 rb->lcd_update();
3198 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
3199 rb->lcd_puts(0, 1, print);
3200 rb->lcd_update();
3203 rb->read(fd, buf_jpeg, filesize);
3204 rb->close(fd);
3206 if(!running_slideshow)
3208 rb->snprintf(print, sizeof(print), "decoding markers");
3209 rb->lcd_puts(0, 2, print);
3210 rb->lcd_update();
3212 #ifndef SIMULATOR
3213 else if(immediate_ata_off)
3215 /* running slideshow and time is long enough: power down disk */
3216 rb->ata_sleep();
3218 #endif
3220 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
3221 /* process markers, unstuffing */
3222 status = process_markers(buf_jpeg, filesize, &jpg);
3224 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
3225 { /* bad format or minimum components not contained */
3226 rb->splashf(HZ, "unsupported %d", status);
3227 file_pt[curfile] = '\0';
3228 return change_filename(direction);
3231 if (!(status & DHT)) /* if no Huffman table present: */
3232 default_huff_tbl(&jpg); /* use default */
3233 build_lut(&jpg); /* derive Huffman and other lookup-tables */
3235 if(!running_slideshow)
3237 rb->snprintf(print, sizeof(print), "image %dx%d", jpg.x_size, jpg.y_size);
3238 rb->lcd_puts(0, 2, print);
3239 rb->lcd_update();
3241 ds_max = max_downscale(&jpg); /* check display constraint */
3242 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */
3243 if (ds_min == 0)
3245 rb->splash(HZ, "too large");
3246 file_pt[curfile] = '\0';
3247 return change_filename(direction);
3250 ds = ds_max; /* initials setting */
3251 cx = jpg.x_size/ds/2; /* center the view */
3252 cy = jpg.y_size/ds/2;
3254 do /* loop the image prepare and decoding when zoomed */
3256 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */
3257 if (p_disp == NULL)
3258 return change_filename(direction);
3260 set_view(p_disp, cx, cy);
3262 if(!running_slideshow)
3264 rb->snprintf(print, sizeof(print), "showing %dx%d",
3265 p_disp->width, p_disp->height);
3266 rb->lcd_puts(0, 3, print);
3267 rb->lcd_update();
3269 MYLCD(clear_display)();
3270 #ifdef HAVE_LCD_COLOR
3271 yuv_bitmap_part(
3272 p_disp->bitmap, p_disp->csub_x, p_disp->csub_y,
3273 p_disp->x, p_disp->y, p_disp->stride,
3274 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3275 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3276 MIN(LCD_WIDTH, p_disp->width),
3277 MIN(LCD_HEIGHT, p_disp->height));
3278 #else
3279 MYXLCD(gray_bitmap_part)(
3280 p_disp->bitmap[0], p_disp->x, p_disp->y, p_disp->stride,
3281 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3282 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3283 MIN(LCD_WIDTH, p_disp->width),
3284 MIN(LCD_HEIGHT, p_disp->height));
3285 #endif
3286 MYLCD_UPDATE();
3288 #ifdef USEGSLIB
3289 grey_show(true); /* switch on greyscale overlay */
3290 #endif
3292 /* drawing is now finished, play around with scrolling
3293 * until you press OFF or connect USB
3295 while (1)
3297 status = scroll_bmp(p_disp);
3298 if (status == ZOOM_IN)
3300 if (ds > ds_min)
3302 ds /= 2; /* reduce downscaling to zoom in */
3303 get_view(p_disp, &cx, &cy);
3304 cx *= 2; /* prepare the position in the new image */
3305 cy *= 2;
3307 else
3308 continue;
3311 if (status == ZOOM_OUT)
3313 if (ds < ds_max)
3315 ds *= 2; /* increase downscaling to zoom out */
3316 get_view(p_disp, &cx, &cy);
3317 cx /= 2; /* prepare the position in the new image */
3318 cy /= 2;
3320 else
3321 continue;
3323 break;
3326 #ifdef USEGSLIB
3327 grey_show(false); /* switch off overlay */
3328 #endif
3329 rb->lcd_clear_display();
3331 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
3332 && status != PLUGIN_OTHER);
3333 #ifdef USEGSLIB
3334 rb->lcd_update();
3335 #endif
3336 return status;
3339 /******************** Plugin entry point *********************/
3341 enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
3343 rb = api;
3345 int condition;
3346 #ifdef USEGSLIB
3347 long greysize; /* helper */
3348 #endif
3349 #if LCD_DEPTH > 1
3350 old_backdrop = rb->lcd_get_backdrop();
3351 #endif
3353 if(!parameter) return PLUGIN_ERROR;
3355 rb->strcpy(np_file, parameter);
3356 get_pic_list();
3358 if(!entries) return PLUGIN_ERROR;
3360 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
3361 if(rb->audio_status())
3363 buf = rb->plugin_get_buffer((size_t *)&buf_size) +
3364 (entries * sizeof(char**));
3365 buf_size -= (entries * sizeof(char**));
3366 plug_buf = true;
3368 else
3369 buf = rb->plugin_get_audio_buffer((size_t *)&buf_size);
3370 #else
3371 buf = rb->plugin_get_audio_buffer(&buf_size) +
3372 (entries * sizeof(char**));
3373 buf_size -= (entries * sizeof(char**));
3374 #endif
3376 #ifdef USEGSLIB
3377 if (!grey_init(rb, buf, buf_size, GREY_ON_COP,
3378 LCD_WIDTH, LCD_HEIGHT, &greysize))
3380 rb->splash(HZ, "grey buf error");
3381 return PLUGIN_ERROR;
3383 buf += greysize;
3384 buf_size -= greysize;
3385 #else
3386 xlcd_init(rb);
3387 #endif
3389 /* should be ok to just load settings since a parameter is present
3390 here and the drive should be spinning */
3391 configfile_init(rb);
3392 configfile_load(JPEG_CONFIGFILE, jpeg_config,
3393 ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION);
3394 old_settings = jpeg_settings;
3396 buf_images = buf; buf_images_size = buf_size;
3398 /* Turn off backlight timeout */
3399 backlight_force_on(rb); /* backlight control in lib/helper.c */
3403 condition = load_and_show(np_file);
3404 }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
3405 && condition != PLUGIN_ERROR);
3407 if (rb->memcmp(&jpeg_settings, &old_settings, sizeof (jpeg_settings)))
3409 /* Just in case drive has to spin, keep it from looking locked */
3410 rb->splash(0, "Saving Settings");
3411 configfile_save(JPEG_CONFIGFILE, jpeg_config,
3412 ARRAYLEN(jpeg_config), JPEG_SETTINGS_VERSION);
3415 #if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
3416 /* set back ata spindown time in case we changed it */
3417 rb->ata_spindown(rb->global_settings->disk_spindown);
3418 #endif
3420 /* Turn on backlight timeout (revert to settings) */
3421 backlight_use_settings(rb); /* backlight control in lib/helper.c */
3423 #ifdef USEGSLIB
3424 grey_release(); /* deinitialize */
3425 #endif
3427 return condition;
3430 #endif /* HAVE_LCD_BITMAP */