1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
11 * (This is a real mess if it has to be coded in one single C file)
13 * File scrolling addition (C) 2005 Alexander Spyridakis
14 * Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon
15 * Heavily borrowed from the IJG implementation (C) Thomas G. Lane
16 * Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
18 * All files in this archive are subject to the GNU General Public License.
19 * See the file COPYING in the source tree root for full license agreement.
21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22 * KIND, either express or implied.
24 ****************************************************************************/
27 #include "playback_control.h"
28 #include "oldmenuapi.h"
30 #include "lib/configfile.h"
32 #ifdef HAVE_LCD_BITMAP
38 /* variable button definitions */
39 #if CONFIG_KEYPAD == RECORDER_PAD
40 #define JPEG_ZOOM_IN BUTTON_PLAY
41 #define JPEG_ZOOM_OUT BUTTON_ON
42 #define JPEG_UP BUTTON_UP
43 #define JPEG_DOWN BUTTON_DOWN
44 #define JPEG_LEFT BUTTON_LEFT
45 #define JPEG_RIGHT BUTTON_RIGHT
46 #define JPEG_NEXT BUTTON_F3
47 #define JPEG_PREVIOUS BUTTON_F2
48 #define JPEG_MENU BUTTON_OFF
50 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
51 #define JPEG_ZOOM_IN BUTTON_SELECT
52 #define JPEG_ZOOM_OUT BUTTON_ON
53 #define JPEG_UP BUTTON_UP
54 #define JPEG_DOWN BUTTON_DOWN
55 #define JPEG_LEFT BUTTON_LEFT
56 #define JPEG_RIGHT BUTTON_RIGHT
57 #define JPEG_NEXT BUTTON_F3
58 #define JPEG_PREVIOUS BUTTON_F2
59 #define JPEG_MENU BUTTON_OFF
61 #elif CONFIG_KEYPAD == ONDIO_PAD
62 #define JPEG_ZOOM_PRE BUTTON_MENU
63 #define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
64 #define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
65 #define JPEG_UP BUTTON_UP
66 #define JPEG_DOWN BUTTON_DOWN
67 #define JPEG_LEFT BUTTON_LEFT
68 #define JPEG_RIGHT BUTTON_RIGHT
69 #define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
70 #define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
71 #define JPEG_MENU BUTTON_OFF
73 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
74 (CONFIG_KEYPAD == IRIVER_H300_PAD)
75 #define JPEG_ZOOM_IN BUTTON_SELECT
76 #define JPEG_ZOOM_OUT BUTTON_MODE
77 #define JPEG_UP BUTTON_UP
78 #define JPEG_DOWN BUTTON_DOWN
79 #define JPEG_LEFT BUTTON_LEFT
80 #define JPEG_RIGHT BUTTON_RIGHT
81 #if (CONFIG_KEYPAD == IRIVER_H100_PAD)
82 #define JPEG_NEXT BUTTON_ON
83 #define JPEG_PREVIOUS BUTTON_REC
85 #define JPEG_NEXT BUTTON_REC
86 #define JPEG_PREVIOUS BUTTON_ON
88 #define JPEG_MENU BUTTON_OFF
89 #define JPEG_RC_MENU BUTTON_RC_STOP
91 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
92 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
93 #define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
94 #define JPEG_ZOOM_OUT BUTTON_SCROLL_BACK
95 #define JPEG_UP BUTTON_MENU
96 #define JPEG_DOWN BUTTON_PLAY
97 #define JPEG_LEFT BUTTON_LEFT
98 #define JPEG_RIGHT BUTTON_RIGHT
99 #define JPEG_MENU (BUTTON_SELECT | BUTTON_MENU)
100 #define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
101 #define JPEG_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
103 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
104 #define JPEG_ZOOM_PRE BUTTON_SELECT
105 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
106 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
107 #define JPEG_UP BUTTON_UP
108 #define JPEG_DOWN BUTTON_DOWN
109 #define JPEG_LEFT BUTTON_LEFT
110 #define JPEG_RIGHT BUTTON_RIGHT
111 #define JPEG_MENU BUTTON_POWER
112 #define JPEG_NEXT BUTTON_PLAY
113 #define JPEG_PREVIOUS BUTTON_REC
115 #elif CONFIG_KEYPAD == GIGABEAT_PAD
116 #define JPEG_ZOOM_IN BUTTON_VOL_UP
117 #define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
118 #define JPEG_UP BUTTON_UP
119 #define JPEG_DOWN BUTTON_DOWN
120 #define JPEG_LEFT BUTTON_LEFT
121 #define JPEG_RIGHT BUTTON_RIGHT
122 #define JPEG_MENU BUTTON_MENU
123 #define JPEG_NEXT (BUTTON_A | BUTTON_RIGHT)
124 #define JPEG_PREVIOUS (BUTTON_A | BUTTON_LEFT)
126 #elif CONFIG_KEYPAD == SANSA_E200_PAD
127 #define JPEG_ZOOM_PRE BUTTON_SELECT
128 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
129 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
130 #define JPEG_UP BUTTON_UP
131 #define JPEG_DOWN BUTTON_DOWN
132 #define JPEG_LEFT BUTTON_LEFT
133 #define JPEG_RIGHT BUTTON_RIGHT
134 #define JPEG_MENU BUTTON_POWER
135 #define JPEG_SLIDE_SHOW BUTTON_REC
136 #define JPEG_NEXT BUTTON_SCROLL_FWD
137 #define JPEG_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
138 #define JPEG_PREVIOUS BUTTON_SCROLL_BACK
139 #define JPEG_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
141 #elif CONFIG_KEYPAD == SANSA_C200_PAD
142 #define JPEG_ZOOM_PRE BUTTON_SELECT
143 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
144 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
145 #define JPEG_UP BUTTON_UP
146 #define JPEG_DOWN BUTTON_DOWN
147 #define JPEG_LEFT BUTTON_LEFT
148 #define JPEG_RIGHT BUTTON_RIGHT
149 #define JPEG_MENU BUTTON_POWER
150 #define JPEG_SLIDE_SHOW BUTTON_REC
151 #define JPEG_NEXT BUTTON_VOL_UP
152 #define JPEG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
153 #define JPEG_PREVIOUS BUTTON_VOL_DOWN
154 #define JPEG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
156 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
157 #define JPEG_ZOOM_PRE BUTTON_PLAY
158 #define JPEG_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
159 #define JPEG_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
160 #define JPEG_UP BUTTON_SCROLL_UP
161 #define JPEG_DOWN BUTTON_SCROLL_DOWN
162 #define JPEG_LEFT BUTTON_LEFT
163 #define JPEG_RIGHT BUTTON_RIGHT
164 #define JPEG_MENU BUTTON_POWER
165 #define JPEG_NEXT BUTTON_FF
166 #define JPEG_PREVIOUS BUTTON_REW
168 #elif CONFIG_KEYPAD == MROBE500_PAD
169 #define JPEG_ZOOM_IN BUTTON_RC_VOL_UP
170 #define JPEG_ZOOM_OUT BUTTON_RC_VOL_DOWN
171 #define JPEG_UP BUTTON_RC_PLAY
172 #define JPEG_DOWN BUTTON_RC_DOWN
173 #define JPEG_LEFT BUTTON_LEFT
174 #define JPEG_RIGHT BUTTON_RIGHT
175 #define JPEG_MENU BUTTON_POWER
176 #define JPEG_NEXT BUTTON_RC_HEART
177 #define JPEG_PREVIOUS BUTTON_RC_MODE
179 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
180 #define JPEG_ZOOM_IN BUTTON_VOL_UP
181 #define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
182 #define JPEG_UP BUTTON_UP
183 #define JPEG_DOWN BUTTON_DOWN
184 #define JPEG_LEFT BUTTON_LEFT
185 #define JPEG_RIGHT BUTTON_RIGHT
186 #define JPEG_MENU BUTTON_MENU
187 #define JPEG_NEXT BUTTON_NEXT
188 #define JPEG_PREVIOUS BUTTON_PREV
190 #elif CONFIG_KEYPAD == MROBE100_PAD
191 #define JPEG_ZOOM_IN BUTTON_SELECT
192 #define JPEG_ZOOM_OUT BUTTON_PLAY
193 #define JPEG_UP BUTTON_UP
194 #define JPEG_DOWN BUTTON_DOWN
195 #define JPEG_LEFT BUTTON_LEFT
196 #define JPEG_RIGHT BUTTON_RIGHT
197 #define JPEG_MENU BUTTON_MENU
198 #define JPEG_NEXT (BUTTON_DISPLAY | BUTTON_RIGHT)
199 #define JPEG_PREVIOUS (BUTTON_DISPLAY | BUTTON_LEFT)
201 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
202 #define JPEG_ZOOM_PRE BUTTON_RC_PLAY
203 #define JPEG_ZOOM_IN (BUTTON_RC_PLAY|BUTTON_REL)
204 #define JPEG_ZOOM_OUT (BUTTON_RC_PLAY|BUTTON_REPEAT)
205 #define JPEG_UP BUTTON_RC_VOL_UP
206 #define JPEG_DOWN BUTTON_RC_VOL_DOWN
207 #define JPEG_LEFT BUTTON_RC_REW
208 #define JPEG_RIGHT BUTTON_RC_FF
209 #define JPEG_MENU BUTTON_RC_REC
210 #define JPEG_NEXT BUTTON_RC_MODE
211 #define JPEG_PREVIOUS BUTTON_RC_MENU
213 #elif CONFIG_KEYPAD == COWOND2_PAD
216 #error No keymap defined!
221 #define JPEG_UP BUTTON_TOPMIDDLE
224 #define JPEG_DOWN BUTTON_BOTTOMMIDDLE
227 #define JPEG_LEFT BUTTON_MIDLEFT
230 #define JPEG_RIGHT BUTTON_MIDRIGHT
233 #define JPEG_ZOOM_IN BUTTON_TOPRIGHT
235 #ifndef JPEG_ZOOM_OUT
236 #define JPEG_ZOOM_OUT BUTTON_TOPLEFT
239 #define JPEG_MENU (BUTTON_CENTER|BUTTON_REL)
242 #define JPEG_NEXT BUTTON_BOTTOMRIGHT
244 #ifndef JPEG_PREVIOUS
245 #define JPEG_PREVIOUS BUTTON_BOTTOMLEFT
249 /* different graphics libraries */
253 #define MYLCD(fn) grey_ub_ ## fn
254 #define MYLCD_UPDATE()
255 #define MYXLCD(fn) grey_ub_ ## fn
257 #define MYLCD(fn) rb->lcd_ ## fn
258 #define MYLCD_UPDATE() rb->lcd_update();
259 #define MYXLCD(fn) xlcd_ ## fn
262 #define MAX_X_SIZE LCD_WIDTH*8
264 /* Min memory allowing us to use the plugin buffer
265 * and thus not stopping the music
266 * *Very* rough estimation:
267 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
268 * + 20k code size = 60 000
269 * + 50k min for jpeg = 120 000
271 #define MIN_MEM 120000
278 #define PLUGIN_OTHER 10 /* State code for output with return. */
280 /******************************* Globals ***********************************/
282 static const struct plugin_api
* rb
;
283 MEM_FUNCTION_WRAPPERS(rb
);
285 /* for portability of below JPEG code */
286 #define MEMSET(p,v,c) rb->memset(p,v,c)
287 #define MEMCPY(d,s,c) rb->memcpy(d,s,c)
288 #define INLINE static inline
289 #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
291 static int slideshow_enabled
= false; /* run slideshow */
292 static int running_slideshow
= false; /* loading image because of slideshw */
294 static int immediate_ata_off
= false; /* power down disk after loading */
297 /* Persistent configuration */
298 #define JPEG_CONFIGFILE "jpeg.cfg"
299 #define JPEG_SETTINGS_MINVERSION 1
300 #define JPEG_SETTINGS_VERSION 2
302 /* Slideshow times */
303 #define SS_MIN_TIMEOUT 1
304 #define SS_MAX_TIMEOUT 20
305 #define SS_DEFAULT_TIMEOUT 5
309 COLOURMODE_COLOUR
= 0,
316 DITHER_NONE
= 0, /* No dithering */
317 DITHER_ORDERED
, /* Bayer ordered */
318 DITHER_DIFFUSION
, /* Floyd/Steinberg error diffusion */
329 static struct jpeg_settings jpeg_settings
=
330 { COLOURMODE_COLOUR
, DITHER_NONE
, SS_DEFAULT_TIMEOUT
};
331 static struct jpeg_settings old_settings
;
333 static struct configdata jpeg_config
[] =
335 #ifdef HAVE_LCD_COLOR
336 { TYPE_ENUM
, 0, COLOUR_NUM_MODES
, &jpeg_settings
.colour_mode
,
337 "Colour Mode", (char *[]){ "Colour", "Grayscale" }, NULL
},
338 { TYPE_ENUM
, 0, DITHER_NUM_MODES
, &jpeg_settings
.dither_mode
,
339 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" }, NULL
},
341 { TYPE_INT
, SS_MIN_TIMEOUT
, SS_MAX_TIMEOUT
, &jpeg_settings
.ss_timeout
,
342 "Slideshow Time", NULL
, NULL
},
346 fb_data
* old_backdrop
;
349 /**************** begin JPEG code ********************/
351 INLINE
unsigned range_limit(int value
)
353 #if CONFIG_CPU == SH7034
355 asm ( /* Note: Uses knowledge that only low byte of result is used */
357 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
358 "extu.b %[v],%[t] \n"
359 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
360 "bt 1f \n" /* yes: no overflow */
361 "cmp/pz %[v] \n" /* overflow: positive? */
362 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
369 #elif defined(CPU_COLDFIRE)
370 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
371 "add.l #128,%[v] \n" /* value += 128; */
372 "cmp.l #255,%[v] \n" /* overflow? */
373 "bls.b 1f \n" /* no: return value */
374 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
380 #elif defined(CPU_ARM)
381 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
382 "add %[v], %[v], #128 \n" /* value += 128 */
383 "cmp %[v], #255 \n" /* out of range 0..255? */
384 "mvnhi %[v], %[v], asr #31 \n" /* yes: set all bits to ~(sign_bit) */
392 if ((unsigned)value
<= 255)
402 /* IDCT implementation */
405 #define CONST_BITS 13
409 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
410 * causing a lot of useless floating-point operations at run time.
411 * To get around this we use the following pre-calculated constants.
412 * If you change CONST_BITS you may want to add appropriate values.
413 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
415 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
416 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
417 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
418 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
419 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
420 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
421 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
422 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
423 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
424 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
425 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
426 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
430 /* Multiply an long variable by an long constant to yield an long result.
431 * For 8-bit samples with the recommended scaling, all the variable
432 * and constant values involved are no more than 16 bits wide, so a
433 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
434 * For 12-bit samples, a full 32-bit multiplication will be needed.
436 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
439 /* Dequantize a coefficient by multiplying it by the multiplier-table
440 * entry; produce an int result. In this module, both inputs and result
441 * are 16 bits or less, so either int or short multiply will work.
443 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
444 #define DEQUANTIZE MULTIPLY16
446 /* Descale and correctly round an int value that's scaled by N bits.
447 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
448 * the fudge factor is correct for either sign of X.
450 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
455 * Perform dequantization and inverse DCT on one block of coefficients,
456 * producing a reduced-size 1x1 output block.
458 void idct1x1(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
460 (void)skip_line
; /* unused */
461 *p_byte
= range_limit(inptr
[0] * quantptr
[0] >> 3);
467 * Perform dequantization and inverse DCT on one block of coefficients,
468 * producing a reduced-size 2x2 output block.
470 void idct2x2(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
472 int tmp0
, tmp1
, tmp2
, tmp3
, tmp4
, tmp5
;
473 unsigned char* outptr
;
475 /* Pass 1: process columns from input, store into work array. */
478 tmp4
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]);
479 tmp5
= DEQUANTIZE(inptr
[8*1], quantptr
[8*1]);
485 tmp4
= DEQUANTIZE(inptr
[8*0+1], quantptr
[8*0+1]);
486 tmp5
= DEQUANTIZE(inptr
[8*1+1], quantptr
[8*1+1]);
491 /* Pass 2: process 2 rows, store into output array. */
496 outptr
[0] = range_limit((int) DESCALE(tmp0
+ tmp1
, 3));
497 outptr
[1] = range_limit((int) DESCALE(tmp0
- tmp1
, 3));
500 outptr
= p_byte
+ skip_line
;
502 outptr
[0] = range_limit((int) DESCALE(tmp2
+ tmp3
, 3));
503 outptr
[1] = range_limit((int) DESCALE(tmp2
- tmp3
, 3));
509 * Perform dequantization and inverse DCT on one block of coefficients,
510 * producing a reduced-size 4x4 output block.
512 void idct4x4(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
514 int tmp0
, tmp2
, tmp10
, tmp12
;
517 unsigned char* outptr
;
519 int workspace
[4*4]; /* buffers data between passes */
521 /* Pass 1: process columns from input, store into work array. */
524 for (ctr
= 0; ctr
< 4; ctr
++, inptr
++, quantptr
++, wsptr
++)
528 tmp0
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]);
529 tmp2
= DEQUANTIZE(inptr
[8*2], quantptr
[8*2]);
531 tmp10
= (tmp0
+ tmp2
) << PASS1_BITS
;
532 tmp12
= (tmp0
- tmp2
) << PASS1_BITS
;
535 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
537 z2
= DEQUANTIZE(inptr
[8*1], quantptr
[8*1]);
538 z3
= DEQUANTIZE(inptr
[8*3], quantptr
[8*3]);
540 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
541 tmp0
= DESCALE(z1
+ MULTIPLY16(z3
, - FIX_1_847759065
), CONST_BITS
-PASS1_BITS
);
542 tmp2
= DESCALE(z1
+ MULTIPLY16(z2
, FIX_0_765366865
), CONST_BITS
-PASS1_BITS
);
544 /* Final output stage */
546 wsptr
[4*0] = (int) (tmp10
+ tmp2
);
547 wsptr
[4*3] = (int) (tmp10
- tmp2
);
548 wsptr
[4*1] = (int) (tmp12
+ tmp0
);
549 wsptr
[4*2] = (int) (tmp12
- tmp0
);
552 /* Pass 2: process 4 rows from work array, store into output array. */
555 for (ctr
= 0; ctr
< 4; ctr
++)
557 outptr
= p_byte
+ (ctr
*skip_line
);
560 tmp0
= (int) wsptr
[0];
561 tmp2
= (int) wsptr
[2];
563 tmp10
= (tmp0
+ tmp2
) << CONST_BITS
;
564 tmp12
= (tmp0
- tmp2
) << CONST_BITS
;
567 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
572 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
573 tmp0
= z1
+ MULTIPLY16(z3
, - FIX_1_847759065
);
574 tmp2
= z1
+ MULTIPLY16(z2
, FIX_0_765366865
);
576 /* Final output stage */
578 outptr
[0] = range_limit((int) DESCALE(tmp10
+ tmp2
,
579 CONST_BITS
+PASS1_BITS
+3));
580 outptr
[3] = range_limit((int) DESCALE(tmp10
- tmp2
,
581 CONST_BITS
+PASS1_BITS
+3));
582 outptr
[1] = range_limit((int) DESCALE(tmp12
+ tmp0
,
583 CONST_BITS
+PASS1_BITS
+3));
584 outptr
[2] = range_limit((int) DESCALE(tmp12
- tmp0
,
585 CONST_BITS
+PASS1_BITS
+3));
587 wsptr
+= 4; /* advance pointer to next row */
594 * Perform dequantization and inverse DCT on one block of coefficients.
596 void idct8x8(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
598 long tmp0
, tmp1
, tmp2
, tmp3
;
599 long tmp10
, tmp11
, tmp12
, tmp13
;
600 long z1
, z2
, z3
, z4
, z5
;
602 unsigned char* outptr
;
604 int workspace
[64]; /* buffers data between passes */
606 /* Pass 1: process columns from input, store into work array. */
607 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
608 /* furthermore, we scale the results by 2**PASS1_BITS. */
611 for (ctr
= 8; ctr
> 0; ctr
--)
613 /* Due to quantization, we will usually find that many of the input
614 * coefficients are zero, especially the AC terms. We can exploit this
615 * by short-circuiting the IDCT calculation for any column in which all
616 * the AC terms are zero. In that case each output is equal to the
617 * DC coefficient (with scale factor as needed).
618 * With typical images and quantization tables, half or more of the
619 * column DCT calculations can be simplified this way.
622 if ((inptr
[8*1] | inptr
[8*2] | inptr
[8*3]
623 | inptr
[8*4] | inptr
[8*5] | inptr
[8*6] | inptr
[8*7]) == 0)
625 /* AC terms all zero */
626 int dcval
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]) << PASS1_BITS
;
628 wsptr
[8*0] = wsptr
[8*1] = wsptr
[8*2] = wsptr
[8*3] = wsptr
[8*4]
629 = wsptr
[8*5] = wsptr
[8*6] = wsptr
[8*7] = dcval
;
630 inptr
++; /* advance pointers to next column */
636 /* Even part: reverse the even part of the forward DCT. */
637 /* The rotator is sqrt(2)*c(-6). */
639 z2
= DEQUANTIZE(inptr
[8*2], quantptr
[8*2]);
640 z3
= DEQUANTIZE(inptr
[8*6], quantptr
[8*6]);
642 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
643 tmp2
= z1
+ MULTIPLY16(z3
, - FIX_1_847759065
);
644 tmp3
= z1
+ MULTIPLY16(z2
, FIX_0_765366865
);
646 z2
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]);
647 z3
= DEQUANTIZE(inptr
[8*4], quantptr
[8*4]);
649 tmp0
= (z2
+ z3
) << CONST_BITS
;
650 tmp1
= (z2
- z3
) << CONST_BITS
;
657 /* Odd part per figure 8; the matrix is unitary and hence its
658 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
660 tmp0
= DEQUANTIZE(inptr
[8*7], quantptr
[8*7]);
661 tmp1
= DEQUANTIZE(inptr
[8*5], quantptr
[8*5]);
662 tmp2
= DEQUANTIZE(inptr
[8*3], quantptr
[8*3]);
663 tmp3
= DEQUANTIZE(inptr
[8*1], quantptr
[8*1]);
669 z5
= MULTIPLY16(z3
+ z4
, FIX_1_175875602
); /* sqrt(2) * c3 */
671 tmp0
= MULTIPLY16(tmp0
, FIX_0_298631336
); /* sqrt(2) * (-c1+c3+c5-c7) */
672 tmp1
= MULTIPLY16(tmp1
, FIX_2_053119869
); /* sqrt(2) * ( c1+c3-c5+c7) */
673 tmp2
= MULTIPLY16(tmp2
, FIX_3_072711026
); /* sqrt(2) * ( c1+c3+c5-c7) */
674 tmp3
= MULTIPLY16(tmp3
, FIX_1_501321110
); /* sqrt(2) * ( c1+c3-c5-c7) */
675 z1
= MULTIPLY16(z1
, - FIX_0_899976223
); /* sqrt(2) * (c7-c3) */
676 z2
= MULTIPLY16(z2
, - FIX_2_562915447
); /* sqrt(2) * (-c1-c3) */
677 z3
= MULTIPLY16(z3
, - FIX_1_961570560
); /* sqrt(2) * (-c3-c5) */
678 z4
= MULTIPLY16(z4
, - FIX_0_390180644
); /* sqrt(2) * (c5-c3) */
688 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
690 wsptr
[8*0] = (int) DESCALE(tmp10
+ tmp3
, CONST_BITS
-PASS1_BITS
);
691 wsptr
[8*7] = (int) DESCALE(tmp10
- tmp3
, CONST_BITS
-PASS1_BITS
);
692 wsptr
[8*1] = (int) DESCALE(tmp11
+ tmp2
, CONST_BITS
-PASS1_BITS
);
693 wsptr
[8*6] = (int) DESCALE(tmp11
- tmp2
, CONST_BITS
-PASS1_BITS
);
694 wsptr
[8*2] = (int) DESCALE(tmp12
+ tmp1
, CONST_BITS
-PASS1_BITS
);
695 wsptr
[8*5] = (int) DESCALE(tmp12
- tmp1
, CONST_BITS
-PASS1_BITS
);
696 wsptr
[8*3] = (int) DESCALE(tmp13
+ tmp0
, CONST_BITS
-PASS1_BITS
);
697 wsptr
[8*4] = (int) DESCALE(tmp13
- tmp0
, CONST_BITS
-PASS1_BITS
);
699 inptr
++; /* advance pointers to next column */
704 /* Pass 2: process rows from work array, store into output array. */
705 /* Note that we must descale the results by a factor of 8 == 2**3, */
706 /* and also undo the PASS1_BITS scaling. */
709 for (ctr
= 0; ctr
< 8; ctr
++)
711 outptr
= p_byte
+ (ctr
*skip_line
);
712 /* Rows of zeroes can be exploited in the same way as we did with columns.
713 * However, the column calculation has created many nonzero AC terms, so
714 * the simplification applies less often (typically 5% to 10% of the time).
715 * On machines with very fast multiplication, it's possible that the
716 * test takes more time than it's worth. In that case this section
717 * may be commented out.
720 #ifndef NO_ZERO_ROW_TEST
721 if ((wsptr
[1] | wsptr
[2] | wsptr
[3]
722 | wsptr
[4] | wsptr
[5] | wsptr
[6] | wsptr
[7]) == 0)
724 /* AC terms all zero */
725 unsigned char dcval
= range_limit((int) DESCALE((long) wsptr
[0],
737 wsptr
+= 8; /* advance pointer to next row */
742 /* Even part: reverse the even part of the forward DCT. */
743 /* The rotator is sqrt(2)*c(-6). */
745 z2
= (long) wsptr
[2];
746 z3
= (long) wsptr
[6];
748 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
749 tmp2
= z1
+ MULTIPLY16(z3
, - FIX_1_847759065
);
750 tmp3
= z1
+ MULTIPLY16(z2
, FIX_0_765366865
);
752 tmp0
= ((long) wsptr
[0] + (long) wsptr
[4]) << CONST_BITS
;
753 tmp1
= ((long) wsptr
[0] - (long) wsptr
[4]) << CONST_BITS
;
760 /* Odd part per figure 8; the matrix is unitary and hence its
761 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
763 tmp0
= (long) wsptr
[7];
764 tmp1
= (long) wsptr
[5];
765 tmp2
= (long) wsptr
[3];
766 tmp3
= (long) wsptr
[1];
772 z5
= MULTIPLY16(z3
+ z4
, FIX_1_175875602
); /* sqrt(2) * c3 */
774 tmp0
= MULTIPLY16(tmp0
, FIX_0_298631336
); /* sqrt(2) * (-c1+c3+c5-c7) */
775 tmp1
= MULTIPLY16(tmp1
, FIX_2_053119869
); /* sqrt(2) * ( c1+c3-c5+c7) */
776 tmp2
= MULTIPLY16(tmp2
, FIX_3_072711026
); /* sqrt(2) * ( c1+c3+c5-c7) */
777 tmp3
= MULTIPLY16(tmp3
, FIX_1_501321110
); /* sqrt(2) * ( c1+c3-c5-c7) */
778 z1
= MULTIPLY16(z1
, - FIX_0_899976223
); /* sqrt(2) * (c7-c3) */
779 z2
= MULTIPLY16(z2
, - FIX_2_562915447
); /* sqrt(2) * (-c1-c3) */
780 z3
= MULTIPLY16(z3
, - FIX_1_961570560
); /* sqrt(2) * (-c3-c5) */
781 z4
= MULTIPLY16(z4
, - FIX_0_390180644
); /* sqrt(2) * (c5-c3) */
791 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
793 outptr
[0] = range_limit((int) DESCALE(tmp10
+ tmp3
,
794 CONST_BITS
+PASS1_BITS
+3));
795 outptr
[7] = range_limit((int) DESCALE(tmp10
- tmp3
,
796 CONST_BITS
+PASS1_BITS
+3));
797 outptr
[1] = range_limit((int) DESCALE(tmp11
+ tmp2
,
798 CONST_BITS
+PASS1_BITS
+3));
799 outptr
[6] = range_limit((int) DESCALE(tmp11
- tmp2
,
800 CONST_BITS
+PASS1_BITS
+3));
801 outptr
[2] = range_limit((int) DESCALE(tmp12
+ tmp1
,
802 CONST_BITS
+PASS1_BITS
+3));
803 outptr
[5] = range_limit((int) DESCALE(tmp12
- tmp1
,
804 CONST_BITS
+PASS1_BITS
+3));
805 outptr
[3] = range_limit((int) DESCALE(tmp13
+ tmp0
,
806 CONST_BITS
+PASS1_BITS
+3));
807 outptr
[4] = range_limit((int) DESCALE(tmp13
- tmp0
,
808 CONST_BITS
+PASS1_BITS
+3));
810 wsptr
+= 8; /* advance pointer to next row */
816 /* JPEG decoder implementation */
819 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
823 /* Basic tables: (element [0] of each array is unused) */
824 long mincode
[17]; /* smallest code of length k */
825 long maxcode
[18]; /* largest code of length k (-1 if none) */
826 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
827 int valptr
[17]; /* huffval[] index of 1st symbol of length k */
829 /* Back link to public Huffman table (needed only in slow_DECODE) */
832 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
833 the input data stream. If the next Huffman code is no more
834 than HUFF_LOOKAHEAD bits long, we can obtain its length and
835 the corresponding symbol directly from these tables. */
836 int look_nbits
[1<<HUFF_LOOKAHEAD
]; /* # bits, or 0 if too long */
837 unsigned char look_sym
[1<<HUFF_LOOKAHEAD
]; /* symbol, or unused */
840 #define QUANT_TABLE_LENGTH 64
842 /* for type of Huffman table */
847 { /* length and code according to JFIF format */
848 int huffmancodes_dc
[DC_LEN
];
849 int huffmancodes_ac
[AC_LEN
];
852 struct frame_component
855 int horizontal_sampling
;
856 int vertical_sampling
;
857 int quanttable_select
;
860 struct scan_component
869 unsigned long get_buffer
; /* current bit-extraction buffer */
870 int bits_left
; /* # of unused bits in it */
871 unsigned char* next_input_byte
;
872 unsigned char* input_end
; /* upper limit +1 */
877 int x_size
, y_size
; /* size of image (can be less than block boundary) */
878 int x_phys
, y_phys
; /* physical size, block aligned */
879 int x_mbl
; /* x dimension of MBL */
880 int y_mbl
; /* y dimension of MBL */
881 int blocks
; /* blocks per MB */
882 int restart_interval
; /* number of MCUs between RSTm markers */
883 int store_pos
[4]; /* for Y block ordering */
885 unsigned char* p_entropy_data
;
886 unsigned char* p_entropy_end
;
888 int quanttable
[4][QUANT_TABLE_LENGTH
]; /* raw quantization tables 0-3 */
889 int qt_idct
[2][QUANT_TABLE_LENGTH
]; /* quantization tables for IDCT */
891 struct huffman_table hufftable
[2]; /* Huffman tables */
892 struct derived_tbl dc_derived_tbls
[2]; /* Huffman-LUTs */
893 struct derived_tbl ac_derived_tbls
[2];
895 struct frame_component frameheader
[3]; /* Component descriptor */
896 struct scan_component scanheader
[3]; /* currently not used */
898 int mcu_membership
[6]; /* info per block */
899 int tab_membership
[6];
900 int subsample_x
[3]; /* info per component */
905 /* possible return flags for process_markers() */
906 #define HUFFTAB 0x0001 /* with huffman table */
907 #define QUANTTAB 0x0002 /* with quantization table */
908 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
909 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
910 #define SOF0 0x0010 /* with SOF0-Segment */
911 #define DHT 0x0020 /* with Definition of huffman tables */
912 #define SOS 0x0040 /* with Start-of-Scan segment */
913 #define DQT 0x0080 /* with definition of quantization table */
915 /* Preprocess the JPEG JFIF file */
916 int process_markers(unsigned char* p_src
, long size
, struct jpeg
* p_jpeg
)
918 unsigned char* p_bytes
= p_src
;
919 int marker_size
; /* variable length of marker segment */
921 int ret
= 0; /* returned flags */
923 p_jpeg
->p_entropy_end
= p_src
+ size
;
925 while (p_src
< p_bytes
+ size
)
927 if (*p_src
++ != 0xFF) /* no marker? */
929 p_src
--; /* it's image data, put it back */
930 p_jpeg
->p_entropy_data
= p_src
;
931 break; /* exit marker processing */
936 case 0xFF: /* Fill byte */
938 case 0x00: /* Zero stuffed byte - entropy data */
939 p_src
--; /* put it back */
942 case 0xC0: /* SOF Huff - Baseline DCT */
945 marker_size
= *p_src
++ << 8; /* Highbyte */
946 marker_size
|= *p_src
++; /* Lowbyte */
947 n
= *p_src
++; /* sample precision (= 8 or 12) */
950 return(-1); /* Unsupported sample precision */
952 p_jpeg
->y_size
= *p_src
++ << 8; /* Highbyte */
953 p_jpeg
->y_size
|= *p_src
++; /* Lowbyte */
954 p_jpeg
->x_size
= *p_src
++ << 8; /* Highbyte */
955 p_jpeg
->x_size
|= *p_src
++; /* Lowbyte */
957 n
= (marker_size
-2-6)/3;
958 if (*p_src
++ != n
|| (n
!= 1 && n
!= 3))
960 return(-2); /* Unsupported SOF0 component specification */
964 p_jpeg
->frameheader
[i
].ID
= *p_src
++; /* Component info */
965 p_jpeg
->frameheader
[i
].horizontal_sampling
= *p_src
>> 4;
966 p_jpeg
->frameheader
[i
].vertical_sampling
= *p_src
++ & 0x0F;
967 p_jpeg
->frameheader
[i
].quanttable_select
= *p_src
++;
968 if (p_jpeg
->frameheader
[i
].horizontal_sampling
> 2
969 || p_jpeg
->frameheader
[i
].vertical_sampling
> 2)
970 return -3; /* Unsupported SOF0 subsampling */
976 case 0xC1: /* SOF Huff - Extended sequential DCT*/
977 case 0xC2: /* SOF Huff - Progressive DCT*/
978 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
979 case 0xC5: /* SOF Huff - Differential sequential DCT*/
980 case 0xC6: /* SOF Huff - Differential progressive DCT*/
981 case 0xC7: /* SOF Huff - Differential spatial*/
982 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
983 case 0xC9: /* SOF Arith - Extended sequential DCT*/
984 case 0xCA: /* SOF Arith - Progressive DCT*/
985 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
986 case 0xCD: /* SOF Arith - Differential sequential DCT*/
987 case 0xCE: /* SOF Arith - Differential progressive DCT*/
988 case 0xCF: /* SOF Arith - Differential spatial*/
990 return (-4); /* other DCT model than baseline not implemented */
993 case 0xC4: /* Define Huffman Table(s) */
995 unsigned char* p_temp
;
998 marker_size
= *p_src
++ << 8; /* Highbyte */
999 marker_size
|= *p_src
++; /* Lowbyte */
1002 while (p_src
< p_temp
+marker_size
-2-17) /* another table */
1005 i
= *p_src
& 0x0F; /* table index */
1008 return (-5); /* Huffman table index out of range */
1010 else if (*p_src
++ & 0xF0) /* AC table */
1012 for (j
=0; j
<16; j
++)
1015 p_jpeg
->hufftable
[i
].huffmancodes_ac
[j
] = *p_src
++;
1017 if(16 + sum
> AC_LEN
)
1018 return -10; /* longer than allowed */
1020 for (; j
< 16 + sum
; j
++)
1021 p_jpeg
->hufftable
[i
].huffmancodes_ac
[j
] = *p_src
++;
1025 for (j
=0; j
<16; j
++)
1028 p_jpeg
->hufftable
[i
].huffmancodes_dc
[j
] = *p_src
++;
1030 if(16 + sum
> DC_LEN
)
1031 return -11; /* longer than allowed */
1033 for (; j
< 16 + sum
; j
++)
1034 p_jpeg
->hufftable
[i
].huffmancodes_dc
[j
] = *p_src
++;
1037 p_src
= p_temp
+marker_size
- 2; /* skip possible residue */
1041 case 0xCC: /* Define Arithmetic coding conditioning(s) */
1042 return(-6); /* Arithmetic coding not supported */
1044 case 0xD8: /* Start of Image */
1045 case 0xD9: /* End of Image */
1046 case 0x01: /* for temp private use arith code */
1047 break; /* skip parameterless marker */
1050 case 0xDA: /* Start of Scan */
1053 marker_size
= *p_src
++ << 8; /* Highbyte */
1054 marker_size
|= *p_src
++; /* Lowbyte */
1056 n
= (marker_size
-2-1-3)/2;
1057 if (*p_src
++ != n
|| (n
!= 1 && n
!= 3))
1059 return (-7); /* Unsupported SOS component specification */
1063 p_jpeg
->scanheader
[i
].ID
= *p_src
++;
1064 p_jpeg
->scanheader
[i
].DC_select
= *p_src
>> 4;
1065 p_jpeg
->scanheader
[i
].AC_select
= *p_src
++ & 0x0F;
1067 p_src
+= 3; /* skip spectral information */
1071 case 0xDB: /* Define quantization Table(s) */
1074 marker_size
= *p_src
++ << 8; /* Highbyte */
1075 marker_size
|= *p_src
++; /* Lowbyte */
1076 n
= (marker_size
-2)/(QUANT_TABLE_LENGTH
+1); /* # of tables */
1079 int id
= *p_src
++; /* ID */
1082 return (-8); /* Unsupported quantization table */
1084 /* Read Quantisation table: */
1085 for (j
=0; j
<QUANT_TABLE_LENGTH
; j
++)
1086 p_jpeg
->quanttable
[id
][j
] = *p_src
++;
1091 case 0xDD: /* Define Restart Interval */
1093 marker_size
= *p_src
++ << 8; /* Highbyte */
1094 marker_size
|= *p_src
++; /* Lowbyte */
1095 p_jpeg
->restart_interval
= *p_src
++ << 8; /* Highbyte */
1096 p_jpeg
->restart_interval
|= *p_src
++; /* Lowbyte */
1097 p_src
+= marker_size
-4; /* skip segment */
1101 case 0xDC: /* Define Number of Lines */
1102 case 0xDE: /* Define Hierarchical progression */
1103 case 0xDF: /* Expand Reference Component(s) */
1104 case 0xE0: /* Application Field 0*/
1105 case 0xE1: /* Application Field 1*/
1106 case 0xE2: /* Application Field 2*/
1107 case 0xE3: /* Application Field 3*/
1108 case 0xE4: /* Application Field 4*/
1109 case 0xE5: /* Application Field 5*/
1110 case 0xE6: /* Application Field 6*/
1111 case 0xE7: /* Application Field 7*/
1112 case 0xE8: /* Application Field 8*/
1113 case 0xE9: /* Application Field 9*/
1114 case 0xEA: /* Application Field 10*/
1115 case 0xEB: /* Application Field 11*/
1116 case 0xEC: /* Application Field 12*/
1117 case 0xED: /* Application Field 13*/
1118 case 0xEE: /* Application Field 14*/
1119 case 0xEF: /* Application Field 15*/
1120 case 0xFE: /* Comment */
1122 marker_size
= *p_src
++ << 8; /* Highbyte */
1123 marker_size
|= *p_src
++; /* Lowbyte */
1124 p_src
+= marker_size
-2; /* skip segment */
1128 case 0xF0: /* Reserved for JPEG extensions */
1129 case 0xF1: /* Reserved for JPEG extensions */
1130 case 0xF2: /* Reserved for JPEG extensions */
1131 case 0xF3: /* Reserved for JPEG extensions */
1132 case 0xF4: /* Reserved for JPEG extensions */
1133 case 0xF5: /* Reserved for JPEG extensions */
1134 case 0xF6: /* Reserved for JPEG extensions */
1135 case 0xF7: /* Reserved for JPEG extensions */
1136 case 0xF8: /* Reserved for JPEG extensions */
1137 case 0xF9: /* Reserved for JPEG extensions */
1138 case 0xFA: /* Reserved for JPEG extensions */
1139 case 0xFB: /* Reserved for JPEG extensions */
1140 case 0xFC: /* Reserved for JPEG extensions */
1141 case 0xFD: /* Reserved for JPEG extensions */
1142 case 0x02: /* Reserved */
1144 return (-9); /* Unknown marker */
1148 return (ret
); /* return flags with seen markers */
1152 void default_huff_tbl(struct jpeg
* p_jpeg
)
1154 static const struct huffman_table luma_table
=
1157 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
1158 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1161 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
1162 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
1163 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
1164 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
1165 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
1166 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1167 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1168 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
1169 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
1170 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
1171 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1176 static const struct huffman_table chroma_table
=
1179 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
1180 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1183 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
1184 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
1185 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1186 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1187 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1188 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1189 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1190 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1191 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1192 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1193 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1198 MEMCPY(&p_jpeg
->hufftable
[0], &luma_table
, sizeof(luma_table
));
1199 MEMCPY(&p_jpeg
->hufftable
[1], &chroma_table
, sizeof(chroma_table
));
1204 /* Compute the derived values for a Huffman table */
1205 void fix_huff_tbl(int* htbl
, struct derived_tbl
* dtbl
)
1210 unsigned int huffcode
[257];
1213 dtbl
->pub
= htbl
; /* fill in back link */
1215 /* Figure C.1: make table of Huffman code length for each symbol */
1216 /* Note that this is in code-length order. */
1219 for (l
= 1; l
<= 16; l
++)
1220 { /* all possible code length */
1221 for (i
= 1; i
<= (int) htbl
[l
-1]; i
++) /* all codes per length */
1222 huffsize
[p
++] = (char) l
;
1226 /* Figure C.2: generate the codes themselves */
1227 /* Note that this is in code-length order. */
1234 while (((int) huffsize
[p
]) == si
)
1236 huffcode
[p
++] = code
;
1243 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1246 for (l
= 1; l
<= 16; l
++)
1250 dtbl
->valptr
[l
] = p
; /* huffval[] index of 1st symbol of code length l */
1251 dtbl
->mincode
[l
] = huffcode
[p
]; /* minimum code of length l */
1253 dtbl
->maxcode
[l
] = huffcode
[p
-1]; /* maximum code of length l */
1257 dtbl
->maxcode
[l
] = -1; /* -1 if no codes of this length */
1260 dtbl
->maxcode
[17] = 0xFFFFFL
; /* ensures huff_DECODE terminates */
1262 /* Compute lookahead tables to speed up decoding.
1263 * First we set all the table entries to 0, indicating "too long";
1264 * then we iterate through the Huffman codes that are short enough and
1265 * fill in all the entries that correspond to bit sequences starting
1269 MEMSET(dtbl
->look_nbits
, 0, sizeof(dtbl
->look_nbits
));
1272 for (l
= 1; l
<= HUFF_LOOKAHEAD
; l
++)
1274 for (i
= 1; i
<= (int) htbl
[l
-1]; i
++, p
++)
1276 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1277 /* Generate left-justified code followed by all possible bit sequences */
1278 lookbits
= huffcode
[p
] << (HUFF_LOOKAHEAD
-l
);
1279 for (ctr
= 1 << (HUFF_LOOKAHEAD
-l
); ctr
> 0; ctr
--)
1281 dtbl
->look_nbits
[lookbits
] = l
;
1282 dtbl
->look_sym
[lookbits
] = htbl
[16+p
];
1290 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1291 * If the incoming data is corrupted, decode_mcu could attempt to
1292 * reference values beyond the end of the array. To avoid a wild store,
1293 * we put some extra zeroes after the real entries.
1295 static const int zag
[] =
1297 0, 1, 8, 16, 9, 2, 3, 10,
1298 17, 24, 32, 25, 18, 11, 4, 5,
1299 12, 19, 26, 33, 40, 48, 41, 34,
1300 27, 20, 13, 6, 7, 14, 21, 28,
1301 35, 42, 49, 56, 57, 50, 43, 36,
1302 29, 22, 15, 23, 30, 37, 44, 51,
1303 58, 59, 52, 45, 38, 31, 39, 46,
1304 53, 60, 61, 54, 47, 55, 62, 63,
1305 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1306 0, 0, 0, 0, 0, 0, 0, 0
1309 void build_lut(struct jpeg
* p_jpeg
)
1312 fix_huff_tbl(p_jpeg
->hufftable
[0].huffmancodes_dc
,
1313 &p_jpeg
->dc_derived_tbls
[0]);
1314 fix_huff_tbl(p_jpeg
->hufftable
[0].huffmancodes_ac
,
1315 &p_jpeg
->ac_derived_tbls
[0]);
1316 fix_huff_tbl(p_jpeg
->hufftable
[1].huffmancodes_dc
,
1317 &p_jpeg
->dc_derived_tbls
[1]);
1318 fix_huff_tbl(p_jpeg
->hufftable
[1].huffmancodes_ac
,
1319 &p_jpeg
->ac_derived_tbls
[1]);
1321 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1322 for (i
=0; i
<64; i
++)
1324 p_jpeg
->qt_idct
[0][zag
[i
]] = p_jpeg
->quanttable
[0][i
];
1325 p_jpeg
->qt_idct
[1][zag
[i
]] = p_jpeg
->quanttable
[1][i
];
1329 p_jpeg
->store_pos
[i
] = i
; /* default ordering */
1331 /* assignments for the decoding of blocks */
1332 if (p_jpeg
->frameheader
[0].horizontal_sampling
== 2
1333 && p_jpeg
->frameheader
[0].vertical_sampling
== 1)
1336 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+15) / 16;
1337 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 16;
1338 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+7) / 8;
1339 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 8;
1340 p_jpeg
->mcu_membership
[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1341 p_jpeg
->mcu_membership
[1] = 0;
1342 p_jpeg
->mcu_membership
[2] = 1;
1343 p_jpeg
->mcu_membership
[3] = 2;
1344 p_jpeg
->tab_membership
[0] = 0; /* DC, DC, AC, AC */
1345 p_jpeg
->tab_membership
[1] = 0;
1346 p_jpeg
->tab_membership
[2] = 1;
1347 p_jpeg
->tab_membership
[3] = 1;
1348 p_jpeg
->subsample_x
[0] = 1;
1349 p_jpeg
->subsample_x
[1] = 2;
1350 p_jpeg
->subsample_x
[2] = 2;
1351 p_jpeg
->subsample_y
[0] = 1;
1352 p_jpeg
->subsample_y
[1] = 1;
1353 p_jpeg
->subsample_y
[2] = 1;
1355 if (p_jpeg
->frameheader
[0].horizontal_sampling
== 1
1356 && p_jpeg
->frameheader
[0].vertical_sampling
== 2)
1357 { /* 4:2:2 vertically subsampled */
1358 p_jpeg
->store_pos
[1] = 2; /* block positions are mirrored */
1359 p_jpeg
->store_pos
[2] = 1;
1361 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+7) / 8;
1362 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 8;
1363 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+15) / 16;
1364 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 16;
1365 p_jpeg
->mcu_membership
[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1366 p_jpeg
->mcu_membership
[1] = 0;
1367 p_jpeg
->mcu_membership
[2] = 1;
1368 p_jpeg
->mcu_membership
[3] = 2;
1369 p_jpeg
->tab_membership
[0] = 0; /* DC, DC, AC, AC */
1370 p_jpeg
->tab_membership
[1] = 0;
1371 p_jpeg
->tab_membership
[2] = 1;
1372 p_jpeg
->tab_membership
[3] = 1;
1373 p_jpeg
->subsample_x
[0] = 1;
1374 p_jpeg
->subsample_x
[1] = 1;
1375 p_jpeg
->subsample_x
[2] = 1;
1376 p_jpeg
->subsample_y
[0] = 1;
1377 p_jpeg
->subsample_y
[1] = 2;
1378 p_jpeg
->subsample_y
[2] = 2;
1380 else if (p_jpeg
->frameheader
[0].horizontal_sampling
== 2
1381 && p_jpeg
->frameheader
[0].vertical_sampling
== 2)
1384 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+15) / 16;
1385 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 16;
1386 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+15) / 16;
1387 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 16;
1388 p_jpeg
->mcu_membership
[0] = 0;
1389 p_jpeg
->mcu_membership
[1] = 0;
1390 p_jpeg
->mcu_membership
[2] = 0;
1391 p_jpeg
->mcu_membership
[3] = 0;
1392 p_jpeg
->mcu_membership
[4] = 1;
1393 p_jpeg
->mcu_membership
[5] = 2;
1394 p_jpeg
->tab_membership
[0] = 0;
1395 p_jpeg
->tab_membership
[1] = 0;
1396 p_jpeg
->tab_membership
[2] = 0;
1397 p_jpeg
->tab_membership
[3] = 0;
1398 p_jpeg
->tab_membership
[4] = 1;
1399 p_jpeg
->tab_membership
[5] = 1;
1400 p_jpeg
->subsample_x
[0] = 1;
1401 p_jpeg
->subsample_x
[1] = 2;
1402 p_jpeg
->subsample_x
[2] = 2;
1403 p_jpeg
->subsample_y
[0] = 1;
1404 p_jpeg
->subsample_y
[1] = 2;
1405 p_jpeg
->subsample_y
[2] = 2;
1407 else if (p_jpeg
->frameheader
[0].horizontal_sampling
== 1
1408 && p_jpeg
->frameheader
[0].vertical_sampling
== 1)
1410 /* don't overwrite p_jpeg->blocks */
1411 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+7) / 8;
1412 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 8;
1413 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+7) / 8;
1414 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 8;
1415 p_jpeg
->mcu_membership
[0] = 0;
1416 p_jpeg
->mcu_membership
[1] = 1;
1417 p_jpeg
->mcu_membership
[2] = 2;
1418 p_jpeg
->tab_membership
[0] = 0;
1419 p_jpeg
->tab_membership
[1] = 1;
1420 p_jpeg
->tab_membership
[2] = 1;
1421 p_jpeg
->subsample_x
[0] = 1;
1422 p_jpeg
->subsample_x
[1] = 1;
1423 p_jpeg
->subsample_x
[2] = 1;
1424 p_jpeg
->subsample_y
[0] = 1;
1425 p_jpeg
->subsample_y
[1] = 1;
1426 p_jpeg
->subsample_y
[2] = 1;
1437 * These functions/macros provide the in-line portion of bit fetching.
1438 * Use check_bit_buffer to ensure there are N bits in get_buffer
1439 * before using get_bits, peek_bits, or drop_bits.
1440 * check_bit_buffer(state,n,action);
1441 * Ensure there are N bits in get_buffer; if suspend, take action.
1442 * val = get_bits(n);
1443 * Fetch next N bits.
1444 * val = peek_bits(n);
1445 * Fetch next N bits without removing them from the buffer.
1447 * Discard next N bits.
1448 * The value N should be a simple variable, not an expression, because it
1449 * is evaluated multiple times.
1452 INLINE
void check_bit_buffer(struct bitstream
* pb
, int nbits
)
1454 if (pb
->bits_left
< nbits
)
1455 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1458 byte
= *pb
->next_input_byte
++;
1459 if (byte
== 0xFF) /* legal marker can be byte stuffing or RSTm */
1460 { /* simplification: just skip the (one-byte) marker code */
1461 pb
->next_input_byte
++;
1463 pb
->get_buffer
= (pb
->get_buffer
<< 8) | byte
;
1465 byte
= *pb
->next_input_byte
++;
1466 if (byte
== 0xFF) /* legal marker can be byte stuffing or RSTm */
1467 { /* simplification: just skip the (one-byte) marker code */
1468 pb
->next_input_byte
++;
1470 pb
->get_buffer
= (pb
->get_buffer
<< 8) | byte
;
1472 pb
->bits_left
+= 16;
1476 INLINE
int get_bits(struct bitstream
* pb
, int nbits
)
1478 return ((int) (pb
->get_buffer
>> (pb
->bits_left
-= nbits
))) & ((1<<nbits
)-1);
1481 INLINE
int peek_bits(struct bitstream
* pb
, int nbits
)
1483 return ((int) (pb
->get_buffer
>> (pb
->bits_left
- nbits
))) & ((1<<nbits
)-1);
1486 INLINE
void drop_bits(struct bitstream
* pb
, int nbits
)
1488 pb
->bits_left
-= nbits
;
1491 /* re-synchronize to entropy data (skip restart marker) */
1492 void search_restart(struct bitstream
* pb
)
1494 pb
->next_input_byte
--; /* we may have overread it, taking 2 bytes */
1495 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1496 while (pb
->next_input_byte
< pb
->input_end
&&
1497 (pb
->next_input_byte
[-2] != 0xFF || pb
->next_input_byte
[-1] == 0x00))
1499 pb
->next_input_byte
++;
1504 /* Figure F.12: extend sign bit. */
1505 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1507 static const int extend_test
[16] = /* entry n is 2**(n-1) */
1509 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1510 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1513 static const int extend_offset
[16] = /* entry n is (-1 << n) + 1 */
1515 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1516 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1517 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1518 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1521 /* Decode a single value */
1522 INLINE
int huff_decode_dc(struct bitstream
* bs
, struct derived_tbl
* tbl
)
1526 check_bit_buffer(bs
, HUFF_LOOKAHEAD
);
1527 look
= peek_bits(bs
, HUFF_LOOKAHEAD
);
1528 if ((nb
= tbl
->look_nbits
[look
]) != 0)
1531 s
= tbl
->look_sym
[look
];
1532 check_bit_buffer(bs
, s
);
1533 r
= get_bits(bs
, s
);
1534 s
= HUFF_EXTEND(r
, s
);
1537 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1539 nb
=HUFF_LOOKAHEAD
+1;
1540 check_bit_buffer(bs
, nb
);
1541 code
= get_bits(bs
, nb
);
1542 while (code
> tbl
->maxcode
[nb
])
1545 check_bit_buffer(bs
, 1);
1546 code
|= get_bits(bs
, 1);
1549 if (nb
> 16) /* error in Huffman */
1551 s
=0; /* fake a zero, this is most safe */
1555 s
= tbl
->pub
[16 + tbl
->valptr
[nb
] + ((int) (code
- tbl
->mincode
[nb
])) ];
1556 check_bit_buffer(bs
, s
);
1557 r
= get_bits(bs
, s
);
1558 s
= HUFF_EXTEND(r
, s
);
1560 } /* end slow decode */
1564 INLINE
int huff_decode_ac(struct bitstream
* bs
, struct derived_tbl
* tbl
)
1568 check_bit_buffer(bs
, HUFF_LOOKAHEAD
);
1569 look
= peek_bits(bs
, HUFF_LOOKAHEAD
);
1570 if ((nb
= tbl
->look_nbits
[look
]) != 0)
1573 s
= tbl
->look_sym
[look
];
1576 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1578 nb
=HUFF_LOOKAHEAD
+1;
1579 check_bit_buffer(bs
, nb
);
1580 code
= get_bits(bs
, nb
);
1581 while (code
> tbl
->maxcode
[nb
])
1584 check_bit_buffer(bs
, 1);
1585 code
|= get_bits(bs
, 1);
1588 if (nb
> 16) /* error in Huffman */
1590 s
=0; /* fake a zero, this is most safe */
1594 s
= tbl
->pub
[16 + tbl
->valptr
[nb
] + ((int) (code
- tbl
->mincode
[nb
])) ];
1596 } /* end slow decode */
1601 #ifdef HAVE_LCD_COLOR
1603 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1604 /* Note: it keeps the original color subsampling, even if resized. */
1605 int jpeg_decode(struct jpeg
* p_jpeg
, unsigned char* p_pixel
[3],
1606 int downscale
, void (*pf_progress
)(int current
, int total
))
1608 struct bitstream bs
; /* bitstream "object" */
1609 int block
[64]; /* decoded DCT coefficients */
1612 int skip_line
[3]; /* bytes from one line to the next (skip_line) */
1613 int skip_strip
[3], skip_mcu
[3]; /* bytes to next DCT row / column */
1615 int i
, x
, y
; /* loop counter */
1617 unsigned char* p_line
[3] = {p_pixel
[0], p_pixel
[1], p_pixel
[2]};
1618 unsigned char* p_byte
[3]; /* bitmap pointer */
1620 void (*pf_idct
)(unsigned char*, int*, int*, int); /* selected IDCT */
1621 int k_need
; /* AC coefficients needed up to here */
1622 int zero_need
; /* init the block with this many zeros */
1624 int last_dc_val
[3] = {0, 0, 0}; /* or 128 for chroma? */
1625 int store_offs
[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1626 int restart
= p_jpeg
->restart_interval
; /* MCUs until restart marker */
1628 /* pick the IDCT we want, determine how to work with coefs */
1632 k_need
= 64; /* all */
1633 zero_need
= 63; /* all */
1635 else if (downscale
== 2)
1638 k_need
= 25; /* this far in zig-zag to cover 4*4 */
1639 zero_need
= 27; /* clear this far in linear order */
1641 else if (downscale
== 4)
1644 k_need
= 5; /* this far in zig-zag to cover 2*2 */
1645 zero_need
= 9; /* clear this far in linear order */
1647 else if (downscale
== 8)
1650 k_need
= 0; /* no AC, not needed */
1651 zero_need
= 0; /* no AC, not needed */
1653 else return -1; /* not supported */
1655 /* init bitstream, fake a restart to make it start */
1656 bs
.next_input_byte
= p_jpeg
->p_entropy_data
;
1658 bs
.input_end
= p_jpeg
->p_entropy_end
;
1660 width
= p_jpeg
->x_phys
/ downscale
;
1661 height
= p_jpeg
->y_phys
/ downscale
;
1662 for (i
=0; i
<3; i
++) /* calculate some strides */
1664 skip_line
[i
] = width
/ p_jpeg
->subsample_x
[i
];
1665 skip_strip
[i
] = skip_line
[i
]
1666 * (height
/ p_jpeg
->y_mbl
) / p_jpeg
->subsample_y
[i
];
1667 skip_mcu
[i
] = width
/p_jpeg
->x_mbl
/ p_jpeg
->subsample_x
[i
];
1670 /* prepare offsets about where to store the different blocks */
1671 store_offs
[p_jpeg
->store_pos
[0]] = 0;
1672 store_offs
[p_jpeg
->store_pos
[1]] = 8 / downscale
; /* to the right */
1673 store_offs
[p_jpeg
->store_pos
[2]] = width
* 8 / downscale
; /* below */
1674 store_offs
[p_jpeg
->store_pos
[3]] = store_offs
[1] + store_offs
[2]; /* r+b */
1676 for(y
=0; y
<p_jpeg
->y_mbl
&& bs
.next_input_byte
<= bs
.input_end
; y
++)
1678 for (i
=0; i
<3; i
++) /* scan line init */
1680 p_byte
[i
] = p_line
[i
];
1681 p_line
[i
] += skip_strip
[i
];
1683 for (x
=0; x
<p_jpeg
->x_mbl
; x
++)
1687 /* Outer loop handles each block in the MCU */
1688 for (blkn
= 0; blkn
< p_jpeg
->blocks
; blkn
++)
1689 { /* Decode a single block's worth of coefficients */
1690 int k
= 1; /* coefficient index */
1691 int s
, r
; /* huffman values */
1692 int ci
= p_jpeg
->mcu_membership
[blkn
]; /* component index */
1693 int ti
= p_jpeg
->tab_membership
[blkn
]; /* table index */
1694 struct derived_tbl
* dctbl
= &p_jpeg
->dc_derived_tbls
[ti
];
1695 struct derived_tbl
* actbl
= &p_jpeg
->ac_derived_tbls
[ti
];
1697 /* Section F.2.2.1: decode the DC coefficient difference */
1698 s
= huff_decode_dc(&bs
, dctbl
);
1700 last_dc_val
[ci
] += s
;
1701 block
[0] = last_dc_val
[ci
]; /* output it (assumes zag[0] = 0) */
1703 /* coefficient buffer must be cleared */
1704 MEMSET(block
+1, 0, zero_need
*sizeof(block
[0]));
1706 /* Section F.2.2.2: decode the AC coefficients */
1707 for (; k
< k_need
; k
++)
1709 s
= huff_decode_ac(&bs
, actbl
);
1716 check_bit_buffer(&bs
, s
);
1717 r
= get_bits(&bs
, s
);
1718 block
[zag
[k
]] = HUFF_EXTEND(r
, s
);
1730 /* In this path we just discard the values */
1733 s
= huff_decode_ac(&bs
, actbl
);
1740 check_bit_buffer(&bs
, s
);
1752 { /* Y component needs to bother about block store */
1753 pf_idct(p_byte
[0]+store_offs
[blkn
], block
,
1754 p_jpeg
->qt_idct
[ti
], skip_line
[0]);
1758 pf_idct(p_byte
[ci
], block
, p_jpeg
->qt_idct
[ti
],
1762 p_byte
[0] += skip_mcu
[0]; /* unrolled for (i=0; i<3; i++) loop */
1763 p_byte
[1] += skip_mcu
[1];
1764 p_byte
[2] += skip_mcu
[2];
1765 if (p_jpeg
->restart_interval
&& --restart
== 0)
1766 { /* if a restart marker is due: */
1767 restart
= p_jpeg
->restart_interval
; /* count again */
1768 search_restart(&bs
); /* align the bitstream */
1769 last_dc_val
[0] = last_dc_val
[1] =
1770 last_dc_val
[2] = 0; /* reset decoder */
1773 if (pf_progress
!= NULL
)
1774 pf_progress(y
, p_jpeg
->y_mbl
-1); /* notify about decoding progress */
1777 return 0; /* success */
1779 #else /* !HAVE_LCD_COLOR */
1781 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1782 int jpeg_decode(struct jpeg
* p_jpeg
, unsigned char* p_pixel
[1], int downscale
,
1783 void (*pf_progress
)(int current
, int total
))
1785 struct bitstream bs
; /* bitstream "object" */
1786 int block
[64]; /* decoded DCT coefficients */
1789 int skip_line
; /* bytes from one line to the next (skip_line) */
1790 int skip_strip
, skip_mcu
; /* bytes to next DCT row / column */
1792 int x
, y
; /* loop counter */
1794 unsigned char* p_line
= p_pixel
[0];
1795 unsigned char* p_byte
; /* bitmap pointer */
1797 void (*pf_idct
)(unsigned char*, int*, int*, int); /* selected IDCT */
1798 int k_need
; /* AC coefficients needed up to here */
1799 int zero_need
; /* init the block with this many zeros */
1801 int last_dc_val
= 0;
1802 int store_offs
[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1803 int restart
= p_jpeg
->restart_interval
; /* MCUs until restart marker */
1805 /* pick the IDCT we want, determine how to work with coefs */
1809 k_need
= 64; /* all */
1810 zero_need
= 63; /* all */
1812 else if (downscale
== 2)
1815 k_need
= 25; /* this far in zig-zag to cover 4*4 */
1816 zero_need
= 27; /* clear this far in linear order */
1818 else if (downscale
== 4)
1821 k_need
= 5; /* this far in zig-zag to cover 2*2 */
1822 zero_need
= 9; /* clear this far in linear order */
1824 else if (downscale
== 8)
1827 k_need
= 0; /* no AC, not needed */
1828 zero_need
= 0; /* no AC, not needed */
1830 else return -1; /* not supported */
1832 /* init bitstream, fake a restart to make it start */
1833 bs
.next_input_byte
= p_jpeg
->p_entropy_data
;
1835 bs
.input_end
= p_jpeg
->p_entropy_end
;
1837 width
= p_jpeg
->x_phys
/ downscale
;
1838 height
= p_jpeg
->y_phys
/ downscale
;
1840 skip_strip
= skip_line
* (height
/ p_jpeg
->y_mbl
);
1841 skip_mcu
= (width
/p_jpeg
->x_mbl
);
1843 /* prepare offsets about where to store the different blocks */
1844 store_offs
[p_jpeg
->store_pos
[0]] = 0;
1845 store_offs
[p_jpeg
->store_pos
[1]] = 8 / downscale
; /* to the right */
1846 store_offs
[p_jpeg
->store_pos
[2]] = width
* 8 / downscale
; /* below */
1847 store_offs
[p_jpeg
->store_pos
[3]] = store_offs
[1] + store_offs
[2]; /* r+b */
1849 for(y
=0; y
<p_jpeg
->y_mbl
&& bs
.next_input_byte
<= bs
.input_end
; y
++)
1852 p_line
+= skip_strip
;
1853 for (x
=0; x
<p_jpeg
->x_mbl
; x
++)
1857 /* Outer loop handles each block in the MCU */
1858 for (blkn
= 0; blkn
< p_jpeg
->blocks
; blkn
++)
1859 { /* Decode a single block's worth of coefficients */
1860 int k
= 1; /* coefficient index */
1861 int s
, r
; /* huffman values */
1862 int ci
= p_jpeg
->mcu_membership
[blkn
]; /* component index */
1863 int ti
= p_jpeg
->tab_membership
[blkn
]; /* table index */
1864 struct derived_tbl
* dctbl
= &p_jpeg
->dc_derived_tbls
[ti
];
1865 struct derived_tbl
* actbl
= &p_jpeg
->ac_derived_tbls
[ti
];
1867 /* Section F.2.2.1: decode the DC coefficient difference */
1868 s
= huff_decode_dc(&bs
, dctbl
);
1870 if (ci
== 0) /* only for Y component */
1873 block
[0] = last_dc_val
; /* output it (assumes zag[0] = 0) */
1875 /* coefficient buffer must be cleared */
1876 MEMSET(block
+1, 0, zero_need
*sizeof(block
[0]));
1878 /* Section F.2.2.2: decode the AC coefficients */
1879 for (; k
< k_need
; k
++)
1881 s
= huff_decode_ac(&bs
, actbl
);
1888 check_bit_buffer(&bs
, s
);
1889 r
= get_bits(&bs
, s
);
1890 block
[zag
[k
]] = HUFF_EXTEND(r
, s
);
1903 /* In this path we just discard the values */
1906 s
= huff_decode_ac(&bs
, actbl
);
1913 check_bit_buffer(&bs
, s
);
1925 { /* only for Y component */
1926 pf_idct(p_byte
+store_offs
[blkn
], block
, p_jpeg
->qt_idct
[ti
],
1931 if (p_jpeg
->restart_interval
&& --restart
== 0)
1932 { /* if a restart marker is due: */
1933 restart
= p_jpeg
->restart_interval
; /* count again */
1934 search_restart(&bs
); /* align the bitstream */
1935 last_dc_val
= 0; /* reset decoder */
1938 if (pf_progress
!= NULL
)
1939 pf_progress(y
, p_jpeg
->y_mbl
-1); /* notify about decoding progress */
1942 return 0; /* success */
1944 #endif /* !HAVE_LCD_COLOR */
1946 /**************** end JPEG code ********************/
1950 /**************** begin Application ********************/
1953 /************************* Types ***************************/
1957 #ifdef HAVE_LCD_COLOR
1958 unsigned char* bitmap
[3]; /* Y, Cr, Cb */
1961 unsigned char* bitmap
[1]; /* Y only */
1969 /************************* Globals ***************************/
1971 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1972 struct t_disp disp
[9];
1974 /* my memory pool (from the mp3 buffer) */
1975 char print
[32]; /* use a common snprintf() buffer */
1976 unsigned char* buf
; /* up to here currently used by image(s) */
1978 /* the remaining free part of the buffer for compressed+uncompressed images */
1979 unsigned char* buf_images
;
1981 ssize_t buf_size
, buf_images_size
;
1982 /* the root of the images, hereafter are decompresed ones */
1983 unsigned char* buf_root
;
1986 int ds
, ds_min
, ds_max
; /* downscaling and limits */
1987 static struct jpeg jpg
; /* too large for stack */
1989 static struct tree_context
*tree
;
1991 /* the current full file name */
1992 static char np_file
[MAX_PATH
];
1993 int curfile
= 0, direction
= DIR_NONE
, entries
= 0;
1995 /* list of the jpeg files */
1997 /* are we using the plugin buffer or the audio buffer? */
1998 bool plug_buf
= false;
2001 /************************* Implementation ***************************/
2003 #ifdef HAVE_LCD_COLOR
2005 * Conversion of full 0-255 range YCrCb to RGB:
2006 * |R| |1.000000 -0.000001 1.402000| |Y'|
2007 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
2008 * |B| |1.000000 1.772000 0.000000| |Pr|
2009 * Scaled (yields s15-bit output):
2010 * |R| |128 0 179| |Y |
2011 * |G| = |128 -43 -91| |Cb - 128|
2012 * |B| |128 227 0| |Cr - 128|
2019 #define YUV_WHITE (255*YFAC)
2020 #define NODITHER_DELTA (127*YFAC)
2021 #define COMPONENT_SHIFT 15
2022 #define MATRIX_SHIFT 7
2024 static inline int clamp_component(int x
)
2026 if ((unsigned)x
> YUV_WHITE
)
2027 x
= x
< 0 ? 0 : YUV_WHITE
;
2031 static inline int clamp_component_bits(int x
, int bits
)
2033 if ((unsigned)x
> (1u << bits
) - 1)
2034 x
= x
< 0 ? 0 : (1 << bits
) - 1;
2038 static inline int component_to_lcd(int x
, int bits
, int delta
)
2040 /* Formula used in core bitmap loader. */
2041 return (((1 << bits
) - 1)*x
+ (x
>> (8 - bits
)) + delta
) >> COMPONENT_SHIFT
;
2044 static inline int lcd_to_component(int x
, int bits
, int delta
)
2046 /* Reasonable, approximate reversal to get a full range back from the
2048 return YUV_WHITE
*x
/ ((1 << bits
) - 1);
2058 int16_t errbuf
[LCD_WIDTH
+2]; /* Error record for line below */
2059 } rgb_err_buffers
[3];
2061 fb_data rgb_linebuf
[LCD_WIDTH
]; /* Line buffer for scrolling when
2062 DITHER_DIFFUSION is set */
2066 int r
, g
, b
; /* Current pixel components in s16.0 */
2067 int inc
; /* Current line increment (-1 or 1) */
2068 int row
; /* Current row in source image */
2069 int col
; /* Current column in source image */
2070 int ce
[3]; /* Errors to apply to current pixel */
2071 struct rgb_err
*e
; /* RED, GRN, BLU */
2072 int epos
; /* Current position in error record */
2075 struct rgb_pixel
*pixel
;
2077 /** round and truncate to lcd depth **/
2078 static fb_data
pixel_to_lcd_colour(void)
2080 struct rgb_pixel
*p
= pixel
;
2083 r
= component_to_lcd(p
->r
, LCD_RED_BITS
, NODITHER_DELTA
);
2084 r
= clamp_component_bits(r
, LCD_RED_BITS
);
2086 g
= component_to_lcd(p
->g
, LCD_GREEN_BITS
, NODITHER_DELTA
);
2087 g
= clamp_component_bits(g
, LCD_GREEN_BITS
);
2089 b
= component_to_lcd(p
->b
, LCD_BLUE_BITS
, NODITHER_DELTA
);
2090 b
= clamp_component_bits(b
, LCD_BLUE_BITS
);
2092 return LCD_RGBPACK_LCD(r
, g
, b
);
2095 /** write a monochrome pixel to the colour LCD **/
2096 static fb_data
pixel_to_lcd_gray(void)
2100 g
= clamp_component(pixel
->g
);
2101 r
= component_to_lcd(g
, LCD_RED_BITS
, NODITHER_DELTA
);
2102 b
= component_to_lcd(g
, LCD_BLUE_BITS
, NODITHER_DELTA
);
2103 g
= component_to_lcd(g
, LCD_GREEN_BITS
, NODITHER_DELTA
);
2105 return LCD_RGBPACK_LCD(r
, g
, b
);
2109 * Bayer ordered dithering - swiped from the core bitmap loader.
2111 static fb_data
pixel_odither_to_lcd(void)
2113 /* canonical ordered dither matrix */
2114 static const unsigned char dither_matrix
[16][16] = {
2115 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
2116 { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
2117 { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
2118 { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
2119 { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
2120 { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
2121 { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
2122 { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
2123 { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
2124 { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
2125 { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
2126 { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
2127 { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
2128 { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
2129 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
2130 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
2133 struct rgb_pixel
*p
= pixel
;
2136 delta
= dither_matrix
[p
->col
& 15][p
->row
& 15] << MATRIX_SHIFT
;
2138 r
= component_to_lcd(p
->r
, LCD_RED_BITS
, delta
);
2139 r
= clamp_component_bits(r
, LCD_RED_BITS
);
2141 g
= component_to_lcd(p
->g
, LCD_GREEN_BITS
, delta
);
2142 g
= clamp_component_bits(g
, LCD_GREEN_BITS
);
2144 b
= component_to_lcd(p
->b
, LCD_BLUE_BITS
, delta
);
2145 b
= clamp_component_bits(b
, LCD_BLUE_BITS
);
2149 return LCD_RGBPACK_LCD(r
, g
, b
);
2153 * Floyd/Steinberg dither to lcd depth.
2155 * Apply filter to each component in serpentine pattern. Kernel shown for
2156 * L->R scan. Kernel is reversed for R->L.
2160 static inline void distribute_error(int *ce
, struct rgb_err
*e
,
2161 int err
, int epos
, int inc
)
2163 *ce
= (7*err
>> 4) + e
->errbuf
[epos
+inc
];
2164 e
->errbuf
[epos
+inc
] = err
>> 4;
2165 e
->errbuf
[epos
] += 5*err
>> 4;
2166 e
->errbuf
[epos
-inc
] += 3*err
>> 4;
2169 static fb_data
pixel_fsdither_to_lcd(void)
2171 struct rgb_pixel
*p
= pixel
;
2172 int rc
, gc
, bc
, r
, g
, b
;
2175 /* Full components with error terms */
2176 rc
= p
->r
+ p
->ce
[RED
];
2177 r
= component_to_lcd(rc
, LCD_RED_BITS
, 0);
2178 r
= clamp_component_bits(r
, LCD_RED_BITS
);
2180 gc
= p
->g
+ p
->ce
[GRN
];
2181 g
= component_to_lcd(gc
, LCD_GREEN_BITS
, 0);
2182 g
= clamp_component_bits(g
, LCD_GREEN_BITS
);
2184 bc
= p
->b
+ p
->ce
[BLU
];
2185 b
= component_to_lcd(bc
, LCD_BLUE_BITS
, 0);
2186 b
= clamp_component_bits(b
, LCD_BLUE_BITS
);
2188 /* Get pixel errors */
2189 rc
-= lcd_to_component(r
, LCD_RED_BITS
, 0);
2190 gc
-= lcd_to_component(g
, LCD_GREEN_BITS
, 0);
2191 bc
-= lcd_to_component(b
, LCD_BLUE_BITS
, 0);
2193 /* Spead error to surrounding pixels. */
2198 distribute_error(&p
->ce
[RED
], &p
->e
[RED
], rc
, epos
, inc
);
2199 distribute_error(&p
->ce
[GRN
], &p
->e
[GRN
], gc
, epos
, inc
);
2200 distribute_error(&p
->ce
[BLU
], &p
->e
[BLU
], bc
, epos
, inc
);
2202 /* Pack and return pixel */
2203 return LCD_RGBPACK_LCD(r
, g
, b
);
2206 /* Functions for each output mode, colour then grayscale. */
2207 static fb_data (* const pixel_funcs
[COLOUR_NUM_MODES
][DITHER_NUM_MODES
])(void) =
2209 [COLOURMODE_COLOUR
] =
2211 [DITHER_NONE
] = pixel_to_lcd_colour
,
2212 [DITHER_ORDERED
] = pixel_odither_to_lcd
,
2213 [DITHER_DIFFUSION
] = pixel_fsdither_to_lcd
,
2217 [DITHER_NONE
] = pixel_to_lcd_gray
,
2218 [DITHER_ORDERED
] = pixel_odither_to_lcd
,
2219 [DITHER_DIFFUSION
] = pixel_fsdither_to_lcd
,
2224 * Draw a partial YUV colour bitmap
2226 * Runs serpentine pattern when dithering is DITHER_DIFFUSION, else scan is
2229 void yuv_bitmap_part(unsigned char *src
[3], int csub_x
, int csub_y
,
2230 int src_x
, int src_y
, int stride
,
2231 int x
, int y
, int width
, int height
)
2233 fb_data
*dst
, *dst_end
;
2234 fb_data (*pixel_func
)(void);
2235 struct rgb_pixel px
;
2237 if (x
+ width
> LCD_WIDTH
)
2238 width
= LCD_WIDTH
- x
; /* Clip right */
2240 width
+= x
, x
= 0; /* Clip left */
2242 return; /* nothing left to do */
2244 if (y
+ height
> LCD_HEIGHT
)
2245 height
= LCD_HEIGHT
- y
; /* Clip bottom */
2247 height
+= y
, y
= 0; /* Clip top */
2249 return; /* nothing left to do */
2253 dst
= rb
->lcd_framebuffer
+ LCD_WIDTH
* y
+ x
;
2254 dst_end
= dst
+ LCD_WIDTH
* height
;
2256 if (jpeg_settings
.colour_mode
== COLOURMODE_GRAY
)
2257 csub_y
= 0; /* Ignore Cb, Cr */
2259 pixel_func
= pixel_funcs
[jpeg_settings
.colour_mode
]
2260 [jpeg_settings
.dither_mode
];
2262 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2264 /* Reset error terms. */
2265 px
.e
= rgb_err_buffers
;
2266 px
.ce
[RED
] = px
.ce
[GRN
] = px
.ce
[BLU
] = 0;
2267 rb
->memset(px
.e
, 0, 3*sizeof (struct rgb_err
));
2272 fb_data
*dst_row
, *row_end
;
2273 const unsigned char *ysrc
;
2276 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2278 /* Use R->L scan on odd lines */
2279 px
.inc
-= (src_y
& 1) << 1;
2283 px
.epos
+= width
- 1;
2290 row_end
= dst_row
+ width
;
2297 dst_row
= row_end
+ width
;
2298 px
.col
= src_x
+ width
- 1;
2301 ysrc
= src
[0] + stride
* src_y
+ px
.col
;
2304 /* Do one row of pixels */
2305 if (csub_y
) /* colour */
2307 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
2308 const unsigned char *usrc
, *vsrc
;
2310 usrc
= src
[1] + (stride
/csub_x
) * (src_y
/csub_y
)
2312 vsrc
= src
[2] + (stride
/csub_x
) * (src_y
/csub_y
)
2314 int xphase
= px
.col
% csub_x
;
2315 int xphase_reset
= px
.inc
* csub_x
;
2316 int y
, v
, u
, rv
, guv
, bu
;
2323 guv
= GUFAC
*u
+ GVFAC
*v
;
2334 *dst_row
= pixel_func();
2337 if (dst_row
== row_end
)
2341 if ((unsigned)xphase
< (unsigned)csub_x
)
2344 /* fetch new chromas */
2350 guv
= GUFAC
*u
+ GVFAC
*v
;
2353 xphase
-= xphase_reset
;
2356 else /* monochrome */
2360 /* Set all components the same for dithering purposes */
2361 px
.g
= px
.r
= px
.b
= YFAC
*(*ysrc
);
2362 *dst_row
= pixel_func();
2366 while (dst_row
!= row_end
);
2372 while (dst
< dst_end
);
2375 #endif /* HAVE_LCD_COLOR */
2378 /* support function for qsort() */
2379 static int compare(const void* p1
, const void* p2
)
2381 return rb
->strcasecmp(*((char **)p1
), *((char **)p2
));
2384 bool jpg_ext(const char ext
[])
2388 if(!rb
->strcasecmp(ext
,".jpg") ||
2389 !rb
->strcasecmp(ext
,".jpe") ||
2390 !rb
->strcasecmp(ext
,".jpeg"))
2396 /*Read directory contents for scrolling. */
2397 void get_pic_list(void)
2400 long int str_len
= 0;
2402 tree
= rb
->tree_get_context();
2404 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2405 file_pt
= rb
->plugin_get_buffer((size_t *)&buf_size
);
2407 file_pt
= rb
->plugin_get_audio_buffer((size_t *)&buf_size
);
2410 for(i
= 0; i
< tree
->filesindir
; i
++)
2412 if(jpg_ext(rb
->strrchr(&tree
->name_buffer
[str_len
],'.')))
2413 file_pt
[entries
++] = &tree
->name_buffer
[str_len
];
2415 str_len
+= rb
->strlen(&tree
->name_buffer
[str_len
]) + 1;
2418 rb
->qsort(file_pt
, entries
, sizeof(char**), compare
);
2420 /* Remove path and leave only the name.*/
2421 pname
= rb
->strrchr(np_file
,'/');
2424 /* Find Selected File. */
2425 for(i
= 0; i
< entries
; i
++)
2426 if(!rb
->strcmp(file_pt
[i
], pname
))
2430 int change_filename(int direct
)
2435 if(direct
== DIR_PREV
)
2441 curfile
= entries
- 1;
2444 }while(file_pt
[curfile
] == '\0' && count
< entries
);
2445 /* we "erase" the file name if we encounter
2446 * a non-supported file, so skip it now */
2448 else /* DIR_NEXT/DIR_NONE */
2453 if(curfile
== entries
- 1)
2457 }while(file_pt
[curfile
] == '\0' && count
< entries
);
2460 if(count
== entries
&& file_pt
[curfile
] == '\0')
2462 rb
->splash(HZ
, "No supported files");
2463 return PLUGIN_ERROR
;
2465 if(rb
->strlen(tree
->currdir
) > 1)
2467 rb
->strcpy(np_file
, tree
->currdir
);
2468 rb
->strcat(np_file
, "/");
2471 rb
->strcpy(np_file
, tree
->currdir
);
2473 rb
->strcat(np_file
, file_pt
[curfile
]);
2475 return PLUGIN_OTHER
;
2478 /* switch off overlay, for handling SYS_ events */
2479 void cleanup(void *parameter
)
2487 #define VSCROLL (LCD_HEIGHT/8)
2488 #define HSCROLL (LCD_WIDTH/10)
2490 #define ZOOM_IN 100 /* return codes for below function */
2491 #define ZOOM_OUT 101
2493 #ifdef HAVE_LCD_COLOR
2494 bool set_option_grayscale(void)
2496 bool gray
= jpeg_settings
.colour_mode
== COLOURMODE_GRAY
;
2497 rb
->set_bool("Grayscale", &gray
);
2498 jpeg_settings
.colour_mode
= gray
? COLOURMODE_GRAY
: COLOURMODE_COLOUR
;
2502 bool set_option_dithering(void)
2504 static const struct opt_items dithering
[DITHER_NUM_MODES
] = {
2505 [DITHER_NONE
] = { "Off", -1 },
2506 [DITHER_ORDERED
] = { "Ordered", -1 },
2507 [DITHER_DIFFUSION
] = { "Diffusion", -1 },
2510 rb
->set_option("Dithering", &jpeg_settings
.dither_mode
, INT
,
2511 dithering
, DITHER_NUM_MODES
, NULL
);
2515 static void display_options(void)
2517 static const struct menu_item items
[] = {
2518 { "Grayscale", set_option_grayscale
},
2519 { "Dithering", set_option_dithering
},
2522 int m
= menu_init(rb
, items
, ARRAYLEN(items
),
2523 NULL
, NULL
, NULL
, NULL
);
2527 #endif /* HAVE_LCD_COLOR */
2529 int show_menu(void) /* return 1 to quit */
2532 rb
->lcd_set_backdrop(old_backdrop
);
2533 #ifdef HAVE_LCD_COLOR
2534 rb
->lcd_set_foreground(rb
->global_settings
->fg_color
);
2535 rb
->lcd_set_background(rb
->global_settings
->bg_color
);
2537 rb
->lcd_set_foreground(LCD_BLACK
);
2538 rb
->lcd_set_background(LCD_WHITE
);
2547 MIID_TOGGLE_SS_MODE
,
2548 MIID_CHANGE_SS_MODE
,
2549 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2550 MIID_SHOW_PLAYBACK_MENU
,
2552 #ifdef HAVE_LCD_COLOR
2553 MIID_DISPLAY_OPTIONS
,
2558 static const struct menu_item items
[] = {
2561 [MIID_TOGGLE_SS_MODE
] =
2562 { "Toggle Slideshow Mode", NULL
},
2563 [MIID_CHANGE_SS_MODE
] =
2564 { "Change Slideshow Time", NULL
},
2565 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2566 [MIID_SHOW_PLAYBACK_MENU
] =
2567 { "Show Playback Menu", NULL
},
2569 #ifdef HAVE_LCD_COLOR
2570 [MIID_DISPLAY_OPTIONS
] =
2571 { "Display Options", NULL
},
2577 static const struct opt_items slideshow
[2] = {
2582 m
= menu_init(rb
, items
, sizeof(items
) / sizeof(*items
),
2583 NULL
, NULL
, NULL
, NULL
);
2584 result
=menu_show(m
);
2592 case MIID_TOGGLE_SS_MODE
:
2593 rb
->set_option("Toggle Slideshow", &slideshow_enabled
, INT
,
2594 slideshow
, 2, NULL
);
2596 case MIID_CHANGE_SS_MODE
:
2597 rb
->set_int("Slideshow Time", "s", UNIT_SEC
,
2598 &jpeg_settings
.ss_timeout
, NULL
, 1,
2599 SS_MIN_TIMEOUT
, SS_MAX_TIMEOUT
, NULL
);
2602 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2603 case MIID_SHOW_PLAYBACK_MENU
:
2606 playback_control(rb
, NULL
);
2610 rb
->splash(HZ
, "Cannot restart playback");
2614 #ifdef HAVE_LCD_COLOR
2615 case MIID_DISPLAY_OPTIONS
:
2623 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
2624 /* change ata spindown time based on slideshow time setting */
2625 immediate_ata_off
= false;
2626 rb
->ata_spindown(rb
->global_settings
->disk_spindown
);
2628 if (slideshow_enabled
)
2630 if(jpeg_settings
.ss_timeout
< 10)
2632 /* slideshow times < 10s keep disk spinning */
2633 rb
->ata_spindown(0);
2635 else if (!rb
->mp3_is_playing())
2637 /* slideshow times > 10s and not playing: ata_off after load */
2638 immediate_ata_off
= true;
2643 rb
->lcd_set_backdrop(NULL
);
2644 rb
->lcd_set_foreground(LCD_WHITE
);
2645 rb
->lcd_set_background(LCD_BLACK
);
2647 rb
->lcd_clear_display();
2651 /* interactively scroll around the image */
2652 int scroll_bmp(struct t_disp
* pdisp
)
2661 if (slideshow_enabled
)
2662 button
= rb
->button_get_w_tmo(jpeg_settings
.ss_timeout
* HZ
);
2663 else button
= rb
->button_get(true);
2665 running_slideshow
= false;
2670 if (!(ds
< ds_max
) && entries
> 0 && jpg
.x_size
<= MAX_X_SIZE
)
2671 return change_filename(DIR_PREV
);
2672 case JPEG_LEFT
| BUTTON_REPEAT
:
2673 move
= MIN(HSCROLL
, pdisp
->x
);
2676 MYXLCD(scroll_right
)(move
); /* scroll right */
2678 #ifdef HAVE_LCD_COLOR
2680 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2681 pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2682 0, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2683 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2685 MYXLCD(gray_bitmap_part
)(
2686 pdisp
->bitmap
[0], pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2687 0, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2688 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2695 if (!(ds
< ds_max
) && entries
> 0 && jpg
.x_size
<= MAX_X_SIZE
)
2696 return change_filename(DIR_NEXT
);
2697 case JPEG_RIGHT
| BUTTON_REPEAT
:
2698 move
= MIN(HSCROLL
, pdisp
->width
- pdisp
->x
- LCD_WIDTH
);
2701 MYXLCD(scroll_left
)(move
); /* scroll left */
2703 #ifdef HAVE_LCD_COLOR
2705 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2706 pdisp
->x
+ LCD_WIDTH
- move
, pdisp
->y
, pdisp
->stride
,
2707 LCD_WIDTH
- move
, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2708 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2710 MYXLCD(gray_bitmap_part
)(
2711 pdisp
->bitmap
[0], pdisp
->x
+ LCD_WIDTH
- move
,
2712 pdisp
->y
, pdisp
->stride
,
2713 LCD_WIDTH
- move
, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2714 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2721 case JPEG_UP
| BUTTON_REPEAT
:
2722 move
= MIN(VSCROLL
, pdisp
->y
);
2725 MYXLCD(scroll_down
)(move
); /* scroll down */
2727 #ifdef HAVE_LCD_COLOR
2728 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2730 /* Draw over the band at the top of the last update
2731 caused by lack of error history on line zero. */
2732 move
= MIN(move
+ 1, pdisp
->y
+ pdisp
->height
);
2736 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2737 pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2738 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), 0, /* x, y */
2739 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2741 MYXLCD(gray_bitmap_part
)(
2742 pdisp
->bitmap
[0], pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2743 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), 0, /* x, y */
2744 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2751 case JPEG_DOWN
| BUTTON_REPEAT
:
2752 move
= MIN(VSCROLL
, pdisp
->height
- pdisp
->y
- LCD_HEIGHT
);
2755 MYXLCD(scroll_up
)(move
); /* scroll up */
2757 #ifdef HAVE_LCD_COLOR
2758 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2760 /* Save the line that was on the last line of the display
2761 and draw one extra line above then recover the line with
2762 image data that had an error history when it was drawn.
2766 rb
->lcd_framebuffer
+ (LCD_HEIGHT
- move
)*LCD_WIDTH
,
2767 LCD_WIDTH
*sizeof (fb_data
));
2771 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
, pdisp
->x
,
2772 pdisp
->y
+ LCD_HEIGHT
- move
, pdisp
->stride
,
2773 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), LCD_HEIGHT
- move
, /* x, y */
2774 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2776 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2778 /* Cover the first row drawn with previous image data. */
2779 MEMCPY(rb
->lcd_framebuffer
+ (LCD_HEIGHT
- move
)*LCD_WIDTH
,
2781 LCD_WIDTH
*sizeof (fb_data
));
2785 MYXLCD(gray_bitmap_part
)(
2786 pdisp
->bitmap
[0], pdisp
->x
,
2787 pdisp
->y
+ LCD_HEIGHT
- move
, pdisp
->stride
,
2788 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), LCD_HEIGHT
- move
, /* x, y */
2789 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2795 if (!slideshow_enabled
)
2797 running_slideshow
= true;
2799 return change_filename(DIR_NEXT
);
2802 #ifdef JPEG_SLIDE_SHOW
2803 case JPEG_SLIDE_SHOW
:
2804 slideshow_enabled
= !slideshow_enabled
;
2805 running_slideshow
= slideshow_enabled
;
2809 #ifdef JPEG_NEXT_REPEAT
2810 case JPEG_NEXT_REPEAT
:
2814 return change_filename(DIR_NEXT
);
2817 #ifdef JPEG_PREVIOUS_REPEAT
2818 case JPEG_PREVIOUS_REPEAT
:
2822 return change_filename(DIR_PREV
);
2826 #ifdef JPEG_ZOOM_PRE
2827 if (lastbutton
!= JPEG_ZOOM_PRE
)
2834 #ifdef JPEG_ZOOM_PRE
2835 if (lastbutton
!= JPEG_ZOOM_PRE
)
2845 grey_show(false); /* switch off greyscale overlay */
2847 if (show_menu() == 1)
2851 grey_show(true); /* switch on greyscale overlay */
2854 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2855 pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2856 MAX(0, (LCD_WIDTH
- pdisp
->width
) / 2),
2857 MAX(0, (LCD_HEIGHT
- pdisp
->height
) / 2),
2858 MIN(LCD_WIDTH
, pdisp
->width
),
2859 MIN(LCD_HEIGHT
, pdisp
->height
));
2864 if (rb
->default_event_handler_ex(button
, cleanup
, NULL
)
2865 == SYS_USB_CONNECTED
)
2866 return PLUGIN_USB_CONNECTED
;
2871 if (button
!= BUTTON_NONE
)
2872 lastbutton
= button
;
2873 } /* while (true) */
2876 /********************* main function *************************/
2878 /* callback updating a progress meter while JPEG decoding */
2879 void cb_progess(int current
, int total
)
2881 rb
->yield(); /* be nice to the other threads */
2882 if(!running_slideshow
)
2884 rb
->gui_scrollbar_draw(rb
->screens
[SCREEN_MAIN
],0, LCD_HEIGHT
-8, LCD_WIDTH
, 8, total
, 0,
2885 current
, HORIZONTAL
);
2886 rb
->lcd_update_rect(0, LCD_HEIGHT
-8, LCD_WIDTH
, 8);
2891 /* in slideshow mode, keep gui interference to a minimum */
2892 rb
->gui_scrollbar_draw(rb
->screens
[SCREEN_MAIN
],0, LCD_HEIGHT
-4, LCD_WIDTH
, 4, total
, 0,
2893 current
, HORIZONTAL
);
2894 rb
->lcd_update_rect(0, LCD_HEIGHT
-4, LCD_WIDTH
, 4);
2899 int jpegmem(struct jpeg
*p_jpg
, int ds
)
2903 size
= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[0])
2904 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[0]);
2905 #ifdef HAVE_LCD_COLOR
2906 if (p_jpg
->blocks
> 1) /* colour, add requirements for chroma */
2908 size
+= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[1])
2909 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[1]);
2910 size
+= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[2])
2911 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[2]);
2917 /* how far can we zoom in without running out of memory */
2918 int min_downscale(struct jpeg
*p_jpg
, int bufsize
)
2922 if (jpegmem(p_jpg
, 8) > bufsize
)
2923 return 0; /* error, too large, even 1:8 doesn't fit */
2925 while (downscale
> 1 && jpegmem(p_jpg
, downscale
/2) <= bufsize
)
2932 /* how far can we zoom out, to fit image into the LCD */
2933 int max_downscale(struct jpeg
*p_jpg
)
2937 while (downscale
< 8 && (p_jpg
->x_size
> LCD_WIDTH
*downscale
2938 || p_jpg
->y_size
> LCD_HEIGHT
*downscale
))
2947 /* return decoded or cached image */
2948 struct t_disp
* get_image(struct jpeg
* p_jpg
, int ds
)
2950 int w
, h
; /* used to center output */
2951 int size
; /* decompressed image size */
2952 long time
; /* measured ticks */
2955 struct t_disp
* p_disp
= &disp
[ds
]; /* short cut */
2957 if (p_disp
->bitmap
[0] != NULL
)
2959 return p_disp
; /* we still have it */
2962 /* assign image buffer */
2964 /* physical size needed for decoding */
2965 size
= jpegmem(p_jpg
, ds
);
2966 if (buf_size
<= size
)
2967 { /* have to discard the current */
2969 for (i
=1; i
<=8; i
++)
2970 disp
[i
].bitmap
[0] = NULL
; /* invalidate all bitmaps */
2971 buf
= buf_root
; /* start again from the beginning of the buffer */
2972 buf_size
= root_size
;
2975 #ifdef HAVE_LCD_COLOR
2976 if (p_jpg
->blocks
> 1) /* colour jpeg */
2980 for (i
= 1; i
< 3; i
++)
2982 size
= (p_jpg
->x_phys
/ ds
/ p_jpg
->subsample_x
[i
])
2983 * (p_jpg
->y_phys
/ ds
/ p_jpg
->subsample_y
[i
]);
2984 p_disp
->bitmap
[i
] = buf
;
2988 p_disp
->csub_x
= p_jpg
->subsample_x
[1];
2989 p_disp
->csub_y
= p_jpg
->subsample_y
[1];
2993 p_disp
->csub_x
= p_disp
->csub_y
= 0;
2994 p_disp
->bitmap
[1] = p_disp
->bitmap
[2] = buf
;
2997 /* size may be less when decoded (if height is not block aligned) */
2998 size
= (p_jpg
->x_phys
/ds
) * (p_jpg
->y_size
/ ds
);
2999 p_disp
->bitmap
[0] = buf
;
3003 if(!running_slideshow
)
3005 rb
->snprintf(print
, sizeof(print
), "decoding %d*%d",
3006 p_jpg
->x_size
/ds
, p_jpg
->y_size
/ds
);
3007 rb
->lcd_puts(0, 3, print
);
3011 /* update image properties */
3012 p_disp
->width
= p_jpg
->x_size
/ ds
;
3013 p_disp
->stride
= p_jpg
->x_phys
/ ds
; /* use physical size for stride */
3014 p_disp
->height
= p_jpg
->y_size
/ ds
;
3016 /* the actual decoding */
3017 time
= *rb
->current_tick
;
3018 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
3019 rb
->cpu_boost(true);
3020 status
= jpeg_decode(p_jpg
, p_disp
->bitmap
, ds
, cb_progess
);
3021 rb
->cpu_boost(false);
3023 status
= jpeg_decode(p_jpg
, p_disp
->bitmap
, ds
, cb_progess
);
3027 rb
->splash(HZ
, "decode error %d", status
);
3028 file_pt
[curfile
] = '\0';
3031 time
= *rb
->current_tick
- time
;
3033 if(!running_slideshow
)
3035 rb
->snprintf(print
, sizeof(print
), " %ld.%02ld sec ", time
/HZ
, time
%HZ
);
3036 rb
->lcd_getstringsize(print
, &w
, &h
); /* centered in progress bar */
3037 rb
->lcd_putsxy((LCD_WIDTH
- w
)/2, LCD_HEIGHT
- h
, print
);
3045 /* set the view to the given center point, limit if necessary */
3046 void set_view (struct t_disp
* p_disp
, int cx
, int cy
)
3050 /* plain center to available width/height */
3051 x
= cx
- MIN(LCD_WIDTH
, p_disp
->width
) / 2;
3052 y
= cy
- MIN(LCD_HEIGHT
, p_disp
->height
) / 2;
3054 /* limit against upper image size */
3055 x
= MIN(p_disp
->width
- LCD_WIDTH
, x
);
3056 y
= MIN(p_disp
->height
- LCD_HEIGHT
, y
);
3058 /* limit against negative side */
3062 p_disp
->x
= x
; /* set the values */
3067 /* calculate the view center based on the bitmap position */
3068 void get_view(struct t_disp
* p_disp
, int* p_cx
, int* p_cy
)
3070 *p_cx
= p_disp
->x
+ MIN(LCD_WIDTH
, p_disp
->width
) / 2;
3071 *p_cy
= p_disp
->y
+ MIN(LCD_HEIGHT
, p_disp
->height
) / 2;
3075 /* load, decode, display the image */
3076 int load_and_show(char* filename
)
3080 unsigned char* buf_jpeg
; /* compressed JPEG image */
3082 struct t_disp
* p_disp
; /* currenly displayed image */
3083 int cx
, cy
; /* view center */
3085 fd
= rb
->open(filename
, O_RDONLY
);
3088 rb
->snprintf(print
,sizeof(print
),"err opening %s:%d",filename
,fd
);
3089 rb
->splash(HZ
, print
);
3090 return PLUGIN_ERROR
;
3092 filesize
= rb
->filesize(fd
);
3093 rb
->memset(&disp
, 0, sizeof(disp
));
3095 buf
= buf_images
+ filesize
;
3096 buf_size
= buf_images_size
- filesize
;
3097 /* allocate JPEG buffer */
3098 buf_jpeg
= buf_images
;
3100 buf_root
= buf
; /* we can start the decompressed images behind it */
3101 root_size
= buf_size
;
3105 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
3109 rb
->lcd_setfont(FONT_SYSFIXED
);
3110 rb
->lcd_clear_display();
3111 rb
->snprintf(print
,sizeof(print
),"%s:",rb
->strrchr(filename
,'/')+1);
3112 rb
->lcd_puts(0,0,print
);
3113 rb
->lcd_puts(0,1,"Not enough plugin memory!");
3114 rb
->lcd_puts(0,2,"Zoom In: Stop playback.");
3116 rb
->lcd_puts(0,3,"Left/Right: Skip File.");
3117 rb
->lcd_puts(0,4,"Off: Quit.");
3119 rb
->lcd_setfont(FONT_UI
);
3121 rb
->button_clear_queue();
3125 int button
= rb
->button_get(true);
3130 buf_images
= rb
->plugin_get_audio_buffer(
3131 (size_t *)&buf_images_size
);
3132 /*try again this file, now using the audio buffer */
3133 return PLUGIN_OTHER
;
3143 rb
->lcd_clear_display();
3144 return change_filename(DIR_PREV
);
3151 rb
->lcd_clear_display();
3152 return change_filename(DIR_NEXT
);
3156 if(rb
->default_event_handler_ex(button
, cleanup
, NULL
)
3157 == SYS_USB_CONNECTED
)
3158 return PLUGIN_USB_CONNECTED
;
3166 rb
->splash(HZ
, "Out of Memory");
3168 return PLUGIN_ERROR
;
3172 if(!running_slideshow
)
3175 rb
->lcd_set_foreground(LCD_WHITE
);
3176 rb
->lcd_set_background(LCD_BLACK
);
3177 rb
->lcd_set_backdrop(NULL
);
3180 rb
->lcd_clear_display();
3181 rb
->snprintf(print
, sizeof(print
), "%s:", rb
->strrchr(filename
,'/')+1);
3182 rb
->lcd_puts(0, 0, print
);
3185 rb
->snprintf(print
, sizeof(print
), "loading %d bytes", filesize
);
3186 rb
->lcd_puts(0, 1, print
);
3190 rb
->read(fd
, buf_jpeg
, filesize
);
3193 if(!running_slideshow
)
3195 rb
->snprintf(print
, sizeof(print
), "decoding markers");
3196 rb
->lcd_puts(0, 2, print
);
3200 else if(immediate_ata_off
)
3202 /* running slideshow and time is long enough: power down disk */
3207 rb
->memset(&jpg
, 0, sizeof(jpg
)); /* clear info struct */
3208 /* process markers, unstuffing */
3209 status
= process_markers(buf_jpeg
, filesize
, &jpg
);
3211 if (status
< 0 || (status
& (DQT
| SOF0
)) != (DQT
| SOF0
))
3212 { /* bad format or minimum components not contained */
3213 rb
->splash(HZ
, "unsupported %d", status
);
3214 file_pt
[curfile
] = '\0';
3215 return change_filename(direction
);
3218 if (!(status
& DHT
)) /* if no Huffman table present: */
3219 default_huff_tbl(&jpg
); /* use default */
3220 build_lut(&jpg
); /* derive Huffman and other lookup-tables */
3222 if(!running_slideshow
)
3224 rb
->snprintf(print
, sizeof(print
), "image %dx%d", jpg
.x_size
, jpg
.y_size
);
3225 rb
->lcd_puts(0, 2, print
);
3228 ds_max
= max_downscale(&jpg
); /* check display constraint */
3229 ds_min
= min_downscale(&jpg
, buf_size
); /* check memory constraint */
3232 rb
->splash(HZ
, "too large");
3233 file_pt
[curfile
] = '\0';
3234 return change_filename(direction
);
3237 ds
= ds_max
; /* initials setting */
3238 cx
= jpg
.x_size
/ds
/2; /* center the view */
3239 cy
= jpg
.y_size
/ds
/2;
3241 do /* loop the image prepare and decoding when zoomed */
3243 p_disp
= get_image(&jpg
, ds
); /* decode or fetch from cache */
3245 return change_filename(direction
);
3247 set_view(p_disp
, cx
, cy
);
3249 if(!running_slideshow
)
3251 rb
->snprintf(print
, sizeof(print
), "showing %dx%d",
3252 p_disp
->width
, p_disp
->height
);
3253 rb
->lcd_puts(0, 3, print
);
3256 MYLCD(clear_display
)();
3257 #ifdef HAVE_LCD_COLOR
3259 p_disp
->bitmap
, p_disp
->csub_x
, p_disp
->csub_y
,
3260 p_disp
->x
, p_disp
->y
, p_disp
->stride
,
3261 MAX(0, (LCD_WIDTH
- p_disp
->width
) / 2),
3262 MAX(0, (LCD_HEIGHT
- p_disp
->height
) / 2),
3263 MIN(LCD_WIDTH
, p_disp
->width
),
3264 MIN(LCD_HEIGHT
, p_disp
->height
));
3266 MYXLCD(gray_bitmap_part
)(
3267 p_disp
->bitmap
[0], p_disp
->x
, p_disp
->y
, p_disp
->stride
,
3268 MAX(0, (LCD_WIDTH
- p_disp
->width
) / 2),
3269 MAX(0, (LCD_HEIGHT
- p_disp
->height
) / 2),
3270 MIN(LCD_WIDTH
, p_disp
->width
),
3271 MIN(LCD_HEIGHT
, p_disp
->height
));
3276 grey_show(true); /* switch on greyscale overlay */
3279 /* drawing is now finished, play around with scrolling
3280 * until you press OFF or connect USB
3284 status
= scroll_bmp(p_disp
);
3285 if (status
== ZOOM_IN
)
3289 ds
/= 2; /* reduce downscaling to zoom in */
3290 get_view(p_disp
, &cx
, &cy
);
3291 cx
*= 2; /* prepare the position in the new image */
3298 if (status
== ZOOM_OUT
)
3302 ds
*= 2; /* increase downscaling to zoom out */
3303 get_view(p_disp
, &cx
, &cy
);
3304 cx
/= 2; /* prepare the position in the new image */
3314 grey_show(false); /* switch off overlay */
3316 rb
->lcd_clear_display();
3318 while (status
!= PLUGIN_OK
&& status
!= PLUGIN_USB_CONNECTED
3319 && status
!= PLUGIN_OTHER
);
3326 /******************** Plugin entry point *********************/
3328 enum plugin_status
plugin_start(const struct plugin_api
* api
, const void* parameter
)
3334 long greysize
; /* helper */
3337 old_backdrop
= rb
->lcd_get_backdrop();
3340 if(!parameter
) return PLUGIN_ERROR
;
3342 rb
->strcpy(np_file
, parameter
);
3345 if(!entries
) return PLUGIN_ERROR
;
3347 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
3348 if(rb
->audio_status())
3350 buf
= rb
->plugin_get_buffer((size_t *)&buf_size
) +
3351 (entries
* sizeof(char**));
3352 buf_size
-= (entries
* sizeof(char**));
3356 buf
= rb
->plugin_get_audio_buffer((size_t *)&buf_size
);
3358 buf
= rb
->plugin_get_audio_buffer(&buf_size
) +
3359 (entries
* sizeof(char**));
3360 buf_size
-= (entries
* sizeof(char**));
3364 if (!grey_init(rb
, buf
, buf_size
, GREY_ON_COP
,
3365 LCD_WIDTH
, LCD_HEIGHT
, &greysize
))
3367 rb
->splash(HZ
, "grey buf error");
3368 return PLUGIN_ERROR
;
3371 buf_size
-= greysize
;
3376 /* should be ok to just load settings since a parameter is present
3377 here and the drive should be spinning */
3378 configfile_init(rb
);
3379 configfile_load(JPEG_CONFIGFILE
, jpeg_config
,
3380 ARRAYLEN(jpeg_config
), JPEG_SETTINGS_MINVERSION
);
3381 old_settings
= jpeg_settings
;
3383 buf_images
= buf
; buf_images_size
= buf_size
;
3385 /* Turn off backlight timeout */
3386 backlight_force_on(rb
); /* backlight control in lib/helper.c */
3390 condition
= load_and_show(np_file
);
3391 }while (condition
!= PLUGIN_OK
&& condition
!= PLUGIN_USB_CONNECTED
3392 && condition
!= PLUGIN_ERROR
);
3394 if (rb
->memcmp(&jpeg_settings
, &old_settings
, sizeof (jpeg_settings
)))
3396 /* Just in case drive has to spin, keep it from looking locked */
3397 rb
->splash(0, "Saving Settings");
3398 configfile_save(JPEG_CONFIGFILE
, jpeg_config
,
3399 ARRAYLEN(jpeg_config
), JPEG_SETTINGS_VERSION
);
3402 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
3403 /* set back ata spindown time in case we changed it */
3404 rb
->ata_spindown(rb
->global_settings
->disk_spindown
);
3407 /* Turn on backlight timeout (revert to settings) */
3408 backlight_use_settings(rb
); /* backlight control in lib/helper.c */
3411 grey_release(); /* deinitialize */
3417 #endif /* HAVE_LCD_BITMAP */