very minor code police. also fix a possible but unlikely missed cpu_boost(false)
[Rockbox.git] / apps / plugins / jpeg.c
bloba17c6d7729b3c1dd5e3770a66eac30491477cc59
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 #else
218 #error No keymap defined!
219 #endif
221 #ifdef HAVE_TOUCHPAD
222 #ifndef JPEG_UP
223 #define JPEG_UP BUTTON_TOPMIDDLE
224 #endif
225 #ifndef JPEG_DOWN
226 #define JPEG_DOWN BUTTON_BOTTOMMIDDLE
227 #endif
228 #ifndef JPEG_LEFT
229 #define JPEG_LEFT BUTTON_MIDLEFT
230 #endif
231 #ifndef JPEG_RIGHT
232 #define JPEG_RIGHT BUTTON_MIDRIGHT
233 #endif
234 #ifndef JPEG_ZOOM_IN
235 #define JPEG_ZOOM_IN BUTTON_TOPRIGHT
236 #endif
237 #ifndef JPEG_ZOOM_OUT
238 #define JPEG_ZOOM_OUT BUTTON_TOPLEFT
239 #endif
240 #ifndef JPEG_MENU
241 #define JPEG_MENU (BUTTON_CENTER|BUTTON_REL)
242 #endif
243 #ifndef JPEG_NEXT
244 #define JPEG_NEXT BUTTON_BOTTOMRIGHT
245 #endif
246 #ifndef JPEG_PREVIOUS
247 #define JPEG_PREVIOUS BUTTON_BOTTOMLEFT
248 #endif
249 #endif
251 /* different graphics libraries */
252 #if LCD_DEPTH < 8
253 #define USEGSLIB
254 GREY_INFO_STRUCT
255 #define MYLCD(fn) grey_ub_ ## fn
256 #define MYLCD_UPDATE()
257 #define MYXLCD(fn) grey_ub_ ## fn
258 #else
259 #define MYLCD(fn) rb->lcd_ ## fn
260 #define MYLCD_UPDATE() rb->lcd_update();
261 #define MYXLCD(fn) xlcd_ ## fn
262 #endif
264 #define MAX_X_SIZE LCD_WIDTH*8
266 /* Min memory allowing us to use the plugin buffer
267 * and thus not stopping the music
268 * *Very* rough estimation:
269 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
270 * + 20k code size = 60 000
271 * + 50k min for jpeg = 120 000
273 #define MIN_MEM 120000
275 /* Headings */
276 #define DIR_PREV 1
277 #define DIR_NEXT -1
278 #define DIR_NONE 0
280 #define PLUGIN_OTHER 10 /* State code for output with return. */
282 /******************************* Globals ***********************************/
284 static const struct plugin_api* rb;
285 MEM_FUNCTION_WRAPPERS(rb);
287 /* for portability of below JPEG code */
288 #define MEMSET(p,v,c) rb->memset(p,v,c)
289 #define MEMCPY(d,s,c) rb->memcpy(d,s,c)
290 #define INLINE static inline
291 #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
293 static int slideshow_enabled = false; /* run slideshow */
294 static int running_slideshow = false; /* loading image because of slideshw */
295 #ifndef SIMULATOR
296 static int immediate_ata_off = false; /* power down disk after loading */
297 #endif
299 /* Persistent configuration */
300 #define JPEG_CONFIGFILE "jpeg.cfg"
301 #define JPEG_SETTINGS_MINVERSION 1
302 #define JPEG_SETTINGS_VERSION 2
304 /* Slideshow times */
305 #define SS_MIN_TIMEOUT 1
306 #define SS_MAX_TIMEOUT 20
307 #define SS_DEFAULT_TIMEOUT 5
309 enum color_modes
311 COLOURMODE_COLOUR = 0,
312 COLOURMODE_GRAY,
313 COLOUR_NUM_MODES
316 enum dither_modes
318 DITHER_NONE = 0, /* No dithering */
319 DITHER_ORDERED, /* Bayer ordered */
320 DITHER_DIFFUSION, /* Floyd/Steinberg error diffusion */
321 DITHER_NUM_MODES
324 struct jpeg_settings
326 int colour_mode;
327 int dither_mode;
328 int ss_timeout;
331 static struct jpeg_settings jpeg_settings =
332 { COLOURMODE_COLOUR, DITHER_NONE, SS_DEFAULT_TIMEOUT };
333 static struct jpeg_settings old_settings;
335 static struct configdata jpeg_config[] =
337 #ifdef HAVE_LCD_COLOR
338 { TYPE_ENUM, 0, COLOUR_NUM_MODES, &jpeg_settings.colour_mode,
339 "Colour Mode", (char *[]){ "Colour", "Grayscale" }, NULL },
340 { TYPE_ENUM, 0, DITHER_NUM_MODES, &jpeg_settings.dither_mode,
341 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" }, NULL },
342 #endif
343 { TYPE_INT, SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, &jpeg_settings.ss_timeout,
344 "Slideshow Time", NULL, NULL},
347 #if LCD_DEPTH > 1
348 fb_data* old_backdrop;
349 #endif
351 /**************** begin JPEG code ********************/
353 INLINE unsigned range_limit(int value)
355 #if CONFIG_CPU == SH7034
356 unsigned tmp;
357 asm ( /* Note: Uses knowledge that only low byte of result is used */
358 "mov #-128,%[t] \n"
359 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
360 "extu.b %[v],%[t] \n"
361 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
362 "bt 1f \n" /* yes: no overflow */
363 "cmp/pz %[v] \n" /* overflow: positive? */
364 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
365 "1: \n"
366 : /* outputs */
367 [v]"+r"(value),
368 [t]"=&r"(tmp)
370 return value;
371 #elif defined(CPU_COLDFIRE)
372 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
373 "add.l #128,%[v] \n" /* value += 128; */
374 "cmp.l #255,%[v] \n" /* overflow? */
375 "bls.b 1f \n" /* no: return value */
376 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
377 "1: \n"
378 : /* outputs */
379 [v]"+d"(value)
381 return value;
382 #elif defined(CPU_ARM)
383 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
384 "add %[v], %[v], #128 \n" /* value += 128 */
385 "cmp %[v], #255 \n" /* out of range 0..255? */
386 "mvnhi %[v], %[v], asr #31 \n" /* yes: set all bits to ~(sign_bit) */
387 : /* outputs */
388 [v]"+r"(value)
390 return value;
391 #else
392 value += 128;
394 if ((unsigned)value <= 255)
395 return value;
397 if (value < 0)
398 return 0;
400 return 255;
401 #endif
404 /* IDCT implementation */
407 #define CONST_BITS 13
408 #define PASS1_BITS 2
411 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
412 * causing a lot of useless floating-point operations at run time.
413 * To get around this we use the following pre-calculated constants.
414 * If you change CONST_BITS you may want to add appropriate values.
415 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
417 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
418 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
419 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
420 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
421 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
422 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
423 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
424 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
425 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
426 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
427 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
428 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
432 /* Multiply an long variable by an long constant to yield an long result.
433 * For 8-bit samples with the recommended scaling, all the variable
434 * and constant values involved are no more than 16 bits wide, so a
435 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
436 * For 12-bit samples, a full 32-bit multiplication will be needed.
438 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
441 /* Dequantize a coefficient by multiplying it by the multiplier-table
442 * entry; produce an int result. In this module, both inputs and result
443 * are 16 bits or less, so either int or short multiply will work.
445 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
446 #define DEQUANTIZE MULTIPLY16
448 /* Descale and correctly round an int value that's scaled by N bits.
449 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
450 * the fudge factor is correct for either sign of X.
452 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
457 * Perform dequantization and inverse DCT on one block of coefficients,
458 * producing a reduced-size 1x1 output block.
460 void idct1x1(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
462 (void)skip_line; /* unused */
463 *p_byte = range_limit(inptr[0] * quantptr[0] >> 3);
469 * Perform dequantization and inverse DCT on one block of coefficients,
470 * producing a reduced-size 2x2 output block.
472 void idct2x2(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
474 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
475 unsigned char* outptr;
477 /* Pass 1: process columns from input, store into work array. */
479 /* Column 0 */
480 tmp4 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
481 tmp5 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
483 tmp0 = tmp4 + tmp5;
484 tmp2 = tmp4 - tmp5;
486 /* Column 1 */
487 tmp4 = DEQUANTIZE(inptr[8*0+1], quantptr[8*0+1]);
488 tmp5 = DEQUANTIZE(inptr[8*1+1], quantptr[8*1+1]);
490 tmp1 = tmp4 + tmp5;
491 tmp3 = tmp4 - tmp5;
493 /* Pass 2: process 2 rows, store into output array. */
495 /* Row 0 */
496 outptr = p_byte;
498 outptr[0] = range_limit((int) DESCALE(tmp0 + tmp1, 3));
499 outptr[1] = range_limit((int) DESCALE(tmp0 - tmp1, 3));
501 /* Row 1 */
502 outptr = p_byte + skip_line;
504 outptr[0] = range_limit((int) DESCALE(tmp2 + tmp3, 3));
505 outptr[1] = range_limit((int) DESCALE(tmp2 - tmp3, 3));
511 * Perform dequantization and inverse DCT on one block of coefficients,
512 * producing a reduced-size 4x4 output block.
514 void idct4x4(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
516 int tmp0, tmp2, tmp10, tmp12;
517 int z1, z2, z3;
518 int * wsptr;
519 unsigned char* outptr;
520 int ctr;
521 int workspace[4*4]; /* buffers data between passes */
523 /* Pass 1: process columns from input, store into work array. */
525 wsptr = workspace;
526 for (ctr = 0; ctr < 4; ctr++, inptr++, quantptr++, wsptr++)
528 /* Even part */
530 tmp0 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
531 tmp2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
533 tmp10 = (tmp0 + tmp2) << PASS1_BITS;
534 tmp12 = (tmp0 - tmp2) << PASS1_BITS;
536 /* Odd part */
537 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
539 z2 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
540 z3 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
542 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
543 tmp0 = DESCALE(z1 + MULTIPLY16(z3, - FIX_1_847759065), CONST_BITS-PASS1_BITS);
544 tmp2 = DESCALE(z1 + MULTIPLY16(z2, FIX_0_765366865), CONST_BITS-PASS1_BITS);
546 /* Final output stage */
548 wsptr[4*0] = (int) (tmp10 + tmp2);
549 wsptr[4*3] = (int) (tmp10 - tmp2);
550 wsptr[4*1] = (int) (tmp12 + tmp0);
551 wsptr[4*2] = (int) (tmp12 - tmp0);
554 /* Pass 2: process 4 rows from work array, store into output array. */
556 wsptr = workspace;
557 for (ctr = 0; ctr < 4; ctr++)
559 outptr = p_byte + (ctr*skip_line);
560 /* Even part */
562 tmp0 = (int) wsptr[0];
563 tmp2 = (int) wsptr[2];
565 tmp10 = (tmp0 + tmp2) << CONST_BITS;
566 tmp12 = (tmp0 - tmp2) << CONST_BITS;
568 /* Odd part */
569 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
571 z2 = (int) wsptr[1];
572 z3 = (int) wsptr[3];
574 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
575 tmp0 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
576 tmp2 = z1 + MULTIPLY16(z2, FIX_0_765366865);
578 /* Final output stage */
580 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp2,
581 CONST_BITS+PASS1_BITS+3));
582 outptr[3] = range_limit((int) DESCALE(tmp10 - tmp2,
583 CONST_BITS+PASS1_BITS+3));
584 outptr[1] = range_limit((int) DESCALE(tmp12 + tmp0,
585 CONST_BITS+PASS1_BITS+3));
586 outptr[2] = range_limit((int) DESCALE(tmp12 - tmp0,
587 CONST_BITS+PASS1_BITS+3));
589 wsptr += 4; /* advance pointer to next row */
596 * Perform dequantization and inverse DCT on one block of coefficients.
598 void idct8x8(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
600 long tmp0, tmp1, tmp2, tmp3;
601 long tmp10, tmp11, tmp12, tmp13;
602 long z1, z2, z3, z4, z5;
603 int * wsptr;
604 unsigned char* outptr;
605 int ctr;
606 int workspace[64]; /* buffers data between passes */
608 /* Pass 1: process columns from input, store into work array. */
609 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
610 /* furthermore, we scale the results by 2**PASS1_BITS. */
612 wsptr = workspace;
613 for (ctr = 8; ctr > 0; ctr--)
615 /* Due to quantization, we will usually find that many of the input
616 * coefficients are zero, especially the AC terms. We can exploit this
617 * by short-circuiting the IDCT calculation for any column in which all
618 * the AC terms are zero. In that case each output is equal to the
619 * DC coefficient (with scale factor as needed).
620 * With typical images and quantization tables, half or more of the
621 * column DCT calculations can be simplified this way.
624 if ((inptr[8*1] | inptr[8*2] | inptr[8*3]
625 | inptr[8*4] | inptr[8*5] | inptr[8*6] | inptr[8*7]) == 0)
627 /* AC terms all zero */
628 int dcval = DEQUANTIZE(inptr[8*0], quantptr[8*0]) << PASS1_BITS;
630 wsptr[8*0] = wsptr[8*1] = wsptr[8*2] = wsptr[8*3] = wsptr[8*4]
631 = wsptr[8*5] = wsptr[8*6] = wsptr[8*7] = dcval;
632 inptr++; /* advance pointers to next column */
633 quantptr++;
634 wsptr++;
635 continue;
638 /* Even part: reverse the even part of the forward DCT. */
639 /* The rotator is sqrt(2)*c(-6). */
641 z2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
642 z3 = DEQUANTIZE(inptr[8*6], quantptr[8*6]);
644 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
645 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
646 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
648 z2 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
649 z3 = DEQUANTIZE(inptr[8*4], quantptr[8*4]);
651 tmp0 = (z2 + z3) << CONST_BITS;
652 tmp1 = (z2 - z3) << CONST_BITS;
654 tmp10 = tmp0 + tmp3;
655 tmp13 = tmp0 - tmp3;
656 tmp11 = tmp1 + tmp2;
657 tmp12 = tmp1 - tmp2;
659 /* Odd part per figure 8; the matrix is unitary and hence its
660 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
662 tmp0 = DEQUANTIZE(inptr[8*7], quantptr[8*7]);
663 tmp1 = DEQUANTIZE(inptr[8*5], quantptr[8*5]);
664 tmp2 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
665 tmp3 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
667 z1 = tmp0 + tmp3;
668 z2 = tmp1 + tmp2;
669 z3 = tmp0 + tmp2;
670 z4 = tmp1 + tmp3;
671 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
673 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
674 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
675 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
676 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
677 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
678 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
679 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
680 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
682 z3 += z5;
683 z4 += z5;
685 tmp0 += z1 + z3;
686 tmp1 += z2 + z4;
687 tmp2 += z2 + z3;
688 tmp3 += z1 + z4;
690 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
692 wsptr[8*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
693 wsptr[8*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
694 wsptr[8*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
695 wsptr[8*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
696 wsptr[8*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
697 wsptr[8*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
698 wsptr[8*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
699 wsptr[8*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
701 inptr++; /* advance pointers to next column */
702 quantptr++;
703 wsptr++;
706 /* Pass 2: process rows from work array, store into output array. */
707 /* Note that we must descale the results by a factor of 8 == 2**3, */
708 /* and also undo the PASS1_BITS scaling. */
710 wsptr = workspace;
711 for (ctr = 0; ctr < 8; ctr++)
713 outptr = p_byte + (ctr*skip_line);
714 /* Rows of zeroes can be exploited in the same way as we did with columns.
715 * However, the column calculation has created many nonzero AC terms, so
716 * the simplification applies less often (typically 5% to 10% of the time).
717 * On machines with very fast multiplication, it's possible that the
718 * test takes more time than it's worth. In that case this section
719 * may be commented out.
722 #ifndef NO_ZERO_ROW_TEST
723 if ((wsptr[1] | wsptr[2] | wsptr[3]
724 | wsptr[4] | wsptr[5] | wsptr[6] | wsptr[7]) == 0)
726 /* AC terms all zero */
727 unsigned char dcval = range_limit((int) DESCALE((long) wsptr[0],
728 PASS1_BITS+3));
730 outptr[0] = dcval;
731 outptr[1] = dcval;
732 outptr[2] = dcval;
733 outptr[3] = dcval;
734 outptr[4] = dcval;
735 outptr[5] = dcval;
736 outptr[6] = dcval;
737 outptr[7] = dcval;
739 wsptr += 8; /* advance pointer to next row */
740 continue;
742 #endif
744 /* Even part: reverse the even part of the forward DCT. */
745 /* The rotator is sqrt(2)*c(-6). */
747 z2 = (long) wsptr[2];
748 z3 = (long) wsptr[6];
750 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
751 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
752 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
754 tmp0 = ((long) wsptr[0] + (long) wsptr[4]) << CONST_BITS;
755 tmp1 = ((long) wsptr[0] - (long) wsptr[4]) << CONST_BITS;
757 tmp10 = tmp0 + tmp3;
758 tmp13 = tmp0 - tmp3;
759 tmp11 = tmp1 + tmp2;
760 tmp12 = tmp1 - tmp2;
762 /* Odd part per figure 8; the matrix is unitary and hence its
763 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
765 tmp0 = (long) wsptr[7];
766 tmp1 = (long) wsptr[5];
767 tmp2 = (long) wsptr[3];
768 tmp3 = (long) wsptr[1];
770 z1 = tmp0 + tmp3;
771 z2 = tmp1 + tmp2;
772 z3 = tmp0 + tmp2;
773 z4 = tmp1 + tmp3;
774 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
776 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
777 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
778 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
779 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
780 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
781 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
782 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
783 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
785 z3 += z5;
786 z4 += z5;
788 tmp0 += z1 + z3;
789 tmp1 += z2 + z4;
790 tmp2 += z2 + z3;
791 tmp3 += z1 + z4;
793 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
795 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp3,
796 CONST_BITS+PASS1_BITS+3));
797 outptr[7] = range_limit((int) DESCALE(tmp10 - tmp3,
798 CONST_BITS+PASS1_BITS+3));
799 outptr[1] = range_limit((int) DESCALE(tmp11 + tmp2,
800 CONST_BITS+PASS1_BITS+3));
801 outptr[6] = range_limit((int) DESCALE(tmp11 - tmp2,
802 CONST_BITS+PASS1_BITS+3));
803 outptr[2] = range_limit((int) DESCALE(tmp12 + tmp1,
804 CONST_BITS+PASS1_BITS+3));
805 outptr[5] = range_limit((int) DESCALE(tmp12 - tmp1,
806 CONST_BITS+PASS1_BITS+3));
807 outptr[3] = range_limit((int) DESCALE(tmp13 + tmp0,
808 CONST_BITS+PASS1_BITS+3));
809 outptr[4] = range_limit((int) DESCALE(tmp13 - tmp0,
810 CONST_BITS+PASS1_BITS+3));
812 wsptr += 8; /* advance pointer to next row */
818 /* JPEG decoder implementation */
821 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
823 struct derived_tbl
825 /* Basic tables: (element [0] of each array is unused) */
826 long mincode[17]; /* smallest code of length k */
827 long maxcode[18]; /* largest code of length k (-1 if none) */
828 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
829 int valptr[17]; /* huffval[] index of 1st symbol of length k */
831 /* Back link to public Huffman table (needed only in slow_DECODE) */
832 int* pub;
834 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
835 the input data stream. If the next Huffman code is no more
836 than HUFF_LOOKAHEAD bits long, we can obtain its length and
837 the corresponding symbol directly from these tables. */
838 int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
839 unsigned char look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
842 #define QUANT_TABLE_LENGTH 64
844 /* for type of Huffman table */
845 #define DC_LEN 28
846 #define AC_LEN 178
848 struct huffman_table
849 { /* length and code according to JFIF format */
850 int huffmancodes_dc[DC_LEN];
851 int huffmancodes_ac[AC_LEN];
854 struct frame_component
856 int ID;
857 int horizontal_sampling;
858 int vertical_sampling;
859 int quanttable_select;
862 struct scan_component
864 int ID;
865 int DC_select;
866 int AC_select;
869 struct bitstream
871 unsigned long get_buffer; /* current bit-extraction buffer */
872 int bits_left; /* # of unused bits in it */
873 unsigned char* next_input_byte;
874 unsigned char* input_end; /* upper limit +1 */
877 struct jpeg
879 int x_size, y_size; /* size of image (can be less than block boundary) */
880 int x_phys, y_phys; /* physical size, block aligned */
881 int x_mbl; /* x dimension of MBL */
882 int y_mbl; /* y dimension of MBL */
883 int blocks; /* blocks per MB */
884 int restart_interval; /* number of MCUs between RSTm markers */
885 int store_pos[4]; /* for Y block ordering */
887 unsigned char* p_entropy_data;
888 unsigned char* p_entropy_end;
890 int quanttable[4][QUANT_TABLE_LENGTH]; /* raw quantization tables 0-3 */
891 int qt_idct[2][QUANT_TABLE_LENGTH]; /* quantization tables for IDCT */
893 struct huffman_table hufftable[2]; /* Huffman tables */
894 struct derived_tbl dc_derived_tbls[2]; /* Huffman-LUTs */
895 struct derived_tbl ac_derived_tbls[2];
897 struct frame_component frameheader[3]; /* Component descriptor */
898 struct scan_component scanheader[3]; /* currently not used */
900 int mcu_membership[6]; /* info per block */
901 int tab_membership[6];
902 int subsample_x[3]; /* info per component */
903 int subsample_y[3];
907 /* possible return flags for process_markers() */
908 #define HUFFTAB 0x0001 /* with huffman table */
909 #define QUANTTAB 0x0002 /* with quantization table */
910 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
911 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
912 #define SOF0 0x0010 /* with SOF0-Segment */
913 #define DHT 0x0020 /* with Definition of huffman tables */
914 #define SOS 0x0040 /* with Start-of-Scan segment */
915 #define DQT 0x0080 /* with definition of quantization table */
917 /* Preprocess the JPEG JFIF file */
918 int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
920 unsigned char* p_bytes = p_src;
921 int marker_size; /* variable length of marker segment */
922 int i, j, n;
923 int ret = 0; /* returned flags */
925 p_jpeg->p_entropy_end = p_src + size;
927 while (p_src < p_bytes + size)
929 if (*p_src++ != 0xFF) /* no marker? */
931 p_src--; /* it's image data, put it back */
932 p_jpeg->p_entropy_data = p_src;
933 break; /* exit marker processing */
936 switch (*p_src++)
938 case 0xFF: /* Fill byte */
939 ret |= FILL_FF;
940 case 0x00: /* Zero stuffed byte - entropy data */
941 p_src--; /* put it back */
942 continue;
944 case 0xC0: /* SOF Huff - Baseline DCT */
946 ret |= SOF0;
947 marker_size = *p_src++ << 8; /* Highbyte */
948 marker_size |= *p_src++; /* Lowbyte */
949 n = *p_src++; /* sample precision (= 8 or 12) */
950 if (n != 8)
952 return(-1); /* Unsupported sample precision */
954 p_jpeg->y_size = *p_src++ << 8; /* Highbyte */
955 p_jpeg->y_size |= *p_src++; /* Lowbyte */
956 p_jpeg->x_size = *p_src++ << 8; /* Highbyte */
957 p_jpeg->x_size |= *p_src++; /* Lowbyte */
959 n = (marker_size-2-6)/3;
960 if (*p_src++ != n || (n != 1 && n != 3))
962 return(-2); /* Unsupported SOF0 component specification */
964 for (i=0; i<n; i++)
966 p_jpeg->frameheader[i].ID = *p_src++; /* Component info */
967 p_jpeg->frameheader[i].horizontal_sampling = *p_src >> 4;
968 p_jpeg->frameheader[i].vertical_sampling = *p_src++ & 0x0F;
969 p_jpeg->frameheader[i].quanttable_select = *p_src++;
970 if (p_jpeg->frameheader[i].horizontal_sampling > 2
971 || p_jpeg->frameheader[i].vertical_sampling > 2)
972 return -3; /* Unsupported SOF0 subsampling */
974 p_jpeg->blocks = n;
976 break;
978 case 0xC1: /* SOF Huff - Extended sequential DCT*/
979 case 0xC2: /* SOF Huff - Progressive DCT*/
980 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
981 case 0xC5: /* SOF Huff - Differential sequential DCT*/
982 case 0xC6: /* SOF Huff - Differential progressive DCT*/
983 case 0xC7: /* SOF Huff - Differential spatial*/
984 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
985 case 0xC9: /* SOF Arith - Extended sequential DCT*/
986 case 0xCA: /* SOF Arith - Progressive DCT*/
987 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
988 case 0xCD: /* SOF Arith - Differential sequential DCT*/
989 case 0xCE: /* SOF Arith - Differential progressive DCT*/
990 case 0xCF: /* SOF Arith - Differential spatial*/
992 return (-4); /* other DCT model than baseline not implemented */
995 case 0xC4: /* Define Huffman Table(s) */
997 unsigned char* p_temp;
999 ret |= DHT;
1000 marker_size = *p_src++ << 8; /* Highbyte */
1001 marker_size |= *p_src++; /* Lowbyte */
1003 p_temp = p_src;
1004 while (p_src < p_temp+marker_size-2-17) /* another table */
1006 int sum = 0;
1007 i = *p_src & 0x0F; /* table index */
1008 if (i > 1)
1010 return (-5); /* Huffman table index out of range */
1012 else if (*p_src++ & 0xF0) /* AC table */
1014 for (j=0; j<16; j++)
1016 sum += *p_src;
1017 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
1019 if(16 + sum > AC_LEN)
1020 return -10; /* longer than allowed */
1022 for (; j < 16 + sum; j++)
1023 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
1025 else /* DC table */
1027 for (j=0; j<16; j++)
1029 sum += *p_src;
1030 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
1032 if(16 + sum > DC_LEN)
1033 return -11; /* longer than allowed */
1035 for (; j < 16 + sum; j++)
1036 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
1038 } /* while */
1039 p_src = p_temp+marker_size - 2; /* skip possible residue */
1041 break;
1043 case 0xCC: /* Define Arithmetic coding conditioning(s) */
1044 return(-6); /* Arithmetic coding not supported */
1046 case 0xD8: /* Start of Image */
1047 case 0xD9: /* End of Image */
1048 case 0x01: /* for temp private use arith code */
1049 break; /* skip parameterless marker */
1052 case 0xDA: /* Start of Scan */
1054 ret |= SOS;
1055 marker_size = *p_src++ << 8; /* Highbyte */
1056 marker_size |= *p_src++; /* Lowbyte */
1058 n = (marker_size-2-1-3)/2;
1059 if (*p_src++ != n || (n != 1 && n != 3))
1061 return (-7); /* Unsupported SOS component specification */
1063 for (i=0; i<n; i++)
1065 p_jpeg->scanheader[i].ID = *p_src++;
1066 p_jpeg->scanheader[i].DC_select = *p_src >> 4;
1067 p_jpeg->scanheader[i].AC_select = *p_src++ & 0x0F;
1069 p_src += 3; /* skip spectral information */
1071 break;
1073 case 0xDB: /* Define quantization Table(s) */
1075 ret |= DQT;
1076 marker_size = *p_src++ << 8; /* Highbyte */
1077 marker_size |= *p_src++; /* Lowbyte */
1078 n = (marker_size-2)/(QUANT_TABLE_LENGTH+1); /* # of tables */
1079 for (i=0; i<n; i++)
1081 int id = *p_src++; /* ID */
1082 if (id >= 4)
1084 return (-8); /* Unsupported quantization table */
1086 /* Read Quantisation table: */
1087 for (j=0; j<QUANT_TABLE_LENGTH; j++)
1088 p_jpeg->quanttable[id][j] = *p_src++;
1091 break;
1093 case 0xDD: /* Define Restart Interval */
1095 marker_size = *p_src++ << 8; /* Highbyte */
1096 marker_size |= *p_src++; /* Lowbyte */
1097 p_jpeg->restart_interval = *p_src++ << 8; /* Highbyte */
1098 p_jpeg->restart_interval |= *p_src++; /* Lowbyte */
1099 p_src += marker_size-4; /* skip segment */
1101 break;
1103 case 0xDC: /* Define Number of Lines */
1104 case 0xDE: /* Define Hierarchical progression */
1105 case 0xDF: /* Expand Reference Component(s) */
1106 case 0xE0: /* Application Field 0*/
1107 case 0xE1: /* Application Field 1*/
1108 case 0xE2: /* Application Field 2*/
1109 case 0xE3: /* Application Field 3*/
1110 case 0xE4: /* Application Field 4*/
1111 case 0xE5: /* Application Field 5*/
1112 case 0xE6: /* Application Field 6*/
1113 case 0xE7: /* Application Field 7*/
1114 case 0xE8: /* Application Field 8*/
1115 case 0xE9: /* Application Field 9*/
1116 case 0xEA: /* Application Field 10*/
1117 case 0xEB: /* Application Field 11*/
1118 case 0xEC: /* Application Field 12*/
1119 case 0xED: /* Application Field 13*/
1120 case 0xEE: /* Application Field 14*/
1121 case 0xEF: /* Application Field 15*/
1122 case 0xFE: /* Comment */
1124 marker_size = *p_src++ << 8; /* Highbyte */
1125 marker_size |= *p_src++; /* Lowbyte */
1126 p_src += marker_size-2; /* skip segment */
1128 break;
1130 case 0xF0: /* Reserved for JPEG extensions */
1131 case 0xF1: /* Reserved for JPEG extensions */
1132 case 0xF2: /* Reserved for JPEG extensions */
1133 case 0xF3: /* Reserved for JPEG extensions */
1134 case 0xF4: /* Reserved for JPEG extensions */
1135 case 0xF5: /* Reserved for JPEG extensions */
1136 case 0xF6: /* Reserved for JPEG extensions */
1137 case 0xF7: /* Reserved for JPEG extensions */
1138 case 0xF8: /* Reserved for JPEG extensions */
1139 case 0xF9: /* Reserved for JPEG extensions */
1140 case 0xFA: /* Reserved for JPEG extensions */
1141 case 0xFB: /* Reserved for JPEG extensions */
1142 case 0xFC: /* Reserved for JPEG extensions */
1143 case 0xFD: /* Reserved for JPEG extensions */
1144 case 0x02: /* Reserved */
1145 default:
1146 return (-9); /* Unknown marker */
1147 } /* switch */
1148 } /* while */
1150 return (ret); /* return flags with seen markers */
1154 void default_huff_tbl(struct jpeg* p_jpeg)
1156 static const struct huffman_table luma_table =
1159 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
1160 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1163 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
1164 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
1165 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
1166 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
1167 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
1168 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1169 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1170 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
1171 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
1172 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
1173 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1174 0xF9,0xFA
1178 static const struct huffman_table chroma_table =
1181 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
1182 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1185 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
1186 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
1187 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1188 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1189 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1190 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1191 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1192 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1193 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1194 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1195 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1196 0xF9,0xFA
1200 MEMCPY(&p_jpeg->hufftable[0], &luma_table, sizeof(luma_table));
1201 MEMCPY(&p_jpeg->hufftable[1], &chroma_table, sizeof(chroma_table));
1203 return;
1206 /* Compute the derived values for a Huffman table */
1207 void fix_huff_tbl(int* htbl, struct derived_tbl* dtbl)
1209 int p, i, l, si;
1210 int lookbits, ctr;
1211 char huffsize[257];
1212 unsigned int huffcode[257];
1213 unsigned int code;
1215 dtbl->pub = htbl; /* fill in back link */
1217 /* Figure C.1: make table of Huffman code length for each symbol */
1218 /* Note that this is in code-length order. */
1220 p = 0;
1221 for (l = 1; l <= 16; l++)
1222 { /* all possible code length */
1223 for (i = 1; i <= (int) htbl[l-1]; i++) /* all codes per length */
1224 huffsize[p++] = (char) l;
1226 huffsize[p] = 0;
1228 /* Figure C.2: generate the codes themselves */
1229 /* Note that this is in code-length order. */
1231 code = 0;
1232 si = huffsize[0];
1233 p = 0;
1234 while (huffsize[p])
1236 while (((int) huffsize[p]) == si)
1238 huffcode[p++] = code;
1239 code++;
1241 code <<= 1;
1242 si++;
1245 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1247 p = 0;
1248 for (l = 1; l <= 16; l++)
1250 if (htbl[l-1])
1252 dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */
1253 dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */
1254 p += htbl[l-1];
1255 dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
1257 else
1259 dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
1262 dtbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */
1264 /* Compute lookahead tables to speed up decoding.
1265 * First we set all the table entries to 0, indicating "too long";
1266 * then we iterate through the Huffman codes that are short enough and
1267 * fill in all the entries that correspond to bit sequences starting
1268 * with that code.
1271 MEMSET(dtbl->look_nbits, 0, sizeof(dtbl->look_nbits));
1273 p = 0;
1274 for (l = 1; l <= HUFF_LOOKAHEAD; l++)
1276 for (i = 1; i <= (int) htbl[l-1]; i++, p++)
1278 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1279 /* Generate left-justified code followed by all possible bit sequences */
1280 lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
1281 for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--)
1283 dtbl->look_nbits[lookbits] = l;
1284 dtbl->look_sym[lookbits] = htbl[16+p];
1285 lookbits++;
1292 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1293 * If the incoming data is corrupted, decode_mcu could attempt to
1294 * reference values beyond the end of the array. To avoid a wild store,
1295 * we put some extra zeroes after the real entries.
1297 static const int zag[] =
1299 0, 1, 8, 16, 9, 2, 3, 10,
1300 17, 24, 32, 25, 18, 11, 4, 5,
1301 12, 19, 26, 33, 40, 48, 41, 34,
1302 27, 20, 13, 6, 7, 14, 21, 28,
1303 35, 42, 49, 56, 57, 50, 43, 36,
1304 29, 22, 15, 23, 30, 37, 44, 51,
1305 58, 59, 52, 45, 38, 31, 39, 46,
1306 53, 60, 61, 54, 47, 55, 62, 63,
1307 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1308 0, 0, 0, 0, 0, 0, 0, 0
1311 void build_lut(struct jpeg* p_jpeg)
1313 int i;
1314 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_dc,
1315 &p_jpeg->dc_derived_tbls[0]);
1316 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_ac,
1317 &p_jpeg->ac_derived_tbls[0]);
1318 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_dc,
1319 &p_jpeg->dc_derived_tbls[1]);
1320 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_ac,
1321 &p_jpeg->ac_derived_tbls[1]);
1323 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1324 for (i=0; i<64; i++)
1326 p_jpeg->qt_idct[0][zag[i]] = p_jpeg->quanttable[0][i];
1327 p_jpeg->qt_idct[1][zag[i]] = p_jpeg->quanttable[1][i];
1330 for (i=0; i<4; i++)
1331 p_jpeg->store_pos[i] = i; /* default ordering */
1333 /* assignments for the decoding of blocks */
1334 if (p_jpeg->frameheader[0].horizontal_sampling == 2
1335 && p_jpeg->frameheader[0].vertical_sampling == 1)
1336 { /* 4:2:2 */
1337 p_jpeg->blocks = 4;
1338 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1339 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1340 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1341 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1342 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1343 p_jpeg->mcu_membership[1] = 0;
1344 p_jpeg->mcu_membership[2] = 1;
1345 p_jpeg->mcu_membership[3] = 2;
1346 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1347 p_jpeg->tab_membership[1] = 0;
1348 p_jpeg->tab_membership[2] = 1;
1349 p_jpeg->tab_membership[3] = 1;
1350 p_jpeg->subsample_x[0] = 1;
1351 p_jpeg->subsample_x[1] = 2;
1352 p_jpeg->subsample_x[2] = 2;
1353 p_jpeg->subsample_y[0] = 1;
1354 p_jpeg->subsample_y[1] = 1;
1355 p_jpeg->subsample_y[2] = 1;
1357 if (p_jpeg->frameheader[0].horizontal_sampling == 1
1358 && p_jpeg->frameheader[0].vertical_sampling == 2)
1359 { /* 4:2:2 vertically subsampled */
1360 p_jpeg->store_pos[1] = 2; /* block positions are mirrored */
1361 p_jpeg->store_pos[2] = 1;
1362 p_jpeg->blocks = 4;
1363 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1364 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1365 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1366 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1367 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1368 p_jpeg->mcu_membership[1] = 0;
1369 p_jpeg->mcu_membership[2] = 1;
1370 p_jpeg->mcu_membership[3] = 2;
1371 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1372 p_jpeg->tab_membership[1] = 0;
1373 p_jpeg->tab_membership[2] = 1;
1374 p_jpeg->tab_membership[3] = 1;
1375 p_jpeg->subsample_x[0] = 1;
1376 p_jpeg->subsample_x[1] = 1;
1377 p_jpeg->subsample_x[2] = 1;
1378 p_jpeg->subsample_y[0] = 1;
1379 p_jpeg->subsample_y[1] = 2;
1380 p_jpeg->subsample_y[2] = 2;
1382 else if (p_jpeg->frameheader[0].horizontal_sampling == 2
1383 && p_jpeg->frameheader[0].vertical_sampling == 2)
1384 { /* 4:2:0 */
1385 p_jpeg->blocks = 6;
1386 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1387 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1388 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1389 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1390 p_jpeg->mcu_membership[0] = 0;
1391 p_jpeg->mcu_membership[1] = 0;
1392 p_jpeg->mcu_membership[2] = 0;
1393 p_jpeg->mcu_membership[3] = 0;
1394 p_jpeg->mcu_membership[4] = 1;
1395 p_jpeg->mcu_membership[5] = 2;
1396 p_jpeg->tab_membership[0] = 0;
1397 p_jpeg->tab_membership[1] = 0;
1398 p_jpeg->tab_membership[2] = 0;
1399 p_jpeg->tab_membership[3] = 0;
1400 p_jpeg->tab_membership[4] = 1;
1401 p_jpeg->tab_membership[5] = 1;
1402 p_jpeg->subsample_x[0] = 1;
1403 p_jpeg->subsample_x[1] = 2;
1404 p_jpeg->subsample_x[2] = 2;
1405 p_jpeg->subsample_y[0] = 1;
1406 p_jpeg->subsample_y[1] = 2;
1407 p_jpeg->subsample_y[2] = 2;
1409 else if (p_jpeg->frameheader[0].horizontal_sampling == 1
1410 && p_jpeg->frameheader[0].vertical_sampling == 1)
1411 { /* 4:4:4 */
1412 /* don't overwrite p_jpeg->blocks */
1413 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1414 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1415 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1416 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1417 p_jpeg->mcu_membership[0] = 0;
1418 p_jpeg->mcu_membership[1] = 1;
1419 p_jpeg->mcu_membership[2] = 2;
1420 p_jpeg->tab_membership[0] = 0;
1421 p_jpeg->tab_membership[1] = 1;
1422 p_jpeg->tab_membership[2] = 1;
1423 p_jpeg->subsample_x[0] = 1;
1424 p_jpeg->subsample_x[1] = 1;
1425 p_jpeg->subsample_x[2] = 1;
1426 p_jpeg->subsample_y[0] = 1;
1427 p_jpeg->subsample_y[1] = 1;
1428 p_jpeg->subsample_y[2] = 1;
1430 else
1432 /* error */
1439 * These functions/macros provide the in-line portion of bit fetching.
1440 * Use check_bit_buffer to ensure there are N bits in get_buffer
1441 * before using get_bits, peek_bits, or drop_bits.
1442 * check_bit_buffer(state,n,action);
1443 * Ensure there are N bits in get_buffer; if suspend, take action.
1444 * val = get_bits(n);
1445 * Fetch next N bits.
1446 * val = peek_bits(n);
1447 * Fetch next N bits without removing them from the buffer.
1448 * drop_bits(n);
1449 * Discard next N bits.
1450 * The value N should be a simple variable, not an expression, because it
1451 * is evaluated multiple times.
1454 INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
1456 if (pb->bits_left < nbits)
1457 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1458 unsigned char byte;
1460 byte = *pb->next_input_byte++;
1461 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1462 { /* simplification: just skip the (one-byte) marker code */
1463 pb->next_input_byte++;
1465 pb->get_buffer = (pb->get_buffer << 8) | byte;
1467 byte = *pb->next_input_byte++;
1468 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1469 { /* simplification: just skip the (one-byte) marker code */
1470 pb->next_input_byte++;
1472 pb->get_buffer = (pb->get_buffer << 8) | byte;
1474 pb->bits_left += 16;
1478 INLINE int get_bits(struct bitstream* pb, int nbits)
1480 return ((int) (pb->get_buffer >> (pb->bits_left -= nbits))) & ((1<<nbits)-1);
1483 INLINE int peek_bits(struct bitstream* pb, int nbits)
1485 return ((int) (pb->get_buffer >> (pb->bits_left - nbits))) & ((1<<nbits)-1);
1488 INLINE void drop_bits(struct bitstream* pb, int nbits)
1490 pb->bits_left -= nbits;
1493 /* re-synchronize to entropy data (skip restart marker) */
1494 void search_restart(struct bitstream* pb)
1496 pb->next_input_byte--; /* we may have overread it, taking 2 bytes */
1497 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1498 while (pb->next_input_byte < pb->input_end &&
1499 (pb->next_input_byte[-2] != 0xFF || pb->next_input_byte[-1] == 0x00))
1501 pb->next_input_byte++;
1503 pb->bits_left = 0;
1506 /* Figure F.12: extend sign bit. */
1507 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1509 static const int extend_test[16] = /* entry n is 2**(n-1) */
1511 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1512 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1515 static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
1517 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1518 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1519 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1520 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1523 /* Decode a single value */
1524 INLINE int huff_decode_dc(struct bitstream* bs, struct derived_tbl* tbl)
1526 int nb, look, s, r;
1528 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1529 look = peek_bits(bs, HUFF_LOOKAHEAD);
1530 if ((nb = tbl->look_nbits[look]) != 0)
1532 drop_bits(bs, nb);
1533 s = tbl->look_sym[look];
1534 check_bit_buffer(bs, s);
1535 r = get_bits(bs, s);
1536 s = HUFF_EXTEND(r, s);
1538 else
1539 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1540 long code;
1541 nb=HUFF_LOOKAHEAD+1;
1542 check_bit_buffer(bs, nb);
1543 code = get_bits(bs, nb);
1544 while (code > tbl->maxcode[nb])
1546 code <<= 1;
1547 check_bit_buffer(bs, 1);
1548 code |= get_bits(bs, 1);
1549 nb++;
1551 if (nb > 16) /* error in Huffman */
1553 s=0; /* fake a zero, this is most safe */
1555 else
1557 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1558 check_bit_buffer(bs, s);
1559 r = get_bits(bs, s);
1560 s = HUFF_EXTEND(r, s);
1562 } /* end slow decode */
1563 return s;
1566 INLINE int huff_decode_ac(struct bitstream* bs, struct derived_tbl* tbl)
1568 int nb, look, s;
1570 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1571 look = peek_bits(bs, HUFF_LOOKAHEAD);
1572 if ((nb = tbl->look_nbits[look]) != 0)
1574 drop_bits(bs, nb);
1575 s = tbl->look_sym[look];
1577 else
1578 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1579 long code;
1580 nb=HUFF_LOOKAHEAD+1;
1581 check_bit_buffer(bs, nb);
1582 code = get_bits(bs, nb);
1583 while (code > tbl->maxcode[nb])
1585 code <<= 1;
1586 check_bit_buffer(bs, 1);
1587 code |= get_bits(bs, 1);
1588 nb++;
1590 if (nb > 16) /* error in Huffman */
1592 s=0; /* fake a zero, this is most safe */
1594 else
1596 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1598 } /* end slow decode */
1599 return s;
1603 #ifdef HAVE_LCD_COLOR
1605 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1606 /* Note: it keeps the original color subsampling, even if resized. */
1607 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1608 int downscale, void (*pf_progress)(int current, int total))
1610 struct bitstream bs; /* bitstream "object" */
1611 int block[64]; /* decoded DCT coefficients */
1613 int width, height;
1614 int skip_line[3]; /* bytes from one line to the next (skip_line) */
1615 int skip_strip[3], skip_mcu[3]; /* bytes to next DCT row / column */
1617 int i, x, y; /* loop counter */
1619 unsigned char* p_line[3] = {p_pixel[0], p_pixel[1], p_pixel[2]};
1620 unsigned char* p_byte[3]; /* bitmap pointer */
1622 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1623 int k_need; /* AC coefficients needed up to here */
1624 int zero_need; /* init the block with this many zeros */
1626 int last_dc_val[3] = {0, 0, 0}; /* or 128 for chroma? */
1627 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1628 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1630 /* pick the IDCT we want, determine how to work with coefs */
1631 if (downscale == 1)
1633 pf_idct = idct8x8;
1634 k_need = 64; /* all */
1635 zero_need = 63; /* all */
1637 else if (downscale == 2)
1639 pf_idct = idct4x4;
1640 k_need = 25; /* this far in zig-zag to cover 4*4 */
1641 zero_need = 27; /* clear this far in linear order */
1643 else if (downscale == 4)
1645 pf_idct = idct2x2;
1646 k_need = 5; /* this far in zig-zag to cover 2*2 */
1647 zero_need = 9; /* clear this far in linear order */
1649 else if (downscale == 8)
1651 pf_idct = idct1x1;
1652 k_need = 0; /* no AC, not needed */
1653 zero_need = 0; /* no AC, not needed */
1655 else return -1; /* not supported */
1657 /* init bitstream, fake a restart to make it start */
1658 bs.next_input_byte = p_jpeg->p_entropy_data;
1659 bs.bits_left = 0;
1660 bs.input_end = p_jpeg->p_entropy_end;
1662 width = p_jpeg->x_phys / downscale;
1663 height = p_jpeg->y_phys / downscale;
1664 for (i=0; i<3; i++) /* calculate some strides */
1666 skip_line[i] = width / p_jpeg->subsample_x[i];
1667 skip_strip[i] = skip_line[i]
1668 * (height / p_jpeg->y_mbl) / p_jpeg->subsample_y[i];
1669 skip_mcu[i] = width/p_jpeg->x_mbl / p_jpeg->subsample_x[i];
1672 /* prepare offsets about where to store the different blocks */
1673 store_offs[p_jpeg->store_pos[0]] = 0;
1674 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1675 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1676 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1678 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1680 for (i=0; i<3; i++) /* scan line init */
1682 p_byte[i] = p_line[i];
1683 p_line[i] += skip_strip[i];
1685 for (x=0; x<p_jpeg->x_mbl; x++)
1687 int blkn;
1689 /* Outer loop handles each block in the MCU */
1690 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1691 { /* Decode a single block's worth of coefficients */
1692 int k = 1; /* coefficient index */
1693 int s, r; /* huffman values */
1694 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1695 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1696 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1697 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1699 /* Section F.2.2.1: decode the DC coefficient difference */
1700 s = huff_decode_dc(&bs, dctbl);
1702 last_dc_val[ci] += s;
1703 block[0] = last_dc_val[ci]; /* output it (assumes zag[0] = 0) */
1705 /* coefficient buffer must be cleared */
1706 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1708 /* Section F.2.2.2: decode the AC coefficients */
1709 for (; k < k_need; k++)
1711 s = huff_decode_ac(&bs, actbl);
1712 r = s >> 4;
1713 s &= 15;
1715 if (s)
1717 k += r;
1718 check_bit_buffer(&bs, s);
1719 r = get_bits(&bs, s);
1720 block[zag[k]] = HUFF_EXTEND(r, s);
1722 else
1724 if (r != 15)
1726 k = 64;
1727 break;
1729 k += r;
1731 } /* for k */
1732 /* In this path we just discard the values */
1733 for (; k < 64; k++)
1735 s = huff_decode_ac(&bs, actbl);
1736 r = s >> 4;
1737 s &= 15;
1739 if (s)
1741 k += r;
1742 check_bit_buffer(&bs, s);
1743 drop_bits(&bs, s);
1745 else
1747 if (r != 15)
1748 break;
1749 k += r;
1751 } /* for k */
1753 if (ci == 0)
1754 { /* Y component needs to bother about block store */
1755 pf_idct(p_byte[0]+store_offs[blkn], block,
1756 p_jpeg->qt_idct[ti], skip_line[0]);
1758 else
1759 { /* chroma */
1760 pf_idct(p_byte[ci], block, p_jpeg->qt_idct[ti],
1761 skip_line[ci]);
1763 } /* for blkn */
1764 p_byte[0] += skip_mcu[0]; /* unrolled for (i=0; i<3; i++) loop */
1765 p_byte[1] += skip_mcu[1];
1766 p_byte[2] += skip_mcu[2];
1767 if (p_jpeg->restart_interval && --restart == 0)
1768 { /* if a restart marker is due: */
1769 restart = p_jpeg->restart_interval; /* count again */
1770 search_restart(&bs); /* align the bitstream */
1771 last_dc_val[0] = last_dc_val[1] =
1772 last_dc_val[2] = 0; /* reset decoder */
1774 } /* for x */
1775 if (pf_progress != NULL)
1776 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1777 } /* for y */
1779 return 0; /* success */
1781 #else /* !HAVE_LCD_COLOR */
1783 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1784 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[1], int downscale,
1785 void (*pf_progress)(int current, int total))
1787 struct bitstream bs; /* bitstream "object" */
1788 int block[64]; /* decoded DCT coefficients */
1790 int width, height;
1791 int skip_line; /* bytes from one line to the next (skip_line) */
1792 int skip_strip, skip_mcu; /* bytes to next DCT row / column */
1794 int x, y; /* loop counter */
1796 unsigned char* p_line = p_pixel[0];
1797 unsigned char* p_byte; /* bitmap pointer */
1799 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1800 int k_need; /* AC coefficients needed up to here */
1801 int zero_need; /* init the block with this many zeros */
1803 int last_dc_val = 0;
1804 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1805 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1807 /* pick the IDCT we want, determine how to work with coefs */
1808 if (downscale == 1)
1810 pf_idct = idct8x8;
1811 k_need = 64; /* all */
1812 zero_need = 63; /* all */
1814 else if (downscale == 2)
1816 pf_idct = idct4x4;
1817 k_need = 25; /* this far in zig-zag to cover 4*4 */
1818 zero_need = 27; /* clear this far in linear order */
1820 else if (downscale == 4)
1822 pf_idct = idct2x2;
1823 k_need = 5; /* this far in zig-zag to cover 2*2 */
1824 zero_need = 9; /* clear this far in linear order */
1826 else if (downscale == 8)
1828 pf_idct = idct1x1;
1829 k_need = 0; /* no AC, not needed */
1830 zero_need = 0; /* no AC, not needed */
1832 else return -1; /* not supported */
1834 /* init bitstream, fake a restart to make it start */
1835 bs.next_input_byte = p_jpeg->p_entropy_data;
1836 bs.bits_left = 0;
1837 bs.input_end = p_jpeg->p_entropy_end;
1839 width = p_jpeg->x_phys / downscale;
1840 height = p_jpeg->y_phys / downscale;
1841 skip_line = width;
1842 skip_strip = skip_line * (height / p_jpeg->y_mbl);
1843 skip_mcu = (width/p_jpeg->x_mbl);
1845 /* prepare offsets about where to store the different blocks */
1846 store_offs[p_jpeg->store_pos[0]] = 0;
1847 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1848 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1849 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1851 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1853 p_byte = p_line;
1854 p_line += skip_strip;
1855 for (x=0; x<p_jpeg->x_mbl; x++)
1857 int blkn;
1859 /* Outer loop handles each block in the MCU */
1860 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1861 { /* Decode a single block's worth of coefficients */
1862 int k = 1; /* coefficient index */
1863 int s, r; /* huffman values */
1864 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1865 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1866 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1867 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1869 /* Section F.2.2.1: decode the DC coefficient difference */
1870 s = huff_decode_dc(&bs, dctbl);
1872 if (ci == 0) /* only for Y component */
1874 last_dc_val += s;
1875 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
1877 /* coefficient buffer must be cleared */
1878 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1880 /* Section F.2.2.2: decode the AC coefficients */
1881 for (; k < k_need; k++)
1883 s = huff_decode_ac(&bs, actbl);
1884 r = s >> 4;
1885 s &= 15;
1887 if (s)
1889 k += r;
1890 check_bit_buffer(&bs, s);
1891 r = get_bits(&bs, s);
1892 block[zag[k]] = HUFF_EXTEND(r, s);
1894 else
1896 if (r != 15)
1898 k = 64;
1899 break;
1901 k += r;
1903 } /* for k */
1905 /* In this path we just discard the values */
1906 for (; k < 64; k++)
1908 s = huff_decode_ac(&bs, actbl);
1909 r = s >> 4;
1910 s &= 15;
1912 if (s)
1914 k += r;
1915 check_bit_buffer(&bs, s);
1916 drop_bits(&bs, s);
1918 else
1920 if (r != 15)
1921 break;
1922 k += r;
1924 } /* for k */
1926 if (ci == 0)
1927 { /* only for Y component */
1928 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
1929 skip_line);
1931 } /* for blkn */
1932 p_byte += skip_mcu;
1933 if (p_jpeg->restart_interval && --restart == 0)
1934 { /* if a restart marker is due: */
1935 restart = p_jpeg->restart_interval; /* count again */
1936 search_restart(&bs); /* align the bitstream */
1937 last_dc_val = 0; /* reset decoder */
1939 } /* for x */
1940 if (pf_progress != NULL)
1941 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1942 } /* for y */
1944 return 0; /* success */
1946 #endif /* !HAVE_LCD_COLOR */
1948 /**************** end JPEG code ********************/
1952 /**************** begin Application ********************/
1955 /************************* Types ***************************/
1957 struct t_disp
1959 #ifdef HAVE_LCD_COLOR
1960 unsigned char* bitmap[3]; /* Y, Cr, Cb */
1961 int csub_x, csub_y;
1962 #else
1963 unsigned char* bitmap[1]; /* Y only */
1964 #endif
1965 int width;
1966 int height;
1967 int stride;
1968 int x, y;
1971 /************************* Globals ***************************/
1973 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1974 struct t_disp disp[9];
1976 /* my memory pool (from the mp3 buffer) */
1977 char print[32]; /* use a common snprintf() buffer */
1978 unsigned char* buf; /* up to here currently used by image(s) */
1980 /* the remaining free part of the buffer for compressed+uncompressed images */
1981 unsigned char* buf_images;
1983 ssize_t buf_size, buf_images_size;
1984 /* the root of the images, hereafter are decompresed ones */
1985 unsigned char* buf_root;
1986 int root_size;
1988 int ds, ds_min, ds_max; /* downscaling and limits */
1989 static struct jpeg jpg; /* too large for stack */
1991 static struct tree_context *tree;
1993 /* the current full file name */
1994 static char np_file[MAX_PATH];
1995 int curfile = 0, direction = DIR_NONE, entries = 0;
1997 /* list of the jpeg files */
1998 char **file_pt;
1999 /* are we using the plugin buffer or the audio buffer? */
2000 bool plug_buf = false;
2003 /************************* Implementation ***************************/
2005 #ifdef HAVE_LCD_COLOR
2007 * Conversion of full 0-255 range YCrCb to RGB:
2008 * |R| |1.000000 -0.000001 1.402000| |Y'|
2009 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
2010 * |B| |1.000000 1.772000 0.000000| |Pr|
2011 * Scaled (yields s15-bit output):
2012 * |R| |128 0 179| |Y |
2013 * |G| = |128 -43 -91| |Cb - 128|
2014 * |B| |128 227 0| |Cr - 128|
2016 #define YFAC 128
2017 #define RVFAC 179
2018 #define GUFAC (-43)
2019 #define GVFAC (-91)
2020 #define BUFAC 227
2021 #define YUV_WHITE (255*YFAC)
2022 #define NODITHER_DELTA (127*YFAC)
2023 #define COMPONENT_SHIFT 15
2024 #define MATRIX_SHIFT 7
2026 static inline int clamp_component(int x)
2028 if ((unsigned)x > YUV_WHITE)
2029 x = x < 0 ? 0 : YUV_WHITE;
2030 return x;
2033 static inline int clamp_component_bits(int x, int bits)
2035 if ((unsigned)x > (1u << bits) - 1)
2036 x = x < 0 ? 0 : (1 << bits) - 1;
2037 return x;
2040 static inline int component_to_lcd(int x, int bits, int delta)
2042 /* Formula used in core bitmap loader. */
2043 return (((1 << bits) - 1)*x + (x >> (8 - bits)) + delta) >> COMPONENT_SHIFT;
2046 static inline int lcd_to_component(int x, int bits, int delta)
2048 /* Reasonable, approximate reversal to get a full range back from the
2049 quantized value. */
2050 return YUV_WHITE*x / ((1 << bits) - 1);
2051 (void)delta;
2054 #define RED 0
2055 #define GRN 1
2056 #define BLU 2
2058 struct rgb_err
2060 int16_t errbuf[LCD_WIDTH+2]; /* Error record for line below */
2061 } rgb_err_buffers[3];
2063 fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
2064 DITHER_DIFFUSION is set */
2066 struct rgb_pixel
2068 int r, g, b; /* Current pixel components in s16.0 */
2069 int inc; /* Current line increment (-1 or 1) */
2070 int row; /* Current row in source image */
2071 int col; /* Current column in source image */
2072 int ce[3]; /* Errors to apply to current pixel */
2073 struct rgb_err *e; /* RED, GRN, BLU */
2074 int epos; /* Current position in error record */
2077 struct rgb_pixel *pixel;
2079 /** round and truncate to lcd depth **/
2080 static fb_data pixel_to_lcd_colour(void)
2082 struct rgb_pixel *p = pixel;
2083 int r, g, b;
2085 r = component_to_lcd(p->r, LCD_RED_BITS, NODITHER_DELTA);
2086 r = clamp_component_bits(r, LCD_RED_BITS);
2088 g = component_to_lcd(p->g, LCD_GREEN_BITS, NODITHER_DELTA);
2089 g = clamp_component_bits(g, LCD_GREEN_BITS);
2091 b = component_to_lcd(p->b, LCD_BLUE_BITS, NODITHER_DELTA);
2092 b = clamp_component_bits(b, LCD_BLUE_BITS);
2094 return LCD_RGBPACK_LCD(r, g, b);
2097 /** write a monochrome pixel to the colour LCD **/
2098 static fb_data pixel_to_lcd_gray(void)
2100 int r, g, b;
2102 g = clamp_component(pixel->g);
2103 r = component_to_lcd(g, LCD_RED_BITS, NODITHER_DELTA);
2104 b = component_to_lcd(g, LCD_BLUE_BITS, NODITHER_DELTA);
2105 g = component_to_lcd(g, LCD_GREEN_BITS, NODITHER_DELTA);
2107 return LCD_RGBPACK_LCD(r, g, b);
2111 * Bayer ordered dithering - swiped from the core bitmap loader.
2113 static fb_data pixel_odither_to_lcd(void)
2115 /* canonical ordered dither matrix */
2116 static const unsigned char dither_matrix[16][16] = {
2117 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
2118 { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
2119 { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
2120 { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
2121 { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
2122 { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
2123 { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
2124 { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
2125 { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
2126 { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
2127 { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
2128 { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
2129 { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
2130 { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
2131 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
2132 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
2135 struct rgb_pixel *p = pixel;
2136 int r, g, b, delta;
2138 delta = dither_matrix[p->col & 15][p->row & 15] << MATRIX_SHIFT;
2140 r = component_to_lcd(p->r, LCD_RED_BITS, delta);
2141 r = clamp_component_bits(r, LCD_RED_BITS);
2143 g = component_to_lcd(p->g, LCD_GREEN_BITS, delta);
2144 g = clamp_component_bits(g, LCD_GREEN_BITS);
2146 b = component_to_lcd(p->b, LCD_BLUE_BITS, delta);
2147 b = clamp_component_bits(b, LCD_BLUE_BITS);
2149 p->col += p->inc;
2151 return LCD_RGBPACK_LCD(r, g, b);
2155 * Floyd/Steinberg dither to lcd depth.
2157 * Apply filter to each component in serpentine pattern. Kernel shown for
2158 * L->R scan. Kernel is reversed for R->L.
2159 * * 7
2160 * 3 5 1 (1/16)
2162 static inline void distribute_error(int *ce, struct rgb_err *e,
2163 int err, int epos, int inc)
2165 *ce = (7*err >> 4) + e->errbuf[epos+inc];
2166 e->errbuf[epos+inc] = err >> 4;
2167 e->errbuf[epos] += 5*err >> 4;
2168 e->errbuf[epos-inc] += 3*err >> 4;
2171 static fb_data pixel_fsdither_to_lcd(void)
2173 struct rgb_pixel *p = pixel;
2174 int rc, gc, bc, r, g, b;
2175 int inc, epos;
2177 /* Full components with error terms */
2178 rc = p->r + p->ce[RED];
2179 r = component_to_lcd(rc, LCD_RED_BITS, 0);
2180 r = clamp_component_bits(r, LCD_RED_BITS);
2182 gc = p->g + p->ce[GRN];
2183 g = component_to_lcd(gc, LCD_GREEN_BITS, 0);
2184 g = clamp_component_bits(g, LCD_GREEN_BITS);
2186 bc = p->b + p->ce[BLU];
2187 b = component_to_lcd(bc, LCD_BLUE_BITS, 0);
2188 b = clamp_component_bits(b, LCD_BLUE_BITS);
2190 /* Get pixel errors */
2191 rc -= lcd_to_component(r, LCD_RED_BITS, 0);
2192 gc -= lcd_to_component(g, LCD_GREEN_BITS, 0);
2193 bc -= lcd_to_component(b, LCD_BLUE_BITS, 0);
2195 /* Spead error to surrounding pixels. */
2196 inc = p->inc;
2197 epos = p->epos;
2198 p->epos += inc;
2200 distribute_error(&p->ce[RED], &p->e[RED], rc, epos, inc);
2201 distribute_error(&p->ce[GRN], &p->e[GRN], gc, epos, inc);
2202 distribute_error(&p->ce[BLU], &p->e[BLU], bc, epos, inc);
2204 /* Pack and return pixel */
2205 return LCD_RGBPACK_LCD(r, g, b);
2208 /* Functions for each output mode, colour then grayscale. */
2209 static fb_data (* const pixel_funcs[COLOUR_NUM_MODES][DITHER_NUM_MODES])(void) =
2211 [COLOURMODE_COLOUR] =
2213 [DITHER_NONE] = pixel_to_lcd_colour,
2214 [DITHER_ORDERED] = pixel_odither_to_lcd,
2215 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2217 [COLOURMODE_GRAY] =
2219 [DITHER_NONE] = pixel_to_lcd_gray,
2220 [DITHER_ORDERED] = pixel_odither_to_lcd,
2221 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2226 * Draw a partial YUV colour bitmap
2228 * Runs serpentine pattern when dithering is DITHER_DIFFUSION, else scan is
2229 * always L->R.
2231 void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
2232 int src_x, int src_y, int stride,
2233 int x, int y, int width, int height)
2235 fb_data *dst, *dst_end;
2236 fb_data (*pixel_func)(void);
2237 struct rgb_pixel px;
2239 if (x + width > LCD_WIDTH)
2240 width = LCD_WIDTH - x; /* Clip right */
2241 if (x < 0)
2242 width += x, x = 0; /* Clip left */
2243 if (width <= 0)
2244 return; /* nothing left to do */
2246 if (y + height > LCD_HEIGHT)
2247 height = LCD_HEIGHT - y; /* Clip bottom */
2248 if (y < 0)
2249 height += y, y = 0; /* Clip top */
2250 if (height <= 0)
2251 return; /* nothing left to do */
2253 pixel = &px;
2255 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
2256 dst_end = dst + LCD_WIDTH * height;
2258 if (jpeg_settings.colour_mode == COLOURMODE_GRAY)
2259 csub_y = 0; /* Ignore Cb, Cr */
2261 pixel_func = pixel_funcs[jpeg_settings.colour_mode]
2262 [jpeg_settings.dither_mode];
2264 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2266 /* Reset error terms. */
2267 px.e = rgb_err_buffers;
2268 px.ce[RED] = px.ce[GRN] = px.ce[BLU] = 0;
2269 rb->memset(px.e, 0, 3*sizeof (struct rgb_err));
2274 fb_data *dst_row, *row_end;
2275 const unsigned char *ysrc;
2276 px.inc = 1;
2278 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2280 /* Use R->L scan on odd lines */
2281 px.inc -= (src_y & 1) << 1;
2282 px.epos = x + 1;
2284 if (px.inc < 0)
2285 px.epos += width - 1;
2288 if (px.inc == 1)
2290 /* Scan is L->R */
2291 dst_row = dst;
2292 row_end = dst_row + width;
2293 px.col = src_x;
2295 else
2297 /* Scan is R->L */
2298 row_end = dst - 1;
2299 dst_row = row_end + width;
2300 px.col = src_x + width - 1;
2303 ysrc = src[0] + stride * src_y + px.col;
2304 px.row = src_y;
2306 /* Do one row of pixels */
2307 if (csub_y) /* colour */
2309 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
2310 const unsigned char *usrc, *vsrc;
2312 usrc = src[1] + (stride/csub_x) * (src_y/csub_y)
2313 + (px.col/csub_x);
2314 vsrc = src[2] + (stride/csub_x) * (src_y/csub_y)
2315 + (px.col/csub_x);
2316 int xphase = px.col % csub_x;
2317 int xphase_reset = px.inc * csub_x;
2318 int y, v, u, rv, guv, bu;
2320 v = *vsrc - 128;
2321 vsrc += px.inc;
2322 u = *usrc - 128;
2323 usrc += px.inc;
2324 rv = RVFAC*v;
2325 guv = GUFAC*u + GVFAC*v;
2326 bu = BUFAC*u;
2328 while (1)
2330 y = YFAC*(*ysrc);
2331 ysrc += px.inc;
2332 px.r = y + rv;
2333 px.g = y + guv;
2334 px.b = y + bu;
2336 *dst_row = pixel_func();
2337 dst_row += px.inc;
2339 if (dst_row == row_end)
2340 break;
2342 xphase += px.inc;
2343 if ((unsigned)xphase < (unsigned)csub_x)
2344 continue;
2346 /* fetch new chromas */
2347 v = *vsrc - 128;
2348 vsrc += px.inc;
2349 u = *usrc - 128;
2350 usrc += px.inc;
2351 rv = RVFAC*v;
2352 guv = GUFAC*u + GVFAC*v;
2353 bu = BUFAC*u;
2355 xphase -= xphase_reset;
2358 else /* monochrome */
2362 /* Set all components the same for dithering purposes */
2363 px.g = px.r = px.b = YFAC*(*ysrc);
2364 *dst_row = pixel_func();
2365 ysrc += px.inc;
2366 dst_row += px.inc;
2368 while (dst_row != row_end);
2371 src_y++;
2372 dst += LCD_WIDTH;
2374 while (dst < dst_end);
2377 #endif /* HAVE_LCD_COLOR */
2380 /* support function for qsort() */
2381 static int compare(const void* p1, const void* p2)
2383 return rb->strcasecmp(*((char **)p1), *((char **)p2));
2386 bool jpg_ext(const char ext[])
2388 if(!ext)
2389 return false;
2390 if(!rb->strcasecmp(ext,".jpg") ||
2391 !rb->strcasecmp(ext,".jpe") ||
2392 !rb->strcasecmp(ext,".jpeg"))
2393 return true;
2394 else
2395 return false;
2398 /*Read directory contents for scrolling. */
2399 void get_pic_list(void)
2401 int i;
2402 long int str_len = 0;
2403 char *pname;
2404 tree = rb->tree_get_context();
2406 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2407 file_pt = rb->plugin_get_buffer((size_t *)&buf_size);
2408 #else
2409 file_pt = rb->plugin_get_audio_buffer((size_t *)&buf_size);
2410 #endif
2412 for(i = 0; i < tree->filesindir; i++)
2414 if(jpg_ext(rb->strrchr(&tree->name_buffer[str_len],'.')))
2415 file_pt[entries++] = &tree->name_buffer[str_len];
2417 str_len += rb->strlen(&tree->name_buffer[str_len]) + 1;
2420 rb->qsort(file_pt, entries, sizeof(char**), compare);
2422 /* Remove path and leave only the name.*/
2423 pname = rb->strrchr(np_file,'/');
2424 pname++;
2426 /* Find Selected File. */
2427 for(i = 0; i < entries; i++)
2428 if(!rb->strcmp(file_pt[i], pname))
2429 curfile = i;
2432 int change_filename(int direct)
2434 int count = 0;
2435 direction = direct;
2437 if(direct == DIR_PREV)
2441 count++;
2442 if(curfile == 0)
2443 curfile = entries - 1;
2444 else
2445 curfile--;
2446 }while(file_pt[curfile] == '\0' && count < entries);
2447 /* we "erase" the file name if we encounter
2448 * a non-supported file, so skip it now */
2450 else /* DIR_NEXT/DIR_NONE */
2454 count++;
2455 if(curfile == entries - 1)
2456 curfile = 0;
2457 else
2458 curfile++;
2459 }while(file_pt[curfile] == '\0' && count < entries);
2462 if(count == entries && file_pt[curfile] == '\0')
2464 rb->splash(HZ, "No supported files");
2465 return PLUGIN_ERROR;
2467 if(rb->strlen(tree->currdir) > 1)
2469 rb->strcpy(np_file, tree->currdir);
2470 rb->strcat(np_file, "/");
2472 else
2473 rb->strcpy(np_file, tree->currdir);
2475 rb->strcat(np_file, file_pt[curfile]);
2477 return PLUGIN_OTHER;
2480 /* switch off overlay, for handling SYS_ events */
2481 void cleanup(void *parameter)
2483 (void)parameter;
2484 #ifdef USEGSLIB
2485 grey_show(false);
2486 #endif
2489 #define VSCROLL (LCD_HEIGHT/8)
2490 #define HSCROLL (LCD_WIDTH/10)
2492 #define ZOOM_IN 100 /* return codes for below function */
2493 #define ZOOM_OUT 101
2495 #ifdef HAVE_LCD_COLOR
2496 bool set_option_grayscale(void)
2498 bool gray = jpeg_settings.colour_mode == COLOURMODE_GRAY;
2499 rb->set_bool("Grayscale", &gray);
2500 jpeg_settings.colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
2501 return false;
2504 bool set_option_dithering(void)
2506 static const struct opt_items dithering[DITHER_NUM_MODES] = {
2507 [DITHER_NONE] = { "Off", -1 },
2508 [DITHER_ORDERED] = { "Ordered", -1 },
2509 [DITHER_DIFFUSION] = { "Diffusion", -1 },
2512 rb->set_option("Dithering", &jpeg_settings.dither_mode, INT,
2513 dithering, DITHER_NUM_MODES, NULL);
2514 return false;
2517 static void display_options(void)
2519 static const struct menu_item items[] = {
2520 { "Grayscale", set_option_grayscale },
2521 { "Dithering", set_option_dithering },
2524 int m = menu_init(rb, items, ARRAYLEN(items),
2525 NULL, NULL, NULL, NULL);
2526 menu_run(m);
2527 menu_exit(m);
2529 #endif /* HAVE_LCD_COLOR */
2531 int show_menu(void) /* return 1 to quit */
2533 #if LCD_DEPTH > 1
2534 rb->lcd_set_backdrop(old_backdrop);
2535 #ifdef HAVE_LCD_COLOR
2536 rb->lcd_set_foreground(rb->global_settings->fg_color);
2537 rb->lcd_set_background(rb->global_settings->bg_color);
2538 #else
2539 rb->lcd_set_foreground(LCD_BLACK);
2540 rb->lcd_set_background(LCD_WHITE);
2541 #endif
2542 #endif
2543 int m;
2544 int result;
2546 enum menu_id
2548 MIID_QUIT = 0,
2549 MIID_TOGGLE_SS_MODE,
2550 MIID_CHANGE_SS_MODE,
2551 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2552 MIID_SHOW_PLAYBACK_MENU,
2553 #endif
2554 #ifdef HAVE_LCD_COLOR
2555 MIID_DISPLAY_OPTIONS,
2556 #endif
2557 MIID_RETURN,
2560 static const struct menu_item items[] = {
2561 [MIID_QUIT] =
2562 { "Quit", NULL },
2563 [MIID_TOGGLE_SS_MODE] =
2564 { "Toggle Slideshow Mode", NULL },
2565 [MIID_CHANGE_SS_MODE] =
2566 { "Change Slideshow Time", NULL },
2567 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2568 [MIID_SHOW_PLAYBACK_MENU] =
2569 { "Show Playback Menu", NULL },
2570 #endif
2571 #ifdef HAVE_LCD_COLOR
2572 [MIID_DISPLAY_OPTIONS] =
2573 { "Display Options", NULL },
2574 #endif
2575 [MIID_RETURN] =
2576 { "Return", NULL },
2579 static const struct opt_items slideshow[2] = {
2580 { "Disable", -1 },
2581 { "Enable", -1 },
2584 m = menu_init(rb, items, sizeof(items) / sizeof(*items),
2585 NULL, NULL, NULL, NULL);
2586 result=menu_show(m);
2588 switch (result)
2590 case MIID_QUIT:
2591 menu_exit(m);
2592 return 1;
2593 break;
2594 case MIID_TOGGLE_SS_MODE:
2595 rb->set_option("Toggle Slideshow", &slideshow_enabled, INT,
2596 slideshow , 2, NULL);
2597 break;
2598 case MIID_CHANGE_SS_MODE:
2599 rb->set_int("Slideshow Time", "s", UNIT_SEC,
2600 &jpeg_settings.ss_timeout, NULL, 1,
2601 SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, NULL);
2602 break;
2604 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2605 case MIID_SHOW_PLAYBACK_MENU:
2606 if (plug_buf)
2608 playback_control(rb, NULL);
2610 else
2612 rb->splash(HZ, "Cannot restart playback");
2614 break;
2615 #endif
2616 #ifdef HAVE_LCD_COLOR
2617 case MIID_DISPLAY_OPTIONS:
2618 display_options();
2619 break;
2620 #endif
2621 case MIID_RETURN:
2622 break;
2625 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
2626 /* change ata spindown time based on slideshow time setting */
2627 immediate_ata_off = false;
2628 rb->ata_spindown(rb->global_settings->disk_spindown);
2630 if (slideshow_enabled)
2632 if(jpeg_settings.ss_timeout < 10)
2634 /* slideshow times < 10s keep disk spinning */
2635 rb->ata_spindown(0);
2637 else if (!rb->mp3_is_playing())
2639 /* slideshow times > 10s and not playing: ata_off after load */
2640 immediate_ata_off = true;
2643 #endif
2644 #if LCD_DEPTH > 1
2645 rb->lcd_set_backdrop(NULL);
2646 rb->lcd_set_foreground(LCD_WHITE);
2647 rb->lcd_set_background(LCD_BLACK);
2648 #endif
2649 rb->lcd_clear_display();
2650 menu_exit(m);
2651 return 0;
2653 /* interactively scroll around the image */
2654 int scroll_bmp(struct t_disp* pdisp)
2656 int lastbutton = 0;
2658 while (true)
2660 int button;
2661 int move;
2663 if (slideshow_enabled)
2664 button = rb->button_get_w_tmo(jpeg_settings.ss_timeout * HZ);
2665 else button = rb->button_get(true);
2667 running_slideshow = false;
2669 switch(button)
2671 case JPEG_LEFT:
2672 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2673 return change_filename(DIR_PREV);
2674 case JPEG_LEFT | BUTTON_REPEAT:
2675 move = MIN(HSCROLL, pdisp->x);
2676 if (move > 0)
2678 MYXLCD(scroll_right)(move); /* scroll right */
2679 pdisp->x -= move;
2680 #ifdef HAVE_LCD_COLOR
2681 yuv_bitmap_part(
2682 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2683 pdisp->x, pdisp->y, pdisp->stride,
2684 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2685 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2686 #else
2687 MYXLCD(gray_bitmap_part)(
2688 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2689 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2690 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2691 #endif
2692 MYLCD_UPDATE();
2694 break;
2696 case JPEG_RIGHT:
2697 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2698 return change_filename(DIR_NEXT);
2699 case JPEG_RIGHT | BUTTON_REPEAT:
2700 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
2701 if (move > 0)
2703 MYXLCD(scroll_left)(move); /* scroll left */
2704 pdisp->x += move;
2705 #ifdef HAVE_LCD_COLOR
2706 yuv_bitmap_part(
2707 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2708 pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride,
2709 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2710 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2711 #else
2712 MYXLCD(gray_bitmap_part)(
2713 pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move,
2714 pdisp->y, pdisp->stride,
2715 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2716 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2717 #endif
2718 MYLCD_UPDATE();
2720 break;
2722 case JPEG_UP:
2723 case JPEG_UP | BUTTON_REPEAT:
2724 move = MIN(VSCROLL, pdisp->y);
2725 if (move > 0)
2727 MYXLCD(scroll_down)(move); /* scroll down */
2728 pdisp->y -= move;
2729 #ifdef HAVE_LCD_COLOR
2730 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2732 /* Draw over the band at the top of the last update
2733 caused by lack of error history on line zero. */
2734 move = MIN(move + 1, pdisp->y + pdisp->height);
2737 yuv_bitmap_part(
2738 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2739 pdisp->x, pdisp->y, pdisp->stride,
2740 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2741 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2742 #else
2743 MYXLCD(gray_bitmap_part)(
2744 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2745 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2746 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2747 #endif
2748 MYLCD_UPDATE();
2750 break;
2752 case JPEG_DOWN:
2753 case JPEG_DOWN | BUTTON_REPEAT:
2754 move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT);
2755 if (move > 0)
2757 MYXLCD(scroll_up)(move); /* scroll up */
2758 pdisp->y += move;
2759 #ifdef HAVE_LCD_COLOR
2760 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2762 /* Save the line that was on the last line of the display
2763 and draw one extra line above then recover the line with
2764 image data that had an error history when it was drawn.
2766 move++, pdisp->y--;
2767 MEMCPY(rgb_linebuf,
2768 rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2769 LCD_WIDTH*sizeof (fb_data));
2772 yuv_bitmap_part(
2773 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x,
2774 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2775 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2776 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2778 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2780 /* Cover the first row drawn with previous image data. */
2781 MEMCPY(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2782 rgb_linebuf,
2783 LCD_WIDTH*sizeof (fb_data));
2784 pdisp->y++;
2786 #else
2787 MYXLCD(gray_bitmap_part)(
2788 pdisp->bitmap[0], pdisp->x,
2789 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2790 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2791 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2792 #endif
2793 MYLCD_UPDATE();
2795 break;
2796 case BUTTON_NONE:
2797 if (!slideshow_enabled)
2798 break;
2799 running_slideshow = true;
2800 if (entries > 0)
2801 return change_filename(DIR_NEXT);
2802 break;
2804 #ifdef JPEG_SLIDE_SHOW
2805 case JPEG_SLIDE_SHOW:
2806 slideshow_enabled = !slideshow_enabled;
2807 running_slideshow = slideshow_enabled;
2808 break;
2809 #endif
2811 #ifdef JPEG_NEXT_REPEAT
2812 case JPEG_NEXT_REPEAT:
2813 #endif
2814 case JPEG_NEXT:
2815 if (entries > 0)
2816 return change_filename(DIR_NEXT);
2817 break;
2819 #ifdef JPEG_PREVIOUS_REPEAT
2820 case JPEG_PREVIOUS_REPEAT:
2821 #endif
2822 case JPEG_PREVIOUS:
2823 if (entries > 0)
2824 return change_filename(DIR_PREV);
2825 break;
2827 case JPEG_ZOOM_IN:
2828 #ifdef JPEG_ZOOM_PRE
2829 if (lastbutton != JPEG_ZOOM_PRE)
2830 break;
2831 #endif
2832 return ZOOM_IN;
2833 break;
2835 case JPEG_ZOOM_OUT:
2836 #ifdef JPEG_ZOOM_PRE
2837 if (lastbutton != JPEG_ZOOM_PRE)
2838 break;
2839 #endif
2840 return ZOOM_OUT;
2841 break;
2842 #ifdef JPEG_RC_MENU
2843 case JPEG_RC_MENU:
2844 #endif
2845 case JPEG_MENU:
2846 #ifdef USEGSLIB
2847 grey_show(false); /* switch off greyscale overlay */
2848 #endif
2849 if (show_menu() == 1)
2850 return PLUGIN_OK;
2852 #ifdef USEGSLIB
2853 grey_show(true); /* switch on greyscale overlay */
2854 #else
2855 yuv_bitmap_part(
2856 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2857 pdisp->x, pdisp->y, pdisp->stride,
2858 MAX(0, (LCD_WIDTH - pdisp->width) / 2),
2859 MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
2860 MIN(LCD_WIDTH, pdisp->width),
2861 MIN(LCD_HEIGHT, pdisp->height));
2862 MYLCD_UPDATE();
2863 #endif
2864 break;
2865 default:
2866 if (rb->default_event_handler_ex(button, cleanup, NULL)
2867 == SYS_USB_CONNECTED)
2868 return PLUGIN_USB_CONNECTED;
2869 break;
2871 } /* switch */
2873 if (button != BUTTON_NONE)
2874 lastbutton = button;
2875 } /* while (true) */
2878 /********************* main function *************************/
2880 /* callback updating a progress meter while JPEG decoding */
2881 void cb_progess(int current, int total)
2883 rb->yield(); /* be nice to the other threads */
2884 if(!running_slideshow)
2886 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-8, LCD_WIDTH, 8, total, 0,
2887 current, HORIZONTAL);
2888 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
2890 #ifndef USEGSLIB
2891 else
2893 /* in slideshow mode, keep gui interference to a minimum */
2894 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-4, LCD_WIDTH, 4, total, 0,
2895 current, HORIZONTAL);
2896 rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4);
2898 #endif
2901 int jpegmem(struct jpeg *p_jpg, int ds)
2903 int size;
2905 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
2906 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
2907 #ifdef HAVE_LCD_COLOR
2908 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
2910 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
2911 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
2912 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
2913 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
2915 #endif
2916 return size;
2919 /* how far can we zoom in without running out of memory */
2920 int min_downscale(struct jpeg *p_jpg, int bufsize)
2922 int downscale = 8;
2924 if (jpegmem(p_jpg, 8) > bufsize)
2925 return 0; /* error, too large, even 1:8 doesn't fit */
2927 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
2928 downscale /= 2;
2930 return downscale;
2934 /* how far can we zoom out, to fit image into the LCD */
2935 int max_downscale(struct jpeg *p_jpg)
2937 int downscale = 1;
2939 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale
2940 || p_jpg->y_size > LCD_HEIGHT*downscale))
2942 downscale *= 2;
2945 return downscale;
2949 /* return decoded or cached image */
2950 struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2952 int w, h; /* used to center output */
2953 int size; /* decompressed image size */
2954 long time; /* measured ticks */
2955 int status;
2957 struct t_disp* p_disp = &disp[ds]; /* short cut */
2959 if (p_disp->bitmap[0] != NULL)
2961 return p_disp; /* we still have it */
2964 /* assign image buffer */
2966 /* physical size needed for decoding */
2967 size = jpegmem(p_jpg, ds);
2968 if (buf_size <= size)
2969 { /* have to discard the current */
2970 int i;
2971 for (i=1; i<=8; i++)
2972 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
2973 buf = buf_root; /* start again from the beginning of the buffer */
2974 buf_size = root_size;
2977 #ifdef HAVE_LCD_COLOR
2978 if (p_jpg->blocks > 1) /* colour jpeg */
2980 int i;
2982 for (i = 1; i < 3; i++)
2984 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
2985 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
2986 p_disp->bitmap[i] = buf;
2987 buf += size;
2988 buf_size -= size;
2990 p_disp->csub_x = p_jpg->subsample_x[1];
2991 p_disp->csub_y = p_jpg->subsample_y[1];
2993 else
2995 p_disp->csub_x = p_disp->csub_y = 0;
2996 p_disp->bitmap[1] = p_disp->bitmap[2] = buf;
2998 #endif
2999 /* size may be less when decoded (if height is not block aligned) */
3000 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
3001 p_disp->bitmap[0] = buf;
3002 buf += size;
3003 buf_size -= size;
3005 if(!running_slideshow)
3007 rb->snprintf(print, sizeof(print), "decoding %d*%d",
3008 p_jpg->x_size/ds, p_jpg->y_size/ds);
3009 rb->lcd_puts(0, 3, print);
3010 rb->lcd_update();
3013 /* update image properties */
3014 p_disp->width = p_jpg->x_size / ds;
3015 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
3016 p_disp->height = p_jpg->y_size / ds;
3018 /* the actual decoding */
3019 time = *rb->current_tick;
3020 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
3021 rb->cpu_boost(true);
3022 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
3023 rb->cpu_boost(false);
3024 #else
3025 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
3026 #endif
3027 if (status)
3029 rb->splash(HZ, "decode error %d", status);
3030 file_pt[curfile] = '\0';
3031 return NULL;
3033 time = *rb->current_tick - time;
3035 if(!running_slideshow)
3037 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
3038 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
3039 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
3040 rb->lcd_update();
3043 return p_disp;
3047 /* set the view to the given center point, limit if necessary */
3048 void set_view (struct t_disp* p_disp, int cx, int cy)
3050 int x, y;
3052 /* plain center to available width/height */
3053 x = cx - MIN(LCD_WIDTH, p_disp->width) / 2;
3054 y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2;
3056 /* limit against upper image size */
3057 x = MIN(p_disp->width - LCD_WIDTH, x);
3058 y = MIN(p_disp->height - LCD_HEIGHT, y);
3060 /* limit against negative side */
3061 x = MAX(0, x);
3062 y = MAX(0, y);
3064 p_disp->x = x; /* set the values */
3065 p_disp->y = y;
3069 /* calculate the view center based on the bitmap position */
3070 void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
3072 *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2;
3073 *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2;
3077 /* load, decode, display the image */
3078 int load_and_show(char* filename)
3080 int fd;
3081 int filesize;
3082 unsigned char* buf_jpeg; /* compressed JPEG image */
3083 int status;
3084 struct t_disp* p_disp; /* currenly displayed image */
3085 int cx, cy; /* view center */
3087 fd = rb->open(filename, O_RDONLY);
3088 if (fd < 0)
3090 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
3091 rb->splash(HZ, print);
3092 return PLUGIN_ERROR;
3094 filesize = rb->filesize(fd);
3095 rb->memset(&disp, 0, sizeof(disp));
3097 buf = buf_images + filesize;
3098 buf_size = buf_images_size - filesize;
3099 /* allocate JPEG buffer */
3100 buf_jpeg = buf_images;
3102 buf_root = buf; /* we can start the decompressed images behind it */
3103 root_size = buf_size;
3105 if (buf_size <= 0)
3107 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
3108 if(plug_buf)
3110 rb->close(fd);
3111 rb->lcd_setfont(FONT_SYSFIXED);
3112 rb->lcd_clear_display();
3113 rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
3114 rb->lcd_puts(0,0,print);
3115 rb->lcd_puts(0,1,"Not enough plugin memory!");
3116 rb->lcd_puts(0,2,"Zoom In: Stop playback.");
3117 if(entries>1)
3118 rb->lcd_puts(0,3,"Left/Right: Skip File.");
3119 rb->lcd_puts(0,4,"Off: Quit.");
3120 rb->lcd_update();
3121 rb->lcd_setfont(FONT_UI);
3123 rb->button_clear_queue();
3125 while (1)
3127 int button = rb->button_get(true);
3128 switch(button)
3130 case JPEG_ZOOM_IN:
3131 plug_buf = false;
3132 buf_images = rb->plugin_get_audio_buffer(
3133 (size_t *)&buf_images_size);
3134 /*try again this file, now using the audio buffer */
3135 return PLUGIN_OTHER;
3136 #ifdef JPEG_RC_MENU
3137 case JPEG_RC_MENU:
3138 #endif
3139 case JPEG_MENU:
3140 return PLUGIN_OK;
3142 case JPEG_LEFT:
3143 if(entries>1)
3145 rb->lcd_clear_display();
3146 return change_filename(DIR_PREV);
3148 break;
3150 case JPEG_RIGHT:
3151 if(entries>1)
3153 rb->lcd_clear_display();
3154 return change_filename(DIR_NEXT);
3156 break;
3157 default:
3158 if(rb->default_event_handler_ex(button, cleanup, NULL)
3159 == SYS_USB_CONNECTED)
3160 return PLUGIN_USB_CONNECTED;
3165 else
3166 #endif
3168 rb->splash(HZ, "Out of Memory");
3169 rb->close(fd);
3170 return PLUGIN_ERROR;
3174 if(!running_slideshow)
3176 #if LCD_DEPTH > 1
3177 rb->lcd_set_foreground(LCD_WHITE);
3178 rb->lcd_set_background(LCD_BLACK);
3179 rb->lcd_set_backdrop(NULL);
3180 #endif
3182 rb->lcd_clear_display();
3183 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
3184 rb->lcd_puts(0, 0, print);
3185 rb->lcd_update();
3187 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
3188 rb->lcd_puts(0, 1, print);
3189 rb->lcd_update();
3192 rb->read(fd, buf_jpeg, filesize);
3193 rb->close(fd);
3195 if(!running_slideshow)
3197 rb->snprintf(print, sizeof(print), "decoding markers");
3198 rb->lcd_puts(0, 2, print);
3199 rb->lcd_update();
3201 #ifndef SIMULATOR
3202 else if(immediate_ata_off)
3204 /* running slideshow and time is long enough: power down disk */
3205 rb->ata_sleep();
3207 #endif
3209 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
3210 /* process markers, unstuffing */
3211 status = process_markers(buf_jpeg, filesize, &jpg);
3213 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
3214 { /* bad format or minimum components not contained */
3215 rb->splash(HZ, "unsupported %d", status);
3216 file_pt[curfile] = '\0';
3217 return change_filename(direction);
3220 if (!(status & DHT)) /* if no Huffman table present: */
3221 default_huff_tbl(&jpg); /* use default */
3222 build_lut(&jpg); /* derive Huffman and other lookup-tables */
3224 if(!running_slideshow)
3226 rb->snprintf(print, sizeof(print), "image %dx%d", jpg.x_size, jpg.y_size);
3227 rb->lcd_puts(0, 2, print);
3228 rb->lcd_update();
3230 ds_max = max_downscale(&jpg); /* check display constraint */
3231 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */
3232 if (ds_min == 0)
3234 rb->splash(HZ, "too large");
3235 file_pt[curfile] = '\0';
3236 return change_filename(direction);
3239 ds = ds_max; /* initials setting */
3240 cx = jpg.x_size/ds/2; /* center the view */
3241 cy = jpg.y_size/ds/2;
3243 do /* loop the image prepare and decoding when zoomed */
3245 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */
3246 if (p_disp == NULL)
3247 return change_filename(direction);
3249 set_view(p_disp, cx, cy);
3251 if(!running_slideshow)
3253 rb->snprintf(print, sizeof(print), "showing %dx%d",
3254 p_disp->width, p_disp->height);
3255 rb->lcd_puts(0, 3, print);
3256 rb->lcd_update();
3258 MYLCD(clear_display)();
3259 #ifdef HAVE_LCD_COLOR
3260 yuv_bitmap_part(
3261 p_disp->bitmap, p_disp->csub_x, p_disp->csub_y,
3262 p_disp->x, p_disp->y, p_disp->stride,
3263 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3264 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3265 MIN(LCD_WIDTH, p_disp->width),
3266 MIN(LCD_HEIGHT, p_disp->height));
3267 #else
3268 MYXLCD(gray_bitmap_part)(
3269 p_disp->bitmap[0], p_disp->x, p_disp->y, p_disp->stride,
3270 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3271 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3272 MIN(LCD_WIDTH, p_disp->width),
3273 MIN(LCD_HEIGHT, p_disp->height));
3274 #endif
3275 MYLCD_UPDATE();
3277 #ifdef USEGSLIB
3278 grey_show(true); /* switch on greyscale overlay */
3279 #endif
3281 /* drawing is now finished, play around with scrolling
3282 * until you press OFF or connect USB
3284 while (1)
3286 status = scroll_bmp(p_disp);
3287 if (status == ZOOM_IN)
3289 if (ds > ds_min)
3291 ds /= 2; /* reduce downscaling to zoom in */
3292 get_view(p_disp, &cx, &cy);
3293 cx *= 2; /* prepare the position in the new image */
3294 cy *= 2;
3296 else
3297 continue;
3300 if (status == ZOOM_OUT)
3302 if (ds < ds_max)
3304 ds *= 2; /* increase downscaling to zoom out */
3305 get_view(p_disp, &cx, &cy);
3306 cx /= 2; /* prepare the position in the new image */
3307 cy /= 2;
3309 else
3310 continue;
3312 break;
3315 #ifdef USEGSLIB
3316 grey_show(false); /* switch off overlay */
3317 #endif
3318 rb->lcd_clear_display();
3320 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
3321 && status != PLUGIN_OTHER);
3322 #ifdef USEGSLIB
3323 rb->lcd_update();
3324 #endif
3325 return status;
3328 /******************** Plugin entry point *********************/
3330 enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
3332 rb = api;
3334 int condition;
3335 #ifdef USEGSLIB
3336 long greysize; /* helper */
3337 #endif
3338 #if LCD_DEPTH > 1
3339 old_backdrop = rb->lcd_get_backdrop();
3340 #endif
3342 if(!parameter) return PLUGIN_ERROR;
3344 rb->strcpy(np_file, parameter);
3345 get_pic_list();
3347 if(!entries) return PLUGIN_ERROR;
3349 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
3350 if(rb->audio_status())
3352 buf = rb->plugin_get_buffer((size_t *)&buf_size) +
3353 (entries * sizeof(char**));
3354 buf_size -= (entries * sizeof(char**));
3355 plug_buf = true;
3357 else
3358 buf = rb->plugin_get_audio_buffer((size_t *)&buf_size);
3359 #else
3360 buf = rb->plugin_get_audio_buffer(&buf_size) +
3361 (entries * sizeof(char**));
3362 buf_size -= (entries * sizeof(char**));
3363 #endif
3365 #ifdef USEGSLIB
3366 if (!grey_init(rb, buf, buf_size, GREY_ON_COP,
3367 LCD_WIDTH, LCD_HEIGHT, &greysize))
3369 rb->splash(HZ, "grey buf error");
3370 return PLUGIN_ERROR;
3372 buf += greysize;
3373 buf_size -= greysize;
3374 #else
3375 xlcd_init(rb);
3376 #endif
3378 /* should be ok to just load settings since a parameter is present
3379 here and the drive should be spinning */
3380 configfile_init(rb);
3381 configfile_load(JPEG_CONFIGFILE, jpeg_config,
3382 ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION);
3383 old_settings = jpeg_settings;
3385 buf_images = buf; buf_images_size = buf_size;
3387 /* Turn off backlight timeout */
3388 backlight_force_on(rb); /* backlight control in lib/helper.c */
3392 condition = load_and_show(np_file);
3393 }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
3394 && condition != PLUGIN_ERROR);
3396 if (rb->memcmp(&jpeg_settings, &old_settings, sizeof (jpeg_settings)))
3398 /* Just in case drive has to spin, keep it from looking locked */
3399 rb->splash(0, "Saving Settings");
3400 configfile_save(JPEG_CONFIGFILE, jpeg_config,
3401 ARRAYLEN(jpeg_config), JPEG_SETTINGS_VERSION);
3404 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
3405 /* set back ata spindown time in case we changed it */
3406 rb->ata_spindown(rb->global_settings->disk_spindown);
3407 #endif
3409 /* Turn on backlight timeout (revert to settings) */
3410 backlight_use_settings(rb); /* backlight control in lib/helper.c */
3412 #ifdef USEGSLIB
3413 grey_release(); /* deinitialize */
3414 #endif
3416 return condition;
3419 #endif /* HAVE_LCD_BITMAP */