Accept FS#7228 by Dagni McPhee enable pitchscreen on sansa
[Rockbox.git] / apps / plugins / jpeg.c
blobff6df6d4e339484279838d9709951ec0ff6d86de
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�g Hohensohn aka [IDC]Dragon
15 * Grayscale framework (C) 2004 Jens Arnold
16 * Heavily borrowed from the IJG implementation (C) Thomas G. Lane
17 * Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
19 * All files in this archive are subject to the GNU General Public License.
20 * See the file COPYING in the source tree root for full license agreement.
22 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
23 * KIND, either express or implied.
25 ****************************************************************************/
27 #include "plugin.h"
28 #include "playback_control.h"
29 #include "oldmenuapi.h"
31 #ifdef HAVE_LCD_BITMAP
32 #include "gray.h"
33 #include "xlcd.h"
35 #ifdef HAVE_LCD_COLOR
36 #include "lib/configfile.h"
37 #endif
39 PLUGIN_HEADER
41 /* variable button definitions */
42 #if CONFIG_KEYPAD == RECORDER_PAD
43 #define JPEG_ZOOM_IN BUTTON_PLAY
44 #define JPEG_ZOOM_OUT BUTTON_ON
45 #define JPEG_UP BUTTON_UP
46 #define JPEG_DOWN BUTTON_DOWN
47 #define JPEG_LEFT BUTTON_LEFT
48 #define JPEG_RIGHT BUTTON_RIGHT
49 #define JPEG_NEXT BUTTON_F3
50 #define JPEG_PREVIOUS BUTTON_F2
51 #define JPEG_MENU BUTTON_OFF
53 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
54 #define JPEG_ZOOM_IN BUTTON_SELECT
55 #define JPEG_ZOOM_OUT BUTTON_ON
56 #define JPEG_UP BUTTON_UP
57 #define JPEG_DOWN BUTTON_DOWN
58 #define JPEG_LEFT BUTTON_LEFT
59 #define JPEG_RIGHT BUTTON_RIGHT
60 #define JPEG_NEXT BUTTON_F3
61 #define JPEG_PREVIOUS BUTTON_F2
62 #define JPEG_MENU BUTTON_OFF
64 #elif CONFIG_KEYPAD == ONDIO_PAD
65 #define JPEG_ZOOM_PRE BUTTON_MENU
66 #define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
67 #define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
68 #define JPEG_UP BUTTON_UP
69 #define JPEG_DOWN BUTTON_DOWN
70 #define JPEG_LEFT BUTTON_LEFT
71 #define JPEG_RIGHT BUTTON_RIGHT
72 #define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
73 #define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
74 #define JPEG_MENU BUTTON_OFF
76 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
77 (CONFIG_KEYPAD == IRIVER_H300_PAD)
78 #define JPEG_ZOOM_IN BUTTON_SELECT
79 #define JPEG_ZOOM_OUT BUTTON_MODE
80 #define JPEG_UP BUTTON_UP
81 #define JPEG_DOWN BUTTON_DOWN
82 #define JPEG_LEFT BUTTON_LEFT
83 #define JPEG_RIGHT BUTTON_RIGHT
84 #if (CONFIG_KEYPAD == IRIVER_H100_PAD)
85 #define JPEG_NEXT BUTTON_ON
86 #define JPEG_PREVIOUS BUTTON_REC
87 #else
88 #define JPEG_NEXT BUTTON_REC
89 #define JPEG_PREVIOUS BUTTON_ON
90 #endif
91 #define JPEG_MENU BUTTON_OFF
92 #define JPEG_RC_MENU BUTTON_RC_STOP
94 #elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
95 #define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
96 #define JPEG_ZOOM_OUT BUTTON_SCROLL_BACK
97 #define JPEG_UP BUTTON_MENU
98 #define JPEG_DOWN BUTTON_PLAY
99 #define JPEG_LEFT BUTTON_LEFT
100 #define JPEG_RIGHT BUTTON_RIGHT
101 #define JPEG_MENU (BUTTON_SELECT | BUTTON_MENU)
102 #define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
103 #define JPEG_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
105 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
106 #define JPEG_ZOOM_PRE BUTTON_SELECT
107 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
108 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
109 #define JPEG_UP BUTTON_UP
110 #define JPEG_DOWN BUTTON_DOWN
111 #define JPEG_LEFT BUTTON_LEFT
112 #define JPEG_RIGHT BUTTON_RIGHT
113 #define JPEG_MENU BUTTON_POWER
114 #define JPEG_NEXT BUTTON_PLAY
115 #define JPEG_PREVIOUS BUTTON_REC
117 #elif CONFIG_KEYPAD == GIGABEAT_PAD
118 #define JPEG_ZOOM_IN BUTTON_VOL_UP
119 #define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
120 #define JPEG_UP BUTTON_UP
121 #define JPEG_DOWN BUTTON_DOWN
122 #define JPEG_LEFT BUTTON_LEFT
123 #define JPEG_RIGHT BUTTON_RIGHT
124 #define JPEG_MENU BUTTON_MENU
125 #define JPEG_NEXT (BUTTON_A | BUTTON_RIGHT)
126 #define JPEG_PREVIOUS (BUTTON_A | BUTTON_LEFT)
128 #elif CONFIG_KEYPAD == SANSA_E200_PAD
129 #define JPEG_ZOOM_PRE BUTTON_SELECT
130 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
131 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
132 #define JPEG_UP BUTTON_UP
133 #define JPEG_DOWN BUTTON_DOWN
134 #define JPEG_LEFT BUTTON_LEFT
135 #define JPEG_RIGHT BUTTON_RIGHT
136 #define JPEG_MENU BUTTON_REC
137 #define JPEG_NEXT BUTTON_SCROLL_DOWN
138 #define JPEG_NEXT_REPEAT (BUTTON_SCROLL_DOWN|BUTTON_REPEAT)
139 #define JPEG_PREVIOUS BUTTON_SCROLL_UP
140 #define JPEG_PREVIOUS_REPEAT (BUTTON_SCROLL_UP|BUTTON_REPEAT)
142 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
143 #define JPEG_ZOOM_PRE BUTTON_PLAY
144 #define JPEG_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
145 #define JPEG_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
146 #define JPEG_UP BUTTON_SCROLL_UP
147 #define JPEG_DOWN BUTTON_SCROLL_DOWN
148 #define JPEG_LEFT BUTTON_LEFT
149 #define JPEG_RIGHT BUTTON_RIGHT
150 #define JPEG_MENU BUTTON_POWER
151 #define JPEG_NEXT BUTTON_FF
152 #define JPEG_PREVIOUS BUTTON_REW
154 #endif
156 /* different graphics libraries */
157 #if LCD_DEPTH < 8
158 #define USEGSLIB
159 #define MYLCD(fn) gray_ub_ ## fn
160 #define MYLCD_UPDATE()
161 #define MYXLCD(fn) gray_ub_ ## fn
162 #else
163 #define MYLCD(fn) rb->lcd_ ## fn
164 #define MYLCD_UPDATE() rb->lcd_update();
165 #define MYXLCD(fn) xlcd_ ## fn
166 #endif
168 #define MAX_X_SIZE LCD_WIDTH*8
170 /* Min memory allowing us to use the plugin buffer
171 * and thus not stopping the music
172 * *Very* rough estimation:
173 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
174 * + 20k code size = 60 000
175 * + 50k min for jpeg = 120 000
177 #define MIN_MEM 120000
179 /* Headings */
180 #define DIR_PREV 1
181 #define DIR_NEXT -1
182 #define DIR_NONE 0
184 #define PLUGIN_OTHER 10 /* State code for output with return. */
186 /******************************* Globals ***********************************/
188 static struct plugin_api* rb;
190 /* for portability of below JPEG code */
191 #define MEMSET(p,v,c) rb->memset(p,v,c)
192 #define MEMCPY(d,s,c) rb->memcpy(d,s,c)
193 #define INLINE static inline
194 #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
196 static int slideshow_enabled = false; /* run slideshow */
197 static int running_slideshow = false; /* loading image because of slideshw */
198 #ifndef SIMULATOR
199 static int immediate_ata_off = false; /* power down disk after loading */
200 #endif
201 static int button_timeout = HZ*5;
203 #ifdef HAVE_LCD_COLOR
205 /* Persistent configuration - only needed for color displays atm */
206 #define JPEG_CONFIGFILE "jpeg.cfg"
207 #define JPEG_SETTINGS_MINVERSION 1
208 #define JPEG_SETTINGS_VERSION 1
210 enum color_modes
212 COLOURMODE_COLOUR = 0,
213 COLOURMODE_GRAY,
214 COLOUR_NUM_MODES
217 enum dither_modes
219 DITHER_NONE = 0, /* No dithering */
220 DITHER_ORDERED, /* Bayer ordered */
221 DITHER_DIFFUSION, /* Floyd/Steinberg error diffusion */
222 DITHER_NUM_MODES
225 struct jpeg_settings
227 int colour_mode;
228 int dither_mode;
231 static struct jpeg_settings jpeg_settings =
232 { COLOURMODE_COLOUR, DITHER_NONE };
233 static struct jpeg_settings old_settings;
235 static struct configdata jpeg_config[] =
237 { TYPE_ENUM, 0, COLOUR_NUM_MODES, &jpeg_settings.colour_mode,
238 "Colour Mode", (char *[]){ "Colour", "Grayscale" }, NULL },
239 { TYPE_ENUM, 0, DITHER_NUM_MODES, &jpeg_settings.dither_mode,
240 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" }, NULL },
243 #endif /* HAVE_LCD_COLOR */
244 #if LCD_DEPTH > 1
245 fb_data* old_backdrop;
246 #endif
248 /**************** begin JPEG code ********************/
250 INLINE unsigned range_limit(int value)
252 #if CONFIG_CPU == SH7034
253 unsigned tmp;
254 asm ( /* Note: Uses knowledge that only low byte of result is used */
255 "mov #-128,%[t] \n"
256 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
257 "extu.b %[v],%[t] \n"
258 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
259 "bt 1f \n" /* yes: no overflow */
260 "cmp/pz %[v] \n" /* overflow: positive? */
261 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
262 "1: \n"
263 : /* outputs */
264 [v]"+r"(value),
265 [t]"=&r"(tmp)
267 return value;
268 #elif defined(CPU_COLDFIRE)
269 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
270 "add.l #128,%[v] \n" /* value += 128; */
271 "cmp.l #255,%[v] \n" /* overflow? */
272 "bls.b 1f \n" /* no: return value */
273 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
274 "1: \n"
275 : /* outputs */
276 [v]"+d"(value)
278 return value;
279 #elif defined(CPU_ARM)
280 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
281 "add %[v], %[v], #128 \n" /* value += 128 */
282 "cmp %[v], #255 \n" /* out of range 0..255? */
283 "mvnhi %[v], %[v], asr #31 \n" /* yes: set all bits to ~(sign_bit) */
284 : /* outputs */
285 [v]"+r"(value)
287 return value;
288 #else
289 value += 128;
291 if ((unsigned)value <= 255)
292 return value;
294 if (value < 0)
295 return 0;
297 return 255;
298 #endif
301 /* IDCT implementation */
304 #define CONST_BITS 13
305 #define PASS1_BITS 2
308 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
309 * causing a lot of useless floating-point operations at run time.
310 * To get around this we use the following pre-calculated constants.
311 * If you change CONST_BITS you may want to add appropriate values.
312 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
314 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
315 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
316 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
317 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
318 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
319 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
320 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
321 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
322 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
323 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
324 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
325 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
329 /* Multiply an long variable by an long constant to yield an long result.
330 * For 8-bit samples with the recommended scaling, all the variable
331 * and constant values involved are no more than 16 bits wide, so a
332 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
333 * For 12-bit samples, a full 32-bit multiplication will be needed.
335 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
338 /* Dequantize a coefficient by multiplying it by the multiplier-table
339 * entry; produce an int result. In this module, both inputs and result
340 * are 16 bits or less, so either int or short multiply will work.
342 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
343 #define DEQUANTIZE MULTIPLY16
345 /* Descale and correctly round an int value that's scaled by N bits.
346 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
347 * the fudge factor is correct for either sign of X.
349 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
354 * Perform dequantization and inverse DCT on one block of coefficients,
355 * producing a reduced-size 1x1 output block.
357 void idct1x1(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
359 (void)skip_line; /* unused */
360 *p_byte = range_limit(inptr[0] * quantptr[0] >> 3);
366 * Perform dequantization and inverse DCT on one block of coefficients,
367 * producing a reduced-size 2x2 output block.
369 void idct2x2(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
371 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
372 unsigned char* outptr;
374 /* Pass 1: process columns from input, store into work array. */
376 /* Column 0 */
377 tmp4 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
378 tmp5 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
380 tmp0 = tmp4 + tmp5;
381 tmp2 = tmp4 - tmp5;
383 /* Column 1 */
384 tmp4 = DEQUANTIZE(inptr[8*0+1], quantptr[8*0+1]);
385 tmp5 = DEQUANTIZE(inptr[8*1+1], quantptr[8*1+1]);
387 tmp1 = tmp4 + tmp5;
388 tmp3 = tmp4 - tmp5;
390 /* Pass 2: process 2 rows, store into output array. */
392 /* Row 0 */
393 outptr = p_byte;
395 outptr[0] = range_limit((int) DESCALE(tmp0 + tmp1, 3));
396 outptr[1] = range_limit((int) DESCALE(tmp0 - tmp1, 3));
398 /* Row 1 */
399 outptr = p_byte + skip_line;
401 outptr[0] = range_limit((int) DESCALE(tmp2 + tmp3, 3));
402 outptr[1] = range_limit((int) DESCALE(tmp2 - tmp3, 3));
408 * Perform dequantization and inverse DCT on one block of coefficients,
409 * producing a reduced-size 4x4 output block.
411 void idct4x4(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
413 int tmp0, tmp2, tmp10, tmp12;
414 int z1, z2, z3;
415 int * wsptr;
416 unsigned char* outptr;
417 int ctr;
418 int workspace[4*4]; /* buffers data between passes */
420 /* Pass 1: process columns from input, store into work array. */
422 wsptr = workspace;
423 for (ctr = 0; ctr < 4; ctr++, inptr++, quantptr++, wsptr++)
425 /* Even part */
427 tmp0 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
428 tmp2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
430 tmp10 = (tmp0 + tmp2) << PASS1_BITS;
431 tmp12 = (tmp0 - tmp2) << PASS1_BITS;
433 /* Odd part */
434 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
436 z2 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
437 z3 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
439 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
440 tmp0 = DESCALE(z1 + MULTIPLY16(z3, - FIX_1_847759065), CONST_BITS-PASS1_BITS);
441 tmp2 = DESCALE(z1 + MULTIPLY16(z2, FIX_0_765366865), CONST_BITS-PASS1_BITS);
443 /* Final output stage */
445 wsptr[4*0] = (int) (tmp10 + tmp2);
446 wsptr[4*3] = (int) (tmp10 - tmp2);
447 wsptr[4*1] = (int) (tmp12 + tmp0);
448 wsptr[4*2] = (int) (tmp12 - tmp0);
451 /* Pass 2: process 4 rows from work array, store into output array. */
453 wsptr = workspace;
454 for (ctr = 0; ctr < 4; ctr++)
456 outptr = p_byte + (ctr*skip_line);
457 /* Even part */
459 tmp0 = (int) wsptr[0];
460 tmp2 = (int) wsptr[2];
462 tmp10 = (tmp0 + tmp2) << CONST_BITS;
463 tmp12 = (tmp0 - tmp2) << CONST_BITS;
465 /* Odd part */
466 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
468 z2 = (int) wsptr[1];
469 z3 = (int) wsptr[3];
471 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
472 tmp0 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
473 tmp2 = z1 + MULTIPLY16(z2, FIX_0_765366865);
475 /* Final output stage */
477 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp2,
478 CONST_BITS+PASS1_BITS+3));
479 outptr[3] = range_limit((int) DESCALE(tmp10 - tmp2,
480 CONST_BITS+PASS1_BITS+3));
481 outptr[1] = range_limit((int) DESCALE(tmp12 + tmp0,
482 CONST_BITS+PASS1_BITS+3));
483 outptr[2] = range_limit((int) DESCALE(tmp12 - tmp0,
484 CONST_BITS+PASS1_BITS+3));
486 wsptr += 4; /* advance pointer to next row */
493 * Perform dequantization and inverse DCT on one block of coefficients.
495 void idct8x8(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line)
497 long tmp0, tmp1, tmp2, tmp3;
498 long tmp10, tmp11, tmp12, tmp13;
499 long z1, z2, z3, z4, z5;
500 int * wsptr;
501 unsigned char* outptr;
502 int ctr;
503 int workspace[64]; /* buffers data between passes */
505 /* Pass 1: process columns from input, store into work array. */
506 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
507 /* furthermore, we scale the results by 2**PASS1_BITS. */
509 wsptr = workspace;
510 for (ctr = 8; ctr > 0; ctr--)
512 /* Due to quantization, we will usually find that many of the input
513 * coefficients are zero, especially the AC terms. We can exploit this
514 * by short-circuiting the IDCT calculation for any column in which all
515 * the AC terms are zero. In that case each output is equal to the
516 * DC coefficient (with scale factor as needed).
517 * With typical images and quantization tables, half or more of the
518 * column DCT calculations can be simplified this way.
521 if ((inptr[8*1] | inptr[8*2] | inptr[8*3]
522 | inptr[8*4] | inptr[8*5] | inptr[8*6] | inptr[8*7]) == 0)
524 /* AC terms all zero */
525 int dcval = DEQUANTIZE(inptr[8*0], quantptr[8*0]) << PASS1_BITS;
527 wsptr[8*0] = wsptr[8*1] = wsptr[8*2] = wsptr[8*3] = wsptr[8*4]
528 = wsptr[8*5] = wsptr[8*6] = wsptr[8*7] = dcval;
529 inptr++; /* advance pointers to next column */
530 quantptr++;
531 wsptr++;
532 continue;
535 /* Even part: reverse the even part of the forward DCT. */
536 /* The rotator is sqrt(2)*c(-6). */
538 z2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]);
539 z3 = DEQUANTIZE(inptr[8*6], quantptr[8*6]);
541 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
542 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
543 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
545 z2 = DEQUANTIZE(inptr[8*0], quantptr[8*0]);
546 z3 = DEQUANTIZE(inptr[8*4], quantptr[8*4]);
548 tmp0 = (z2 + z3) << CONST_BITS;
549 tmp1 = (z2 - z3) << CONST_BITS;
551 tmp10 = tmp0 + tmp3;
552 tmp13 = tmp0 - tmp3;
553 tmp11 = tmp1 + tmp2;
554 tmp12 = tmp1 - tmp2;
556 /* Odd part per figure 8; the matrix is unitary and hence its
557 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
559 tmp0 = DEQUANTIZE(inptr[8*7], quantptr[8*7]);
560 tmp1 = DEQUANTIZE(inptr[8*5], quantptr[8*5]);
561 tmp2 = DEQUANTIZE(inptr[8*3], quantptr[8*3]);
562 tmp3 = DEQUANTIZE(inptr[8*1], quantptr[8*1]);
564 z1 = tmp0 + tmp3;
565 z2 = tmp1 + tmp2;
566 z3 = tmp0 + tmp2;
567 z4 = tmp1 + tmp3;
568 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
570 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
571 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
572 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
573 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
574 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
575 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
576 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
577 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
579 z3 += z5;
580 z4 += z5;
582 tmp0 += z1 + z3;
583 tmp1 += z2 + z4;
584 tmp2 += z2 + z3;
585 tmp3 += z1 + z4;
587 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
589 wsptr[8*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
590 wsptr[8*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
591 wsptr[8*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
592 wsptr[8*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
593 wsptr[8*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
594 wsptr[8*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
595 wsptr[8*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
596 wsptr[8*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
598 inptr++; /* advance pointers to next column */
599 quantptr++;
600 wsptr++;
603 /* Pass 2: process rows from work array, store into output array. */
604 /* Note that we must descale the results by a factor of 8 == 2**3, */
605 /* and also undo the PASS1_BITS scaling. */
607 wsptr = workspace;
608 for (ctr = 0; ctr < 8; ctr++)
610 outptr = p_byte + (ctr*skip_line);
611 /* Rows of zeroes can be exploited in the same way as we did with columns.
612 * However, the column calculation has created many nonzero AC terms, so
613 * the simplification applies less often (typically 5% to 10% of the time).
614 * On machines with very fast multiplication, it's possible that the
615 * test takes more time than it's worth. In that case this section
616 * may be commented out.
619 #ifndef NO_ZERO_ROW_TEST
620 if ((wsptr[1] | wsptr[2] | wsptr[3]
621 | wsptr[4] | wsptr[5] | wsptr[6] | wsptr[7]) == 0)
623 /* AC terms all zero */
624 unsigned char dcval = range_limit((int) DESCALE((long) wsptr[0],
625 PASS1_BITS+3));
627 outptr[0] = dcval;
628 outptr[1] = dcval;
629 outptr[2] = dcval;
630 outptr[3] = dcval;
631 outptr[4] = dcval;
632 outptr[5] = dcval;
633 outptr[6] = dcval;
634 outptr[7] = dcval;
636 wsptr += 8; /* advance pointer to next row */
637 continue;
639 #endif
641 /* Even part: reverse the even part of the forward DCT. */
642 /* The rotator is sqrt(2)*c(-6). */
644 z2 = (long) wsptr[2];
645 z3 = (long) wsptr[6];
647 z1 = MULTIPLY16(z2 + z3, FIX_0_541196100);
648 tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065);
649 tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865);
651 tmp0 = ((long) wsptr[0] + (long) wsptr[4]) << CONST_BITS;
652 tmp1 = ((long) wsptr[0] - (long) wsptr[4]) << CONST_BITS;
654 tmp10 = tmp0 + tmp3;
655 tmp13 = tmp0 - tmp3;
656 tmp11 = tmp1 + tmp2;
657 tmp12 = tmp1 - tmp2;
659 /* Odd part per figure 8; the matrix is unitary and hence its
660 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
662 tmp0 = (long) wsptr[7];
663 tmp1 = (long) wsptr[5];
664 tmp2 = (long) wsptr[3];
665 tmp3 = (long) wsptr[1];
667 z1 = tmp0 + tmp3;
668 z2 = tmp1 + tmp2;
669 z3 = tmp0 + tmp2;
670 z4 = tmp1 + tmp3;
671 z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
673 tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
674 tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
675 tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
676 tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
677 z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
678 z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
679 z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
680 z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
682 z3 += z5;
683 z4 += z5;
685 tmp0 += z1 + z3;
686 tmp1 += z2 + z4;
687 tmp2 += z2 + z3;
688 tmp3 += z1 + z4;
690 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
692 outptr[0] = range_limit((int) DESCALE(tmp10 + tmp3,
693 CONST_BITS+PASS1_BITS+3));
694 outptr[7] = range_limit((int) DESCALE(tmp10 - tmp3,
695 CONST_BITS+PASS1_BITS+3));
696 outptr[1] = range_limit((int) DESCALE(tmp11 + tmp2,
697 CONST_BITS+PASS1_BITS+3));
698 outptr[6] = range_limit((int) DESCALE(tmp11 - tmp2,
699 CONST_BITS+PASS1_BITS+3));
700 outptr[2] = range_limit((int) DESCALE(tmp12 + tmp1,
701 CONST_BITS+PASS1_BITS+3));
702 outptr[5] = range_limit((int) DESCALE(tmp12 - tmp1,
703 CONST_BITS+PASS1_BITS+3));
704 outptr[3] = range_limit((int) DESCALE(tmp13 + tmp0,
705 CONST_BITS+PASS1_BITS+3));
706 outptr[4] = range_limit((int) DESCALE(tmp13 - tmp0,
707 CONST_BITS+PASS1_BITS+3));
709 wsptr += 8; /* advance pointer to next row */
715 /* JPEG decoder implementation */
718 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
720 struct derived_tbl
722 /* Basic tables: (element [0] of each array is unused) */
723 long mincode[17]; /* smallest code of length k */
724 long maxcode[18]; /* largest code of length k (-1 if none) */
725 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
726 int valptr[17]; /* huffval[] index of 1st symbol of length k */
728 /* Back link to public Huffman table (needed only in slow_DECODE) */
729 int* pub;
731 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
732 the input data stream. If the next Huffman code is no more
733 than HUFF_LOOKAHEAD bits long, we can obtain its length and
734 the corresponding symbol directly from these tables. */
735 int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
736 unsigned char look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
739 #define QUANT_TABLE_LENGTH 64
741 /* for type of Huffman table */
742 #define DC_LEN 28
743 #define AC_LEN 178
745 struct huffman_table
746 { /* length and code according to JFIF format */
747 int huffmancodes_dc[DC_LEN];
748 int huffmancodes_ac[AC_LEN];
751 struct frame_component
753 int ID;
754 int horizontal_sampling;
755 int vertical_sampling;
756 int quanttable_select;
759 struct scan_component
761 int ID;
762 int DC_select;
763 int AC_select;
766 struct bitstream
768 unsigned long get_buffer; /* current bit-extraction buffer */
769 int bits_left; /* # of unused bits in it */
770 unsigned char* next_input_byte;
771 unsigned char* input_end; /* upper limit +1 */
774 struct jpeg
776 int x_size, y_size; /* size of image (can be less than block boundary) */
777 int x_phys, y_phys; /* physical size, block aligned */
778 int x_mbl; /* x dimension of MBL */
779 int y_mbl; /* y dimension of MBL */
780 int blocks; /* blocks per MB */
781 int restart_interval; /* number of MCUs between RSTm markers */
782 int store_pos[4]; /* for Y block ordering */
784 unsigned char* p_entropy_data;
785 unsigned char* p_entropy_end;
787 int quanttable[4][QUANT_TABLE_LENGTH]; /* raw quantization tables 0-3 */
788 int qt_idct[2][QUANT_TABLE_LENGTH]; /* quantization tables for IDCT */
790 struct huffman_table hufftable[2]; /* Huffman tables */
791 struct derived_tbl dc_derived_tbls[2]; /* Huffman-LUTs */
792 struct derived_tbl ac_derived_tbls[2];
794 struct frame_component frameheader[3]; /* Component descriptor */
795 struct scan_component scanheader[3]; /* currently not used */
797 int mcu_membership[6]; /* info per block */
798 int tab_membership[6];
799 int subsample_x[3]; /* info per component */
800 int subsample_y[3];
804 /* possible return flags for process_markers() */
805 #define HUFFTAB 0x0001 /* with huffman table */
806 #define QUANTTAB 0x0002 /* with quantization table */
807 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
808 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
809 #define SOF0 0x0010 /* with SOF0-Segment */
810 #define DHT 0x0020 /* with Definition of huffman tables */
811 #define SOS 0x0040 /* with Start-of-Scan segment */
812 #define DQT 0x0080 /* with definition of quantization table */
814 /* Preprocess the JPEG JFIF file */
815 int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
817 unsigned char* p_bytes = p_src;
818 int marker_size; /* variable length of marker segment */
819 int i, j, n;
820 int ret = 0; /* returned flags */
822 p_jpeg->p_entropy_end = p_src + size;
824 while (p_src < p_bytes + size)
826 if (*p_src++ != 0xFF) /* no marker? */
828 p_src--; /* it's image data, put it back */
829 p_jpeg->p_entropy_data = p_src;
830 break; /* exit marker processing */
833 switch (*p_src++)
835 case 0xFF: /* Fill byte */
836 ret |= FILL_FF;
837 case 0x00: /* Zero stuffed byte - entropy data */
838 p_src--; /* put it back */
839 continue;
841 case 0xC0: /* SOF Huff - Baseline DCT */
843 ret |= SOF0;
844 marker_size = *p_src++ << 8; /* Highbyte */
845 marker_size |= *p_src++; /* Lowbyte */
846 n = *p_src++; /* sample precision (= 8 or 12) */
847 if (n != 8)
849 return(-1); /* Unsupported sample precision */
851 p_jpeg->y_size = *p_src++ << 8; /* Highbyte */
852 p_jpeg->y_size |= *p_src++; /* Lowbyte */
853 p_jpeg->x_size = *p_src++ << 8; /* Highbyte */
854 p_jpeg->x_size |= *p_src++; /* Lowbyte */
856 n = (marker_size-2-6)/3;
857 if (*p_src++ != n || (n != 1 && n != 3))
859 return(-2); /* Unsupported SOF0 component specification */
861 for (i=0; i<n; i++)
863 p_jpeg->frameheader[i].ID = *p_src++; /* Component info */
864 p_jpeg->frameheader[i].horizontal_sampling = *p_src >> 4;
865 p_jpeg->frameheader[i].vertical_sampling = *p_src++ & 0x0F;
866 p_jpeg->frameheader[i].quanttable_select = *p_src++;
867 if (p_jpeg->frameheader[i].horizontal_sampling > 2
868 || p_jpeg->frameheader[i].vertical_sampling > 2)
869 return -3; /* Unsupported SOF0 subsampling */
871 p_jpeg->blocks = n;
873 break;
875 case 0xC1: /* SOF Huff - Extended sequential DCT*/
876 case 0xC2: /* SOF Huff - Progressive DCT*/
877 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
878 case 0xC5: /* SOF Huff - Differential sequential DCT*/
879 case 0xC6: /* SOF Huff - Differential progressive DCT*/
880 case 0xC7: /* SOF Huff - Differential spatial*/
881 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
882 case 0xC9: /* SOF Arith - Extended sequential DCT*/
883 case 0xCA: /* SOF Arith - Progressive DCT*/
884 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
885 case 0xCD: /* SOF Arith - Differential sequential DCT*/
886 case 0xCE: /* SOF Arith - Differential progressive DCT*/
887 case 0xCF: /* SOF Arith - Differential spatial*/
889 return (-4); /* other DCT model than baseline not implemented */
892 case 0xC4: /* Define Huffman Table(s) */
894 unsigned char* p_temp;
896 ret |= DHT;
897 marker_size = *p_src++ << 8; /* Highbyte */
898 marker_size |= *p_src++; /* Lowbyte */
900 p_temp = p_src;
901 while (p_src < p_temp+marker_size-2-17) /* another table */
903 int sum = 0;
904 i = *p_src & 0x0F; /* table index */
905 if (i > 1)
907 return (-5); /* Huffman table index out of range */
909 else if (*p_src++ & 0xF0) /* AC table */
911 for (j=0; j<16; j++)
913 sum += *p_src;
914 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
916 if(16 + sum > AC_LEN)
917 return -10; /* longer than allowed */
919 for (; j < 16 + sum; j++)
920 p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
922 else /* DC table */
924 for (j=0; j<16; j++)
926 sum += *p_src;
927 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
929 if(16 + sum > DC_LEN)
930 return -11; /* longer than allowed */
932 for (; j < 16 + sum; j++)
933 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
935 } /* while */
936 p_src = p_temp+marker_size - 2; /* skip possible residue */
938 break;
940 case 0xCC: /* Define Arithmetic coding conditioning(s) */
941 return(-6); /* Arithmetic coding not supported */
943 case 0xD8: /* Start of Image */
944 case 0xD9: /* End of Image */
945 case 0x01: /* for temp private use arith code */
946 break; /* skip parameterless marker */
949 case 0xDA: /* Start of Scan */
951 ret |= SOS;
952 marker_size = *p_src++ << 8; /* Highbyte */
953 marker_size |= *p_src++; /* Lowbyte */
955 n = (marker_size-2-1-3)/2;
956 if (*p_src++ != n || (n != 1 && n != 3))
958 return (-7); /* Unsupported SOS component specification */
960 for (i=0; i<n; i++)
962 p_jpeg->scanheader[i].ID = *p_src++;
963 p_jpeg->scanheader[i].DC_select = *p_src >> 4;
964 p_jpeg->scanheader[i].AC_select = *p_src++ & 0x0F;
966 p_src += 3; /* skip spectral information */
968 break;
970 case 0xDB: /* Define quantization Table(s) */
972 ret |= DQT;
973 marker_size = *p_src++ << 8; /* Highbyte */
974 marker_size |= *p_src++; /* Lowbyte */
975 n = (marker_size-2)/(QUANT_TABLE_LENGTH+1); /* # of tables */
976 for (i=0; i<n; i++)
978 int id = *p_src++; /* ID */
979 if (id >= 4)
981 return (-8); /* Unsupported quantization table */
983 /* Read Quantisation table: */
984 for (j=0; j<QUANT_TABLE_LENGTH; j++)
985 p_jpeg->quanttable[id][j] = *p_src++;
988 break;
990 case 0xDD: /* Define Restart Interval */
992 marker_size = *p_src++ << 8; /* Highbyte */
993 marker_size |= *p_src++; /* Lowbyte */
994 p_jpeg->restart_interval = *p_src++ << 8; /* Highbyte */
995 p_jpeg->restart_interval |= *p_src++; /* Lowbyte */
996 p_src += marker_size-4; /* skip segment */
998 break;
1000 case 0xDC: /* Define Number of Lines */
1001 case 0xDE: /* Define Hierarchical progression */
1002 case 0xDF: /* Expand Reference Component(s) */
1003 case 0xE0: /* Application Field 0*/
1004 case 0xE1: /* Application Field 1*/
1005 case 0xE2: /* Application Field 2*/
1006 case 0xE3: /* Application Field 3*/
1007 case 0xE4: /* Application Field 4*/
1008 case 0xE5: /* Application Field 5*/
1009 case 0xE6: /* Application Field 6*/
1010 case 0xE7: /* Application Field 7*/
1011 case 0xE8: /* Application Field 8*/
1012 case 0xE9: /* Application Field 9*/
1013 case 0xEA: /* Application Field 10*/
1014 case 0xEB: /* Application Field 11*/
1015 case 0xEC: /* Application Field 12*/
1016 case 0xED: /* Application Field 13*/
1017 case 0xEE: /* Application Field 14*/
1018 case 0xEF: /* Application Field 15*/
1019 case 0xFE: /* Comment */
1021 marker_size = *p_src++ << 8; /* Highbyte */
1022 marker_size |= *p_src++; /* Lowbyte */
1023 p_src += marker_size-2; /* skip segment */
1025 break;
1027 case 0xF0: /* Reserved for JPEG extensions */
1028 case 0xF1: /* Reserved for JPEG extensions */
1029 case 0xF2: /* Reserved for JPEG extensions */
1030 case 0xF3: /* Reserved for JPEG extensions */
1031 case 0xF4: /* Reserved for JPEG extensions */
1032 case 0xF5: /* Reserved for JPEG extensions */
1033 case 0xF6: /* Reserved for JPEG extensions */
1034 case 0xF7: /* Reserved for JPEG extensions */
1035 case 0xF8: /* Reserved for JPEG extensions */
1036 case 0xF9: /* Reserved for JPEG extensions */
1037 case 0xFA: /* Reserved for JPEG extensions */
1038 case 0xFB: /* Reserved for JPEG extensions */
1039 case 0xFC: /* Reserved for JPEG extensions */
1040 case 0xFD: /* Reserved for JPEG extensions */
1041 case 0x02: /* Reserved */
1042 default:
1043 return (-9); /* Unknown marker */
1044 } /* switch */
1045 } /* while */
1047 return (ret); /* return flags with seen markers */
1051 void default_huff_tbl(struct jpeg* p_jpeg)
1053 static const struct huffman_table luma_table =
1056 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
1057 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1060 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
1061 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
1062 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
1063 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
1064 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
1065 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1066 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1067 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
1068 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
1069 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
1070 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1071 0xF9,0xFA
1075 static const struct huffman_table chroma_table =
1078 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
1079 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1082 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
1083 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
1084 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1085 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1086 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1087 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1088 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1089 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1090 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1091 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1092 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1093 0xF9,0xFA
1097 MEMCPY(&p_jpeg->hufftable[0], &luma_table, sizeof(luma_table));
1098 MEMCPY(&p_jpeg->hufftable[1], &chroma_table, sizeof(chroma_table));
1100 return;
1103 /* Compute the derived values for a Huffman table */
1104 void fix_huff_tbl(int* htbl, struct derived_tbl* dtbl)
1106 int p, i, l, si;
1107 int lookbits, ctr;
1108 char huffsize[257];
1109 unsigned int huffcode[257];
1110 unsigned int code;
1112 dtbl->pub = htbl; /* fill in back link */
1114 /* Figure C.1: make table of Huffman code length for each symbol */
1115 /* Note that this is in code-length order. */
1117 p = 0;
1118 for (l = 1; l <= 16; l++)
1119 { /* all possible code length */
1120 for (i = 1; i <= (int) htbl[l-1]; i++) /* all codes per length */
1121 huffsize[p++] = (char) l;
1123 huffsize[p] = 0;
1125 /* Figure C.2: generate the codes themselves */
1126 /* Note that this is in code-length order. */
1128 code = 0;
1129 si = huffsize[0];
1130 p = 0;
1131 while (huffsize[p])
1133 while (((int) huffsize[p]) == si)
1135 huffcode[p++] = code;
1136 code++;
1138 code <<= 1;
1139 si++;
1142 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1144 p = 0;
1145 for (l = 1; l <= 16; l++)
1147 if (htbl[l-1])
1149 dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */
1150 dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */
1151 p += htbl[l-1];
1152 dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
1154 else
1156 dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
1159 dtbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */
1161 /* Compute lookahead tables to speed up decoding.
1162 * First we set all the table entries to 0, indicating "too long";
1163 * then we iterate through the Huffman codes that are short enough and
1164 * fill in all the entries that correspond to bit sequences starting
1165 * with that code.
1168 MEMSET(dtbl->look_nbits, 0, sizeof(dtbl->look_nbits));
1170 p = 0;
1171 for (l = 1; l <= HUFF_LOOKAHEAD; l++)
1173 for (i = 1; i <= (int) htbl[l-1]; i++, p++)
1175 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1176 /* Generate left-justified code followed by all possible bit sequences */
1177 lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
1178 for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--)
1180 dtbl->look_nbits[lookbits] = l;
1181 dtbl->look_sym[lookbits] = htbl[16+p];
1182 lookbits++;
1189 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1190 * If the incoming data is corrupted, decode_mcu could attempt to
1191 * reference values beyond the end of the array. To avoid a wild store,
1192 * we put some extra zeroes after the real entries.
1194 static const int zag[] =
1196 0, 1, 8, 16, 9, 2, 3, 10,
1197 17, 24, 32, 25, 18, 11, 4, 5,
1198 12, 19, 26, 33, 40, 48, 41, 34,
1199 27, 20, 13, 6, 7, 14, 21, 28,
1200 35, 42, 49, 56, 57, 50, 43, 36,
1201 29, 22, 15, 23, 30, 37, 44, 51,
1202 58, 59, 52, 45, 38, 31, 39, 46,
1203 53, 60, 61, 54, 47, 55, 62, 63,
1204 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1205 0, 0, 0, 0, 0, 0, 0, 0
1208 void build_lut(struct jpeg* p_jpeg)
1210 int i;
1211 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_dc,
1212 &p_jpeg->dc_derived_tbls[0]);
1213 fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_ac,
1214 &p_jpeg->ac_derived_tbls[0]);
1215 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_dc,
1216 &p_jpeg->dc_derived_tbls[1]);
1217 fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_ac,
1218 &p_jpeg->ac_derived_tbls[1]);
1220 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1221 for (i=0; i<64; i++)
1223 p_jpeg->qt_idct[0][zag[i]] = p_jpeg->quanttable[0][i];
1224 p_jpeg->qt_idct[1][zag[i]] = p_jpeg->quanttable[1][i];
1227 for (i=0; i<4; i++)
1228 p_jpeg->store_pos[i] = i; /* default ordering */
1230 /* assignments for the decoding of blocks */
1231 if (p_jpeg->frameheader[0].horizontal_sampling == 2
1232 && p_jpeg->frameheader[0].vertical_sampling == 1)
1233 { /* 4:2:2 */
1234 p_jpeg->blocks = 4;
1235 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1236 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1237 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1238 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1239 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1240 p_jpeg->mcu_membership[1] = 0;
1241 p_jpeg->mcu_membership[2] = 1;
1242 p_jpeg->mcu_membership[3] = 2;
1243 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1244 p_jpeg->tab_membership[1] = 0;
1245 p_jpeg->tab_membership[2] = 1;
1246 p_jpeg->tab_membership[3] = 1;
1247 p_jpeg->subsample_x[0] = 1;
1248 p_jpeg->subsample_x[1] = 2;
1249 p_jpeg->subsample_x[2] = 2;
1250 p_jpeg->subsample_y[0] = 1;
1251 p_jpeg->subsample_y[1] = 1;
1252 p_jpeg->subsample_y[2] = 1;
1254 if (p_jpeg->frameheader[0].horizontal_sampling == 1
1255 && p_jpeg->frameheader[0].vertical_sampling == 2)
1256 { /* 4:2:2 vertically subsampled */
1257 p_jpeg->store_pos[1] = 2; /* block positions are mirrored */
1258 p_jpeg->store_pos[2] = 1;
1259 p_jpeg->blocks = 4;
1260 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1261 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1262 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1263 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1264 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1265 p_jpeg->mcu_membership[1] = 0;
1266 p_jpeg->mcu_membership[2] = 1;
1267 p_jpeg->mcu_membership[3] = 2;
1268 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1269 p_jpeg->tab_membership[1] = 0;
1270 p_jpeg->tab_membership[2] = 1;
1271 p_jpeg->tab_membership[3] = 1;
1272 p_jpeg->subsample_x[0] = 1;
1273 p_jpeg->subsample_x[1] = 1;
1274 p_jpeg->subsample_x[2] = 1;
1275 p_jpeg->subsample_y[0] = 1;
1276 p_jpeg->subsample_y[1] = 2;
1277 p_jpeg->subsample_y[2] = 2;
1279 else if (p_jpeg->frameheader[0].horizontal_sampling == 2
1280 && p_jpeg->frameheader[0].vertical_sampling == 2)
1281 { /* 4:2:0 */
1282 p_jpeg->blocks = 6;
1283 p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16;
1284 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1285 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1286 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1287 p_jpeg->mcu_membership[0] = 0;
1288 p_jpeg->mcu_membership[1] = 0;
1289 p_jpeg->mcu_membership[2] = 0;
1290 p_jpeg->mcu_membership[3] = 0;
1291 p_jpeg->mcu_membership[4] = 1;
1292 p_jpeg->mcu_membership[5] = 2;
1293 p_jpeg->tab_membership[0] = 0;
1294 p_jpeg->tab_membership[1] = 0;
1295 p_jpeg->tab_membership[2] = 0;
1296 p_jpeg->tab_membership[3] = 0;
1297 p_jpeg->tab_membership[4] = 1;
1298 p_jpeg->tab_membership[5] = 1;
1299 p_jpeg->subsample_x[0] = 1;
1300 p_jpeg->subsample_x[1] = 2;
1301 p_jpeg->subsample_x[2] = 2;
1302 p_jpeg->subsample_y[0] = 1;
1303 p_jpeg->subsample_y[1] = 2;
1304 p_jpeg->subsample_y[2] = 2;
1306 else if (p_jpeg->frameheader[0].horizontal_sampling == 1
1307 && p_jpeg->frameheader[0].vertical_sampling == 1)
1308 { /* 4:4:4 */
1309 /* don't overwrite p_jpeg->blocks */
1310 p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8;
1311 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1312 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1313 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1314 p_jpeg->mcu_membership[0] = 0;
1315 p_jpeg->mcu_membership[1] = 1;
1316 p_jpeg->mcu_membership[2] = 2;
1317 p_jpeg->tab_membership[0] = 0;
1318 p_jpeg->tab_membership[1] = 1;
1319 p_jpeg->tab_membership[2] = 1;
1320 p_jpeg->subsample_x[0] = 1;
1321 p_jpeg->subsample_x[1] = 1;
1322 p_jpeg->subsample_x[2] = 1;
1323 p_jpeg->subsample_y[0] = 1;
1324 p_jpeg->subsample_y[1] = 1;
1325 p_jpeg->subsample_y[2] = 1;
1327 else
1329 /* error */
1336 * These functions/macros provide the in-line portion of bit fetching.
1337 * Use check_bit_buffer to ensure there are N bits in get_buffer
1338 * before using get_bits, peek_bits, or drop_bits.
1339 * check_bit_buffer(state,n,action);
1340 * Ensure there are N bits in get_buffer; if suspend, take action.
1341 * val = get_bits(n);
1342 * Fetch next N bits.
1343 * val = peek_bits(n);
1344 * Fetch next N bits without removing them from the buffer.
1345 * drop_bits(n);
1346 * Discard next N bits.
1347 * The value N should be a simple variable, not an expression, because it
1348 * is evaluated multiple times.
1351 INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
1353 if (pb->bits_left < nbits)
1354 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1355 unsigned char byte;
1357 byte = *pb->next_input_byte++;
1358 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1359 { /* simplification: just skip the (one-byte) marker code */
1360 pb->next_input_byte++;
1362 pb->get_buffer = (pb->get_buffer << 8) | byte;
1364 byte = *pb->next_input_byte++;
1365 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1366 { /* simplification: just skip the (one-byte) marker code */
1367 pb->next_input_byte++;
1369 pb->get_buffer = (pb->get_buffer << 8) | byte;
1371 pb->bits_left += 16;
1375 INLINE int get_bits(struct bitstream* pb, int nbits)
1377 return ((int) (pb->get_buffer >> (pb->bits_left -= nbits))) & ((1<<nbits)-1);
1380 INLINE int peek_bits(struct bitstream* pb, int nbits)
1382 return ((int) (pb->get_buffer >> (pb->bits_left - nbits))) & ((1<<nbits)-1);
1385 INLINE void drop_bits(struct bitstream* pb, int nbits)
1387 pb->bits_left -= nbits;
1390 /* re-synchronize to entropy data (skip restart marker) */
1391 void search_restart(struct bitstream* pb)
1393 pb->next_input_byte--; /* we may have overread it, taking 2 bytes */
1394 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1395 while (pb->next_input_byte < pb->input_end &&
1396 (pb->next_input_byte[-2] != 0xFF || pb->next_input_byte[-1] == 0x00))
1398 pb->next_input_byte++;
1400 pb->bits_left = 0;
1403 /* Figure F.12: extend sign bit. */
1404 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1406 static const int extend_test[16] = /* entry n is 2**(n-1) */
1408 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1409 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1412 static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
1414 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1415 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1416 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1417 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1420 /* Decode a single value */
1421 INLINE int huff_decode_dc(struct bitstream* bs, struct derived_tbl* tbl)
1423 int nb, look, s, r;
1425 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1426 look = peek_bits(bs, HUFF_LOOKAHEAD);
1427 if ((nb = tbl->look_nbits[look]) != 0)
1429 drop_bits(bs, nb);
1430 s = tbl->look_sym[look];
1431 check_bit_buffer(bs, s);
1432 r = get_bits(bs, s);
1433 s = HUFF_EXTEND(r, s);
1435 else
1436 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1437 long code;
1438 nb=HUFF_LOOKAHEAD+1;
1439 check_bit_buffer(bs, nb);
1440 code = get_bits(bs, nb);
1441 while (code > tbl->maxcode[nb])
1443 code <<= 1;
1444 check_bit_buffer(bs, 1);
1445 code |= get_bits(bs, 1);
1446 nb++;
1448 if (nb > 16) /* error in Huffman */
1450 s=0; /* fake a zero, this is most safe */
1452 else
1454 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1455 check_bit_buffer(bs, s);
1456 r = get_bits(bs, s);
1457 s = HUFF_EXTEND(r, s);
1459 } /* end slow decode */
1460 return s;
1463 INLINE int huff_decode_ac(struct bitstream* bs, struct derived_tbl* tbl)
1465 int nb, look, s;
1467 check_bit_buffer(bs, HUFF_LOOKAHEAD);
1468 look = peek_bits(bs, HUFF_LOOKAHEAD);
1469 if ((nb = tbl->look_nbits[look]) != 0)
1471 drop_bits(bs, nb);
1472 s = tbl->look_sym[look];
1474 else
1475 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1476 long code;
1477 nb=HUFF_LOOKAHEAD+1;
1478 check_bit_buffer(bs, nb);
1479 code = get_bits(bs, nb);
1480 while (code > tbl->maxcode[nb])
1482 code <<= 1;
1483 check_bit_buffer(bs, 1);
1484 code |= get_bits(bs, 1);
1485 nb++;
1487 if (nb > 16) /* error in Huffman */
1489 s=0; /* fake a zero, this is most safe */
1491 else
1493 s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ];
1495 } /* end slow decode */
1496 return s;
1500 #ifdef HAVE_LCD_COLOR
1502 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1503 /* Note: it keeps the original color subsampling, even if resized. */
1504 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1505 int downscale, void (*pf_progress)(int current, int total))
1507 struct bitstream bs; /* bitstream "object" */
1508 int block[64]; /* decoded DCT coefficients */
1510 int width, height;
1511 int skip_line[3]; /* bytes from one line to the next (skip_line) */
1512 int skip_strip[3], skip_mcu[3]; /* bytes to next DCT row / column */
1514 int i, x, y; /* loop counter */
1516 unsigned char* p_line[3] = {p_pixel[0], p_pixel[1], p_pixel[2]};
1517 unsigned char* p_byte[3]; /* bitmap pointer */
1519 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1520 int k_need; /* AC coefficients needed up to here */
1521 int zero_need; /* init the block with this many zeros */
1523 int last_dc_val[3] = {0, 0, 0}; /* or 128 for chroma? */
1524 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1525 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1527 /* pick the IDCT we want, determine how to work with coefs */
1528 if (downscale == 1)
1530 pf_idct = idct8x8;
1531 k_need = 64; /* all */
1532 zero_need = 63; /* all */
1534 else if (downscale == 2)
1536 pf_idct = idct4x4;
1537 k_need = 25; /* this far in zig-zag to cover 4*4 */
1538 zero_need = 27; /* clear this far in linear order */
1540 else if (downscale == 4)
1542 pf_idct = idct2x2;
1543 k_need = 5; /* this far in zig-zag to cover 2*2 */
1544 zero_need = 9; /* clear this far in linear order */
1546 else if (downscale == 8)
1548 pf_idct = idct1x1;
1549 k_need = 0; /* no AC, not needed */
1550 zero_need = 0; /* no AC, not needed */
1552 else return -1; /* not supported */
1554 /* init bitstream, fake a restart to make it start */
1555 bs.next_input_byte = p_jpeg->p_entropy_data;
1556 bs.bits_left = 0;
1557 bs.input_end = p_jpeg->p_entropy_end;
1559 width = p_jpeg->x_phys / downscale;
1560 height = p_jpeg->y_phys / downscale;
1561 for (i=0; i<3; i++) /* calculate some strides */
1563 skip_line[i] = width / p_jpeg->subsample_x[i];
1564 skip_strip[i] = skip_line[i]
1565 * (height / p_jpeg->y_mbl) / p_jpeg->subsample_y[i];
1566 skip_mcu[i] = width/p_jpeg->x_mbl / p_jpeg->subsample_x[i];
1569 /* prepare offsets about where to store the different blocks */
1570 store_offs[p_jpeg->store_pos[0]] = 0;
1571 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1572 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1573 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1575 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1577 for (i=0; i<3; i++) /* scan line init */
1579 p_byte[i] = p_line[i];
1580 p_line[i] += skip_strip[i];
1582 for (x=0; x<p_jpeg->x_mbl; x++)
1584 int blkn;
1586 /* Outer loop handles each block in the MCU */
1587 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1588 { /* Decode a single block's worth of coefficients */
1589 int k = 1; /* coefficient index */
1590 int s, r; /* huffman values */
1591 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1592 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1593 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1594 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1596 /* Section F.2.2.1: decode the DC coefficient difference */
1597 s = huff_decode_dc(&bs, dctbl);
1599 last_dc_val[ci] += s;
1600 block[0] = last_dc_val[ci]; /* output it (assumes zag[0] = 0) */
1602 /* coefficient buffer must be cleared */
1603 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1605 /* Section F.2.2.2: decode the AC coefficients */
1606 for (; k < k_need; k++)
1608 s = huff_decode_ac(&bs, actbl);
1609 r = s >> 4;
1610 s &= 15;
1612 if (s)
1614 k += r;
1615 check_bit_buffer(&bs, s);
1616 r = get_bits(&bs, s);
1617 block[zag[k]] = HUFF_EXTEND(r, s);
1619 else
1621 if (r != 15)
1623 k = 64;
1624 break;
1626 k += r;
1628 } /* for k */
1629 /* In this path we just discard the values */
1630 for (; k < 64; k++)
1632 s = huff_decode_ac(&bs, actbl);
1633 r = s >> 4;
1634 s &= 15;
1636 if (s)
1638 k += r;
1639 check_bit_buffer(&bs, s);
1640 drop_bits(&bs, s);
1642 else
1644 if (r != 15)
1645 break;
1646 k += r;
1648 } /* for k */
1650 if (ci == 0)
1651 { /* Y component needs to bother about block store */
1652 pf_idct(p_byte[0]+store_offs[blkn], block,
1653 p_jpeg->qt_idct[ti], skip_line[0]);
1655 else
1656 { /* chroma */
1657 pf_idct(p_byte[ci], block, p_jpeg->qt_idct[ti],
1658 skip_line[ci]);
1660 } /* for blkn */
1661 p_byte[0] += skip_mcu[0]; /* unrolled for (i=0; i<3; i++) loop */
1662 p_byte[1] += skip_mcu[1];
1663 p_byte[2] += skip_mcu[2];
1664 if (p_jpeg->restart_interval && --restart == 0)
1665 { /* if a restart marker is due: */
1666 restart = p_jpeg->restart_interval; /* count again */
1667 search_restart(&bs); /* align the bitstream */
1668 last_dc_val[0] = last_dc_val[1] =
1669 last_dc_val[2] = 0; /* reset decoder */
1671 } /* for x */
1672 if (pf_progress != NULL)
1673 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1674 } /* for y */
1676 return 0; /* success */
1678 #else /* !HAVE_LCD_COLOR */
1680 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1681 int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[1], int downscale,
1682 void (*pf_progress)(int current, int total))
1684 struct bitstream bs; /* bitstream "object" */
1685 int block[64]; /* decoded DCT coefficients */
1687 int width, height;
1688 int skip_line; /* bytes from one line to the next (skip_line) */
1689 int skip_strip, skip_mcu; /* bytes to next DCT row / column */
1691 int x, y; /* loop counter */
1693 unsigned char* p_line = p_pixel[0];
1694 unsigned char* p_byte; /* bitmap pointer */
1696 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1697 int k_need; /* AC coefficients needed up to here */
1698 int zero_need; /* init the block with this many zeros */
1700 int last_dc_val = 0;
1701 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1702 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1704 /* pick the IDCT we want, determine how to work with coefs */
1705 if (downscale == 1)
1707 pf_idct = idct8x8;
1708 k_need = 64; /* all */
1709 zero_need = 63; /* all */
1711 else if (downscale == 2)
1713 pf_idct = idct4x4;
1714 k_need = 25; /* this far in zig-zag to cover 4*4 */
1715 zero_need = 27; /* clear this far in linear order */
1717 else if (downscale == 4)
1719 pf_idct = idct2x2;
1720 k_need = 5; /* this far in zig-zag to cover 2*2 */
1721 zero_need = 9; /* clear this far in linear order */
1723 else if (downscale == 8)
1725 pf_idct = idct1x1;
1726 k_need = 0; /* no AC, not needed */
1727 zero_need = 0; /* no AC, not needed */
1729 else return -1; /* not supported */
1731 /* init bitstream, fake a restart to make it start */
1732 bs.next_input_byte = p_jpeg->p_entropy_data;
1733 bs.bits_left = 0;
1734 bs.input_end = p_jpeg->p_entropy_end;
1736 width = p_jpeg->x_phys / downscale;
1737 height = p_jpeg->y_phys / downscale;
1738 skip_line = width;
1739 skip_strip = skip_line * (height / p_jpeg->y_mbl);
1740 skip_mcu = (width/p_jpeg->x_mbl);
1742 /* prepare offsets about where to store the different blocks */
1743 store_offs[p_jpeg->store_pos[0]] = 0;
1744 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1745 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1746 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1748 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1750 p_byte = p_line;
1751 p_line += skip_strip;
1752 for (x=0; x<p_jpeg->x_mbl; x++)
1754 int blkn;
1756 /* Outer loop handles each block in the MCU */
1757 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1758 { /* Decode a single block's worth of coefficients */
1759 int k = 1; /* coefficient index */
1760 int s, r; /* huffman values */
1761 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1762 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1763 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1764 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1766 /* Section F.2.2.1: decode the DC coefficient difference */
1767 s = huff_decode_dc(&bs, dctbl);
1769 if (ci == 0) /* only for Y component */
1771 last_dc_val += s;
1772 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
1774 /* coefficient buffer must be cleared */
1775 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1777 /* Section F.2.2.2: decode the AC coefficients */
1778 for (; k < k_need; k++)
1780 s = huff_decode_ac(&bs, actbl);
1781 r = s >> 4;
1782 s &= 15;
1784 if (s)
1786 k += r;
1787 check_bit_buffer(&bs, s);
1788 r = get_bits(&bs, s);
1789 block[zag[k]] = HUFF_EXTEND(r, s);
1791 else
1793 if (r != 15)
1795 k = 64;
1796 break;
1798 k += r;
1800 } /* for k */
1802 /* In this path we just discard the values */
1803 for (; k < 64; k++)
1805 s = huff_decode_ac(&bs, actbl);
1806 r = s >> 4;
1807 s &= 15;
1809 if (s)
1811 k += r;
1812 check_bit_buffer(&bs, s);
1813 drop_bits(&bs, s);
1815 else
1817 if (r != 15)
1818 break;
1819 k += r;
1821 } /* for k */
1823 if (ci == 0)
1824 { /* only for Y component */
1825 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
1826 skip_line);
1828 } /* for blkn */
1829 p_byte += skip_mcu;
1830 if (p_jpeg->restart_interval && --restart == 0)
1831 { /* if a restart marker is due: */
1832 restart = p_jpeg->restart_interval; /* count again */
1833 search_restart(&bs); /* align the bitstream */
1834 last_dc_val = 0; /* reset decoder */
1836 } /* for x */
1837 if (pf_progress != NULL)
1838 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1839 } /* for y */
1841 return 0; /* success */
1843 #endif /* !HAVE_LCD_COLOR */
1845 /**************** end JPEG code ********************/
1849 /**************** begin Application ********************/
1852 /************************* Types ***************************/
1854 struct t_disp
1856 #ifdef HAVE_LCD_COLOR
1857 unsigned char* bitmap[3]; /* Y, Cr, Cb */
1858 int csub_x, csub_y;
1859 #else
1860 unsigned char* bitmap[1]; /* Y only */
1861 #endif
1862 int width;
1863 int height;
1864 int stride;
1865 int x, y;
1868 /************************* Globals ***************************/
1870 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1871 struct t_disp disp[9];
1873 /* my memory pool (from the mp3 buffer) */
1874 char print[32]; /* use a common snprintf() buffer */
1875 unsigned char* buf; /* up to here currently used by image(s) */
1877 /* the remaining free part of the buffer for compressed+uncompressed images */
1878 unsigned char* buf_images;
1880 ssize_t buf_size, buf_images_size;
1881 /* the root of the images, hereafter are decompresed ones */
1882 unsigned char* buf_root;
1883 int root_size;
1885 int ds, ds_min, ds_max; /* downscaling and limits */
1886 static struct jpeg jpg; /* too large for stack */
1888 static struct tree_context *tree;
1890 /* the current full file name */
1891 static char np_file[MAX_PATH];
1892 int curfile = 0, direction = DIR_NONE, entries = 0;
1894 /* list of the jpeg files */
1895 char **file_pt;
1896 /* are we using the plugin buffer or the audio buffer? */
1897 bool plug_buf = false;
1900 /************************* Implementation ***************************/
1902 #ifdef HAVE_LCD_COLOR
1904 * Conversion of full 0-255 range YCrCb to RGB:
1905 * |R| |1.000000 -0.000001 1.402000| |Y'|
1906 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
1907 * |B| |1.000000 1.772000 0.000000| |Pr|
1908 * Scaled (yields s15-bit output):
1909 * |R| |128 0 179| |Y |
1910 * |G| = |128 -43 -91| |Cb - 128|
1911 * |B| |128 227 0| |Cr - 128|
1913 #define YFAC 128
1914 #define RVFAC 179
1915 #define GUFAC (-43)
1916 #define GVFAC (-91)
1917 #define BUFAC 227
1918 #define YUV_WHITE (255*YFAC)
1919 #define NODITHER_DELTA (127*YFAC)
1920 #define COMPONENT_SHIFT 15
1921 #define MATRIX_SHIFT 7
1923 static inline int clamp_component(int x)
1925 if ((unsigned)x > YUV_WHITE)
1926 x = x < 0 ? 0 : YUV_WHITE;
1927 return x;
1930 static inline int clamp_component_bits(int x, int bits)
1932 if ((unsigned)x > (1u << bits) - 1)
1933 x = x < 0 ? 0 : (1 << bits) - 1;
1934 return x;
1937 static inline int component_to_lcd(int x, int bits, int delta)
1939 /* Formula used in core bitmap loader. */
1940 return (((1 << bits) - 1)*x + (x >> (8 - bits)) + delta) >> COMPONENT_SHIFT;
1943 static inline int lcd_to_component(int x, int bits, int delta)
1945 /* Reasonable, approximate reversal to get a full range back from the
1946 quantized value. */
1947 return YUV_WHITE*x / ((1 << bits) - 1);
1948 (void)delta;
1951 #define RED 0
1952 #define GRN 1
1953 #define BLU 2
1955 struct rgb_err
1957 int16_t errbuf[LCD_WIDTH+2]; /* Error record for line below */
1958 } rgb_err_buffers[3];
1960 fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
1961 DITHER_DIFFUSION is set */
1963 struct rgb_pixel
1965 int r, g, b; /* Current pixel components in s16.0 */
1966 int inc; /* Current line increment (-1 or 1) */
1967 int row; /* Current row in source image */
1968 int col; /* Current column in source image */
1969 int ce[3]; /* Errors to apply to current pixel */
1970 struct rgb_err *e; /* RED, GRN, BLU */
1971 int epos; /* Current position in error record */
1974 struct rgb_pixel *pixel;
1976 /** round and truncate to lcd depth **/
1977 static fb_data pixel_to_lcd_colour(void)
1979 struct rgb_pixel *p = pixel;
1980 int r, g, b;
1982 r = component_to_lcd(p->r, LCD_RED_BITS, NODITHER_DELTA);
1983 r = clamp_component_bits(r, LCD_RED_BITS);
1985 g = component_to_lcd(p->g, LCD_GREEN_BITS, NODITHER_DELTA);
1986 g = clamp_component_bits(g, LCD_GREEN_BITS);
1988 b = component_to_lcd(p->b, LCD_BLUE_BITS, NODITHER_DELTA);
1989 b = clamp_component_bits(b, LCD_BLUE_BITS);
1991 return LCD_RGBPACK_LCD(r, g, b);
1994 /** write a monochrome pixel to the colour LCD **/
1995 static fb_data pixel_to_lcd_gray(void)
1997 int r, g, b;
1999 g = clamp_component(pixel->g);
2000 r = component_to_lcd(g, LCD_RED_BITS, NODITHER_DELTA);
2001 b = component_to_lcd(g, LCD_BLUE_BITS, NODITHER_DELTA);
2002 g = component_to_lcd(g, LCD_GREEN_BITS, NODITHER_DELTA);
2004 return LCD_RGBPACK_LCD(r, g, b);
2008 * Bayer ordered dithering - swiped from the core bitmap loader.
2010 static fb_data pixel_odither_to_lcd(void)
2012 /* canonical ordered dither matrix */
2013 static const unsigned char dither_matrix[16][16] = {
2014 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
2015 { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
2016 { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
2017 { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
2018 { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
2019 { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
2020 { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
2021 { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
2022 { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
2023 { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
2024 { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
2025 { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
2026 { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
2027 { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
2028 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
2029 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
2032 struct rgb_pixel *p = pixel;
2033 int r, g, b, delta;
2035 delta = dither_matrix[p->col & 15][p->row & 15] << MATRIX_SHIFT;
2037 r = component_to_lcd(p->r, LCD_RED_BITS, delta);
2038 r = clamp_component_bits(r, LCD_RED_BITS);
2040 g = component_to_lcd(p->g, LCD_GREEN_BITS, delta);
2041 g = clamp_component_bits(g, LCD_GREEN_BITS);
2043 b = component_to_lcd(p->b, LCD_BLUE_BITS, delta);
2044 b = clamp_component_bits(b, LCD_BLUE_BITS);
2046 p->col += p->inc;
2048 return LCD_RGBPACK_LCD(r, g, b);
2052 * Floyd/Steinberg dither to lcd depth.
2054 * Apply filter to each component in serpentine pattern. Kernel shown for
2055 * L->R scan. Kernel is reversed for R->L.
2056 * * 7
2057 * 3 5 1 (1/16)
2059 static inline void distribute_error(int *ce, struct rgb_err *e,
2060 int err, int epos, int inc)
2062 *ce = (7*err >> 4) + e->errbuf[epos+inc];
2063 e->errbuf[epos+inc] = err >> 4;
2064 e->errbuf[epos] += 5*err >> 4;
2065 e->errbuf[epos-inc] += 3*err >> 4;
2068 static fb_data pixel_fsdither_to_lcd(void)
2070 struct rgb_pixel *p = pixel;
2071 int rc, gc, bc, r, g, b;
2072 int inc, epos;
2074 /* Full components with error terms */
2075 rc = p->r + p->ce[RED];
2076 r = component_to_lcd(rc, LCD_RED_BITS, 0);
2077 r = clamp_component_bits(r, LCD_RED_BITS);
2079 gc = p->g + p->ce[GRN];
2080 g = component_to_lcd(gc, LCD_GREEN_BITS, 0);
2081 g = clamp_component_bits(g, LCD_GREEN_BITS);
2083 bc = p->b + p->ce[BLU];
2084 b = component_to_lcd(bc, LCD_BLUE_BITS, 0);
2085 b = clamp_component_bits(b, LCD_BLUE_BITS);
2087 /* Get pixel errors */
2088 rc -= lcd_to_component(r, LCD_RED_BITS, 0);
2089 gc -= lcd_to_component(g, LCD_GREEN_BITS, 0);
2090 bc -= lcd_to_component(b, LCD_BLUE_BITS, 0);
2092 /* Spead error to surrounding pixels. */
2093 inc = p->inc;
2094 epos = p->epos;
2095 p->epos += inc;
2097 distribute_error(&p->ce[RED], &p->e[RED], rc, epos, inc);
2098 distribute_error(&p->ce[GRN], &p->e[GRN], gc, epos, inc);
2099 distribute_error(&p->ce[BLU], &p->e[BLU], bc, epos, inc);
2101 /* Pack and return pixel */
2102 return LCD_RGBPACK_LCD(r, g, b);
2105 /* Functions for each output mode, colour then grayscale. */
2106 static fb_data (* const pixel_funcs[COLOUR_NUM_MODES][DITHER_NUM_MODES])(void) =
2108 [COLOURMODE_COLOUR] =
2110 [DITHER_NONE] = pixel_to_lcd_colour,
2111 [DITHER_ORDERED] = pixel_odither_to_lcd,
2112 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2114 [COLOURMODE_GRAY] =
2116 [DITHER_NONE] = pixel_to_lcd_gray,
2117 [DITHER_ORDERED] = pixel_odither_to_lcd,
2118 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
2123 * Draw a partial YUV colour bitmap
2125 * Runs serpentine pattern when dithering is DITHER_DIFFUSION, else scan is
2126 * always L->R.
2128 void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
2129 int src_x, int src_y, int stride,
2130 int x, int y, int width, int height)
2132 fb_data *dst, *dst_end;
2133 fb_data (*pixel_func)(void);
2134 struct rgb_pixel px;
2136 if (x + width > LCD_WIDTH)
2137 width = LCD_WIDTH - x; /* Clip right */
2138 if (x < 0)
2139 width += x, x = 0; /* Clip left */
2140 if (width <= 0)
2141 return; /* nothing left to do */
2143 if (y + height > LCD_HEIGHT)
2144 height = LCD_HEIGHT - y; /* Clip bottom */
2145 if (y < 0)
2146 height += y, y = 0; /* Clip top */
2147 if (height <= 0)
2148 return; /* nothing left to do */
2150 pixel = &px;
2152 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
2153 dst_end = dst + LCD_WIDTH * height;
2155 if (jpeg_settings.colour_mode == COLOURMODE_GRAY)
2156 csub_y = 0; /* Ignore Cb, Cr */
2158 pixel_func = pixel_funcs[jpeg_settings.colour_mode]
2159 [jpeg_settings.dither_mode];
2161 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2163 /* Reset error terms. */
2164 px.e = rgb_err_buffers;
2165 px.ce[RED] = px.ce[GRN] = px.ce[BLU] = 0;
2166 rb->memset(px.e, 0, 3*sizeof (struct rgb_err));
2171 fb_data *dst_row, *row_end;
2172 const unsigned char *ysrc;
2173 px.inc = 1;
2175 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2177 /* Use R->L scan on odd lines */
2178 px.inc -= (src_y & 1) << 1;
2179 px.epos = x + 1;
2181 if (px.inc < 0)
2182 px.epos += width - 1;
2185 if (px.inc == 1)
2187 /* Scan is L->R */
2188 dst_row = dst;
2189 row_end = dst_row + width;
2190 px.col = src_x;
2192 else
2194 /* Scan is R->L */
2195 row_end = dst - 1;
2196 dst_row = row_end + width;
2197 px.col = src_x + width - 1;
2200 ysrc = src[0] + stride * src_y + px.col;
2201 px.row = src_y;
2203 /* Do one row of pixels */
2204 if (csub_y) /* colour */
2206 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
2207 const unsigned char *usrc, *vsrc;
2209 usrc = src[1] + (stride/csub_x) * (src_y/csub_y)
2210 + (px.col/csub_x);
2211 vsrc = src[2] + (stride/csub_x) * (src_y/csub_y)
2212 + (px.col/csub_x);
2213 int xphase = px.col % csub_x;
2214 int xphase_reset = px.inc * csub_x;
2215 int y, v, u, rv, guv, bu;
2217 v = *vsrc - 128;
2218 vsrc += px.inc;
2219 u = *usrc - 128;
2220 usrc += px.inc;
2221 rv = RVFAC*v;
2222 guv = GUFAC*u + GVFAC*v;
2223 bu = BUFAC*u;
2225 while (1)
2227 y = YFAC*(*ysrc);
2228 ysrc += px.inc;
2229 px.r = y + rv;
2230 px.g = y + guv;
2231 px.b = y + bu;
2233 *dst_row = pixel_func();
2234 dst_row += px.inc;
2236 if (dst_row == row_end)
2237 break;
2239 xphase += px.inc;
2240 if ((unsigned)xphase < (unsigned)csub_x)
2241 continue;
2243 /* fetch new chromas */
2244 v = *vsrc - 128;
2245 vsrc += px.inc;
2246 u = *usrc - 128;
2247 usrc += px.inc;
2248 rv = RVFAC*v;
2249 guv = GUFAC*u + GVFAC*v;
2250 bu = BUFAC*u;
2252 xphase -= xphase_reset;
2255 else /* monochrome */
2259 /* Set all components the same for dithering purposes */
2260 px.g = px.r = px.b = YFAC*(*ysrc);
2261 *dst_row = pixel_func();
2262 ysrc += px.inc;
2263 dst_row += px.inc;
2265 while (dst_row != row_end);
2268 src_y++;
2269 dst += LCD_WIDTH;
2271 while (dst < dst_end);
2274 #endif /* HAVE_LCD_COLOR */
2277 /* support function for qsort() */
2278 static int compare(const void* p1, const void* p2)
2280 return rb->strcasecmp(*((char **)p1), *((char **)p2));
2283 bool jpg_ext(const char ext[])
2285 if(!ext)
2286 return false;
2287 if(!rb->strcasecmp(ext,".jpg") ||
2288 !rb->strcasecmp(ext,".jpe") ||
2289 !rb->strcasecmp(ext,".jpeg"))
2290 return true;
2291 else
2292 return false;
2295 /*Read directory contents for scrolling. */
2296 void get_pic_list(void)
2298 int i;
2299 long int str_len = 0;
2300 char *pname;
2301 tree = rb->tree_get_context();
2303 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2304 file_pt = rb->plugin_get_buffer((size_t *)&buf_size);
2305 #else
2306 file_pt = rb->plugin_get_audio_buffer((size_t *)&buf_size);
2307 #endif
2309 for(i = 0; i < tree->filesindir; i++)
2311 if(jpg_ext(rb->strrchr(&tree->name_buffer[str_len],'.')))
2312 file_pt[entries++] = &tree->name_buffer[str_len];
2314 str_len += rb->strlen(&tree->name_buffer[str_len]) + 1;
2317 rb->qsort(file_pt, entries, sizeof(char**), compare);
2319 /* Remove path and leave only the name.*/
2320 pname = rb->strrchr(np_file,'/');
2321 pname++;
2323 /* Find Selected File. */
2324 for(i = 0; i < entries; i++)
2325 if(!rb->strcmp(file_pt[i], pname))
2326 curfile = i;
2329 int change_filename(int direct)
2331 int count = 0;
2332 direction = direct;
2334 if(direct == DIR_PREV)
2338 count++;
2339 if(curfile == 0)
2340 curfile = entries - 1;
2341 else
2342 curfile--;
2343 }while(file_pt[curfile] == '\0' && count < entries);
2344 /* we "erase" the file name if we encounter
2345 * a non-supported file, so skip it now */
2347 else /* DIR_NEXT/DIR_NONE */
2351 count++;
2352 if(curfile == entries - 1)
2353 curfile = 0;
2354 else
2355 curfile++;
2356 }while(file_pt[curfile] == '\0' && count < entries);
2359 if(count == entries && file_pt[curfile] == '\0')
2361 rb->splash(HZ, "No supported files");
2362 return PLUGIN_ERROR;
2364 if(rb->strlen(tree->currdir) > 1)
2366 rb->strcpy(np_file, tree->currdir);
2367 rb->strcat(np_file, "/");
2369 else
2370 rb->strcpy(np_file, tree->currdir);
2372 rb->strcat(np_file, file_pt[curfile]);
2374 return PLUGIN_OTHER;
2377 /* switch off overlay, for handling SYS_ events */
2378 void cleanup(void *parameter)
2380 (void)parameter;
2381 #ifdef USEGSLIB
2382 gray_show(false);
2383 #endif
2386 #define VSCROLL (LCD_HEIGHT/8)
2387 #define HSCROLL (LCD_WIDTH/10)
2389 #define ZOOM_IN 100 /* return codes for below function */
2390 #define ZOOM_OUT 101
2392 #ifdef HAVE_LCD_COLOR
2393 bool set_option_grayscale(void)
2395 bool gray = jpeg_settings.colour_mode == COLOURMODE_GRAY;
2396 rb->set_bool("Grayscale", &gray);
2397 jpeg_settings.colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
2398 return false;
2401 bool set_option_dithering(void)
2403 static const struct opt_items dithering[DITHER_NUM_MODES] = {
2404 [DITHER_NONE] = { "Off", -1 },
2405 [DITHER_ORDERED] = { "Ordered", -1 },
2406 [DITHER_DIFFUSION] = { "Diffusion", -1 },
2409 rb->set_option("Dithering", &jpeg_settings.dither_mode, INT,
2410 dithering, DITHER_NUM_MODES, NULL);
2411 return false;
2414 static void display_options(void)
2416 static const struct menu_item items[] = {
2417 { "Grayscale", set_option_grayscale },
2418 { "Dithering", set_option_dithering },
2421 int m = menu_init(rb, items, ARRAYLEN(items),
2422 NULL, NULL, NULL, NULL);
2423 menu_run(m);
2424 menu_exit(m);
2426 #endif /* HAVE_LCD_COLOR */
2428 int show_menu(void) /* return 1 to quit */
2430 #if LCD_DEPTH > 1
2431 rb->lcd_set_backdrop(old_backdrop);
2432 #ifdef HAVE_LCD_COLOR
2433 rb->lcd_set_foreground(rb->global_settings->fg_color);
2434 rb->lcd_set_background(rb->global_settings->bg_color);
2435 #else
2436 rb->lcd_set_foreground(LCD_BLACK);
2437 rb->lcd_set_background(LCD_WHITE);
2438 #endif
2439 #endif
2440 int m;
2441 int result;
2443 enum menu_id
2445 MIID_QUIT = 0,
2446 MIID_TOGGLE_SS_MODE,
2447 MIID_CHANGE_SS_MODE,
2448 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2449 MIID_SHOW_PLAYBACK_MENU,
2450 #endif
2451 #ifdef HAVE_LCD_COLOR
2452 MIID_DISPLAY_OPTIONS,
2453 #endif
2454 MIID_RETURN,
2457 static const struct menu_item items[] = {
2458 [MIID_QUIT] =
2459 { "Quit", NULL },
2460 [MIID_TOGGLE_SS_MODE] =
2461 { "Toggle Slideshow Mode", NULL },
2462 [MIID_CHANGE_SS_MODE] =
2463 { "Change Slideshow Time", NULL },
2464 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2465 [MIID_SHOW_PLAYBACK_MENU] =
2466 { "Show Playback Menu", NULL },
2467 #endif
2468 #ifdef HAVE_LCD_COLOR
2469 [MIID_DISPLAY_OPTIONS] =
2470 { "Display Options", NULL },
2471 #endif
2472 [MIID_RETURN] =
2473 { "Return", NULL },
2476 static const struct opt_items slideshow[2] = {
2477 { "Disable", -1 },
2478 { "Enable", -1 },
2481 static const struct opt_items timeout[12] = {
2482 { "1 second", -1 },
2483 { "2 seconds", -1 },
2484 { "3 seconds", -1 },
2485 { "4 seconds", -1 },
2486 { "5 seconds", -1 },
2487 { "6 seconds", -1 },
2488 { "7 seconds", -1 },
2489 { "8 seconds", -1 },
2490 { "9 seconds", -1 },
2491 { "10 seconds", -1 },
2492 { "15 seconds", -1 },
2493 { "20 seconds", -1 },
2496 m = menu_init(rb, items, sizeof(items) / sizeof(*items),
2497 NULL, NULL, NULL, NULL);
2498 result=menu_show(m);
2500 switch (result)
2502 case MIID_QUIT:
2503 menu_exit(m);
2504 return 1;
2505 break;
2506 case MIID_TOGGLE_SS_MODE:
2507 rb->set_option("Toggle Slideshow", &slideshow_enabled, INT,
2508 slideshow , 2, NULL);
2509 break;
2510 case MIID_CHANGE_SS_MODE:
2511 switch (button_timeout/HZ)
2513 case 10: result = 9; break;
2514 case 15: result = 10; break;
2515 case 20: result = 11; break;
2516 default: result = (button_timeout/HZ)-1; break;
2518 rb->set_option("Slideshow Time", &result, INT,
2519 timeout , 12, NULL);
2520 switch (result)
2522 case 9: button_timeout = 10*HZ; break;
2523 case 10: button_timeout = 15*HZ; break;
2524 case 11: button_timeout = 20*HZ; break;
2525 default: button_timeout = (result+1)*HZ; break;
2527 break;
2528 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2529 case MIID_SHOW_PLAYBACK_MENU:
2530 playback_control(rb);
2531 break;
2532 #endif
2533 #ifdef HAVE_LCD_COLOR
2534 case MIID_DISPLAY_OPTIONS:
2535 display_options();
2536 break;
2537 #endif
2538 case MIID_RETURN:
2539 break;
2542 #ifndef SIMULATOR
2543 /* change ata spindown time based on slideshow time setting */
2544 immediate_ata_off = false;
2545 rb->ata_spindown(rb->global_settings->disk_spindown);
2547 if (slideshow_enabled)
2549 if(button_timeout/HZ < 10)
2551 /* slideshow times < 10s keep disk spinning */
2552 rb->ata_spindown(0);
2554 else if (!rb->mp3_is_playing())
2556 /* slideshow times > 10s and not playing: ata_off after load */
2557 immediate_ata_off = true;
2560 #endif
2561 #if LCD_DEPTH > 1
2562 rb->lcd_set_backdrop(NULL);
2563 rb->lcd_set_foreground(LCD_WHITE);
2564 rb->lcd_set_background(LCD_BLACK);
2565 #endif
2566 rb->lcd_clear_display();
2567 menu_exit(m);
2568 return 0;
2570 /* interactively scroll around the image */
2571 int scroll_bmp(struct t_disp* pdisp)
2573 int lastbutton = 0;
2575 while (true)
2577 int button;
2578 int move;
2580 if (slideshow_enabled)
2581 button = rb->button_get_w_tmo(button_timeout);
2582 else button = rb->button_get(true);
2584 running_slideshow = false;
2586 switch(button)
2588 case JPEG_LEFT:
2589 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2590 return change_filename(DIR_PREV);
2591 case JPEG_LEFT | BUTTON_REPEAT:
2592 move = MIN(HSCROLL, pdisp->x);
2593 if (move > 0)
2595 MYXLCD(scroll_right)(move); /* scroll right */
2596 pdisp->x -= move;
2597 #ifdef HAVE_LCD_COLOR
2598 yuv_bitmap_part(
2599 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2600 pdisp->x, pdisp->y, pdisp->stride,
2601 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2602 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2603 #else
2604 MYXLCD(gray_bitmap_part)(
2605 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2606 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2607 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2608 #endif
2609 MYLCD_UPDATE();
2611 break;
2613 case JPEG_RIGHT:
2614 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2615 return change_filename(DIR_NEXT);
2616 case JPEG_RIGHT | BUTTON_REPEAT:
2617 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
2618 if (move > 0)
2620 MYXLCD(scroll_left)(move); /* scroll left */
2621 pdisp->x += move;
2622 #ifdef HAVE_LCD_COLOR
2623 yuv_bitmap_part(
2624 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2625 pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride,
2626 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2627 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2628 #else
2629 MYXLCD(gray_bitmap_part)(
2630 pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move,
2631 pdisp->y, pdisp->stride,
2632 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2633 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
2634 #endif
2635 MYLCD_UPDATE();
2637 break;
2639 case JPEG_UP:
2640 case JPEG_UP | BUTTON_REPEAT:
2641 move = MIN(VSCROLL, pdisp->y);
2642 if (move > 0)
2644 MYXLCD(scroll_down)(move); /* scroll down */
2645 pdisp->y -= move;
2646 #ifdef HAVE_LCD_COLOR
2647 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2649 /* Draw over the band at the top of the last update
2650 caused by lack of error history on line zero. */
2651 move = MIN(move + 1, pdisp->y + pdisp->height);
2654 yuv_bitmap_part(
2655 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2656 pdisp->x, pdisp->y, pdisp->stride,
2657 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2658 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2659 #else
2660 MYXLCD(gray_bitmap_part)(
2661 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
2662 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2663 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2664 #endif
2665 MYLCD_UPDATE();
2667 break;
2669 case JPEG_DOWN:
2670 case JPEG_DOWN | BUTTON_REPEAT:
2671 move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT);
2672 if (move > 0)
2674 MYXLCD(scroll_up)(move); /* scroll up */
2675 pdisp->y += move;
2676 #ifdef HAVE_LCD_COLOR
2677 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2679 /* Save the line that was on the last line of the display
2680 and draw one extra line above then recover the line with
2681 image data that had an error history when it was drawn.
2683 move++, pdisp->y--;
2684 MEMCPY(rgb_linebuf,
2685 rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2686 LCD_WIDTH*sizeof (fb_data));
2689 yuv_bitmap_part(
2690 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x,
2691 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2692 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2693 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2695 if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
2697 /* Cover the first row drawn with previous image data. */
2698 MEMCPY(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
2699 rgb_linebuf,
2700 LCD_WIDTH*sizeof (fb_data));
2701 pdisp->y++;
2703 #else
2704 MYXLCD(gray_bitmap_part)(
2705 pdisp->bitmap[0], pdisp->x,
2706 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2707 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2708 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2709 #endif
2710 MYLCD_UPDATE();
2712 break;
2713 case BUTTON_NONE:
2714 if (!slideshow_enabled)
2715 break;
2716 running_slideshow = true;
2717 if (entries > 0)
2718 return change_filename(DIR_NEXT);
2719 break;
2720 #ifdef JPEG_NEXT_REPEAT
2721 case JPEG_NEXT_REPEAT:
2722 #endif
2723 case JPEG_NEXT:
2724 if (entries > 0)
2725 return change_filename(DIR_NEXT);
2726 break;
2728 #ifdef JPEG_PREVIOUS_REPEAT
2729 case JPEG_PREVIOUS_REPEAT:
2730 #endif
2731 case JPEG_PREVIOUS:
2732 if (entries > 0)
2733 return change_filename(DIR_PREV);
2734 break;
2736 case JPEG_ZOOM_IN:
2737 #ifdef JPEG_ZOOM_PRE
2738 if (lastbutton != JPEG_ZOOM_PRE)
2739 break;
2740 #endif
2741 return ZOOM_IN;
2742 break;
2744 case JPEG_ZOOM_OUT:
2745 #ifdef JPEG_ZOOM_PRE
2746 if (lastbutton != JPEG_ZOOM_PRE)
2747 break;
2748 #endif
2749 return ZOOM_OUT;
2750 break;
2751 #ifdef JPEG_RC_MENU
2752 case JPEG_RC_MENU:
2753 #endif
2754 case JPEG_MENU:
2755 #ifdef USEGSLIB
2756 gray_show(false); /* switch off grayscale overlay */
2757 #endif
2758 if (show_menu() == 1)
2759 return PLUGIN_OK;
2761 #ifdef USEGSLIB
2762 gray_show(true); /* switch on grayscale overlay */
2763 #else
2764 yuv_bitmap_part(
2765 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2766 pdisp->x, pdisp->y, pdisp->stride,
2767 MAX(0, (LCD_WIDTH - pdisp->width) / 2),
2768 MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
2769 MIN(LCD_WIDTH, pdisp->width),
2770 MIN(LCD_HEIGHT, pdisp->height));
2771 MYLCD_UPDATE();
2772 #endif
2773 break;
2774 default:
2775 if (rb->default_event_handler_ex(button, cleanup, NULL)
2776 == SYS_USB_CONNECTED)
2777 return PLUGIN_USB_CONNECTED;
2778 break;
2780 } /* switch */
2782 if (button != BUTTON_NONE)
2783 lastbutton = button;
2784 } /* while (true) */
2787 /********************* main function *************************/
2789 /* callback updating a progress meter while JPEG decoding */
2790 void cb_progess(int current, int total)
2792 rb->yield(); /* be nice to the other threads */
2793 if(!running_slideshow)
2795 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-8, LCD_WIDTH, 8, total, 0,
2796 current, HORIZONTAL);
2797 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
2799 #ifndef USEGSLIB
2800 else
2802 /* in slideshow mode, keep gui interference to a minimum */
2803 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-4, LCD_WIDTH, 4, total, 0,
2804 current, HORIZONTAL);
2805 rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4);
2807 #endif
2810 int jpegmem(struct jpeg *p_jpg, int ds)
2812 int size;
2814 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
2815 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
2816 #ifdef HAVE_LCD_COLOR
2817 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
2819 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
2820 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
2821 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
2822 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
2824 #endif
2825 return size;
2828 /* how far can we zoom in without running out of memory */
2829 int min_downscale(struct jpeg *p_jpg, int bufsize)
2831 int downscale = 8;
2833 if (jpegmem(p_jpg, 8) > bufsize)
2834 return 0; /* error, too large, even 1:8 doesn't fit */
2836 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
2837 downscale /= 2;
2839 return downscale;
2843 /* how far can we zoom out, to fit image into the LCD */
2844 int max_downscale(struct jpeg *p_jpg)
2846 int downscale = 1;
2848 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale
2849 || p_jpg->y_size > LCD_HEIGHT*downscale))
2851 downscale *= 2;
2854 return downscale;
2858 /* return decoded or cached image */
2859 struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2861 int w, h; /* used to center output */
2862 int size; /* decompressed image size */
2863 long time; /* measured ticks */
2864 int status;
2866 struct t_disp* p_disp = &disp[ds]; /* short cut */
2868 if (p_disp->bitmap[0] != NULL)
2870 return p_disp; /* we still have it */
2873 /* assign image buffer */
2875 /* physical size needed for decoding */
2876 size = jpegmem(p_jpg, ds);
2877 if (buf_size <= size)
2878 { /* have to discard the current */
2879 int i;
2880 for (i=1; i<=8; i++)
2881 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
2882 buf = buf_root; /* start again from the beginning of the buffer */
2883 buf_size = root_size;
2886 #ifdef HAVE_LCD_COLOR
2887 if (p_jpg->blocks > 1) /* colour jpeg */
2889 int i;
2891 for (i = 1; i < 3; i++)
2893 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
2894 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
2895 p_disp->bitmap[i] = buf;
2896 buf += size;
2897 buf_size -= size;
2899 p_disp->csub_x = p_jpg->subsample_x[1];
2900 p_disp->csub_y = p_jpg->subsample_y[1];
2902 else
2904 p_disp->csub_x = p_disp->csub_y = 0;
2905 p_disp->bitmap[1] = p_disp->bitmap[2] = buf;
2907 #endif
2908 /* size may be less when decoded (if height is not block aligned) */
2909 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
2910 p_disp->bitmap[0] = buf;
2911 buf += size;
2912 buf_size -= size;
2914 if(!running_slideshow)
2916 rb->snprintf(print, sizeof(print), "decoding %d*%d",
2917 p_jpg->x_size/ds, p_jpg->y_size/ds);
2918 rb->lcd_puts(0, 3, print);
2919 rb->lcd_update();
2922 /* update image properties */
2923 p_disp->width = p_jpg->x_size / ds;
2924 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
2925 p_disp->height = p_jpg->y_size / ds;
2927 /* the actual decoding */
2928 time = *rb->current_tick;
2929 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2930 rb->cpu_boost(true);
2931 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2932 rb->cpu_boost(false);
2933 #else
2934 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess);
2935 #endif
2936 if (status)
2938 rb->splash(HZ, "decode error %d", status);
2939 file_pt[curfile] = '\0';
2940 return NULL;
2942 time = *rb->current_tick - time;
2944 if(!running_slideshow)
2946 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
2947 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
2948 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
2949 rb->lcd_update();
2952 return p_disp;
2956 /* set the view to the given center point, limit if necessary */
2957 void set_view (struct t_disp* p_disp, int cx, int cy)
2959 int x, y;
2961 /* plain center to available width/height */
2962 x = cx - MIN(LCD_WIDTH, p_disp->width) / 2;
2963 y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2;
2965 /* limit against upper image size */
2966 x = MIN(p_disp->width - LCD_WIDTH, x);
2967 y = MIN(p_disp->height - LCD_HEIGHT, y);
2969 /* limit against negative side */
2970 x = MAX(0, x);
2971 y = MAX(0, y);
2973 p_disp->x = x; /* set the values */
2974 p_disp->y = y;
2978 /* calculate the view center based on the bitmap position */
2979 void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
2981 *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2;
2982 *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2;
2986 /* load, decode, display the image */
2987 int load_and_show(char* filename)
2989 int fd;
2990 int filesize;
2991 unsigned char* buf_jpeg; /* compressed JPEG image */
2992 int status;
2993 struct t_disp* p_disp; /* currenly displayed image */
2994 int cx, cy; /* view center */
2996 fd = rb->open(filename, O_RDONLY);
2997 if (fd < 0)
2999 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
3000 rb->splash(HZ, print);
3001 return PLUGIN_ERROR;
3003 filesize = rb->filesize(fd);
3004 rb->memset(&disp, 0, sizeof(disp));
3006 buf = buf_images + filesize;
3007 buf_size = buf_images_size - filesize;
3008 /* allocate JPEG buffer */
3009 buf_jpeg = buf_images;
3011 buf_root = buf; /* we can start the decompressed images behind it */
3012 root_size = buf_size;
3014 if (buf_size <= 0)
3016 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
3017 if(plug_buf)
3019 rb->close(fd);
3020 rb->lcd_setfont(FONT_SYSFIXED);
3021 rb->lcd_clear_display();
3022 rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
3023 rb->lcd_puts(0,0,print);
3024 rb->lcd_puts(0,1,"Not enough plugin memory!");
3025 rb->lcd_puts(0,2,"Zoom In: Stop playback.");
3026 if(entries>1)
3027 rb->lcd_puts(0,3,"Left/Right: Skip File.");
3028 rb->lcd_puts(0,4,"Off: Quit.");
3029 rb->lcd_update();
3030 rb->lcd_setfont(FONT_UI);
3032 rb->button_clear_queue();
3034 while (1)
3036 int button = rb->button_get(true);
3037 switch(button)
3039 case JPEG_ZOOM_IN:
3040 plug_buf = false;
3041 buf_images = rb->plugin_get_audio_buffer(
3042 (size_t *)&buf_images_size);
3043 /*try again this file, now using the audio buffer */
3044 return PLUGIN_OTHER;
3045 #ifdef JPEG_RC_MENU
3046 case JPEG_RC_MENU:
3047 #endif
3048 case JPEG_MENU:
3049 return PLUGIN_OK;
3051 case JPEG_LEFT:
3052 if(entries>1)
3054 rb->lcd_clear_display();
3055 return change_filename(DIR_PREV);
3057 break;
3059 case JPEG_RIGHT:
3060 if(entries>1)
3062 rb->lcd_clear_display();
3063 return change_filename(DIR_NEXT);
3065 break;
3066 default:
3067 if(rb->default_event_handler_ex(button, cleanup, NULL)
3068 == SYS_USB_CONNECTED)
3069 return PLUGIN_USB_CONNECTED;
3074 else
3075 #endif
3077 rb->splash(HZ, "Out of Memory");
3078 rb->close(fd);
3079 return PLUGIN_ERROR;
3083 if(!running_slideshow)
3085 #if LCD_DEPTH > 1
3086 rb->lcd_set_foreground(LCD_WHITE);
3087 rb->lcd_set_background(LCD_BLACK);
3088 rb->lcd_set_backdrop(NULL);
3089 #endif
3091 rb->lcd_clear_display();
3092 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
3093 rb->lcd_puts(0, 0, print);
3094 rb->lcd_update();
3096 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
3097 rb->lcd_puts(0, 1, print);
3098 rb->lcd_update();
3101 rb->read(fd, buf_jpeg, filesize);
3102 rb->close(fd);
3104 if(!running_slideshow)
3106 rb->snprintf(print, sizeof(print), "decoding markers");
3107 rb->lcd_puts(0, 2, print);
3108 rb->lcd_update();
3110 #ifndef SIMULATOR
3111 else if(immediate_ata_off)
3113 /* running slideshow and time is long enough: power down disk */
3114 rb->ata_sleep();
3116 #endif
3118 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
3119 /* process markers, unstuffing */
3120 status = process_markers(buf_jpeg, filesize, &jpg);
3122 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
3123 { /* bad format or minimum components not contained */
3124 rb->splash(HZ, "unsupported %d", status);
3125 file_pt[curfile] = '\0';
3126 return change_filename(direction);
3129 if (!(status & DHT)) /* if no Huffman table present: */
3130 default_huff_tbl(&jpg); /* use default */
3131 build_lut(&jpg); /* derive Huffman and other lookup-tables */
3133 if(!running_slideshow)
3135 rb->snprintf(print, sizeof(print), "image %dx%d", jpg.x_size, jpg.y_size);
3136 rb->lcd_puts(0, 2, print);
3137 rb->lcd_update();
3139 ds_max = max_downscale(&jpg); /* check display constraint */
3140 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */
3141 if (ds_min == 0)
3143 rb->splash(HZ, "too large");
3144 file_pt[curfile] = '\0';
3145 return change_filename(direction);
3148 ds = ds_max; /* initials setting */
3149 cx = jpg.x_size/ds/2; /* center the view */
3150 cy = jpg.y_size/ds/2;
3152 do /* loop the image prepare and decoding when zoomed */
3154 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */
3155 if (p_disp == NULL)
3156 return change_filename(direction);
3158 set_view(p_disp, cx, cy);
3160 if(!running_slideshow)
3162 rb->snprintf(print, sizeof(print), "showing %dx%d",
3163 p_disp->width, p_disp->height);
3164 rb->lcd_puts(0, 3, print);
3165 rb->lcd_update();
3167 MYLCD(clear_display)();
3168 #ifdef HAVE_LCD_COLOR
3169 yuv_bitmap_part(
3170 p_disp->bitmap, p_disp->csub_x, p_disp->csub_y,
3171 p_disp->x, p_disp->y, p_disp->stride,
3172 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3173 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3174 MIN(LCD_WIDTH, p_disp->width),
3175 MIN(LCD_HEIGHT, p_disp->height));
3176 #else
3177 MYXLCD(gray_bitmap_part)(
3178 p_disp->bitmap[0], p_disp->x, p_disp->y, p_disp->stride,
3179 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
3180 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
3181 MIN(LCD_WIDTH, p_disp->width),
3182 MIN(LCD_HEIGHT, p_disp->height));
3183 #endif
3184 MYLCD_UPDATE();
3186 #ifdef USEGSLIB
3187 gray_show(true); /* switch on grayscale overlay */
3188 #endif
3190 /* drawing is now finished, play around with scrolling
3191 * until you press OFF or connect USB
3193 while (1)
3195 status = scroll_bmp(p_disp);
3196 if (status == ZOOM_IN)
3198 if (ds > ds_min)
3200 ds /= 2; /* reduce downscaling to zoom in */
3201 get_view(p_disp, &cx, &cy);
3202 cx *= 2; /* prepare the position in the new image */
3203 cy *= 2;
3205 else
3206 continue;
3209 if (status == ZOOM_OUT)
3211 if (ds < ds_max)
3213 ds *= 2; /* increase downscaling to zoom out */
3214 get_view(p_disp, &cx, &cy);
3215 cx /= 2; /* prepare the position in the new image */
3216 cy /= 2;
3218 else
3219 continue;
3221 break;
3224 #ifdef USEGSLIB
3225 gray_show(false); /* switch off overlay */
3226 #endif
3227 rb->lcd_clear_display();
3229 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
3230 && status != PLUGIN_OTHER);
3231 #ifdef USEGSLIB
3232 rb->lcd_update();
3233 #endif
3234 return status;
3237 /******************** Plugin entry point *********************/
3239 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
3241 rb = api;
3243 int condition;
3244 #ifdef USEGSLIB
3245 int grayscales;
3246 long graysize; /* helper */
3247 #endif
3248 #if LCD_DEPTH > 1
3249 old_backdrop = rb->lcd_get_backdrop();
3250 #endif
3252 if(!parameter) return PLUGIN_ERROR;
3254 rb->strcpy(np_file, parameter);
3255 get_pic_list();
3257 if(!entries) return PLUGIN_ERROR;
3259 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
3260 if(rb->audio_status())
3262 buf = rb->plugin_get_buffer((size_t *)&buf_size) +
3263 (entries * sizeof(char**));
3264 buf_size -= (entries * sizeof(char**));
3265 plug_buf = true;
3267 else
3268 buf = rb->plugin_get_audio_buffer((size_t *)&buf_size);
3269 #else
3270 buf = rb->plugin_get_audio_buffer(&buf_size) +
3271 (entries * sizeof(char**));
3272 buf_size -= (entries * sizeof(char**));
3273 #endif
3275 #ifdef USEGSLIB
3276 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */
3277 grayscales = gray_init(rb, buf, buf_size, false, LCD_WIDTH, LCD_HEIGHT,
3278 32, 2<<8, &graysize) + 1;
3279 buf += graysize;
3280 buf_size -= graysize;
3281 if (grayscales < 33 || buf_size <= 0)
3283 rb->splash(HZ, "gray buf error");
3284 return PLUGIN_ERROR;
3286 #else
3287 xlcd_init(rb);
3288 #endif
3290 #ifdef HAVE_LCD_COLOR
3291 /* should be ok to just load settings since a parameter is present
3292 here and the drive should be spinning */
3293 configfile_init(rb);
3294 configfile_load(JPEG_CONFIGFILE, jpeg_config,
3295 ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION);
3296 old_settings = jpeg_settings;
3297 #endif
3299 buf_images = buf; buf_images_size = buf_size;
3301 /* make sure the backlight is always on when viewing pictures
3302 (actually it should also set the timeout when plugged in,
3303 but the function backlight_set_timeout_plugged is not
3304 available in plugins) */
3305 #ifdef HAVE_BACKLIGHT
3306 if (rb->global_settings->backlight_timeout > 0)
3307 rb->backlight_set_timeout(1);
3308 #endif
3312 condition = load_and_show(np_file);
3313 }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
3314 && condition != PLUGIN_ERROR);
3316 #ifdef HAVE_LCD_COLOR
3317 if (rb->memcmp(&jpeg_settings, &old_settings, sizeof (jpeg_settings)))
3319 /* Just in case drive has to spin, keep it from looking locked */
3320 rb->splash(0, "Saving Settings");
3321 configfile_save(JPEG_CONFIGFILE, jpeg_config,
3322 ARRAYLEN(jpeg_config), JPEG_SETTINGS_VERSION);
3324 #endif
3326 #ifndef SIMULATOR
3327 /* set back ata spindown time in case we changed it */
3328 rb->ata_spindown(rb->global_settings->disk_spindown);
3329 #endif
3331 #ifdef HAVE_BACKLIGHT
3332 /* reset backlight settings */
3333 rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
3334 #endif
3336 #ifdef USEGSLIB
3337 gray_release(); /* deinitialize */
3338 #endif
3340 return condition;
3343 #endif /* HAVE_LCD_BITMAP */