D2: Enable plugin building (using initial keymaps from FS#8708 by Andreas Mueller...
[kugel-rb.git] / apps / plugins / jpeg.c
blobe2c1b4861bc86fad3804bc040432a8977b02a985
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * JPEG image viewer
11 * (This is a real mess if it has to be coded in one single C file)
13 * File scrolling addition (C) 2005 Alexander Spyridakis
14 * Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon
15 * Heavily borrowed from the IJG implementation (C) Thomas G. Lane
16 * Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
18 * All files in this archive are subject to the GNU General Public License.
19 * See the file COPYING in the source tree root for full license agreement.
21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22 * KIND, either express or implied.
24 ****************************************************************************/
26 #include "plugin.h"
27 #include "playback_control.h"
28 #include "oldmenuapi.h"
29 #include "helper.h"
30 #include "lib/configfile.h"
32 #ifdef HAVE_LCD_BITMAP
33 #include "grey.h"
34 #include "xlcd.h"
36 PLUGIN_HEADER
38 /* variable button definitions */
39 #if CONFIG_KEYPAD == RECORDER_PAD
40 #define JPEG_ZOOM_IN BUTTON_PLAY
41 #define JPEG_ZOOM_OUT BUTTON_ON
42 #define JPEG_UP BUTTON_UP
43 #define JPEG_DOWN BUTTON_DOWN
44 #define JPEG_LEFT BUTTON_LEFT
45 #define JPEG_RIGHT BUTTON_RIGHT
46 #define JPEG_NEXT BUTTON_F3
47 #define JPEG_PREVIOUS BUTTON_F2
48 #define JPEG_MENU BUTTON_OFF
50 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
51 #define JPEG_ZOOM_IN BUTTON_SELECT
52 #define JPEG_ZOOM_OUT BUTTON_ON
53 #define JPEG_UP BUTTON_UP
54 #define JPEG_DOWN BUTTON_DOWN
55 #define JPEG_LEFT BUTTON_LEFT
56 #define JPEG_RIGHT BUTTON_RIGHT
57 #define JPEG_NEXT BUTTON_F3
58 #define JPEG_PREVIOUS BUTTON_F2
59 #define JPEG_MENU BUTTON_OFF
61 #elif CONFIG_KEYPAD == ONDIO_PAD
62 #define JPEG_ZOOM_PRE BUTTON_MENU
63 #define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
64 #define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
65 #define JPEG_UP BUTTON_UP
66 #define JPEG_DOWN BUTTON_DOWN
67 #define JPEG_LEFT BUTTON_LEFT
68 #define JPEG_RIGHT BUTTON_RIGHT
69 #define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
70 #define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
71 #define JPEG_MENU BUTTON_OFF
73 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
74 (CONFIG_KEYPAD == IRIVER_H300_PAD)
75 #define JPEG_ZOOM_IN BUTTON_SELECT
76 #define JPEG_ZOOM_OUT BUTTON_MODE
77 #define JPEG_UP BUTTON_UP
78 #define JPEG_DOWN BUTTON_DOWN
79 #define JPEG_LEFT BUTTON_LEFT
80 #define JPEG_RIGHT BUTTON_RIGHT
81 #if (CONFIG_KEYPAD == IRIVER_H100_PAD)
82 #define JPEG_NEXT BUTTON_ON
83 #define JPEG_PREVIOUS BUTTON_REC
84 #else
85 #define JPEG_NEXT BUTTON_REC
86 #define JPEG_PREVIOUS BUTTON_ON
87 #endif
88 #define JPEG_MENU BUTTON_OFF
89 #define JPEG_RC_MENU BUTTON_RC_STOP
91 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
92 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
93 #define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
94 #define JPEG_ZOOM_OUT BUTTON_SCROLL_BACK
95 #define JPEG_UP BUTTON_MENU
96 #define JPEG_DOWN BUTTON_PLAY
97 #define JPEG_LEFT BUTTON_LEFT
98 #define JPEG_RIGHT BUTTON_RIGHT
99 #define JPEG_MENU (BUTTON_SELECT | BUTTON_MENU)
100 #define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
101 #define JPEG_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
103 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
104 #define JPEG_ZOOM_PRE BUTTON_SELECT
105 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
106 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
107 #define JPEG_UP BUTTON_UP
108 #define JPEG_DOWN BUTTON_DOWN
109 #define JPEG_LEFT BUTTON_LEFT
110 #define JPEG_RIGHT BUTTON_RIGHT
111 #define JPEG_MENU BUTTON_POWER
112 #define JPEG_NEXT BUTTON_PLAY
113 #define JPEG_PREVIOUS BUTTON_REC
115 #elif CONFIG_KEYPAD == GIGABEAT_PAD
116 #define JPEG_ZOOM_IN BUTTON_VOL_UP
117 #define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
118 #define JPEG_UP BUTTON_UP
119 #define JPEG_DOWN BUTTON_DOWN
120 #define JPEG_LEFT BUTTON_LEFT
121 #define JPEG_RIGHT BUTTON_RIGHT
122 #define JPEG_MENU BUTTON_MENU
123 #define JPEG_NEXT (BUTTON_A | BUTTON_RIGHT)
124 #define JPEG_PREVIOUS (BUTTON_A | BUTTON_LEFT)
126 #elif CONFIG_KEYPAD == SANSA_E200_PAD
127 #define JPEG_ZOOM_PRE BUTTON_SELECT
128 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
129 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
130 #define JPEG_UP BUTTON_UP
131 #define JPEG_DOWN BUTTON_DOWN
132 #define JPEG_LEFT BUTTON_LEFT
133 #define JPEG_RIGHT BUTTON_RIGHT
134 #define JPEG_MENU BUTTON_POWER
135 #define JPEG_SLIDE_SHOW BUTTON_REC
136 #define JPEG_NEXT BUTTON_SCROLL_FWD
137 #define JPEG_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
138 #define JPEG_PREVIOUS BUTTON_SCROLL_BACK
139 #define JPEG_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
141 #elif CONFIG_KEYPAD == SANSA_C200_PAD
142 #define JPEG_ZOOM_PRE BUTTON_SELECT
143 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
144 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
145 #define JPEG_UP BUTTON_UP
146 #define JPEG_DOWN BUTTON_DOWN
147 #define JPEG_LEFT BUTTON_LEFT
148 #define JPEG_RIGHT BUTTON_RIGHT
149 #define JPEG_MENU BUTTON_POWER
150 #define JPEG_SLIDE_SHOW BUTTON_REC
151 #define JPEG_NEXT BUTTON_VOL_UP
152 #define JPEG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
153 #define JPEG_PREVIOUS BUTTON_VOL_DOWN
154 #define JPEG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
156 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
157 #define JPEG_ZOOM_PRE BUTTON_PLAY
158 #define JPEG_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
159 #define JPEG_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
160 #define JPEG_UP BUTTON_SCROLL_UP
161 #define JPEG_DOWN BUTTON_SCROLL_DOWN
162 #define JPEG_LEFT BUTTON_LEFT
163 #define JPEG_RIGHT BUTTON_RIGHT
164 #define JPEG_MENU BUTTON_POWER
165 #define JPEG_NEXT BUTTON_FF
166 #define JPEG_PREVIOUS BUTTON_REW
168 #elif CONFIG_KEYPAD == MROBE500_PAD
169 #define JPEG_ZOOM_IN BUTTON_RC_VOL_UP
170 #define JPEG_ZOOM_OUT BUTTON_RC_VOL_DOWN
171 #define JPEG_UP BUTTON_RC_PLAY
172 #define JPEG_DOWN BUTTON_RC_DOWN
173 #define JPEG_LEFT BUTTON_LEFT
174 #define JPEG_RIGHT BUTTON_RIGHT
175 #define JPEG_MENU BUTTON_POWER
176 #define JPEG_NEXT BUTTON_RC_HEART
177 #define JPEG_PREVIOUS BUTTON_RC_MODE
179 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
180 #define JPEG_ZOOM_IN BUTTON_VOL_UP
181 #define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
182 #define JPEG_UP BUTTON_UP
183 #define JPEG_DOWN BUTTON_DOWN
184 #define JPEG_LEFT BUTTON_LEFT
185 #define JPEG_RIGHT BUTTON_RIGHT
186 #define JPEG_MENU BUTTON_MENU
187 #define JPEG_NEXT BUTTON_NEXT
188 #define JPEG_PREVIOUS BUTTON_PREV
190 #elif CONFIG_KEYPAD == MROBE100_PAD
191 #define JPEG_ZOOM_IN BUTTON_SELECT
192 #define JPEG_ZOOM_OUT BUTTON_PLAY
193 #define JPEG_UP BUTTON_UP
194 #define JPEG_DOWN BUTTON_DOWN
195 #define JPEG_LEFT BUTTON_LEFT
196 #define JPEG_RIGHT BUTTON_RIGHT
197 #define JPEG_MENU BUTTON_MENU
198 #define JPEG_NEXT (BUTTON_DISPLAY | BUTTON_RIGHT)
199 #define JPEG_PREVIOUS (BUTTON_DISPLAY | BUTTON_LEFT)
201 #elif CONFIG_KEYPAD == COWOND2_PAD
202 #define JPEG_ZOOM_IN BUTTON_PLUS
203 #define JPEG_ZOOM_OUT BUTTON_MINUS
204 #define JPEG_UP BUTTON_UP
205 #define JPEG_DOWN BUTTON_DOWN
206 #define JPEG_LEFT BUTTON_LEFT
207 #define JPEG_RIGHT BUTTON_RIGHT
208 #define JPEG_MENU BUTTON_MENU
209 #define JPEG_NEXT (BUTTON_SELECT|BUTTON_PLUS)
210 #define JPEG_PREVIOUS (BUTTON_SELECT|BUTTON_MINUS)
212 #else
213 #error No keymap defined!
214 #endif
216 /* different graphics libraries */
217 #if LCD_DEPTH < 8
218 #define USEGSLIB
219 GREY_INFO_STRUCT
220 #define MYLCD(fn) grey_ub_ ## fn
221 #define MYLCD_UPDATE()
222 #define MYXLCD(fn) grey_ub_ ## fn
223 #else
224 #define MYLCD(fn) rb->lcd_ ## fn
225 #define MYLCD_UPDATE() rb->lcd_update();
226 #define MYXLCD(fn) xlcd_ ## fn
227 #endif
229 #define MAX_X_SIZE LCD_WIDTH*8
231 /* Min memory allowing us to use the plugin buffer
232 * and thus not stopping the music
233 * *Very* rough estimation:
234 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
235 * + 20k code size = 60 000
236 * + 50k min for jpeg = 120 000
238 #define MIN_MEM 120000
240 /* Headings */
241 #define DIR_PREV 1
242 #define DIR_NEXT -1
243 #define DIR_NONE 0
245 #define PLUGIN_OTHER 10 /* State code for output with return. */
247 /******************************* Globals ***********************************/
249 static struct plugin_api* rb;
250 MEM_FUNCTION_WRAPPERS(rb);
252 /* for portability of below JPEG code */
253 #define MEMSET(p,v,c) rb->memset(p,v,c)
254 #define MEMCPY(d,s,c) rb->memcpy(d,s,c)
255 #define INLINE static inline
256 #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
258 static int slideshow_enabled = false; /* run slideshow */
259 static int running_slideshow = false; /* loading image because of slideshw */
260 #ifndef SIMULATOR
261 static int immediate_ata_off = false; /* power down disk after loading */
262 #endif
264 /* Persistent configuration */
265 #define JPEG_CONFIGFILE "jpeg.cfg"
266 #define JPEG_SETTINGS_MINVERSION 1
267 #define JPEG_SETTINGS_VERSION 2
269 /* Slideshow times */
270 #define SS_MIN_TIMEOUT 1
271 #define SS_MAX_TIMEOUT 20
272 #define SS_DEFAULT_TIMEOUT 5
274 enum color_modes
276 COLOURMODE_COLOUR = 0,
277 COLOURMODE_GRAY,
278 COLOUR_NUM_MODES
281 enum dither_modes
283 DITHER_NONE = 0, /* No dithering */
284 DITHER_ORDERED, /* Bayer ordered */
285 DITHER_DIFFUSION, /* Floyd/Steinberg error diffusion */
286 DITHER_NUM_MODES
289 struct jpeg_settings
291 int colour_mode;
292 int dither_mode;
293 int ss_timeout;
296 static struct jpeg_settings jpeg_settings =
297 { COLOURMODE_COLOUR, DITHER_NONE, SS_DEFAULT_TIMEOUT };
298 static struct jpeg_settings old_settings;
300 static struct configdata jpeg_config[] =
302 #ifdef HAVE_LCD_COLOR
303 { TYPE_ENUM, 0, COLOUR_NUM_MODES, &jpeg_settings.colour_mode,
304 "Colour Mode", (char *[]){ "Colour", "Grayscale" }, NULL },
305 { TYPE_ENUM, 0, DITHER_NUM_MODES, &jpeg_settings.dither_mode,
306 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" }, NULL },
307 #endif
308 { TYPE_INT, SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, &jpeg_settings.ss_timeout,
309 "Slideshow Time", NULL, NULL},
312 #if LCD_DEPTH > 1
313 fb_data* old_backdrop;
314 #endif
316 /**************** begin JPEG code ********************/
318 INLINE unsigned range_limit(int value)
320 #if CONFIG_CPU == SH7034
321 unsigned tmp;
322 asm ( /* Note: Uses knowledge that only low byte of result is used */
323 "mov #-128,%[t] \n"
324 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
325 "extu.b %[v],%[t] \n"
326 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
327 "bt 1f \n" /* yes: no overflow */
328 "cmp/pz %[v] \n" /* overflow: positive? */
329 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
330 "1: \n"
331 : /* outputs */
332 [v]"+r"(value),
333 [t]"=&r"(tmp)
335 return value;
336 #elif defined(CPU_COLDFIRE)
337 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
338 "add.l #128,%[v] \n" /* value += 128; */
339 "cmp.l #255,%[v] \n" /* overflow? */
340 "bls.b 1f \n" /* no: return value */
341 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
342 "1: \n"
343 : /* outputs */
344 [v]"+d"(value)
346 return value;
347 #elif defined(CPU_ARM)
348 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
349 "add %[v], %[v], #128 \n" /* value += 128 */
350 "cmp %[v], #255 \n" /* out of range 0..255? */
351 "mvnhi %[v], %[v], asr #31 \n" /* yes: set all bits to ~(sign_bit) */
352 : /* outputs */
353 [v]"+r"(value)
355 return value;
356 #else
357 value += 128;
359 if ((unsigned)value <= 255)
360 return value;
362 if (value < 0)
363 return 0;
365 return 255;
366 #endif
369 /* IDCT implementation */
372 #define CONST_BITS 13
373 #define PASS1_BITS 2
376 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
377 * causing a lot of useless floating-point operations at run time.
378 * To get around this we use the following pre-calculated constants.
379 * If you change CONST_BITS you may want to add appropriate values.
380 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
382 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
383 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
384 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
385 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
386 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
387 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
388 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
389 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
390 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
391 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
392 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
393 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
397 /* Multiply an long variable by an long constant to yield an long result.
398 * For 8-bit samples with the recommended scaling, all the variable
399 * and constant values involved are no more than 16 bits wide, so a
400 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
401 * For 12-bit samples, a full 32-bit multiplication will be needed.
403 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
406 /* Dequantize a coefficient by multiplying it by the multiplier-table
407 * entry; produce an int result. In this module, both inputs and result
408 * are 16 bits or less, so either int or short multiply will work.
410 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
411 #define DEQUANTIZE MULTIPLY16
413 /* Descale and correctly round an int value that's scaled by N bits.
414 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
415 * the fudge factor is correct for either sign of X.
417 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
422 * Perform dequantization and inverse DCT on one block of coefficients,
423 * producing a reduced-size 1x1 output block.
425 void idct1x1(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
427 (void)skip_line; /* unused */
428 *p_byte = range_limit(inptr[0] * quantptr[0] >> 3);
434 * Perform dequantization and inverse DCT on one block of coefficients,
435 * producing a reduced-size 2x2 output block.
437 void idct2x2(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
439 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
440 unsigned char* outptr;
442 /* Pass 1: process columns from input, store into work array. */
444 /* Column 0 */
445 tmp4 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
446 tmp5 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
448 tmp0 = tmp4 + tmp5;
449 tmp2 = tmp4 - tmp5;
451 /* Column 1 */
452 tmp4 = DEQUANTIZE(inptr[8*0+1], quantptr[8*0+1]);
453 tmp5 = DEQUANTIZE(inptr[8*1+1], quantptr[8*1+1]);
455 tmp1 = tmp4 + tmp5;
456 tmp3 = tmp4 - tmp5;
458 /* Pass 2: process 2 rows, store into output array. */
460 /* Row 0 */
461 outptr = p_byte;
463 outptr[0] = range_limit((int) DESCALE(tmp0 + tmp1, 3));
464 outptr[1] = range_limit((int) DESCALE(tmp0 - tmp1, 3));
466 /* Row 1 */
467 outptr = p_byte + skip_line;
469 outptr[0] = range_limit((int) DESCALE(tmp2 + tmp3, 3));
470 outptr[1] = range_limit((int) DESCALE(tmp2 - tmp3, 3));
476 * Perform dequantization and inverse DCT on one block of coefficients,
477 * producing a reduced-size 4x4 output block.
479 void idct4x4(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
481 int tmp0, tmp2, tmp10, tmp12;
482 int z1, z2, z3;
483 int * wsptr;
484 unsigned char* outptr;
485 int ctr;
486 int workspace[4*4]; /* buffers data between passes */
488 /* Pass 1: process columns from input, store into work array. */
490 wsptr = workspace;
491 for (ctr = 0; ctr < 4; ctr++, inptr++, quantptr++, wsptr++)
493 /* Even part */
495 tmp0 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
496 tmp2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
498 tmp10 = (tmp0 + tmp2) << PASS1_BITS;
499 tmp12 = (tmp0 - tmp2) << PASS1_BITS;
501 /* Odd part */
502 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
504 z2 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
505 z3 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
507 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
508 tmp0 = DESCALE(z1 + MULTIPLY16(z3, - FIX_1_847759065), CONST_BITS-PASS1_BITS);
509 tmp2 = DESCALE(z1 + MULTIPLY16(z2, FIX_0_765366865), CONST_BITS-PASS1_BITS);
511 /* Final output stage */
513 wsptr[4*0] = (int) (tmp10 + tmp2);
514 wsptr[4*3] = (int) (tmp10 - tmp2);
515 wsptr[4*1] = (int) (tmp12 + tmp0);
516 wsptr[4*2] = (int) (tmp12 - tmp0);
519 /* Pass 2: process 4 rows from work array, store into output array. */
521 wsptr = workspace;
522 for (ctr = 0; ctr < 4; ctr++)
524 outptr = p_byte + (ctr*skip_line);
525 /* Even part */
527 tmp0 = (int) wsptr[0];
528 tmp2 = (int) wsptr[2];
530 tmp10 = (tmp0 + tmp2) << CONST_BITS;
531 tmp12 = (tmp0 - tmp2) << CONST_BITS;
533 /* Odd part */
534 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
536 z2 = (int) wsptr[1];
537 z3 = (int) wsptr[3];
539 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
540 tmp0 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
541 tmp2 = z1 + MULTIPLY16(z2, FIX_0_765366865);
543 /* Final output stage */
545 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp2,
546 CONST_BITS+PASS1_BITS+3));
547 outptr[3] = range_limit((int) DESCALE(tmp10 - tmp2,
548 CONST_BITS+PASS1_BITS+3));
549 outptr[1] = range_limit((int) DESCALE(tmp12 + tmp0,
550 CONST_BITS+PASS1_BITS+3));
551 outptr[2] = range_limit((int) DESCALE(tmp12 - tmp0,
552 CONST_BITS+PASS1_BITS+3));
554 wsptr += 4; /* advance pointer to next row */
561 * Perform dequantization and inverse DCT on one block of coefficients.
563 void idct8x8(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
565 long tmp0, tmp1, tmp2, tmp3;
566 long tmp10, tmp11, tmp12, tmp13;
567 long z1, z2, z3, z4, z5;
568 int * wsptr;
569 unsigned char* outptr;
570 int ctr;
571 int workspace[64]; /* buffers data between passes */
573 /* Pass 1: process columns from input, store into work array. */
574 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
575 /* furthermore, we scale the results by 2**PASS1_BITS. */
577 wsptr = workspace;
578 for (ctr = 8; ctr > 0; ctr--)
580 /* Due to quantization, we will usually find that many of the input
581 * coefficients are zero, especially the AC terms. We can exploit this
582 * by short-circuiting the IDCT calculation for any column in which all
583 * the AC terms are zero. In that case each output is equal to the
584 * DC coefficient (with scale factor as needed).
585 * With typical images and quantization tables, half or more of the
586 * column DCT calculations can be simplified this way.
589 if ((inptr[8*1] | inptr[8*2] | inptr[8*3]
590 | inptr[8*4] | inptr[8*5] | inptr[8*6] | inptr[8*7]) == 0)
592 /* AC terms all zero */
593 int dcval = DEQUANTIZE(inptr[8*0], quantptr[8*0]) << PASS1_BITS;
595 wsptr[8*0] = wsptr[8*1] = wsptr[8*2] = wsptr[8*3] = wsptr[8*4]
596 = wsptr[8*5] = wsptr[8*6] = wsptr[8*7] = dcval;
597 inptr++; /* advance pointers to next column */
598 quantptr++;
599 wsptr++;
600 continue;
603 /* Even part: reverse the even part of the forward DCT. */
604 /* The rotator is sqrt(2)*c(-6). */
606 z2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
607 z3 = DEQUANTIZE(inptr[8*6], quantptr[8*6]);
609 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
610 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
611 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
613 z2 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
614 z3 = DEQUANTIZE(inptr[8*4], quantptr[8*4]);
616 tmp0 = (z2 + z3) << CONST_BITS;
617 tmp1 = (z2 - z3) << CONST_BITS;
619 tmp10 = tmp0 + tmp3;
620 tmp13 = tmp0 - tmp3;
621 tmp11 = tmp1 + tmp2;
622 tmp12 = tmp1 - tmp2;
624 /* Odd part per figure 8; the matrix is unitary and hence its
625 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
627 tmp0 = DEQUANTIZE(inptr[8*7], quantptr[8*7]);
628 tmp1 = DEQUANTIZE(inptr[8*5], quantptr[8*5]);
629 tmp2 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
630 tmp3 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
632 z1 = tmp0 + tmp3;
633 z2 = tmp1 + tmp2;
634 z3 = tmp0 + tmp2;
635 z4 = tmp1 + tmp3;
636 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
638 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
639 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
640 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
641 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
642 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
643 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
644 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
645 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
647 z3 += z5;
648 z4 += z5;
650 tmp0 += z1 + z3;
651 tmp1 += z2 + z4;
652 tmp2 += z2 + z3;
653 tmp3 += z1 + z4;
655 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
657 wsptr[8*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
658 wsptr[8*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
659 wsptr[8*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
660 wsptr[8*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
661 wsptr[8*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
662 wsptr[8*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
663 wsptr[8*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
664 wsptr[8*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
666 inptr++; /* advance pointers to next column */
667 quantptr++;
668 wsptr++;
671 /* Pass 2: process rows from work array, store into output array. */
672 /* Note that we must descale the results by a factor of 8 == 2**3, */
673 /* and also undo the PASS1_BITS scaling. */
675 wsptr = workspace;
676 for (ctr = 0; ctr < 8; ctr++)
678 outptr = p_byte + (ctr*skip_line);
679 /* Rows of zeroes can be exploited in the same way as we did with columns.
680 * However, the column calculation has created many nonzero AC terms, so
681 * the simplification applies less often (typically 5% to 10% of the time).
682 * On machines with very fast multiplication, it's possible that the
683 * test takes more time than it's worth. In that case this section
684 * may be commented out.
687 #ifndef NO_ZERO_ROW_TEST
688 if ((wsptr[1] | wsptr[2] | wsptr[3]
689 | wsptr[4] | wsptr[5] | wsptr[6] | wsptr[7]) == 0)
691 /* AC terms all zero */
692 unsigned char dcval = range_limit((int) DESCALE((long) wsptr[0],
693 PASS1_BITS+3));
695 outptr[0] = dcval;
696 outptr[1] = dcval;
697 outptr[2] = dcval;
698 outptr[3] = dcval;
699 outptr[4] = dcval;
700 outptr[5] = dcval;
701 outptr[6] = dcval;
702 outptr[7] = dcval;
704 wsptr += 8; /* advance pointer to next row */
705 continue;
707 #endif
709 /* Even part: reverse the even part of the forward DCT. */
710 /* The rotator is sqrt(2)*c(-6). */
712 z2 = (long) wsptr[2];
713 z3 = (long) wsptr[6];
715 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
716 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
717 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
719 tmp0 = ((long) wsptr[0] + (long) wsptr[4]) << CONST_BITS;
720 tmp1 = ((long) wsptr[0] - (long) wsptr[4]) << CONST_BITS;
722 tmp10 = tmp0 + tmp3;
723 tmp13 = tmp0 - tmp3;
724 tmp11 = tmp1 + tmp2;
725 tmp12 = tmp1 - tmp2;
727 /* Odd part per figure 8; the matrix is unitary and hence its
728 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
730 tmp0 = (long) wsptr[7];
731 tmp1 = (long) wsptr[5];
732 tmp2 = (long) wsptr[3];
733 tmp3 = (long) wsptr[1];
735 z1 = tmp0 + tmp3;
736 z2 = tmp1 + tmp2;
737 z3 = tmp0 + tmp2;
738 z4 = tmp1 + tmp3;
739 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
741 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
742 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
743 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
744 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
745 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
746 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
747 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
748 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
750 z3 += z5;
751 z4 += z5;
753 tmp0 += z1 + z3;
754 tmp1 += z2 + z4;
755 tmp2 += z2 + z3;
756 tmp3 += z1 + z4;
758 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
760 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp3,
761 CONST_BITS+PASS1_BITS+3));
762 outptr[7] = range_limit((int) DESCALE(tmp10 - tmp3,
763 CONST_BITS+PASS1_BITS+3));
764 outptr[1] = range_limit((int) DESCALE(tmp11 + tmp2,
765 CONST_BITS+PASS1_BITS+3));
766 outptr[6] = range_limit((int) DESCALE(tmp11 - tmp2,
767 CONST_BITS+PASS1_BITS+3));
768 outptr[2] = range_limit((int) DESCALE(tmp12 + tmp1,
769 CONST_BITS+PASS1_BITS+3));
770 outptr[5] = range_limit((int) DESCALE(tmp12 - tmp1,
771 CONST_BITS+PASS1_BITS+3));
772 outptr[3] = range_limit((int) DESCALE(tmp13 + tmp0,
773 CONST_BITS+PASS1_BITS+3));
774 outptr[4] = range_limit((int) DESCALE(tmp13 - tmp0,
775 CONST_BITS+PASS1_BITS+3));
777 wsptr += 8; /* advance pointer to next row */
783 /* JPEG decoder implementation */
786 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
788 struct derived_tbl
790 /* Basic tables: (element [0] of each array is unused) */
791 long mincode[17]; /* smallest code of length k */
792 long maxcode[18]; /* largest code of length k (-1 if none) */
793 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
794 int valptr[17]; /* huffval[] index of 1st symbol of length k */
796 /* Back link to public Huffman table (needed only in slow_DECODE) */
797 int* pub;
799 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
800 the input data stream. If the next Huffman code is no more
801 than HUFF_LOOKAHEAD bits long, we can obtain its length and
802 the corresponding symbol directly from these tables. */
803 int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
804 unsigned char look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
807 #define QUANT_TABLE_LENGTH 64
809 /* for type of Huffman table */
810 #define DC_LEN 28
811 #define AC_LEN 178
813 struct huffman_table
814 { /* length and code according to JFIF format */
815 int huffmancodes_dc[DC_LEN];
816 int huffmancodes_ac[AC_LEN];
819 struct frame_component
821 int ID;
822 int horizontal_sampling;
823 int vertical_sampling;
824 int quanttable_select;
827 struct scan_component
829 int ID;
830 int DC_select;
831 int AC_select;
834 struct bitstream
836 unsigned long get_buffer; /* current bit-extraction buffer */
837 int bits_left; /* # of unused bits in it */
838 unsigned char* next_input_byte;
839 unsigned char* input_end; /* upper limit +1 */
842 struct jpeg
844 int x_size, y_size; /* size of image (can be less than block boundary) */
845 int x_phys, y_phys; /* physical size, block aligned */
846 int x_mbl; /* x dimension of MBL */
847 int y_mbl; /* y dimension of MBL */
848 int blocks; /* blocks per MB */
849 int restart_interval; /* number of MCUs between RSTm markers */
850 int store_pos[4]; /* for Y block ordering */
852 unsigned char* p_entropy_data;
853 unsigned char* p_entropy_end;
855 int quanttable[4][QUANT_TABLE_LENGTH]; /* raw quantization tables 0-3 */
856 int qt_idct[2][QUANT_TABLE_LENGTH]; /* quantization tables for IDCT */
858 struct huffman_table hufftable[2]; /* Huffman tables */
859 struct derived_tbl dc_derived_tbls[2]; /* Huffman-LUTs */
860 struct derived_tbl ac_derived_tbls[2];
862 struct frame_component frameheader[3]; /* Component descriptor */
863 struct scan_component scanheader[3]; /* currently not used */
865 int mcu_membership[6]; /* info per block */
866 int tab_membership[6];
867 int subsample_x[3]; /* info per component */
868 int subsample_y[3];
872 /* possible return flags for process_markers() */
873 #define HUFFTAB 0x0001 /* with huffman table */
874 #define QUANTTAB 0x0002 /* with quantization table */
875 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
876 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
877 #define SOF0 0x0010 /* with SOF0-Segment */
878 #define DHT 0x0020 /* with Definition of huffman tables */
879 #define SOS 0x0040 /* with Start-of-Scan segment */
880 #define DQT 0x0080 /* with definition of quantization table */
882 /* Preprocess the JPEG JFIF file */
883 int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
885 unsigned char* p_bytes = p_src;
886 int marker_size; /* variable length of marker segment */
887 int i, j, n;
888 int ret = 0; /* returned flags */
890 p_jpeg->p_entropy_end = p_src + size;
892 while (p_src < p_bytes + size)
894 if (*p_src++ != 0xFF) /* no marker? */
896 p_src--; /* it's image data, put it back */
897 p_jpeg->p_entropy_data = p_src;
898 break; /* exit marker processing */
901 switch (*p_src++)
903 case 0xFF: /* Fill byte */
904 ret |= FILL_FF;
905 case 0x00: /* Zero stuffed byte - entropy data */
906 p_src--; /* put it back */
907 continue;
909 case 0xC0: /* SOF Huff - Baseline DCT */
911 ret |= SOF0;
912 marker_size = *p_src++ << 8; /* Highbyte */
913 marker_size |= *p_src++; /* Lowbyte */
914 n = *p_src++; /* sample precision (= 8 or 12) */
915 if (n != 8)
917 return(-1); /* Unsupported sample precision */
919 p_jpeg->y_size = *p_src++ << 8; /* Highbyte */
920 p_jpeg->y_size |= *p_src++; /* Lowbyte */
921 p_jpeg->x_size = *p_src++ << 8; /* Highbyte */
922 p_jpeg->x_size |= *p_src++; /* Lowbyte */
924 n = (marker_size-2-6)/3;
925 if (*p_src++ != n || (n != 1 && n != 3))
927 return(-2); /* Unsupported SOF0 component specification */
929 for (i=0; i<n; i++)
931 p_jpeg->frameheader[i].ID = *p_src++; /* Component info */
932 p_jpeg->frameheader[i].horizontal_sampling = *p_src >> 4;
933 p_jpeg->frameheader[i].vertical_sampling = *p_src++ & 0x0F;
934 p_jpeg->frameheader[i].quanttable_select = *p_src++;
935 if (p_jpeg->frameheader[i].horizontal_sampling > 2
936 || p_jpeg->frameheader[i].vertical_sampling > 2)
937 return -3; /* Unsupported SOF0 subsampling */
939 p_jpeg->blocks = n;
941 break;
943 case 0xC1: /* SOF Huff - Extended sequential DCT*/
944 case 0xC2: /* SOF Huff - Progressive DCT*/
945 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
946 case 0xC5: /* SOF Huff - Differential sequential DCT*/
947 case 0xC6: /* SOF Huff - Differential progressive DCT*/
948 case 0xC7: /* SOF Huff - Differential spatial*/
949 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
950 case 0xC9: /* SOF Arith - Extended sequential DCT*/
951 case 0xCA: /* SOF Arith - Progressive DCT*/
952 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
953 case 0xCD: /* SOF Arith - Differential sequential DCT*/
954 case 0xCE: /* SOF Arith - Differential progressive DCT*/
955 case 0xCF: /* SOF Arith - Differential spatial*/
957 return (-4); /* other DCT model than baseline not implemented */
960 case 0xC4: /* Define Huffman Table(s) */
962 unsigned char* p_temp;
964 ret |= DHT;
965 marker_size = *p_src++ << 8; /* Highbyte */
966 marker_size |= *p_src++; /* Lowbyte */
968 p_temp = p_src;
969 while (p_src < p_temp+marker_size-2-17) /* another table */
971 int sum = 0;
972 i = *p_src & 0x0F; /* table index */
973 if (i > 1)
975 return (-5); /* Huffman table index out of range */
977 else if (*p_src++ & 0xF0) /* AC table */
979 for (j=0; j<16; j++)
981 sum += *p_src;
982 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
984 if(16 + sum > AC_LEN)
985 return -10; /* longer than allowed */
987 for (; j < 16 + sum; j++)
988 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
990 else /* DC table */
992 for (j=0; j<16; j++)
994 sum += *p_src;
995 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
997 if(16 + sum > DC_LEN)
998 return -11; /* longer than allowed */
1000 for (; j < 16 + sum; j++)
1001 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
1003 } /* while */
1004 p_src = p_temp+marker_size - 2; /* skip possible residue */
1006 break;
1008 case 0xCC: /* Define Arithmetic coding conditioning(s) */
1009 return(-6); /* Arithmetic coding not supported */
1011 case 0xD8: /* Start of Image */
1012 case 0xD9: /* End of Image */
1013 case 0x01: /* for temp private use arith code */
1014 break; /* skip parameterless marker */
1017 case 0xDA: /* Start of Scan */
1019 ret |= SOS;
1020 marker_size = *p_src++ << 8; /* Highbyte */
1021 marker_size |= *p_src++; /* Lowbyte */
1023 n = (marker_size-2-1-3)/2;
1024 if (*p_src++ != n || (n != 1 && n != 3))
1026 return (-7); /* Unsupported SOS component specification */
1028 for (i=0; i<n; i++)
1030 p_jpeg->scanheader[i].ID = *p_src++;
1031 p_jpeg->scanheader[i].DC_select = *p_src >> 4;
1032 p_jpeg->scanheader[i].AC_select = *p_src++ & 0x0F;
1034 p_src += 3; /* skip spectral information */
1036 break;
1038 case 0xDB: /* Define quantization Table(s) */
1040 ret |= DQT;
1041 marker_size = *p_src++ << 8; /* Highbyte */
1042 marker_size |= *p_src++; /* Lowbyte */
1043 n = (marker_size-2)/(QUANT_TABLE_LENGTH+1); /* # of tables */
1044 for (i=0; i<n; i++)
1046 int id = *p_src++; /* ID */
1047 if (id >= 4)
1049 return (-8); /* Unsupported quantization table */
1051 /* Read Quantisation table: */
1052 for (j=0; j<QUANT_TABLE_LENGTH; j++)
1053 p_jpeg->quanttable[id][j] = *p_src++;
1056 break;
1058 case 0xDD: /* Define Restart Interval */
1060 marker_size = *p_src++ << 8; /* Highbyte */
1061 marker_size |= *p_src++; /* Lowbyte */
1062 p_jpeg->restart_interval = *p_src++ << 8; /* Highbyte */
1063 p_jpeg->restart_interval |= *p_src++; /* Lowbyte */
1064 p_src += marker_size-4; /* skip segment */
1066 break;
1068 case 0xDC: /* Define Number of Lines */
1069 case 0xDE: /* Define Hierarchical progression */
1070 case 0xDF: /* Expand Reference Component(s) */
1071 case 0xE0: /* Application Field 0*/
1072 case 0xE1: /* Application Field 1*/
1073 case 0xE2: /* Application Field 2*/
1074 case 0xE3: /* Application Field 3*/
1075 case 0xE4: /* Application Field 4*/
1076 case 0xE5: /* Application Field 5*/
1077 case 0xE6: /* Application Field 6*/
1078 case 0xE7: /* Application Field 7*/
1079 case 0xE8: /* Application Field 8*/
1080 case 0xE9: /* Application Field 9*/
1081 case 0xEA: /* Application Field 10*/
1082 case 0xEB: /* Application Field 11*/
1083 case 0xEC: /* Application Field 12*/
1084 case 0xED: /* Application Field 13*/
1085 case 0xEE: /* Application Field 14*/
1086 case 0xEF: /* Application Field 15*/
1087 case 0xFE: /* Comment */
1089 marker_size = *p_src++ << 8; /* Highbyte */
1090 marker_size |= *p_src++; /* Lowbyte */
1091 p_src += marker_size-2; /* skip segment */
1093 break;
1095 case 0xF0: /* Reserved for JPEG extensions */
1096 case 0xF1: /* Reserved for JPEG extensions */
1097 case 0xF2: /* Reserved for JPEG extensions */
1098 case 0xF3: /* Reserved for JPEG extensions */
1099 case 0xF4: /* Reserved for JPEG extensions */
1100 case 0xF5: /* Reserved for JPEG extensions */
1101 case 0xF6: /* Reserved for JPEG extensions */
1102 case 0xF7: /* Reserved for JPEG extensions */
1103 case 0xF8: /* Reserved for JPEG extensions */
1104 case 0xF9: /* Reserved for JPEG extensions */
1105 case 0xFA: /* Reserved for JPEG extensions */
1106 case 0xFB: /* Reserved for JPEG extensions */
1107 case 0xFC: /* Reserved for JPEG extensions */
1108 case 0xFD: /* Reserved for JPEG extensions */
1109 case 0x02: /* Reserved */
1110 default:
1111 return (-9); /* Unknown marker */
1112 } /* switch */
1113 } /* while */
1115 return (ret); /* return flags with seen markers */
1119 void default_huff_tbl(struct jpeg* p_jpeg)
1121 static const struct huffman_table luma_table =
1124 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
1125 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1128 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
1129 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
1130 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
1131 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
1132 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
1133 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1134 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1135 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
1136 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
1137 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
1138 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1139 0xF9,0xFA
1143 static const struct huffman_table chroma_table =
1146 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
1147 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1150 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
1151 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
1152 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1153 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1154 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1155 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1156 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1157 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1158 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1159 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1160 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1161 0xF9,0xFA
1165 MEMCPY(&p_jpeg->hufftable[0], &luma_table, sizeof(luma_table));
1166 MEMCPY(&p_jpeg->hufftable[1], &chroma_table, sizeof(chroma_table));
1168 return;
1171 /* Compute the derived values for a Huffman table */
1172 void fix_huff_tbl(int* htbl, struct derived_tbl* dtbl)
1174 int p, i, l, si;
1175 int lookbits, ctr;
1176 char huffsize[257];
1177 unsigned int huffcode[257];
1178 unsigned int code;
1180 dtbl->pub = htbl; /* fill in back link */
1182 /* Figure C.1: make table of Huffman code length for each symbol */
1183 /* Note that this is in code-length order. */
1185 p = 0;
1186 for (l = 1; l <= 16; l++)
1187 { /* all possible code length */
1188 for (i = 1; i <= (int) htbl[l-1]; i++) /* all codes per length */
1189 huffsize[p++] = (char) l;
1191 huffsize[p] = 0;
1193 /* Figure C.2: generate the codes themselves */
1194 /* Note that this is in code-length order. */
1196 code = 0;
1197 si = huffsize[0];
1198 p = 0;
1199 while (huffsize[p])
1201 while (((int) huffsize[p]) == si)
1203 huffcode[p++] = code;
1204 code++;
1206 code <<= 1;
1207 si++;
1210 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1212 p = 0;
1213 for (l = 1; l <= 16; l++)
1215 if (htbl[l-1])
1217 dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */
1218 dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */
1219 p += htbl[l-1];
1220 dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
1222 else
1224 dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
1227 dtbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */
1229 /* Compute lookahead tables to speed up decoding.
1230 * First we set all the table entries to 0, indicating "too long";
1231 * then we iterate through the Huffman codes that are short enough and
1232 * fill in all the entries that correspond to bit sequences starting
1233 * with that code.
1236 MEMSET(dtbl->look_nbits, 0, sizeof(dtbl->look_nbits));
1238 p = 0;
1239 for (l = 1; l <= HUFF_LOOKAHEAD; l++)
1241 for (i = 1; i <= (int) htbl[l-1]; i++, p++)
1243 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1244 /* Generate left-justified code followed by all possible bit sequences */
1245 lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
1246 for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--)
1248 dtbl->look_nbits[lookbits] = l;
1249 dtbl->look_sym[lookbits] = htbl[16+p];
1250 lookbits++;
1257 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1258 * If the incoming data is corrupted, decode_mcu could attempt to
1259 * reference values beyond the end of the array. To avoid a wild store,
1260 * we put some extra zeroes after the real entries.
1262 static const int zag[] =
1264 0, 1, 8, 16, 9, 2, 3, 10,
1265 17, 24, 32, 25, 18, 11, 4, 5,
1266 12, 19, 26, 33, 40, 48, 41, 34,
1267 27, 20, 13, 6, 7, 14, 21, 28,
1268 35, 42, 49, 56, 57, 50, 43, 36,
1269 29, 22, 15, 23, 30, 37, 44, 51,
1270 58, 59, 52, 45, 38, 31, 39, 46,
1271 53, 60, 61, 54, 47, 55, 62, 63,
1272 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1273 0, 0, 0, 0, 0, 0, 0, 0
1276 void build_lut(struct jpeg* p_jpeg)
1278 int i;
1279 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_dc,
1280 &p_jpeg->dc_derived_tbls[0]);
1281 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_ac,
1282 &p_jpeg->ac_derived_tbls[0]);
1283 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_dc,
1284 &p_jpeg->dc_derived_tbls[1]);
1285 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_ac,
1286 &p_jpeg->ac_derived_tbls[1]);
1288 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1289 for (i=0; i<64; i++)
1291 p_jpeg->qt_idct[0][zag[i]] = p_jpeg->quanttable[0][i];
1292 p_jpeg->qt_idct[1][zag[i]] = p_jpeg->quanttable[1][i];
1295 for (i=0; i<4; i++)
1296 p_jpeg->store_pos[i] = i; /* default ordering */
1298 /* assignments for the decoding of blocks */
1299 if (p_jpeg->frameheader[0].horizontal_sampling == 2
1300 && p_jpeg->frameheader[0].vertical_sampling == 1)
1301 { /* 4:2:2 */
1302 p_jpeg->blocks = 4;
1303 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1304 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1305 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1306 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1307 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1308 p_jpeg->mcu_membership[1] = 0;
1309 p_jpeg->mcu_membership[2] = 1;
1310 p_jpeg->mcu_membership[3] = 2;
1311 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1312 p_jpeg->tab_membership[1] = 0;
1313 p_jpeg->tab_membership[2] = 1;
1314 p_jpeg->tab_membership[3] = 1;
1315 p_jpeg->subsample_x[0] = 1;
1316 p_jpeg->subsample_x[1] = 2;
1317 p_jpeg->subsample_x[2] = 2;
1318 p_jpeg->subsample_y[0] = 1;
1319 p_jpeg->subsample_y[1] = 1;
1320 p_jpeg->subsample_y[2] = 1;
1322 if (p_jpeg->frameheader[0].horizontal_sampling == 1
1323 && p_jpeg->frameheader[0].vertical_sampling == 2)
1324 { /* 4:2:2 vertically subsampled */
1325 p_jpeg->store_pos[1] = 2; /* block positions are mirrored */
1326 p_jpeg->store_pos[2] = 1;
1327 p_jpeg->blocks = 4;
1328 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1329 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1330 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1331 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1332 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1333 p_jpeg->mcu_membership[1] = 0;
1334 p_jpeg->mcu_membership[2] = 1;
1335 p_jpeg->mcu_membership[3] = 2;
1336 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1337 p_jpeg->tab_membership[1] = 0;
1338 p_jpeg->tab_membership[2] = 1;
1339 p_jpeg->tab_membership[3] = 1;
1340 p_jpeg->subsample_x[0] = 1;
1341 p_jpeg->subsample_x[1] = 1;
1342 p_jpeg->subsample_x[2] = 1;
1343 p_jpeg->subsample_y[0] = 1;
1344 p_jpeg->subsample_y[1] = 2;
1345 p_jpeg->subsample_y[2] = 2;
1347 else if (p_jpeg->frameheader[0].horizontal_sampling == 2
1348 && p_jpeg->frameheader[0].vertical_sampling == 2)
1349 { /* 4:2:0 */
1350 p_jpeg->blocks = 6;
1351 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1352 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1353 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1354 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1355 p_jpeg->mcu_membership[0] = 0;
1356 p_jpeg->mcu_membership[1] = 0;
1357 p_jpeg->mcu_membership[2] = 0;
1358 p_jpeg->mcu_membership[3] = 0;
1359 p_jpeg->mcu_membership[4] = 1;
1360 p_jpeg->mcu_membership[5] = 2;
1361 p_jpeg->tab_membership[0] = 0;
1362 p_jpeg->tab_membership[1] = 0;
1363 p_jpeg->tab_membership[2] = 0;
1364 p_jpeg->tab_membership[3] = 0;
1365 p_jpeg->tab_membership[4] = 1;
1366 p_jpeg->tab_membership[5] = 1;
1367 p_jpeg->subsample_x[0] = 1;
1368 p_jpeg->subsample_x[1] = 2;
1369 p_jpeg->subsample_x[2] = 2;
1370 p_jpeg->subsample_y[0] = 1;
1371 p_jpeg->subsample_y[1] = 2;
1372 p_jpeg->subsample_y[2] = 2;
1374 else if (p_jpeg->frameheader[0].horizontal_sampling == 1
1375 && p_jpeg->frameheader[0].vertical_sampling == 1)
1376 { /* 4:4:4 */
1377 /* don't overwrite p_jpeg->blocks */
1378 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1379 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1380 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1381 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1382 p_jpeg->mcu_membership[0] = 0;
1383 p_jpeg->mcu_membership[1] = 1;
1384 p_jpeg->mcu_membership[2] = 2;
1385 p_jpeg->tab_membership[0] = 0;
1386 p_jpeg->tab_membership[1] = 1;
1387 p_jpeg->tab_membership[2] = 1;
1388 p_jpeg->subsample_x[0] = 1;
1389 p_jpeg->subsample_x[1] = 1;
1390 p_jpeg->subsample_x[2] = 1;
1391 p_jpeg->subsample_y[0] = 1;
1392 p_jpeg->subsample_y[1] = 1;
1393 p_jpeg->subsample_y[2] = 1;
1395 else
1397 /* error */
1404 * These functions/macros provide the in-line portion of bit fetching.
1405 * Use check_bit_buffer to ensure there are N bits in get_buffer
1406 * before using get_bits, peek_bits, or drop_bits.
1407 * check_bit_buffer(state,n,action);
1408 * Ensure there are N bits in get_buffer; if suspend, take action.
1409 * val = get_bits(n);
1410 * Fetch next N bits.
1411 * val = peek_bits(n);
1412 * Fetch next N bits without removing them from the buffer.
1413 * drop_bits(n);
1414 * Discard next N bits.
1415 * The value N should be a simple variable, not an expression, because it
1416 * is evaluated multiple times.
1419 INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
1421 if (pb->bits_left < nbits)
1422 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1423 unsigned char byte;
1425 byte = *pb->next_input_byte++;
1426 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1427 { /* simplification: just skip the (one-byte) marker code */
1428 pb->next_input_byte++;
1430 pb->get_buffer = (pb->get_buffer << 8) | byte;
1432 byte = *pb->next_input_byte++;
1433 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1434 { /* simplification: just skip the (one-byte) marker code */
1435 pb->next_input_byte++;
1437 pb->get_buffer = (pb->get_buffer << 8) | byte;
1439 pb->bits_left += 16;
1443 INLINE int get_bits(struct bitstream* pb, int nbits)
1445 return ((int) (pb->get_buffer >> (pb->bits_left -= nbits))) & ((1<<nbits)-1);
1448 INLINE int peek_bits(struct bitstream* pb, int nbits)
1450 return ((int) (pb->get_buffer >> (pb->bits_left - nbits))) & ((1<<nbits)-1);
1453 INLINE void drop_bits(struct bitstream* pb, int nbits)
1455 pb->bits_left -= nbits;
1458 /* re-synchronize to entropy data (skip restart marker) */
1459 void search_restart(struct bitstream* pb)
1461 pb->next_input_byte--; /* we may have overread it, taking 2 bytes */
1462 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1463 while (pb->next_input_byte < pb->input_end &&
1464 (pb->next_input_byte[-2] != 0xFF || pb->next_input_byte[-1] == 0x00))
1466 pb->next_input_byte++;
1468 pb->bits_left = 0;
1471 /* Figure F.12: extend sign bit. */
1472 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1474 static const int extend_test[16] = /* entry n is 2**(n-1) */
1476 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1477 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1480 static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
1482 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1483 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1484 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1485 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1488 /* Decode a single value */
1489 INLINE int huff_decode_dc(struct bitstream* bs, struct derived_tbl* tbl)
1491 int nb, look, s, r;
1493 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1494 look = peek_bits(bs, HUFF_LOOKAHEAD);
1495 if ((nb = tbl->look_nbits[look]) != 0)
1497 drop_bits(bs, nb);
1498 s = tbl->look_sym[look];
1499 check_bit_buffer(bs, s);
1500 r = get_bits(bs, s);
1501 s = HUFF_EXTEND(r, s);
1503 else
1504 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1505 long code;
1506 nb=HUFF_LOOKAHEAD+1;
1507 check_bit_buffer(bs, nb);
1508 code = get_bits(bs, nb);
1509 while (code > tbl->maxcode[nb])
1511 code <<= 1;
1512 check_bit_buffer(bs, 1);
1513 code |= get_bits(bs, 1);
1514 nb++;
1516 if (nb > 16) /* error in Huffman */
1518 s=0; /* fake a zero, this is most safe */
1520 else
1522 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1523 check_bit_buffer(bs, s);
1524 r = get_bits(bs, s);
1525 s = HUFF_EXTEND(r, s);
1527 } /* end slow decode */
1528 return s;
1531 INLINE int huff_decode_ac(struct bitstream* bs, struct derived_tbl* tbl)
1533 int nb, look, s;
1535 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1536 look = peek_bits(bs, HUFF_LOOKAHEAD);
1537 if ((nb = tbl->look_nbits[look]) != 0)
1539 drop_bits(bs, nb);
1540 s = tbl->look_sym[look];
1542 else
1543 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1544 long code;
1545 nb=HUFF_LOOKAHEAD+1;
1546 check_bit_buffer(bs, nb);
1547 code = get_bits(bs, nb);
1548 while (code > tbl->maxcode[nb])
1550 code <<= 1;
1551 check_bit_buffer(bs, 1);
1552 code |= get_bits(bs, 1);
1553 nb++;
1555 if (nb > 16) /* error in Huffman */
1557 s=0; /* fake a zero, this is most safe */
1559 else
1561 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1563 } /* end slow decode */
1564 return s;
1568 #ifdef HAVE_LCD_COLOR
1570 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1571 /* Note: it keeps the original color subsampling, even if resized. */
1572 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1573 int downscale, void (*pf_progress)(int current, int total))
1575 struct bitstream bs; /* bitstream "object" */
1576 int block[64]; /* decoded DCT coefficients */
1578 int width, height;
1579 int skip_line[3]; /* bytes from one line to the next (skip_line) */
1580 int skip_strip[3], skip_mcu[3]; /* bytes to next DCT row / column */
1582 int i, x, y; /* loop counter */
1584 unsigned char* p_line[3] = {p_pixel[0], p_pixel[1], p_pixel[2]};
1585 unsigned char* p_byte[3]; /* bitmap pointer */
1587 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1588 int k_need; /* AC coefficients needed up to here */
1589 int zero_need; /* init the block with this many zeros */
1591 int last_dc_val[3] = {0, 0, 0}; /* or 128 for chroma? */
1592 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1593 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1595 /* pick the IDCT we want, determine how to work with coefs */
1596 if (downscale == 1)
1598 pf_idct = idct8x8;
1599 k_need = 64; /* all */
1600 zero_need = 63; /* all */
1602 else if (downscale == 2)
1604 pf_idct = idct4x4;
1605 k_need = 25; /* this far in zig-zag to cover 4*4 */
1606 zero_need = 27; /* clear this far in linear order */
1608 else if (downscale == 4)
1610 pf_idct = idct2x2;
1611 k_need = 5; /* this far in zig-zag to cover 2*2 */
1612 zero_need = 9; /* clear this far in linear order */
1614 else if (downscale == 8)
1616 pf_idct = idct1x1;
1617 k_need = 0; /* no AC, not needed */
1618 zero_need = 0; /* no AC, not needed */
1620 else return -1; /* not supported */
1622 /* init bitstream, fake a restart to make it start */
1623 bs.next_input_byte = p_jpeg->p_entropy_data;
1624 bs.bits_left = 0;
1625 bs.input_end = p_jpeg->p_entropy_end;
1627 width = p_jpeg->x_phys / downscale;
1628 height = p_jpeg->y_phys / downscale;
1629 for (i=0; i<3; i++) /* calculate some strides */
1631 skip_line[i] = width / p_jpeg->subsample_x[i];
1632 skip_strip[i] = skip_line[i]
1633 * (height / p_jpeg->y_mbl) / p_jpeg->subsample_y[i];
1634 skip_mcu[i] = width/p_jpeg->x_mbl / p_jpeg->subsample_x[i];
1637 /* prepare offsets about where to store the different blocks */
1638 store_offs[p_jpeg->store_pos[0]] = 0;
1639 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1640 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1641 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1643 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1645 for (i=0; i<3; i++) /* scan line init */
1647 p_byte[i] = p_line[i];
1648 p_line[i] += skip_strip[i];
1650 for (x=0; x<p_jpeg->x_mbl; x++)
1652 int blkn;
1654 /* Outer loop handles each block in the MCU */
1655 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1656 { /* Decode a single block's worth of coefficients */
1657 int k = 1; /* coefficient index */
1658 int s, r; /* huffman values */
1659 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1660 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1661 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1662 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1664 /* Section F.2.2.1: decode the DC coefficient difference */
1665 s = huff_decode_dc(&bs, dctbl);
1667 last_dc_val[ci] += s;
1668 block[0] = last_dc_val[ci]; /* output it (assumes zag[0] = 0) */
1670 /* coefficient buffer must be cleared */
1671 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1673 /* Section F.2.2.2: decode the AC coefficients */
1674 for (; k < k_need; k++)
1676 s = huff_decode_ac(&bs, actbl);
1677 r = s >> 4;
1678 s &= 15;
1680 if (s)
1682 k += r;
1683 check_bit_buffer(&bs, s);
1684 r = get_bits(&bs, s);
1685 block[zag[k]] = HUFF_EXTEND(r, s);
1687 else
1689 if (r != 15)
1691 k = 64;
1692 break;
1694 k += r;
1696 } /* for k */
1697 /* In this path we just discard the values */
1698 for (; k < 64; k++)
1700 s = huff_decode_ac(&bs, actbl);
1701 r = s >> 4;
1702 s &= 15;
1704 if (s)
1706 k += r;
1707 check_bit_buffer(&bs, s);
1708 drop_bits(&bs, s);
1710 else
1712 if (r != 15)
1713 break;
1714 k += r;
1716 } /* for k */
1718 if (ci == 0)
1719 { /* Y component needs to bother about block store */
1720 pf_idct(p_byte[0]+store_offs[blkn], block,
1721 p_jpeg->qt_idct[ti], skip_line[0]);
1723 else
1724 { /* chroma */
1725 pf_idct(p_byte[ci], block, p_jpeg->qt_idct[ti],
1726 skip_line[ci]);
1728 } /* for blkn */
1729 p_byte[0] += skip_mcu[0]; /* unrolled for (i=0; i<3; i++) loop */
1730 p_byte[1] += skip_mcu[1];
1731 p_byte[2] += skip_mcu[2];
1732 if (p_jpeg->restart_interval && --restart == 0)
1733 { /* if a restart marker is due: */
1734 restart = p_jpeg->restart_interval; /* count again */
1735 search_restart(&bs); /* align the bitstream */
1736 last_dc_val[0] = last_dc_val[1] =
1737 last_dc_val[2] = 0; /* reset decoder */
1739 } /* for x */
1740 if (pf_progress != NULL)
1741 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1742 } /* for y */
1744 return 0; /* success */
1746 #else /* !HAVE_LCD_COLOR */
1748 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1749 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[1], int downscale,
1750 void (*pf_progress)(int current, int total))
1752 struct bitstream bs; /* bitstream "object" */
1753 int block[64]; /* decoded DCT coefficients */
1755 int width, height;
1756 int skip_line; /* bytes from one line to the next (skip_line) */
1757 int skip_strip, skip_mcu; /* bytes to next DCT row / column */
1759 int x, y; /* loop counter */
1761 unsigned char* p_line = p_pixel[0];
1762 unsigned char* p_byte; /* bitmap pointer */
1764 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1765 int k_need; /* AC coefficients needed up to here */
1766 int zero_need; /* init the block with this many zeros */
1768 int last_dc_val = 0;
1769 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1770 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1772 /* pick the IDCT we want, determine how to work with coefs */
1773 if (downscale == 1)
1775 pf_idct = idct8x8;
1776 k_need = 64; /* all */
1777 zero_need = 63; /* all */
1779 else if (downscale == 2)
1781 pf_idct = idct4x4;
1782 k_need = 25; /* this far in zig-zag to cover 4*4 */
1783 zero_need = 27; /* clear this far in linear order */
1785 else if (downscale == 4)
1787 pf_idct = idct2x2;
1788 k_need = 5; /* this far in zig-zag to cover 2*2 */
1789 zero_need = 9; /* clear this far in linear order */
1791 else if (downscale == 8)
1793 pf_idct = idct1x1;
1794 k_need = 0; /* no AC, not needed */
1795 zero_need = 0; /* no AC, not needed */
1797 else return -1; /* not supported */
1799 /* init bitstream, fake a restart to make it start */
1800 bs.next_input_byte = p_jpeg->p_entropy_data;
1801 bs.bits_left = 0;
1802 bs.input_end = p_jpeg->p_entropy_end;
1804 width = p_jpeg->x_phys / downscale;
1805 height = p_jpeg->y_phys / downscale;
1806 skip_line = width;
1807 skip_strip = skip_line * (height / p_jpeg->y_mbl);
1808 skip_mcu = (width/p_jpeg->x_mbl);
1810 /* prepare offsets about where to store the different blocks */
1811 store_offs[p_jpeg->store_pos[0]] = 0;
1812 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1813 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1814 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1816 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1818 p_byte = p_line;
1819 p_line += skip_strip;
1820 for (x=0; x<p_jpeg->x_mbl; x++)
1822 int blkn;
1824 /* Outer loop handles each block in the MCU */
1825 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1826 { /* Decode a single block's worth of coefficients */
1827 int k = 1; /* coefficient index */
1828 int s, r; /* huffman values */
1829 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1830 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1831 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1832 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1834 /* Section F.2.2.1: decode the DC coefficient difference */
1835 s = huff_decode_dc(&bs, dctbl);
1837 if (ci == 0) /* only for Y component */
1839 last_dc_val += s;
1840 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
1842 /* coefficient buffer must be cleared */
1843 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1845 /* Section F.2.2.2: decode the AC coefficients */
1846 for (; k < k_need; k++)
1848 s = huff_decode_ac(&bs, actbl);
1849 r = s >> 4;
1850 s &= 15;
1852 if (s)
1854 k += r;
1855 check_bit_buffer(&bs, s);
1856 r = get_bits(&bs, s);
1857 block[zag[k]] = HUFF_EXTEND(r, s);
1859 else
1861 if (r != 15)
1863 k = 64;
1864 break;
1866 k += r;
1868 } /* for k */
1870 /* In this path we just discard the values */
1871 for (; k < 64; k++)
1873 s = huff_decode_ac(&bs, actbl);
1874 r = s >> 4;
1875 s &= 15;
1877 if (s)
1879 k += r;
1880 check_bit_buffer(&bs, s);
1881 drop_bits(&bs, s);
1883 else
1885 if (r != 15)
1886 break;
1887 k += r;
1889 } /* for k */
1891 if (ci == 0)
1892 { /* only for Y component */
1893 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
1894 skip_line);
1896 } /* for blkn */
1897 p_byte += skip_mcu;
1898 if (p_jpeg->restart_interval && --restart == 0)
1899 { /* if a restart marker is due: */
1900 restart = p_jpeg->restart_interval; /* count again */
1901 search_restart(&bs); /* align the bitstream */
1902 last_dc_val = 0; /* reset decoder */
1904 } /* for x */
1905 if (pf_progress != NULL)
1906 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1907 } /* for y */
1909 return 0; /* success */
1911 #endif /* !HAVE_LCD_COLOR */
1913 /**************** end JPEG code ********************/
1917 /**************** begin Application ********************/
1920 /************************* Types ***************************/
1922 struct t_disp
1924 #ifdef HAVE_LCD_COLOR
1925 unsigned char* bitmap[3]; /* Y, Cr, Cb */
1926 int csub_x, csub_y;
1927 #else
1928 unsigned char* bitmap[1]; /* Y only */
1929 #endif
1930 int width;
1931 int height;
1932 int stride;
1933 int x, y;
1936 /************************* Globals ***************************/
1938 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1939 struct t_disp disp[9];
1941 /* my memory pool (from the mp3 buffer) */
1942 char print[32]; /* use a common snprintf() buffer */
1943 unsigned char* buf; /* up to here currently used by image(s) */
1945 /* the remaining free part of the buffer for compressed+uncompressed images */
1946 unsigned char* buf_images;
1948 ssize_t buf_size, buf_images_size;
1949 /* the root of the images, hereafter are decompresed ones */
1950 unsigned char* buf_root;
1951 int root_size;
1953 int ds, ds_min, ds_max; /* downscaling and limits */
1954 static struct jpeg jpg; /* too large for stack */
1956 static struct tree_context *tree;
1958 /* the current full file name */
1959 static char np_file[MAX_PATH];
1960 int curfile = 0, direction = DIR_NONE, entries = 0;
1962 /* list of the jpeg files */
1963 char **file_pt;
1964 /* are we using the plugin buffer or the audio buffer? */
1965 bool plug_buf = false;
1968 /************************* Implementation ***************************/
1970 #ifdef HAVE_LCD_COLOR
1972 * Conversion of full 0-255 range YCrCb to RGB:
1973 * |R| |1.000000 -0.000001 1.402000| |Y'|
1974 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
1975 * |B| |1.000000 1.772000 0.000000| |Pr|
1976 * Scaled (yields s15-bit output):
1977 * |R| |128 0 179| |Y |
1978 * |G| = |128 -43 -91| |Cb - 128|
1979 * |B| |128 227 0| |Cr - 128|
1981 #define YFAC 128
1982 #define RVFAC 179
1983 #define GUFAC (-43)
1984 #define GVFAC (-91)
1985 #define BUFAC 227
1986 #define YUV_WHITE (255*YFAC)
1987 #define NODITHER_DELTA (127*YFAC)
1988 #define COMPONENT_SHIFT 15
1989 #define MATRIX_SHIFT 7
1991 static inline int clamp_component(int x)
1993 if ((unsigned)x > YUV_WHITE)
1994 x = x < 0 ? 0 : YUV_WHITE;
1995 return x;
1998 static inline int clamp_component_bits(int x, int bits)
2000 if ((unsigned)x > (1u << bits) - 1)
2001 x = x < 0 ? 0 : (1 << bits) - 1;
2002 return x;
2005 static inline int component_to_lcd(int x, int bits, int delta)
2007 /* Formula used in core bitmap loader. */
2008 return (((1 << bits) - 1)*x + (x >> (8 - bits)) + delta) >> COMPONENT_SHIFT;
2011 static inline int lcd_to_component(int x, int bits, int delta)
2013 /* Reasonable, approximate reversal to get a full range back from the
2014 quantized value. */
2015 return YUV_WHITE*x / ((1 << bits) - 1);
2016 (void)delta;
2019 #define RED 0
2020 #define GRN 1
2021 #define BLU 2
2023 struct rgb_err
2025 int16_t errbuf[LCD_WIDTH+2]; /* Error record for line below */
2026 } rgb_err_buffers[3];
2028 fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
2029 DITHER_DIFFUSION is set */
2031 struct rgb_pixel
2033 int r, g, b; /* Current pixel components in s16.0 */
2034 int inc; /* Current line increment (-1 or 1) */
2035 int row; /* Current row in source image */
2036 int col; /* Current column in source image */
2037 int ce[3]; /* Errors to apply to current pixel */
2038 struct rgb_err *e; /* RED, GRN, BLU */
2039 int epos; /* Current position in error record */
2042 struct rgb_pixel *pixel;
2044 /** round and truncate to lcd depth **/
2045 static fb_data pixel_to_lcd_colour(void)
2047 struct rgb_pixel *p = pixel;
2048 int r, g, b;
2050 r = component_to_lcd(p->r, LCD_RED_BITS, NODITHER_DELTA);
2051 r = clamp_component_bits(r, LCD_RED_BITS);
2053 g = component_to_lcd(p->g, LCD_GREEN_BITS, NODITHER_DELTA);
2054 g = clamp_component_bits(g, LCD_GREEN_BITS);
2056 b = component_to_lcd(p->b, LCD_BLUE_BITS, NODITHER_DELTA);
2057 b = clamp_component_bits(b, LCD_BLUE_BITS);
2059 return LCD_RGBPACK_LCD(r, g, b);
2062 /** write a monochrome pixel to the colour LCD **/
2063 static fb_data pixel_to_lcd_gray(void)
2065 int r, g, b;
2067 g = clamp_component(pixel->g);
2068 r = component_to_lcd(g, LCD_RED_BITS, NODITHER_DELTA);
2069 b = component_to_lcd(g, LCD_BLUE_BITS, NODITHER_DELTA);
2070 g = component_to_lcd(g, LCD_GREEN_BITS, NODITHER_DELTA);
2072 return LCD_RGBPACK_LCD(r, g, b);
2076 * Bayer ordered dithering - swiped from the core bitmap loader.
2078 static fb_data pixel_odither_to_lcd(void)
2080 /* canonical ordered dither matrix */
2081 static const unsigned char dither_matrix[16][16] = {
2082 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
2083 { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
2084 { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
2085 { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
2086 { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
2087 { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
2088 { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
2089 { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
2090 { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
2091 { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
2092 { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
2093 { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
2094 { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
2095 { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
2096 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
2097 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
2100 struct rgb_pixel *p = pixel;
2101 int r, g, b, delta;
2103 delta = dither_matrix[p->col & 15][p->row & 15] << MATRIX_SHIFT;
2105 r = component_to_lcd(p->r, LCD_RED_BITS, delta);
2106 r = clamp_component_bits(r, LCD_RED_BITS);
2108 g = component_to_lcd(p->g, LCD_GREEN_BITS, delta);
2109 g = clamp_component_bits(g, LCD_GREEN_BITS);
2111 b = component_to_lcd(p->b, LCD_BLUE_BITS, delta);
2112 b = clamp_component_bits(b, LCD_BLUE_BITS);
2114 p->col += p->inc;
2116 return LCD_RGBPACK_LCD(r, g, b);
2120 * Floyd/Steinberg dither to lcd depth.
2122 * Apply filter to each component in serpentine pattern. Kernel shown for
2123 * L->R scan. Kernel is reversed for R->L.
2124 * * 7
2125 * 3 5 1 (1/16)
2127 static inline void distribute_error(int *ce, struct rgb_err *e,
2128 int err, int epos, int inc)
2130 *ce = (7*err >> 4) + e->errbuf[epos+inc];
2131 e->errbuf[epos+inc] = err >> 4;
2132 e->errbuf[epos] += 5*err >> 4;
2133 e->errbuf[epos-inc] += 3*err >> 4;
2136 static fb_data pixel_fsdither_to_lcd(void)
2138 struct rgb_pixel *p = pixel;
2139 int rc, gc, bc, r, g, b;
2140 int inc, epos;
2142 /* Full components with error terms */
2143 rc = p->r + p->ce[RED];
2144 r = component_to_lcd(rc, LCD_RED_BITS, 0);
2145 r = clamp_component_bits(r, LCD_RED_BITS);
2147 gc = p->g + p->ce[GRN];
2148 g = component_to_lcd(gc, LCD_GREEN_BITS, 0);
2149 g = clamp_component_bits(g, LCD_GREEN_BITS);
2151 bc = p->b + p->ce[BLU];
2152 b = component_to_lcd(bc, LCD_BLUE_BITS, 0);
2153 b = clamp_component_bits(b, LCD_BLUE_BITS);
2155 /* Get pixel errors */
2156 rc -= lcd_to_component(r, LCD_RED_BITS, 0);
2157 gc -= lcd_to_component(g, LCD_GREEN_BITS, 0);
2158 bc -= lcd_to_component(b, LCD_BLUE_BITS, 0);
2160 /* Spead error to surrounding pixels. */
2161 inc = p->inc;
2162 epos = p->epos;
2163 p->epos += inc;
2165 distribute_error(&p->ce[RED], &p->e[RED], rc, epos, inc);
2166 distribute_error(&p->ce[GRN], &p->e[GRN], gc, epos, inc);
2167 distribute_error(&p->ce[BLU], &p->e[BLU], bc, epos, inc);
2169 /* Pack and return pixel */
2170 return LCD_RGBPACK_LCD(r, g, b);
2173 /* Functions for each output mode, colour then grayscale. */
2174 static fb_data (* const pixel_funcs[COLOUR_NUM_MODES][DITHER_NUM_MODES])(void) =
2176 [COLOURMODE_COLOUR] =
2178 [DITHER_NONE] = pixel_to_lcd_colour,
2179 [DITHER_ORDERED] = pixel_odither_to_lcd,
2180 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2182 [COLOURMODE_GRAY] =
2184 [DITHER_NONE] = pixel_to_lcd_gray,
2185 [DITHER_ORDERED] = pixel_odither_to_lcd,
2186 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2191 * Draw a partial YUV colour bitmap
2193 * Runs serpentine pattern when dithering is DITHER_DIFFUSION, else scan is
2194 * always L->R.
2196 void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
2197 int src_x, int src_y, int stride,
2198 int x, int y, int width, int height)
2200 fb_data *dst, *dst_end;
2201 fb_data (*pixel_func)(void);
2202 struct rgb_pixel px;
2204 if (x + width > LCD_WIDTH)
2205 width = LCD_WIDTH - x; /* Clip right */
2206 if (x < 0)
2207 width += x, x = 0; /* Clip left */
2208 if (width <= 0)
2209 return; /* nothing left to do */
2211 if (y + height > LCD_HEIGHT)
2212 height = LCD_HEIGHT - y; /* Clip bottom */
2213 if (y < 0)
2214 height += y, y = 0; /* Clip top */
2215 if (height <= 0)
2216 return; /* nothing left to do */
2218 pixel = &px;
2220 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
2221 dst_end = dst + LCD_WIDTH * height;
2223 if (jpeg_settings.colour_mode == COLOURMODE_GRAY)
2224 csub_y = 0; /* Ignore Cb, Cr */
2226 pixel_func = pixel_funcs[jpeg_settings.colour_mode]
2227 [jpeg_settings.dither_mode];
2229 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2231 /* Reset error terms. */
2232 px.e = rgb_err_buffers;
2233 px.ce[RED] = px.ce[GRN] = px.ce[BLU] = 0;
2234 rb->memset(px.e, 0, 3*sizeof (struct rgb_err));
2239 fb_data *dst_row, *row_end;
2240 const unsigned char *ysrc;
2241 px.inc = 1;
2243 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2245 /* Use R->L scan on odd lines */
2246 px.inc -= (src_y & 1) << 1;
2247 px.epos = x + 1;
2249 if (px.inc < 0)
2250 px.epos += width - 1;
2253 if (px.inc == 1)
2255 /* Scan is L->R */
2256 dst_row = dst;
2257 row_end = dst_row + width;
2258 px.col = src_x;
2260 else
2262 /* Scan is R->L */
2263 row_end = dst - 1;
2264 dst_row = row_end + width;
2265 px.col = src_x + width - 1;
2268 ysrc = src[0] + stride * src_y + px.col;
2269 px.row = src_y;
2271 /* Do one row of pixels */
2272 if (csub_y) /* colour */
2274 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
2275 const unsigned char *usrc, *vsrc;
2277 usrc = src[1] + (stride/csub_x) * (src_y/csub_y)
2278 + (px.col/csub_x);
2279 vsrc = src[2] + (stride/csub_x) * (src_y/csub_y)
2280 + (px.col/csub_x);
2281 int xphase = px.col % csub_x;
2282 int xphase_reset = px.inc * csub_x;
2283 int y, v, u, rv, guv, bu;
2285 v = *vsrc - 128;
2286 vsrc += px.inc;
2287 u = *usrc - 128;
2288 usrc += px.inc;
2289 rv = RVFAC*v;
2290 guv = GUFAC*u + GVFAC*v;
2291 bu = BUFAC*u;
2293 while (1)
2295 y = YFAC*(*ysrc);
2296 ysrc += px.inc;
2297 px.r = y + rv;
2298 px.g = y + guv;
2299 px.b = y + bu;
2301 *dst_row = pixel_func();
2302 dst_row += px.inc;
2304 if (dst_row == row_end)
2305 break;
2307 xphase += px.inc;
2308 if ((unsigned)xphase < (unsigned)csub_x)
2309 continue;
2311 /* fetch new chromas */
2312 v = *vsrc - 128;
2313 vsrc += px.inc;
2314 u = *usrc - 128;
2315 usrc += px.inc;
2316 rv = RVFAC*v;
2317 guv = GUFAC*u + GVFAC*v;
2318 bu = BUFAC*u;
2320 xphase -= xphase_reset;
2323 else /* monochrome */
2327 /* Set all components the same for dithering purposes */
2328 px.g = px.r = px.b = YFAC*(*ysrc);
2329 *dst_row = pixel_func();
2330 ysrc += px.inc;
2331 dst_row += px.inc;
2333 while (dst_row != row_end);
2336 src_y++;
2337 dst += LCD_WIDTH;
2339 while (dst < dst_end);
2342 #endif /* HAVE_LCD_COLOR */
2345 /* support function for qsort() */
2346 static int compare(const void* p1, const void* p2)
2348 return rb->strcasecmp(*((char **)p1), *((char **)p2));
2351 bool jpg_ext(const char ext[])
2353 if(!ext)
2354 return false;
2355 if(!rb->strcasecmp(ext,".jpg") ||
2356 !rb->strcasecmp(ext,".jpe") ||
2357 !rb->strcasecmp(ext,".jpeg"))
2358 return true;
2359 else
2360 return false;
2363 /*Read directory contents for scrolling. */
2364 void get_pic_list(void)
2366 int i;
2367 long int str_len = 0;
2368 char *pname;
2369 tree = rb->tree_get_context();
2371 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2372 file_pt = rb->plugin_get_buffer((size_t *)&buf_size);
2373 #else
2374 file_pt = rb->plugin_get_audio_buffer((size_t *)&buf_size);
2375 #endif
2377 for(i = 0; i < tree->filesindir; i++)
2379 if(jpg_ext(rb->strrchr(&tree->name_buffer[str_len],'.')))
2380 file_pt[entries++] = &tree->name_buffer[str_len];
2382 str_len += rb->strlen(&tree->name_buffer[str_len]) + 1;
2385 rb->qsort(file_pt, entries, sizeof(char**), compare);
2387 /* Remove path and leave only the name.*/
2388 pname = rb->strrchr(np_file,'/');
2389 pname++;
2391 /* Find Selected File. */
2392 for(i = 0; i < entries; i++)
2393 if(!rb->strcmp(file_pt[i], pname))
2394 curfile = i;
2397 int change_filename(int direct)
2399 int count = 0;
2400 direction = direct;
2402 if(direct == DIR_PREV)
2406 count++;
2407 if(curfile == 0)
2408 curfile = entries - 1;
2409 else
2410 curfile--;
2411 }while(file_pt[curfile] == '\0' && count < entries);
2412 /* we "erase" the file name if we encounter
2413 * a non-supported file, so skip it now */
2415 else /* DIR_NEXT/DIR_NONE */
2419 count++;
2420 if(curfile == entries - 1)
2421 curfile = 0;
2422 else
2423 curfile++;
2424 }while(file_pt[curfile] == '\0' && count < entries);
2427 if(count == entries && file_pt[curfile] == '\0')
2429 rb->splash(HZ, "No supported files");
2430 return PLUGIN_ERROR;
2432 if(rb->strlen(tree->currdir) > 1)
2434 rb->strcpy(np_file, tree->currdir);
2435 rb->strcat(np_file, "/");
2437 else
2438 rb->strcpy(np_file, tree->currdir);
2440 rb->strcat(np_file, file_pt[curfile]);
2442 return PLUGIN_OTHER;
2445 /* switch off overlay, for handling SYS_ events */
2446 void cleanup(void *parameter)
2448 (void)parameter;
2449 #ifdef USEGSLIB
2450 grey_show(false);
2451 #endif
2454 #define VSCROLL (LCD_HEIGHT/8)
2455 #define HSCROLL (LCD_WIDTH/10)
2457 #define ZOOM_IN 100 /* return codes for below function */
2458 #define ZOOM_OUT 101
2460 #ifdef HAVE_LCD_COLOR
2461 bool set_option_grayscale(void)
2463 bool gray = jpeg_settings.colour_mode == COLOURMODE_GRAY;
2464 rb->set_bool("Grayscale", &gray);
2465 jpeg_settings.colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
2466 return false;
2469 bool set_option_dithering(void)
2471 static const struct opt_items dithering[DITHER_NUM_MODES] = {
2472 [DITHER_NONE] = { "Off", -1 },
2473 [DITHER_ORDERED] = { "Ordered", -1 },
2474 [DITHER_DIFFUSION] = { "Diffusion", -1 },
2477 rb->set_option("Dithering", &jpeg_settings.dither_mode, INT,
2478 dithering, DITHER_NUM_MODES, NULL);
2479 return false;
2482 static void display_options(void)
2484 static const struct menu_item items[] = {
2485 { "Grayscale", set_option_grayscale },
2486 { "Dithering", set_option_dithering },
2489 int m = menu_init(rb, items, ARRAYLEN(items),
2490 NULL, NULL, NULL, NULL);
2491 menu_run(m);
2492 menu_exit(m);
2494 #endif /* HAVE_LCD_COLOR */
2496 int show_menu(void) /* return 1 to quit */
2498 #if LCD_DEPTH > 1
2499 rb->lcd_set_backdrop(old_backdrop);
2500 #ifdef HAVE_LCD_COLOR
2501 rb->lcd_set_foreground(rb->global_settings->fg_color);
2502 rb->lcd_set_background(rb->global_settings->bg_color);
2503 #else
2504 rb->lcd_set_foreground(LCD_BLACK);
2505 rb->lcd_set_background(LCD_WHITE);
2506 #endif
2507 #endif
2508 int m;
2509 int result;
2511 enum menu_id
2513 MIID_QUIT = 0,
2514 MIID_TOGGLE_SS_MODE,
2515 MIID_CHANGE_SS_MODE,
2516 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2517 MIID_SHOW_PLAYBACK_MENU,
2518 #endif
2519 #ifdef HAVE_LCD_COLOR
2520 MIID_DISPLAY_OPTIONS,
2521 #endif
2522 MIID_RETURN,
2525 static const struct menu_item items[] = {
2526 [MIID_QUIT] =
2527 { "Quit", NULL },
2528 [MIID_TOGGLE_SS_MODE] =
2529 { "Toggle Slideshow Mode", NULL },
2530 [MIID_CHANGE_SS_MODE] =
2531 { "Change Slideshow Time", NULL },
2532 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2533 [MIID_SHOW_PLAYBACK_MENU] =
2534 { "Show Playback Menu", NULL },
2535 #endif
2536 #ifdef HAVE_LCD_COLOR
2537 [MIID_DISPLAY_OPTIONS] =
2538 { "Display Options", NULL },
2539 #endif
2540 [MIID_RETURN] =
2541 { "Return", NULL },
2544 static const struct opt_items slideshow[2] = {
2545 { "Disable", -1 },
2546 { "Enable", -1 },
2549 m = menu_init(rb, items, sizeof(items) / sizeof(*items),
2550 NULL, NULL, NULL, NULL);
2551 result=menu_show(m);
2553 switch (result)
2555 case MIID_QUIT:
2556 menu_exit(m);
2557 return 1;
2558 break;
2559 case MIID_TOGGLE_SS_MODE:
2560 rb->set_option("Toggle Slideshow", &slideshow_enabled, INT,
2561 slideshow , 2, NULL);
2562 break;
2563 case MIID_CHANGE_SS_MODE:
2564 rb->set_int("Slideshow Time", "s", UNIT_SEC,
2565 &jpeg_settings.ss_timeout, NULL, 1,
2566 SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, NULL);
2567 break;
2569 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2570 case MIID_SHOW_PLAYBACK_MENU:
2571 playback_control(rb);
2572 break;
2573 #endif
2574 #ifdef HAVE_LCD_COLOR
2575 case MIID_DISPLAY_OPTIONS:
2576 display_options();
2577 break;
2578 #endif
2579 case MIID_RETURN:
2580 break;
2583 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
2584 /* change ata spindown time based on slideshow time setting */
2585 immediate_ata_off = false;
2586 rb->ata_spindown(rb->global_settings->disk_spindown);
2588 if (slideshow_enabled)
2590 if(jpeg_settings.ss_timeout < 10)
2592 /* slideshow times < 10s keep disk spinning */
2593 rb->ata_spindown(0);
2595 else if (!rb->mp3_is_playing())
2597 /* slideshow times > 10s and not playing: ata_off after load */
2598 immediate_ata_off = true;
2601 #endif
2602 #if LCD_DEPTH > 1
2603 rb->lcd_set_backdrop(NULL);
2604 rb->lcd_set_foreground(LCD_WHITE);
2605 rb->lcd_set_background(LCD_BLACK);
2606 #endif
2607 rb->lcd_clear_display();
2608 menu_exit(m);
2609 return 0;
2611 /* interactively scroll around the image */
2612 int scroll_bmp(struct t_disp* pdisp)
2614 int lastbutton = 0;
2616 while (true)
2618 int button;
2619 int move;
2621 if (slideshow_enabled)
2622 button = rb->button_get_w_tmo(jpeg_settings.ss_timeout * HZ);
2623 else button = rb->button_get(true);
2625 running_slideshow = false;
2627 switch(button)
2629 case JPEG_LEFT:
2630 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2631 return change_filename(DIR_PREV);
2632 case JPEG_LEFT | BUTTON_REPEAT:
2633 move = MIN(HSCROLL, pdisp->x);
2634 if (move > 0)
2636 MYXLCD(scroll_right)(move); /* scroll right */
2637 pdisp->x -= move;
2638 #ifdef HAVE_LCD_COLOR
2639 yuv_bitmap_part(
2640 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2641 pdisp->x, pdisp->y, pdisp->stride,
2642 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2643 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2644 #else
2645 MYXLCD(gray_bitmap_part)(
2646 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2647 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2648 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2649 #endif
2650 MYLCD_UPDATE();
2652 break;
2654 case JPEG_RIGHT:
2655 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2656 return change_filename(DIR_NEXT);
2657 case JPEG_RIGHT | BUTTON_REPEAT:
2658 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
2659 if (move > 0)
2661 MYXLCD(scroll_left)(move); /* scroll left */
2662 pdisp->x += move;
2663 #ifdef HAVE_LCD_COLOR
2664 yuv_bitmap_part(
2665 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2666 pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride,
2667 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2668 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2669 #else
2670 MYXLCD(gray_bitmap_part)(
2671 pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move,
2672 pdisp->y, pdisp->stride,
2673 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2674 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2675 #endif
2676 MYLCD_UPDATE();
2678 break;
2680 case JPEG_UP:
2681 case JPEG_UP | BUTTON_REPEAT:
2682 move = MIN(VSCROLL, pdisp->y);
2683 if (move > 0)
2685 MYXLCD(scroll_down)(move); /* scroll down */
2686 pdisp->y -= move;
2687 #ifdef HAVE_LCD_COLOR
2688 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2690 /* Draw over the band at the top of the last update
2691 caused by lack of error history on line zero. */
2692 move = MIN(move + 1, pdisp->y + pdisp->height);
2695 yuv_bitmap_part(
2696 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2697 pdisp->x, pdisp->y, pdisp->stride,
2698 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2699 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2700 #else
2701 MYXLCD(gray_bitmap_part)(
2702 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2703 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2704 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2705 #endif
2706 MYLCD_UPDATE();
2708 break;
2710 case JPEG_DOWN:
2711 case JPEG_DOWN | BUTTON_REPEAT:
2712 move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT);
2713 if (move > 0)
2715 MYXLCD(scroll_up)(move); /* scroll up */
2716 pdisp->y += move;
2717 #ifdef HAVE_LCD_COLOR
2718 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2720 /* Save the line that was on the last line of the display
2721 and draw one extra line above then recover the line with
2722 image data that had an error history when it was drawn.
2724 move++, pdisp->y--;
2725 MEMCPY(rgb_linebuf,
2726 rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2727 LCD_WIDTH*sizeof (fb_data));
2730 yuv_bitmap_part(
2731 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x,
2732 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2733 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2734 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2736 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2738 /* Cover the first row drawn with previous image data. */
2739 MEMCPY(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2740 rgb_linebuf,
2741 LCD_WIDTH*sizeof (fb_data));
2742 pdisp->y++;
2744 #else
2745 MYXLCD(gray_bitmap_part)(
2746 pdisp->bitmap[0], pdisp->x,
2747 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2748 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2749 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2750 #endif
2751 MYLCD_UPDATE();
2753 break;
2754 case BUTTON_NONE:
2755 if (!slideshow_enabled)
2756 break;
2757 running_slideshow = true;
2758 if (entries > 0)
2759 return change_filename(DIR_NEXT);
2760 break;
2762 #ifdef JPEG_SLIDE_SHOW
2763 case JPEG_SLIDE_SHOW:
2764 slideshow_enabled = !slideshow_enabled;
2765 running_slideshow = slideshow_enabled;
2766 break;
2767 #endif
2769 #ifdef JPEG_NEXT_REPEAT
2770 case JPEG_NEXT_REPEAT:
2771 #endif
2772 case JPEG_NEXT:
2773 if (entries > 0)
2774 return change_filename(DIR_NEXT);
2775 break;
2777 #ifdef JPEG_PREVIOUS_REPEAT
2778 case JPEG_PREVIOUS_REPEAT:
2779 #endif
2780 case JPEG_PREVIOUS:
2781 if (entries > 0)
2782 return change_filename(DIR_PREV);
2783 break;
2785 case JPEG_ZOOM_IN:
2786 #ifdef JPEG_ZOOM_PRE
2787 if (lastbutton != JPEG_ZOOM_PRE)
2788 break;
2789 #endif
2790 return ZOOM_IN;
2791 break;
2793 case JPEG_ZOOM_OUT:
2794 #ifdef JPEG_ZOOM_PRE
2795 if (lastbutton != JPEG_ZOOM_PRE)
2796 break;
2797 #endif
2798 return ZOOM_OUT;
2799 break;
2800 #ifdef JPEG_RC_MENU
2801 case JPEG_RC_MENU:
2802 #endif
2803 case JPEG_MENU:
2804 #ifdef USEGSLIB
2805 grey_show(false); /* switch off greyscale overlay */
2806 #endif
2807 if (show_menu() == 1)
2808 return PLUGIN_OK;
2810 #ifdef USEGSLIB
2811 grey_show(true); /* switch on greyscale overlay */
2812 #else
2813 yuv_bitmap_part(
2814 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2815 pdisp->x, pdisp->y, pdisp->stride,
2816 MAX(0, (LCD_WIDTH - pdisp->width) / 2),
2817 MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
2818 MIN(LCD_WIDTH, pdisp->width),
2819 MIN(LCD_HEIGHT, pdisp->height));
2820 MYLCD_UPDATE();
2821 #endif
2822 break;
2823 default:
2824 if (rb->default_event_handler_ex(button, cleanup, NULL)
2825 == SYS_USB_CONNECTED)
2826 return PLUGIN_USB_CONNECTED;
2827 break;
2829 } /* switch */
2831 if (button != BUTTON_NONE)
2832 lastbutton = button;
2833 } /* while (true) */
2836 /********************* main function *************************/
2838 /* callback updating a progress meter while JPEG decoding */
2839 void cb_progess(int current, int total)
2841 rb->yield(); /* be nice to the other threads */
2842 if(!running_slideshow)
2844 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-8, LCD_WIDTH, 8, total, 0,
2845 current, HORIZONTAL);
2846 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
2848 #ifndef USEGSLIB
2849 else
2851 /* in slideshow mode, keep gui interference to a minimum */
2852 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-4, LCD_WIDTH, 4, total, 0,
2853 current, HORIZONTAL);
2854 rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4);
2856 #endif
2859 int jpegmem(struct jpeg *p_jpg, int ds)
2861 int size;
2863 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
2864 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
2865 #ifdef HAVE_LCD_COLOR
2866 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
2868 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
2869 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
2870 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
2871 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
2873 #endif
2874 return size;
2877 /* how far can we zoom in without running out of memory */
2878 int min_downscale(struct jpeg *p_jpg, int bufsize)
2880 int downscale = 8;
2882 if (jpegmem(p_jpg, 8) > bufsize)
2883 return 0; /* error, too large, even 1:8 doesn't fit */
2885 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
2886 downscale /= 2;
2888 return downscale;
2892 /* how far can we zoom out, to fit image into the LCD */
2893 int max_downscale(struct jpeg *p_jpg)
2895 int downscale = 1;
2897 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale
2898 || p_jpg->y_size > LCD_HEIGHT*downscale))
2900 downscale *= 2;
2903 return downscale;
2907 /* return decoded or cached image */
2908 struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2910 int w, h; /* used to center output */
2911 int size; /* decompressed image size */
2912 long time; /* measured ticks */
2913 int status;
2915 struct t_disp* p_disp = &disp[ds]; /* short cut */
2917 if (p_disp->bitmap[0] != NULL)
2919 return p_disp; /* we still have it */
2922 /* assign image buffer */
2924 /* physical size needed for decoding */
2925 size = jpegmem(p_jpg, ds);
2926 if (buf_size <= size)
2927 { /* have to discard the current */
2928 int i;
2929 for (i=1; i<=8; i++)
2930 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
2931 buf = buf_root; /* start again from the beginning of the buffer */
2932 buf_size = root_size;
2935 #ifdef HAVE_LCD_COLOR
2936 if (p_jpg->blocks > 1) /* colour jpeg */
2938 int i;
2940 for (i = 1; i < 3; i++)
2942 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
2943 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
2944 p_disp->bitmap[i] = buf;
2945 buf += size;
2946 buf_size -= size;
2948 p_disp->csub_x = p_jpg->subsample_x[1];
2949 p_disp->csub_y = p_jpg->subsample_y[1];
2951 else
2953 p_disp->csub_x = p_disp->csub_y = 0;
2954 p_disp->bitmap[1] = p_disp->bitmap[2] = buf;
2956 #endif
2957 /* size may be less when decoded (if height is not block aligned) */
2958 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
2959 p_disp->bitmap[0] = buf;
2960 buf += size;
2961 buf_size -= size;
2963 if(!running_slideshow)
2965 rb->snprintf(print, sizeof(print), "decoding %d*%d",
2966 p_jpg->x_size/ds, p_jpg->y_size/ds);
2967 rb->lcd_puts(0, 3, print);
2968 rb->lcd_update();
2971 /* update image properties */
2972 p_disp->width = p_jpg->x_size / ds;
2973 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
2974 p_disp->height = p_jpg->y_size / ds;
2976 /* the actual decoding */
2977 time = *rb->current_tick;
2978 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2979 rb->cpu_boost(true);
2980 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2981 rb->cpu_boost(false);
2982 #else
2983 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2984 #endif
2985 if (status)
2987 rb->splash(HZ, "decode error %d", status);
2988 file_pt[curfile] = '\0';
2989 return NULL;
2991 time = *rb->current_tick - time;
2993 if(!running_slideshow)
2995 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
2996 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
2997 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
2998 rb->lcd_update();
3001 return p_disp;
3005 /* set the view to the given center point, limit if necessary */
3006 void set_view (struct t_disp* p_disp, int cx, int cy)
3008 int x, y;
3010 /* plain center to available width/height */
3011 x = cx - MIN(LCD_WIDTH, p_disp->width) / 2;
3012 y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2;
3014 /* limit against upper image size */
3015 x = MIN(p_disp->width - LCD_WIDTH, x);
3016 y = MIN(p_disp->height - LCD_HEIGHT, y);
3018 /* limit against negative side */
3019 x = MAX(0, x);
3020 y = MAX(0, y);
3022 p_disp->x = x; /* set the values */
3023 p_disp->y = y;
3027 /* calculate the view center based on the bitmap position */
3028 void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
3030 *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2;
3031 *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2;
3035 /* load, decode, display the image */
3036 int load_and_show(char* filename)
3038 int fd;
3039 int filesize;
3040 unsigned char* buf_jpeg; /* compressed JPEG image */
3041 int status;
3042 struct t_disp* p_disp; /* currenly displayed image */
3043 int cx, cy; /* view center */
3045 fd = rb->open(filename, O_RDONLY);
3046 if (fd < 0)
3048 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
3049 rb->splash(HZ, print);
3050 return PLUGIN_ERROR;
3052 filesize = rb->filesize(fd);
3053 rb->memset(&disp, 0, sizeof(disp));
3055 buf = buf_images + filesize;
3056 buf_size = buf_images_size - filesize;
3057 /* allocate JPEG buffer */
3058 buf_jpeg = buf_images;
3060 buf_root = buf; /* we can start the decompressed images behind it */
3061 root_size = buf_size;
3063 if (buf_size <= 0)
3065 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
3066 if(plug_buf)
3068 rb->close(fd);
3069 rb->lcd_setfont(FONT_SYSFIXED);
3070 rb->lcd_clear_display();
3071 rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
3072 rb->lcd_puts(0,0,print);
3073 rb->lcd_puts(0,1,"Not enough plugin memory!");
3074 rb->lcd_puts(0,2,"Zoom In: Stop playback.");
3075 if(entries>1)
3076 rb->lcd_puts(0,3,"Left/Right: Skip File.");
3077 rb->lcd_puts(0,4,"Off: Quit.");
3078 rb->lcd_update();
3079 rb->lcd_setfont(FONT_UI);
3081 rb->button_clear_queue();
3083 while (1)
3085 int button = rb->button_get(true);
3086 switch(button)
3088 case JPEG_ZOOM_IN:
3089 plug_buf = false;
3090 buf_images = rb->plugin_get_audio_buffer(
3091 (size_t *)&buf_images_size);
3092 /*try again this file, now using the audio buffer */
3093 return PLUGIN_OTHER;
3094 #ifdef JPEG_RC_MENU
3095 case JPEG_RC_MENU:
3096 #endif
3097 case JPEG_MENU:
3098 return PLUGIN_OK;
3100 case JPEG_LEFT:
3101 if(entries>1)
3103 rb->lcd_clear_display();
3104 return change_filename(DIR_PREV);
3106 break;
3108 case JPEG_RIGHT:
3109 if(entries>1)
3111 rb->lcd_clear_display();
3112 return change_filename(DIR_NEXT);
3114 break;
3115 default:
3116 if(rb->default_event_handler_ex(button, cleanup, NULL)
3117 == SYS_USB_CONNECTED)
3118 return PLUGIN_USB_CONNECTED;
3123 else
3124 #endif
3126 rb->splash(HZ, "Out of Memory");
3127 rb->close(fd);
3128 return PLUGIN_ERROR;
3132 if(!running_slideshow)
3134 #if LCD_DEPTH > 1
3135 rb->lcd_set_foreground(LCD_WHITE);
3136 rb->lcd_set_background(LCD_BLACK);
3137 rb->lcd_set_backdrop(NULL);
3138 #endif
3140 rb->lcd_clear_display();
3141 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
3142 rb->lcd_puts(0, 0, print);
3143 rb->lcd_update();
3145 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
3146 rb->lcd_puts(0, 1, print);
3147 rb->lcd_update();
3150 rb->read(fd, buf_jpeg, filesize);
3151 rb->close(fd);
3153 if(!running_slideshow)
3155 rb->snprintf(print, sizeof(print), "decoding markers");
3156 rb->lcd_puts(0, 2, print);
3157 rb->lcd_update();
3159 #ifndef SIMULATOR
3160 else if(immediate_ata_off)
3162 /* running slideshow and time is long enough: power down disk */
3163 rb->ata_sleep();
3165 #endif
3167 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
3168 /* process markers, unstuffing */
3169 status = process_markers(buf_jpeg, filesize, &jpg);
3171 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
3172 { /* bad format or minimum components not contained */
3173 rb->splash(HZ, "unsupported %d", status);
3174 file_pt[curfile] = '\0';
3175 return change_filename(direction);
3178 if (!(status & DHT)) /* if no Huffman table present: */
3179 default_huff_tbl(&jpg); /* use default */
3180 build_lut(&jpg); /* derive Huffman and other lookup-tables */
3182 if(!running_slideshow)
3184 rb->snprintf(print, sizeof(print), "image %dx%d", jpg.x_size, jpg.y_size);
3185 rb->lcd_puts(0, 2, print);
3186 rb->lcd_update();
3188 ds_max = max_downscale(&jpg); /* check display constraint */
3189 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */
3190 if (ds_min == 0)
3192 rb->splash(HZ, "too large");
3193 file_pt[curfile] = '\0';
3194 return change_filename(direction);
3197 ds = ds_max; /* initials setting */
3198 cx = jpg.x_size/ds/2; /* center the view */
3199 cy = jpg.y_size/ds/2;
3201 do /* loop the image prepare and decoding when zoomed */
3203 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */
3204 if (p_disp == NULL)
3205 return change_filename(direction);
3207 set_view(p_disp, cx, cy);
3209 if(!running_slideshow)
3211 rb->snprintf(print, sizeof(print), "showing %dx%d",
3212 p_disp->width, p_disp->height);
3213 rb->lcd_puts(0, 3, print);
3214 rb->lcd_update();
3216 MYLCD(clear_display)();
3217 #ifdef HAVE_LCD_COLOR
3218 yuv_bitmap_part(
3219 p_disp->bitmap, p_disp->csub_x, p_disp->csub_y,
3220 p_disp->x, p_disp->y, p_disp->stride,
3221 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3222 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3223 MIN(LCD_WIDTH, p_disp->width),
3224 MIN(LCD_HEIGHT, p_disp->height));
3225 #else
3226 MYXLCD(gray_bitmap_part)(
3227 p_disp->bitmap[0], p_disp->x, p_disp->y, p_disp->stride,
3228 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3229 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3230 MIN(LCD_WIDTH, p_disp->width),
3231 MIN(LCD_HEIGHT, p_disp->height));
3232 #endif
3233 MYLCD_UPDATE();
3235 #ifdef USEGSLIB
3236 grey_show(true); /* switch on greyscale overlay */
3237 #endif
3239 /* drawing is now finished, play around with scrolling
3240 * until you press OFF or connect USB
3242 while (1)
3244 status = scroll_bmp(p_disp);
3245 if (status == ZOOM_IN)
3247 if (ds > ds_min)
3249 ds /= 2; /* reduce downscaling to zoom in */
3250 get_view(p_disp, &cx, &cy);
3251 cx *= 2; /* prepare the position in the new image */
3252 cy *= 2;
3254 else
3255 continue;
3258 if (status == ZOOM_OUT)
3260 if (ds < ds_max)
3262 ds *= 2; /* increase downscaling to zoom out */
3263 get_view(p_disp, &cx, &cy);
3264 cx /= 2; /* prepare the position in the new image */
3265 cy /= 2;
3267 else
3268 continue;
3270 break;
3273 #ifdef USEGSLIB
3274 grey_show(false); /* switch off overlay */
3275 #endif
3276 rb->lcd_clear_display();
3278 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
3279 && status != PLUGIN_OTHER);
3280 #ifdef USEGSLIB
3281 rb->lcd_update();
3282 #endif
3283 return status;
3286 /******************** Plugin entry point *********************/
3288 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
3290 rb = api;
3292 int condition;
3293 #ifdef USEGSLIB
3294 long greysize; /* helper */
3295 #endif
3296 #if LCD_DEPTH > 1
3297 old_backdrop = rb->lcd_get_backdrop();
3298 #endif
3300 if(!parameter) return PLUGIN_ERROR;
3302 rb->strcpy(np_file, parameter);
3303 get_pic_list();
3305 if(!entries) return PLUGIN_ERROR;
3307 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
3308 if(rb->audio_status())
3310 buf = rb->plugin_get_buffer((size_t *)&buf_size) +
3311 (entries * sizeof(char**));
3312 buf_size -= (entries * sizeof(char**));
3313 plug_buf = true;
3315 else
3316 buf = rb->plugin_get_audio_buffer((size_t *)&buf_size);
3317 #else
3318 buf = rb->plugin_get_audio_buffer(&buf_size) +
3319 (entries * sizeof(char**));
3320 buf_size -= (entries * sizeof(char**));
3321 #endif
3323 #ifdef USEGSLIB
3324 if (!grey_init(rb, buf, buf_size, 0, LCD_WIDTH, LCD_HEIGHT, &greysize))
3326 rb->splash(HZ, "grey buf error");
3327 return PLUGIN_ERROR;
3329 buf += greysize;
3330 buf_size -= greysize;
3331 #else
3332 xlcd_init(rb);
3333 #endif
3335 /* should be ok to just load settings since a parameter is present
3336 here and the drive should be spinning */
3337 configfile_init(rb);
3338 configfile_load(JPEG_CONFIGFILE, jpeg_config,
3339 ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION);
3340 old_settings = jpeg_settings;
3342 buf_images = buf; buf_images_size = buf_size;
3344 /* Turn off backlight timeout */
3345 backlight_force_on(rb); /* backlight control in lib/helper.c */
3349 condition = load_and_show(np_file);
3350 }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
3351 && condition != PLUGIN_ERROR);
3353 if (rb->memcmp(&jpeg_settings, &old_settings, sizeof (jpeg_settings)))
3355 /* Just in case drive has to spin, keep it from looking locked */
3356 rb->splash(0, "Saving Settings");
3357 configfile_save(JPEG_CONFIGFILE, jpeg_config,
3358 ARRAYLEN(jpeg_config), JPEG_SETTINGS_VERSION);
3361 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
3362 /* set back ata spindown time in case we changed it */
3363 rb->ata_spindown(rb->global_settings->disk_spindown);
3364 #endif
3366 /* Turn on backlight timeout (revert to settings) */
3367 backlight_use_settings(rb); /* backlight control in lib/helper.c */
3369 #ifdef USEGSLIB
3370 grey_release(); /* deinitialize */
3371 #endif
3373 return condition;
3376 #endif /* HAVE_LCD_BITMAP */