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