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
217 #elif CONFIG_KEYPAD == IAUDIO67_PAD
218 #define JPEG_ZOOM_IN BUTTON_VOLUP
219 #define JPEG_ZOOM_OUT BUTTON_VOLDOWN
220 #define JPEG_UP BUTTON_STOP
221 #define JPEG_DOWN BUTTON_PLAY
222 #define JPEG_LEFT BUTTON_LEFT
223 #define JPEG_RIGHT BUTTON_RIGHT
224 #define JPEG_MENU BUTTON_MENU
225 #define JPEG_NEXT (BUTTON_PLAY|BUTTON_VOLUP)
226 #define JPEG_PREVIOUS (BUTTON_PLAY|BUTTON_VOLDOWN)
229 #error No keymap defined!
232 #ifdef HAVE_TOUCHSCREEN
234 #define JPEG_UP BUTTON_TOPMIDDLE
237 #define JPEG_DOWN BUTTON_BOTTOMMIDDLE
240 #define JPEG_LEFT BUTTON_MIDLEFT
243 #define JPEG_RIGHT BUTTON_MIDRIGHT
246 #define JPEG_ZOOM_IN BUTTON_TOPRIGHT
248 #ifndef JPEG_ZOOM_OUT
249 #define JPEG_ZOOM_OUT BUTTON_TOPLEFT
252 #define JPEG_MENU (BUTTON_CENTER|BUTTON_REL)
255 #define JPEG_NEXT BUTTON_BOTTOMRIGHT
257 #ifndef JPEG_PREVIOUS
258 #define JPEG_PREVIOUS BUTTON_BOTTOMLEFT
262 /* different graphics libraries */
266 #define MYLCD(fn) grey_ub_ ## fn
267 #define MYLCD_UPDATE()
268 #define MYXLCD(fn) grey_ub_ ## fn
270 #define MYLCD(fn) rb->lcd_ ## fn
271 #define MYLCD_UPDATE() rb->lcd_update();
272 #define MYXLCD(fn) xlcd_ ## fn
275 #define MAX_X_SIZE LCD_WIDTH*8
277 /* Min memory allowing us to use the plugin buffer
278 * and thus not stopping the music
279 * *Very* rough estimation:
280 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
281 * + 20k code size = 60 000
282 * + 50k min for jpeg = 120 000
284 #define MIN_MEM 120000
291 #define PLUGIN_OTHER 10 /* State code for output with return. */
293 /******************************* Globals ***********************************/
295 static const struct plugin_api
* rb
;
296 MEM_FUNCTION_WRAPPERS(rb
);
298 /* for portability of below JPEG code */
299 #define MEMSET(p,v,c) rb->memset(p,v,c)
300 #define MEMCPY(d,s,c) rb->memcpy(d,s,c)
301 #define INLINE static inline
302 #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
304 static int slideshow_enabled
= false; /* run slideshow */
305 static int running_slideshow
= false; /* loading image because of slideshw */
307 static int immediate_ata_off
= false; /* power down disk after loading */
310 /* Persistent configuration */
311 #define JPEG_CONFIGFILE "jpeg.cfg"
312 #define JPEG_SETTINGS_MINVERSION 1
313 #define JPEG_SETTINGS_VERSION 2
315 /* Slideshow times */
316 #define SS_MIN_TIMEOUT 1
317 #define SS_MAX_TIMEOUT 20
318 #define SS_DEFAULT_TIMEOUT 5
322 COLOURMODE_COLOUR
= 0,
329 DITHER_NONE
= 0, /* No dithering */
330 DITHER_ORDERED
, /* Bayer ordered */
331 DITHER_DIFFUSION
, /* Floyd/Steinberg error diffusion */
342 static struct jpeg_settings jpeg_settings
=
343 { COLOURMODE_COLOUR
, DITHER_NONE
, SS_DEFAULT_TIMEOUT
};
344 static struct jpeg_settings old_settings
;
346 static struct configdata jpeg_config
[] =
348 #ifdef HAVE_LCD_COLOR
349 { TYPE_ENUM
, 0, COLOUR_NUM_MODES
, &jpeg_settings
.colour_mode
,
350 "Colour Mode", (char *[]){ "Colour", "Grayscale" }, NULL
},
351 { TYPE_ENUM
, 0, DITHER_NUM_MODES
, &jpeg_settings
.dither_mode
,
352 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" }, NULL
},
354 { TYPE_INT
, SS_MIN_TIMEOUT
, SS_MAX_TIMEOUT
, &jpeg_settings
.ss_timeout
,
355 "Slideshow Time", NULL
, NULL
},
359 fb_data
* old_backdrop
;
362 /**************** begin JPEG code ********************/
364 INLINE
unsigned range_limit(int value
)
366 #if CONFIG_CPU == SH7034
368 asm ( /* Note: Uses knowledge that only low byte of result is used */
370 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
371 "extu.b %[v],%[t] \n"
372 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
373 "bt 1f \n" /* yes: no overflow */
374 "cmp/pz %[v] \n" /* overflow: positive? */
375 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
382 #elif defined(CPU_COLDFIRE)
383 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
384 "add.l #128,%[v] \n" /* value += 128; */
385 "cmp.l #255,%[v] \n" /* overflow? */
386 "bls.b 1f \n" /* no: return value */
387 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
393 #elif defined(CPU_ARM)
394 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
395 "add %[v], %[v], #128 \n" /* value += 128 */
396 "cmp %[v], #255 \n" /* out of range 0..255? */
397 "mvnhi %[v], %[v], asr #31 \n" /* yes: set all bits to ~(sign_bit) */
405 if ((unsigned)value
<= 255)
415 /* IDCT implementation */
418 #define CONST_BITS 13
422 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
423 * causing a lot of useless floating-point operations at run time.
424 * To get around this we use the following pre-calculated constants.
425 * If you change CONST_BITS you may want to add appropriate values.
426 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
428 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
429 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
430 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
431 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
432 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
433 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
434 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
435 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
436 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
437 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
438 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
439 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
443 /* Multiply an long variable by an long constant to yield an long result.
444 * For 8-bit samples with the recommended scaling, all the variable
445 * and constant values involved are no more than 16 bits wide, so a
446 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
447 * For 12-bit samples, a full 32-bit multiplication will be needed.
449 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
452 /* Dequantize a coefficient by multiplying it by the multiplier-table
453 * entry; produce an int result. In this module, both inputs and result
454 * are 16 bits or less, so either int or short multiply will work.
456 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
457 #define DEQUANTIZE MULTIPLY16
459 /* Descale and correctly round an int value that's scaled by N bits.
460 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
461 * the fudge factor is correct for either sign of X.
463 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
468 * Perform dequantization and inverse DCT on one block of coefficients,
469 * producing a reduced-size 1x1 output block.
471 void idct1x1(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
473 (void)skip_line
; /* unused */
474 *p_byte
= range_limit(inptr
[0] * quantptr
[0] >> 3);
480 * Perform dequantization and inverse DCT on one block of coefficients,
481 * producing a reduced-size 2x2 output block.
483 void idct2x2(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
485 int tmp0
, tmp1
, tmp2
, tmp3
, tmp4
, tmp5
;
486 unsigned char* outptr
;
488 /* Pass 1: process columns from input, store into work array. */
491 tmp4
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]);
492 tmp5
= DEQUANTIZE(inptr
[8*1], quantptr
[8*1]);
498 tmp4
= DEQUANTIZE(inptr
[8*0+1], quantptr
[8*0+1]);
499 tmp5
= DEQUANTIZE(inptr
[8*1+1], quantptr
[8*1+1]);
504 /* Pass 2: process 2 rows, store into output array. */
509 outptr
[0] = range_limit((int) DESCALE(tmp0
+ tmp1
, 3));
510 outptr
[1] = range_limit((int) DESCALE(tmp0
- tmp1
, 3));
513 outptr
= p_byte
+ skip_line
;
515 outptr
[0] = range_limit((int) DESCALE(tmp2
+ tmp3
, 3));
516 outptr
[1] = range_limit((int) DESCALE(tmp2
- tmp3
, 3));
522 * Perform dequantization and inverse DCT on one block of coefficients,
523 * producing a reduced-size 4x4 output block.
525 void idct4x4(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
527 int tmp0
, tmp2
, tmp10
, tmp12
;
530 unsigned char* outptr
;
532 int workspace
[4*4]; /* buffers data between passes */
534 /* Pass 1: process columns from input, store into work array. */
537 for (ctr
= 0; ctr
< 4; ctr
++, inptr
++, quantptr
++, wsptr
++)
541 tmp0
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]);
542 tmp2
= DEQUANTIZE(inptr
[8*2], quantptr
[8*2]);
544 tmp10
= (tmp0
+ tmp2
) << PASS1_BITS
;
545 tmp12
= (tmp0
- tmp2
) << PASS1_BITS
;
548 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
550 z2
= DEQUANTIZE(inptr
[8*1], quantptr
[8*1]);
551 z3
= DEQUANTIZE(inptr
[8*3], quantptr
[8*3]);
553 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
554 tmp0
= DESCALE(z1
+ MULTIPLY16(z3
, - FIX_1_847759065
), CONST_BITS
-PASS1_BITS
);
555 tmp2
= DESCALE(z1
+ MULTIPLY16(z2
, FIX_0_765366865
), CONST_BITS
-PASS1_BITS
);
557 /* Final output stage */
559 wsptr
[4*0] = (int) (tmp10
+ tmp2
);
560 wsptr
[4*3] = (int) (tmp10
- tmp2
);
561 wsptr
[4*1] = (int) (tmp12
+ tmp0
);
562 wsptr
[4*2] = (int) (tmp12
- tmp0
);
565 /* Pass 2: process 4 rows from work array, store into output array. */
568 for (ctr
= 0; ctr
< 4; ctr
++)
570 outptr
= p_byte
+ (ctr
*skip_line
);
573 tmp0
= (int) wsptr
[0];
574 tmp2
= (int) wsptr
[2];
576 tmp10
= (tmp0
+ tmp2
) << CONST_BITS
;
577 tmp12
= (tmp0
- tmp2
) << CONST_BITS
;
580 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
585 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
586 tmp0
= z1
+ MULTIPLY16(z3
, - FIX_1_847759065
);
587 tmp2
= z1
+ MULTIPLY16(z2
, FIX_0_765366865
);
589 /* Final output stage */
591 outptr
[0] = range_limit((int) DESCALE(tmp10
+ tmp2
,
592 CONST_BITS
+PASS1_BITS
+3));
593 outptr
[3] = range_limit((int) DESCALE(tmp10
- tmp2
,
594 CONST_BITS
+PASS1_BITS
+3));
595 outptr
[1] = range_limit((int) DESCALE(tmp12
+ tmp0
,
596 CONST_BITS
+PASS1_BITS
+3));
597 outptr
[2] = range_limit((int) DESCALE(tmp12
- tmp0
,
598 CONST_BITS
+PASS1_BITS
+3));
600 wsptr
+= 4; /* advance pointer to next row */
607 * Perform dequantization and inverse DCT on one block of coefficients.
609 void idct8x8(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
611 long tmp0
, tmp1
, tmp2
, tmp3
;
612 long tmp10
, tmp11
, tmp12
, tmp13
;
613 long z1
, z2
, z3
, z4
, z5
;
615 unsigned char* outptr
;
617 int workspace
[64]; /* buffers data between passes */
619 /* Pass 1: process columns from input, store into work array. */
620 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
621 /* furthermore, we scale the results by 2**PASS1_BITS. */
624 for (ctr
= 8; ctr
> 0; ctr
--)
626 /* Due to quantization, we will usually find that many of the input
627 * coefficients are zero, especially the AC terms. We can exploit this
628 * by short-circuiting the IDCT calculation for any column in which all
629 * the AC terms are zero. In that case each output is equal to the
630 * DC coefficient (with scale factor as needed).
631 * With typical images and quantization tables, half or more of the
632 * column DCT calculations can be simplified this way.
635 if ((inptr
[8*1] | inptr
[8*2] | inptr
[8*3]
636 | inptr
[8*4] | inptr
[8*5] | inptr
[8*6] | inptr
[8*7]) == 0)
638 /* AC terms all zero */
639 int dcval
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]) << PASS1_BITS
;
641 wsptr
[8*0] = wsptr
[8*1] = wsptr
[8*2] = wsptr
[8*3] = wsptr
[8*4]
642 = wsptr
[8*5] = wsptr
[8*6] = wsptr
[8*7] = dcval
;
643 inptr
++; /* advance pointers to next column */
649 /* Even part: reverse the even part of the forward DCT. */
650 /* The rotator is sqrt(2)*c(-6). */
652 z2
= DEQUANTIZE(inptr
[8*2], quantptr
[8*2]);
653 z3
= DEQUANTIZE(inptr
[8*6], quantptr
[8*6]);
655 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
656 tmp2
= z1
+ MULTIPLY16(z3
, - FIX_1_847759065
);
657 tmp3
= z1
+ MULTIPLY16(z2
, FIX_0_765366865
);
659 z2
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]);
660 z3
= DEQUANTIZE(inptr
[8*4], quantptr
[8*4]);
662 tmp0
= (z2
+ z3
) << CONST_BITS
;
663 tmp1
= (z2
- z3
) << CONST_BITS
;
670 /* Odd part per figure 8; the matrix is unitary and hence its
671 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
673 tmp0
= DEQUANTIZE(inptr
[8*7], quantptr
[8*7]);
674 tmp1
= DEQUANTIZE(inptr
[8*5], quantptr
[8*5]);
675 tmp2
= DEQUANTIZE(inptr
[8*3], quantptr
[8*3]);
676 tmp3
= DEQUANTIZE(inptr
[8*1], quantptr
[8*1]);
682 z5
= MULTIPLY16(z3
+ z4
, FIX_1_175875602
); /* sqrt(2) * c3 */
684 tmp0
= MULTIPLY16(tmp0
, FIX_0_298631336
); /* sqrt(2) * (-c1+c3+c5-c7) */
685 tmp1
= MULTIPLY16(tmp1
, FIX_2_053119869
); /* sqrt(2) * ( c1+c3-c5+c7) */
686 tmp2
= MULTIPLY16(tmp2
, FIX_3_072711026
); /* sqrt(2) * ( c1+c3+c5-c7) */
687 tmp3
= MULTIPLY16(tmp3
, FIX_1_501321110
); /* sqrt(2) * ( c1+c3-c5-c7) */
688 z1
= MULTIPLY16(z1
, - FIX_0_899976223
); /* sqrt(2) * (c7-c3) */
689 z2
= MULTIPLY16(z2
, - FIX_2_562915447
); /* sqrt(2) * (-c1-c3) */
690 z3
= MULTIPLY16(z3
, - FIX_1_961570560
); /* sqrt(2) * (-c3-c5) */
691 z4
= MULTIPLY16(z4
, - FIX_0_390180644
); /* sqrt(2) * (c5-c3) */
701 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
703 wsptr
[8*0] = (int) DESCALE(tmp10
+ tmp3
, CONST_BITS
-PASS1_BITS
);
704 wsptr
[8*7] = (int) DESCALE(tmp10
- tmp3
, CONST_BITS
-PASS1_BITS
);
705 wsptr
[8*1] = (int) DESCALE(tmp11
+ tmp2
, CONST_BITS
-PASS1_BITS
);
706 wsptr
[8*6] = (int) DESCALE(tmp11
- tmp2
, CONST_BITS
-PASS1_BITS
);
707 wsptr
[8*2] = (int) DESCALE(tmp12
+ tmp1
, CONST_BITS
-PASS1_BITS
);
708 wsptr
[8*5] = (int) DESCALE(tmp12
- tmp1
, CONST_BITS
-PASS1_BITS
);
709 wsptr
[8*3] = (int) DESCALE(tmp13
+ tmp0
, CONST_BITS
-PASS1_BITS
);
710 wsptr
[8*4] = (int) DESCALE(tmp13
- tmp0
, CONST_BITS
-PASS1_BITS
);
712 inptr
++; /* advance pointers to next column */
717 /* Pass 2: process rows from work array, store into output array. */
718 /* Note that we must descale the results by a factor of 8 == 2**3, */
719 /* and also undo the PASS1_BITS scaling. */
722 for (ctr
= 0; ctr
< 8; ctr
++)
724 outptr
= p_byte
+ (ctr
*skip_line
);
725 /* Rows of zeroes can be exploited in the same way as we did with columns.
726 * However, the column calculation has created many nonzero AC terms, so
727 * the simplification applies less often (typically 5% to 10% of the time).
728 * On machines with very fast multiplication, it's possible that the
729 * test takes more time than it's worth. In that case this section
730 * may be commented out.
733 #ifndef NO_ZERO_ROW_TEST
734 if ((wsptr
[1] | wsptr
[2] | wsptr
[3]
735 | wsptr
[4] | wsptr
[5] | wsptr
[6] | wsptr
[7]) == 0)
737 /* AC terms all zero */
738 unsigned char dcval
= range_limit((int) DESCALE((long) wsptr
[0],
750 wsptr
+= 8; /* advance pointer to next row */
755 /* Even part: reverse the even part of the forward DCT. */
756 /* The rotator is sqrt(2)*c(-6). */
758 z2
= (long) wsptr
[2];
759 z3
= (long) wsptr
[6];
761 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
762 tmp2
= z1
+ MULTIPLY16(z3
, - FIX_1_847759065
);
763 tmp3
= z1
+ MULTIPLY16(z2
, FIX_0_765366865
);
765 tmp0
= ((long) wsptr
[0] + (long) wsptr
[4]) << CONST_BITS
;
766 tmp1
= ((long) wsptr
[0] - (long) wsptr
[4]) << CONST_BITS
;
773 /* Odd part per figure 8; the matrix is unitary and hence its
774 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
776 tmp0
= (long) wsptr
[7];
777 tmp1
= (long) wsptr
[5];
778 tmp2
= (long) wsptr
[3];
779 tmp3
= (long) wsptr
[1];
785 z5
= MULTIPLY16(z3
+ z4
, FIX_1_175875602
); /* sqrt(2) * c3 */
787 tmp0
= MULTIPLY16(tmp0
, FIX_0_298631336
); /* sqrt(2) * (-c1+c3+c5-c7) */
788 tmp1
= MULTIPLY16(tmp1
, FIX_2_053119869
); /* sqrt(2) * ( c1+c3-c5+c7) */
789 tmp2
= MULTIPLY16(tmp2
, FIX_3_072711026
); /* sqrt(2) * ( c1+c3+c5-c7) */
790 tmp3
= MULTIPLY16(tmp3
, FIX_1_501321110
); /* sqrt(2) * ( c1+c3-c5-c7) */
791 z1
= MULTIPLY16(z1
, - FIX_0_899976223
); /* sqrt(2) * (c7-c3) */
792 z2
= MULTIPLY16(z2
, - FIX_2_562915447
); /* sqrt(2) * (-c1-c3) */
793 z3
= MULTIPLY16(z3
, - FIX_1_961570560
); /* sqrt(2) * (-c3-c5) */
794 z4
= MULTIPLY16(z4
, - FIX_0_390180644
); /* sqrt(2) * (c5-c3) */
804 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
806 outptr
[0] = range_limit((int) DESCALE(tmp10
+ tmp3
,
807 CONST_BITS
+PASS1_BITS
+3));
808 outptr
[7] = range_limit((int) DESCALE(tmp10
- tmp3
,
809 CONST_BITS
+PASS1_BITS
+3));
810 outptr
[1] = range_limit((int) DESCALE(tmp11
+ tmp2
,
811 CONST_BITS
+PASS1_BITS
+3));
812 outptr
[6] = range_limit((int) DESCALE(tmp11
- tmp2
,
813 CONST_BITS
+PASS1_BITS
+3));
814 outptr
[2] = range_limit((int) DESCALE(tmp12
+ tmp1
,
815 CONST_BITS
+PASS1_BITS
+3));
816 outptr
[5] = range_limit((int) DESCALE(tmp12
- tmp1
,
817 CONST_BITS
+PASS1_BITS
+3));
818 outptr
[3] = range_limit((int) DESCALE(tmp13
+ tmp0
,
819 CONST_BITS
+PASS1_BITS
+3));
820 outptr
[4] = range_limit((int) DESCALE(tmp13
- tmp0
,
821 CONST_BITS
+PASS1_BITS
+3));
823 wsptr
+= 8; /* advance pointer to next row */
829 /* JPEG decoder implementation */
832 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
836 /* Basic tables: (element [0] of each array is unused) */
837 long mincode
[17]; /* smallest code of length k */
838 long maxcode
[18]; /* largest code of length k (-1 if none) */
839 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
840 int valptr
[17]; /* huffval[] index of 1st symbol of length k */
842 /* Back link to public Huffman table (needed only in slow_DECODE) */
845 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
846 the input data stream. If the next Huffman code is no more
847 than HUFF_LOOKAHEAD bits long, we can obtain its length and
848 the corresponding symbol directly from these tables. */
849 int look_nbits
[1<<HUFF_LOOKAHEAD
]; /* # bits, or 0 if too long */
850 unsigned char look_sym
[1<<HUFF_LOOKAHEAD
]; /* symbol, or unused */
853 #define QUANT_TABLE_LENGTH 64
855 /* for type of Huffman table */
860 { /* length and code according to JFIF format */
861 int huffmancodes_dc
[DC_LEN
];
862 int huffmancodes_ac
[AC_LEN
];
865 struct frame_component
868 int horizontal_sampling
;
869 int vertical_sampling
;
870 int quanttable_select
;
873 struct scan_component
882 unsigned long get_buffer
; /* current bit-extraction buffer */
883 int bits_left
; /* # of unused bits in it */
884 unsigned char* next_input_byte
;
885 unsigned char* input_end
; /* upper limit +1 */
890 int x_size
, y_size
; /* size of image (can be less than block boundary) */
891 int x_phys
, y_phys
; /* physical size, block aligned */
892 int x_mbl
; /* x dimension of MBL */
893 int y_mbl
; /* y dimension of MBL */
894 int blocks
; /* blocks per MB */
895 int restart_interval
; /* number of MCUs between RSTm markers */
896 int store_pos
[4]; /* for Y block ordering */
898 unsigned char* p_entropy_data
;
899 unsigned char* p_entropy_end
;
901 int quanttable
[4][QUANT_TABLE_LENGTH
]; /* raw quantization tables 0-3 */
902 int qt_idct
[2][QUANT_TABLE_LENGTH
]; /* quantization tables for IDCT */
904 struct huffman_table hufftable
[2]; /* Huffman tables */
905 struct derived_tbl dc_derived_tbls
[2]; /* Huffman-LUTs */
906 struct derived_tbl ac_derived_tbls
[2];
908 struct frame_component frameheader
[3]; /* Component descriptor */
909 struct scan_component scanheader
[3]; /* currently not used */
911 int mcu_membership
[6]; /* info per block */
912 int tab_membership
[6];
913 int subsample_x
[3]; /* info per component */
918 /* possible return flags for process_markers() */
919 #define HUFFTAB 0x0001 /* with huffman table */
920 #define QUANTTAB 0x0002 /* with quantization table */
921 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
922 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
923 #define SOF0 0x0010 /* with SOF0-Segment */
924 #define DHT 0x0020 /* with Definition of huffman tables */
925 #define SOS 0x0040 /* with Start-of-Scan segment */
926 #define DQT 0x0080 /* with definition of quantization table */
928 /* Preprocess the JPEG JFIF file */
929 int process_markers(unsigned char* p_src
, long size
, struct jpeg
* p_jpeg
)
931 unsigned char* p_bytes
= p_src
;
932 int marker_size
; /* variable length of marker segment */
934 int ret
= 0; /* returned flags */
936 p_jpeg
->p_entropy_end
= p_src
+ size
;
938 while (p_src
< p_bytes
+ size
)
940 if (*p_src
++ != 0xFF) /* no marker? */
942 p_src
--; /* it's image data, put it back */
943 p_jpeg
->p_entropy_data
= p_src
;
944 break; /* exit marker processing */
949 case 0xFF: /* Fill byte */
951 case 0x00: /* Zero stuffed byte - entropy data */
952 p_src
--; /* put it back */
955 case 0xC0: /* SOF Huff - Baseline DCT */
958 marker_size
= *p_src
++ << 8; /* Highbyte */
959 marker_size
|= *p_src
++; /* Lowbyte */
960 n
= *p_src
++; /* sample precision (= 8 or 12) */
963 return(-1); /* Unsupported sample precision */
965 p_jpeg
->y_size
= *p_src
++ << 8; /* Highbyte */
966 p_jpeg
->y_size
|= *p_src
++; /* Lowbyte */
967 p_jpeg
->x_size
= *p_src
++ << 8; /* Highbyte */
968 p_jpeg
->x_size
|= *p_src
++; /* Lowbyte */
970 n
= (marker_size
-2-6)/3;
971 if (*p_src
++ != n
|| (n
!= 1 && n
!= 3))
973 return(-2); /* Unsupported SOF0 component specification */
977 p_jpeg
->frameheader
[i
].ID
= *p_src
++; /* Component info */
978 p_jpeg
->frameheader
[i
].horizontal_sampling
= *p_src
>> 4;
979 p_jpeg
->frameheader
[i
].vertical_sampling
= *p_src
++ & 0x0F;
980 p_jpeg
->frameheader
[i
].quanttable_select
= *p_src
++;
981 if (p_jpeg
->frameheader
[i
].horizontal_sampling
> 2
982 || p_jpeg
->frameheader
[i
].vertical_sampling
> 2)
983 return -3; /* Unsupported SOF0 subsampling */
989 case 0xC1: /* SOF Huff - Extended sequential DCT*/
990 case 0xC2: /* SOF Huff - Progressive DCT*/
991 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
992 case 0xC5: /* SOF Huff - Differential sequential DCT*/
993 case 0xC6: /* SOF Huff - Differential progressive DCT*/
994 case 0xC7: /* SOF Huff - Differential spatial*/
995 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
996 case 0xC9: /* SOF Arith - Extended sequential DCT*/
997 case 0xCA: /* SOF Arith - Progressive DCT*/
998 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
999 case 0xCD: /* SOF Arith - Differential sequential DCT*/
1000 case 0xCE: /* SOF Arith - Differential progressive DCT*/
1001 case 0xCF: /* SOF Arith - Differential spatial*/
1003 return (-4); /* other DCT model than baseline not implemented */
1006 case 0xC4: /* Define Huffman Table(s) */
1008 unsigned char* p_temp
;
1011 marker_size
= *p_src
++ << 8; /* Highbyte */
1012 marker_size
|= *p_src
++; /* Lowbyte */
1015 while (p_src
< p_temp
+marker_size
-2-17) /* another table */
1018 i
= *p_src
& 0x0F; /* table index */
1021 return (-5); /* Huffman table index out of range */
1023 else if (*p_src
++ & 0xF0) /* AC table */
1025 for (j
=0; j
<16; j
++)
1028 p_jpeg
->hufftable
[i
].huffmancodes_ac
[j
] = *p_src
++;
1030 if(16 + sum
> AC_LEN
)
1031 return -10; /* longer than allowed */
1033 for (; j
< 16 + sum
; j
++)
1034 p_jpeg
->hufftable
[i
].huffmancodes_ac
[j
] = *p_src
++;
1038 for (j
=0; j
<16; j
++)
1041 p_jpeg
->hufftable
[i
].huffmancodes_dc
[j
] = *p_src
++;
1043 if(16 + sum
> DC_LEN
)
1044 return -11; /* longer than allowed */
1046 for (; j
< 16 + sum
; j
++)
1047 p_jpeg
->hufftable
[i
].huffmancodes_dc
[j
] = *p_src
++;
1050 p_src
= p_temp
+marker_size
- 2; /* skip possible residue */
1054 case 0xCC: /* Define Arithmetic coding conditioning(s) */
1055 return(-6); /* Arithmetic coding not supported */
1057 case 0xD8: /* Start of Image */
1058 case 0xD9: /* End of Image */
1059 case 0x01: /* for temp private use arith code */
1060 break; /* skip parameterless marker */
1063 case 0xDA: /* Start of Scan */
1066 marker_size
= *p_src
++ << 8; /* Highbyte */
1067 marker_size
|= *p_src
++; /* Lowbyte */
1069 n
= (marker_size
-2-1-3)/2;
1070 if (*p_src
++ != n
|| (n
!= 1 && n
!= 3))
1072 return (-7); /* Unsupported SOS component specification */
1076 p_jpeg
->scanheader
[i
].ID
= *p_src
++;
1077 p_jpeg
->scanheader
[i
].DC_select
= *p_src
>> 4;
1078 p_jpeg
->scanheader
[i
].AC_select
= *p_src
++ & 0x0F;
1080 p_src
+= 3; /* skip spectral information */
1084 case 0xDB: /* Define quantization Table(s) */
1087 marker_size
= *p_src
++ << 8; /* Highbyte */
1088 marker_size
|= *p_src
++; /* Lowbyte */
1089 n
= (marker_size
-2)/(QUANT_TABLE_LENGTH
+1); /* # of tables */
1092 int id
= *p_src
++; /* ID */
1095 return (-8); /* Unsupported quantization table */
1097 /* Read Quantisation table: */
1098 for (j
=0; j
<QUANT_TABLE_LENGTH
; j
++)
1099 p_jpeg
->quanttable
[id
][j
] = *p_src
++;
1104 case 0xDD: /* Define Restart Interval */
1106 marker_size
= *p_src
++ << 8; /* Highbyte */
1107 marker_size
|= *p_src
++; /* Lowbyte */
1108 p_jpeg
->restart_interval
= *p_src
++ << 8; /* Highbyte */
1109 p_jpeg
->restart_interval
|= *p_src
++; /* Lowbyte */
1110 p_src
+= marker_size
-4; /* skip segment */
1114 case 0xDC: /* Define Number of Lines */
1115 case 0xDE: /* Define Hierarchical progression */
1116 case 0xDF: /* Expand Reference Component(s) */
1117 case 0xE0: /* Application Field 0*/
1118 case 0xE1: /* Application Field 1*/
1119 case 0xE2: /* Application Field 2*/
1120 case 0xE3: /* Application Field 3*/
1121 case 0xE4: /* Application Field 4*/
1122 case 0xE5: /* Application Field 5*/
1123 case 0xE6: /* Application Field 6*/
1124 case 0xE7: /* Application Field 7*/
1125 case 0xE8: /* Application Field 8*/
1126 case 0xE9: /* Application Field 9*/
1127 case 0xEA: /* Application Field 10*/
1128 case 0xEB: /* Application Field 11*/
1129 case 0xEC: /* Application Field 12*/
1130 case 0xED: /* Application Field 13*/
1131 case 0xEE: /* Application Field 14*/
1132 case 0xEF: /* Application Field 15*/
1133 case 0xFE: /* Comment */
1135 marker_size
= *p_src
++ << 8; /* Highbyte */
1136 marker_size
|= *p_src
++; /* Lowbyte */
1137 p_src
+= marker_size
-2; /* skip segment */
1141 case 0xF0: /* Reserved for JPEG extensions */
1142 case 0xF1: /* Reserved for JPEG extensions */
1143 case 0xF2: /* Reserved for JPEG extensions */
1144 case 0xF3: /* Reserved for JPEG extensions */
1145 case 0xF4: /* Reserved for JPEG extensions */
1146 case 0xF5: /* Reserved for JPEG extensions */
1147 case 0xF6: /* Reserved for JPEG extensions */
1148 case 0xF7: /* Reserved for JPEG extensions */
1149 case 0xF8: /* Reserved for JPEG extensions */
1150 case 0xF9: /* Reserved for JPEG extensions */
1151 case 0xFA: /* Reserved for JPEG extensions */
1152 case 0xFB: /* Reserved for JPEG extensions */
1153 case 0xFC: /* Reserved for JPEG extensions */
1154 case 0xFD: /* Reserved for JPEG extensions */
1155 case 0x02: /* Reserved */
1157 return (-9); /* Unknown marker */
1161 return (ret
); /* return flags with seen markers */
1165 void default_huff_tbl(struct jpeg
* p_jpeg
)
1167 static const struct huffman_table luma_table
=
1170 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
1171 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1174 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
1175 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
1176 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
1177 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
1178 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
1179 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1180 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1181 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
1182 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
1183 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
1184 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1189 static const struct huffman_table chroma_table
=
1192 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
1193 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1196 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
1197 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
1198 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1199 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1200 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1201 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1202 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1203 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1204 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1205 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1206 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1211 MEMCPY(&p_jpeg
->hufftable
[0], &luma_table
, sizeof(luma_table
));
1212 MEMCPY(&p_jpeg
->hufftable
[1], &chroma_table
, sizeof(chroma_table
));
1217 /* Compute the derived values for a Huffman table */
1218 void fix_huff_tbl(int* htbl
, struct derived_tbl
* dtbl
)
1223 unsigned int huffcode
[257];
1226 dtbl
->pub
= htbl
; /* fill in back link */
1228 /* Figure C.1: make table of Huffman code length for each symbol */
1229 /* Note that this is in code-length order. */
1232 for (l
= 1; l
<= 16; l
++)
1233 { /* all possible code length */
1234 for (i
= 1; i
<= (int) htbl
[l
-1]; i
++) /* all codes per length */
1235 huffsize
[p
++] = (char) l
;
1239 /* Figure C.2: generate the codes themselves */
1240 /* Note that this is in code-length order. */
1247 while (((int) huffsize
[p
]) == si
)
1249 huffcode
[p
++] = code
;
1256 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1259 for (l
= 1; l
<= 16; l
++)
1263 dtbl
->valptr
[l
] = p
; /* huffval[] index of 1st symbol of code length l */
1264 dtbl
->mincode
[l
] = huffcode
[p
]; /* minimum code of length l */
1266 dtbl
->maxcode
[l
] = huffcode
[p
-1]; /* maximum code of length l */
1270 dtbl
->maxcode
[l
] = -1; /* -1 if no codes of this length */
1273 dtbl
->maxcode
[17] = 0xFFFFFL
; /* ensures huff_DECODE terminates */
1275 /* Compute lookahead tables to speed up decoding.
1276 * First we set all the table entries to 0, indicating "too long";
1277 * then we iterate through the Huffman codes that are short enough and
1278 * fill in all the entries that correspond to bit sequences starting
1282 MEMSET(dtbl
->look_nbits
, 0, sizeof(dtbl
->look_nbits
));
1285 for (l
= 1; l
<= HUFF_LOOKAHEAD
; l
++)
1287 for (i
= 1; i
<= (int) htbl
[l
-1]; i
++, p
++)
1289 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1290 /* Generate left-justified code followed by all possible bit sequences */
1291 lookbits
= huffcode
[p
] << (HUFF_LOOKAHEAD
-l
);
1292 for (ctr
= 1 << (HUFF_LOOKAHEAD
-l
); ctr
> 0; ctr
--)
1294 dtbl
->look_nbits
[lookbits
] = l
;
1295 dtbl
->look_sym
[lookbits
] = htbl
[16+p
];
1303 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1304 * If the incoming data is corrupted, decode_mcu could attempt to
1305 * reference values beyond the end of the array. To avoid a wild store,
1306 * we put some extra zeroes after the real entries.
1308 static const int zag
[] =
1310 0, 1, 8, 16, 9, 2, 3, 10,
1311 17, 24, 32, 25, 18, 11, 4, 5,
1312 12, 19, 26, 33, 40, 48, 41, 34,
1313 27, 20, 13, 6, 7, 14, 21, 28,
1314 35, 42, 49, 56, 57, 50, 43, 36,
1315 29, 22, 15, 23, 30, 37, 44, 51,
1316 58, 59, 52, 45, 38, 31, 39, 46,
1317 53, 60, 61, 54, 47, 55, 62, 63,
1318 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1319 0, 0, 0, 0, 0, 0, 0, 0
1322 void build_lut(struct jpeg
* p_jpeg
)
1325 fix_huff_tbl(p_jpeg
->hufftable
[0].huffmancodes_dc
,
1326 &p_jpeg
->dc_derived_tbls
[0]);
1327 fix_huff_tbl(p_jpeg
->hufftable
[0].huffmancodes_ac
,
1328 &p_jpeg
->ac_derived_tbls
[0]);
1329 fix_huff_tbl(p_jpeg
->hufftable
[1].huffmancodes_dc
,
1330 &p_jpeg
->dc_derived_tbls
[1]);
1331 fix_huff_tbl(p_jpeg
->hufftable
[1].huffmancodes_ac
,
1332 &p_jpeg
->ac_derived_tbls
[1]);
1334 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1335 for (i
=0; i
<64; i
++)
1337 p_jpeg
->qt_idct
[0][zag
[i
]] = p_jpeg
->quanttable
[0][i
];
1338 p_jpeg
->qt_idct
[1][zag
[i
]] = p_jpeg
->quanttable
[1][i
];
1342 p_jpeg
->store_pos
[i
] = i
; /* default ordering */
1344 /* assignments for the decoding of blocks */
1345 if (p_jpeg
->frameheader
[0].horizontal_sampling
== 2
1346 && p_jpeg
->frameheader
[0].vertical_sampling
== 1)
1349 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+15) / 16;
1350 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 16;
1351 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+7) / 8;
1352 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 8;
1353 p_jpeg
->mcu_membership
[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1354 p_jpeg
->mcu_membership
[1] = 0;
1355 p_jpeg
->mcu_membership
[2] = 1;
1356 p_jpeg
->mcu_membership
[3] = 2;
1357 p_jpeg
->tab_membership
[0] = 0; /* DC, DC, AC, AC */
1358 p_jpeg
->tab_membership
[1] = 0;
1359 p_jpeg
->tab_membership
[2] = 1;
1360 p_jpeg
->tab_membership
[3] = 1;
1361 p_jpeg
->subsample_x
[0] = 1;
1362 p_jpeg
->subsample_x
[1] = 2;
1363 p_jpeg
->subsample_x
[2] = 2;
1364 p_jpeg
->subsample_y
[0] = 1;
1365 p_jpeg
->subsample_y
[1] = 1;
1366 p_jpeg
->subsample_y
[2] = 1;
1368 if (p_jpeg
->frameheader
[0].horizontal_sampling
== 1
1369 && p_jpeg
->frameheader
[0].vertical_sampling
== 2)
1370 { /* 4:2:2 vertically subsampled */
1371 p_jpeg
->store_pos
[1] = 2; /* block positions are mirrored */
1372 p_jpeg
->store_pos
[2] = 1;
1374 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+7) / 8;
1375 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 8;
1376 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+15) / 16;
1377 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 16;
1378 p_jpeg
->mcu_membership
[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1379 p_jpeg
->mcu_membership
[1] = 0;
1380 p_jpeg
->mcu_membership
[2] = 1;
1381 p_jpeg
->mcu_membership
[3] = 2;
1382 p_jpeg
->tab_membership
[0] = 0; /* DC, DC, AC, AC */
1383 p_jpeg
->tab_membership
[1] = 0;
1384 p_jpeg
->tab_membership
[2] = 1;
1385 p_jpeg
->tab_membership
[3] = 1;
1386 p_jpeg
->subsample_x
[0] = 1;
1387 p_jpeg
->subsample_x
[1] = 1;
1388 p_jpeg
->subsample_x
[2] = 1;
1389 p_jpeg
->subsample_y
[0] = 1;
1390 p_jpeg
->subsample_y
[1] = 2;
1391 p_jpeg
->subsample_y
[2] = 2;
1393 else if (p_jpeg
->frameheader
[0].horizontal_sampling
== 2
1394 && p_jpeg
->frameheader
[0].vertical_sampling
== 2)
1397 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+15) / 16;
1398 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 16;
1399 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+15) / 16;
1400 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 16;
1401 p_jpeg
->mcu_membership
[0] = 0;
1402 p_jpeg
->mcu_membership
[1] = 0;
1403 p_jpeg
->mcu_membership
[2] = 0;
1404 p_jpeg
->mcu_membership
[3] = 0;
1405 p_jpeg
->mcu_membership
[4] = 1;
1406 p_jpeg
->mcu_membership
[5] = 2;
1407 p_jpeg
->tab_membership
[0] = 0;
1408 p_jpeg
->tab_membership
[1] = 0;
1409 p_jpeg
->tab_membership
[2] = 0;
1410 p_jpeg
->tab_membership
[3] = 0;
1411 p_jpeg
->tab_membership
[4] = 1;
1412 p_jpeg
->tab_membership
[5] = 1;
1413 p_jpeg
->subsample_x
[0] = 1;
1414 p_jpeg
->subsample_x
[1] = 2;
1415 p_jpeg
->subsample_x
[2] = 2;
1416 p_jpeg
->subsample_y
[0] = 1;
1417 p_jpeg
->subsample_y
[1] = 2;
1418 p_jpeg
->subsample_y
[2] = 2;
1420 else if (p_jpeg
->frameheader
[0].horizontal_sampling
== 1
1421 && p_jpeg
->frameheader
[0].vertical_sampling
== 1)
1423 /* don't overwrite p_jpeg->blocks */
1424 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+7) / 8;
1425 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 8;
1426 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+7) / 8;
1427 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 8;
1428 p_jpeg
->mcu_membership
[0] = 0;
1429 p_jpeg
->mcu_membership
[1] = 1;
1430 p_jpeg
->mcu_membership
[2] = 2;
1431 p_jpeg
->tab_membership
[0] = 0;
1432 p_jpeg
->tab_membership
[1] = 1;
1433 p_jpeg
->tab_membership
[2] = 1;
1434 p_jpeg
->subsample_x
[0] = 1;
1435 p_jpeg
->subsample_x
[1] = 1;
1436 p_jpeg
->subsample_x
[2] = 1;
1437 p_jpeg
->subsample_y
[0] = 1;
1438 p_jpeg
->subsample_y
[1] = 1;
1439 p_jpeg
->subsample_y
[2] = 1;
1450 * These functions/macros provide the in-line portion of bit fetching.
1451 * Use check_bit_buffer to ensure there are N bits in get_buffer
1452 * before using get_bits, peek_bits, or drop_bits.
1453 * check_bit_buffer(state,n,action);
1454 * Ensure there are N bits in get_buffer; if suspend, take action.
1455 * val = get_bits(n);
1456 * Fetch next N bits.
1457 * val = peek_bits(n);
1458 * Fetch next N bits without removing them from the buffer.
1460 * Discard next N bits.
1461 * The value N should be a simple variable, not an expression, because it
1462 * is evaluated multiple times.
1465 INLINE
void check_bit_buffer(struct bitstream
* pb
, int nbits
)
1467 if (pb
->bits_left
< nbits
)
1468 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1471 byte
= *pb
->next_input_byte
++;
1472 if (byte
== 0xFF) /* legal marker can be byte stuffing or RSTm */
1473 { /* simplification: just skip the (one-byte) marker code */
1474 pb
->next_input_byte
++;
1476 pb
->get_buffer
= (pb
->get_buffer
<< 8) | byte
;
1478 byte
= *pb
->next_input_byte
++;
1479 if (byte
== 0xFF) /* legal marker can be byte stuffing or RSTm */
1480 { /* simplification: just skip the (one-byte) marker code */
1481 pb
->next_input_byte
++;
1483 pb
->get_buffer
= (pb
->get_buffer
<< 8) | byte
;
1485 pb
->bits_left
+= 16;
1489 INLINE
int get_bits(struct bitstream
* pb
, int nbits
)
1491 return ((int) (pb
->get_buffer
>> (pb
->bits_left
-= nbits
))) & ((1<<nbits
)-1);
1494 INLINE
int peek_bits(struct bitstream
* pb
, int nbits
)
1496 return ((int) (pb
->get_buffer
>> (pb
->bits_left
- nbits
))) & ((1<<nbits
)-1);
1499 INLINE
void drop_bits(struct bitstream
* pb
, int nbits
)
1501 pb
->bits_left
-= nbits
;
1504 /* re-synchronize to entropy data (skip restart marker) */
1505 void search_restart(struct bitstream
* pb
)
1507 pb
->next_input_byte
--; /* we may have overread it, taking 2 bytes */
1508 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1509 while (pb
->next_input_byte
< pb
->input_end
&&
1510 (pb
->next_input_byte
[-2] != 0xFF || pb
->next_input_byte
[-1] == 0x00))
1512 pb
->next_input_byte
++;
1517 /* Figure F.12: extend sign bit. */
1518 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1520 static const int extend_test
[16] = /* entry n is 2**(n-1) */
1522 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1523 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1526 static const int extend_offset
[16] = /* entry n is (-1 << n) + 1 */
1528 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1529 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1530 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1531 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1534 /* Decode a single value */
1535 INLINE
int huff_decode_dc(struct bitstream
* bs
, struct derived_tbl
* tbl
)
1539 check_bit_buffer(bs
, HUFF_LOOKAHEAD
);
1540 look
= peek_bits(bs
, HUFF_LOOKAHEAD
);
1541 if ((nb
= tbl
->look_nbits
[look
]) != 0)
1544 s
= tbl
->look_sym
[look
];
1545 check_bit_buffer(bs
, s
);
1546 r
= get_bits(bs
, s
);
1547 s
= HUFF_EXTEND(r
, s
);
1550 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1552 nb
=HUFF_LOOKAHEAD
+1;
1553 check_bit_buffer(bs
, nb
);
1554 code
= get_bits(bs
, nb
);
1555 while (code
> tbl
->maxcode
[nb
])
1558 check_bit_buffer(bs
, 1);
1559 code
|= get_bits(bs
, 1);
1562 if (nb
> 16) /* error in Huffman */
1564 s
=0; /* fake a zero, this is most safe */
1568 s
= tbl
->pub
[16 + tbl
->valptr
[nb
] + ((int) (code
- tbl
->mincode
[nb
])) ];
1569 check_bit_buffer(bs
, s
);
1570 r
= get_bits(bs
, s
);
1571 s
= HUFF_EXTEND(r
, s
);
1573 } /* end slow decode */
1577 INLINE
int huff_decode_ac(struct bitstream
* bs
, struct derived_tbl
* tbl
)
1581 check_bit_buffer(bs
, HUFF_LOOKAHEAD
);
1582 look
= peek_bits(bs
, HUFF_LOOKAHEAD
);
1583 if ((nb
= tbl
->look_nbits
[look
]) != 0)
1586 s
= tbl
->look_sym
[look
];
1589 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1591 nb
=HUFF_LOOKAHEAD
+1;
1592 check_bit_buffer(bs
, nb
);
1593 code
= get_bits(bs
, nb
);
1594 while (code
> tbl
->maxcode
[nb
])
1597 check_bit_buffer(bs
, 1);
1598 code
|= get_bits(bs
, 1);
1601 if (nb
> 16) /* error in Huffman */
1603 s
=0; /* fake a zero, this is most safe */
1607 s
= tbl
->pub
[16 + tbl
->valptr
[nb
] + ((int) (code
- tbl
->mincode
[nb
])) ];
1609 } /* end slow decode */
1614 #ifdef HAVE_LCD_COLOR
1616 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1617 /* Note: it keeps the original color subsampling, even if resized. */
1618 int jpeg_decode(struct jpeg
* p_jpeg
, unsigned char* p_pixel
[3],
1619 int downscale
, void (*pf_progress
)(int current
, int total
))
1621 struct bitstream bs
; /* bitstream "object" */
1622 int block
[64]; /* decoded DCT coefficients */
1625 int skip_line
[3]; /* bytes from one line to the next (skip_line) */
1626 int skip_strip
[3], skip_mcu
[3]; /* bytes to next DCT row / column */
1628 int i
, x
, y
; /* loop counter */
1630 unsigned char* p_line
[3] = {p_pixel
[0], p_pixel
[1], p_pixel
[2]};
1631 unsigned char* p_byte
[3]; /* bitmap pointer */
1633 void (*pf_idct
)(unsigned char*, int*, int*, int); /* selected IDCT */
1634 int k_need
; /* AC coefficients needed up to here */
1635 int zero_need
; /* init the block with this many zeros */
1637 int last_dc_val
[3] = {0, 0, 0}; /* or 128 for chroma? */
1638 int store_offs
[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1639 int restart
= p_jpeg
->restart_interval
; /* MCUs until restart marker */
1641 /* pick the IDCT we want, determine how to work with coefs */
1645 k_need
= 64; /* all */
1646 zero_need
= 63; /* all */
1648 else if (downscale
== 2)
1651 k_need
= 25; /* this far in zig-zag to cover 4*4 */
1652 zero_need
= 27; /* clear this far in linear order */
1654 else if (downscale
== 4)
1657 k_need
= 5; /* this far in zig-zag to cover 2*2 */
1658 zero_need
= 9; /* clear this far in linear order */
1660 else if (downscale
== 8)
1663 k_need
= 0; /* no AC, not needed */
1664 zero_need
= 0; /* no AC, not needed */
1666 else return -1; /* not supported */
1668 /* init bitstream, fake a restart to make it start */
1669 bs
.next_input_byte
= p_jpeg
->p_entropy_data
;
1671 bs
.input_end
= p_jpeg
->p_entropy_end
;
1673 width
= p_jpeg
->x_phys
/ downscale
;
1674 height
= p_jpeg
->y_phys
/ downscale
;
1675 for (i
=0; i
<3; i
++) /* calculate some strides */
1677 skip_line
[i
] = width
/ p_jpeg
->subsample_x
[i
];
1678 skip_strip
[i
] = skip_line
[i
]
1679 * (height
/ p_jpeg
->y_mbl
) / p_jpeg
->subsample_y
[i
];
1680 skip_mcu
[i
] = width
/p_jpeg
->x_mbl
/ p_jpeg
->subsample_x
[i
];
1683 /* prepare offsets about where to store the different blocks */
1684 store_offs
[p_jpeg
->store_pos
[0]] = 0;
1685 store_offs
[p_jpeg
->store_pos
[1]] = 8 / downscale
; /* to the right */
1686 store_offs
[p_jpeg
->store_pos
[2]] = width
* 8 / downscale
; /* below */
1687 store_offs
[p_jpeg
->store_pos
[3]] = store_offs
[1] + store_offs
[2]; /* r+b */
1689 for(y
=0; y
<p_jpeg
->y_mbl
&& bs
.next_input_byte
<= bs
.input_end
; y
++)
1691 for (i
=0; i
<3; i
++) /* scan line init */
1693 p_byte
[i
] = p_line
[i
];
1694 p_line
[i
] += skip_strip
[i
];
1696 for (x
=0; x
<p_jpeg
->x_mbl
; x
++)
1700 /* Outer loop handles each block in the MCU */
1701 for (blkn
= 0; blkn
< p_jpeg
->blocks
; blkn
++)
1702 { /* Decode a single block's worth of coefficients */
1703 int k
= 1; /* coefficient index */
1704 int s
, r
; /* huffman values */
1705 int ci
= p_jpeg
->mcu_membership
[blkn
]; /* component index */
1706 int ti
= p_jpeg
->tab_membership
[blkn
]; /* table index */
1707 struct derived_tbl
* dctbl
= &p_jpeg
->dc_derived_tbls
[ti
];
1708 struct derived_tbl
* actbl
= &p_jpeg
->ac_derived_tbls
[ti
];
1710 /* Section F.2.2.1: decode the DC coefficient difference */
1711 s
= huff_decode_dc(&bs
, dctbl
);
1713 last_dc_val
[ci
] += s
;
1714 block
[0] = last_dc_val
[ci
]; /* output it (assumes zag[0] = 0) */
1716 /* coefficient buffer must be cleared */
1717 MEMSET(block
+1, 0, zero_need
*sizeof(block
[0]));
1719 /* Section F.2.2.2: decode the AC coefficients */
1720 for (; k
< k_need
; k
++)
1722 s
= huff_decode_ac(&bs
, actbl
);
1729 check_bit_buffer(&bs
, s
);
1730 r
= get_bits(&bs
, s
);
1731 block
[zag
[k
]] = HUFF_EXTEND(r
, s
);
1743 /* In this path we just discard the values */
1746 s
= huff_decode_ac(&bs
, actbl
);
1753 check_bit_buffer(&bs
, s
);
1765 { /* Y component needs to bother about block store */
1766 pf_idct(p_byte
[0]+store_offs
[blkn
], block
,
1767 p_jpeg
->qt_idct
[ti
], skip_line
[0]);
1771 pf_idct(p_byte
[ci
], block
, p_jpeg
->qt_idct
[ti
],
1775 p_byte
[0] += skip_mcu
[0]; /* unrolled for (i=0; i<3; i++) loop */
1776 p_byte
[1] += skip_mcu
[1];
1777 p_byte
[2] += skip_mcu
[2];
1778 if (p_jpeg
->restart_interval
&& --restart
== 0)
1779 { /* if a restart marker is due: */
1780 restart
= p_jpeg
->restart_interval
; /* count again */
1781 search_restart(&bs
); /* align the bitstream */
1782 last_dc_val
[0] = last_dc_val
[1] =
1783 last_dc_val
[2] = 0; /* reset decoder */
1786 if (pf_progress
!= NULL
)
1787 pf_progress(y
, p_jpeg
->y_mbl
-1); /* notify about decoding progress */
1790 return 0; /* success */
1792 #else /* !HAVE_LCD_COLOR */
1794 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1795 int jpeg_decode(struct jpeg
* p_jpeg
, unsigned char* p_pixel
[1], int downscale
,
1796 void (*pf_progress
)(int current
, int total
))
1798 struct bitstream bs
; /* bitstream "object" */
1799 int block
[64]; /* decoded DCT coefficients */
1802 int skip_line
; /* bytes from one line to the next (skip_line) */
1803 int skip_strip
, skip_mcu
; /* bytes to next DCT row / column */
1805 int x
, y
; /* loop counter */
1807 unsigned char* p_line
= p_pixel
[0];
1808 unsigned char* p_byte
; /* bitmap pointer */
1810 void (*pf_idct
)(unsigned char*, int*, int*, int); /* selected IDCT */
1811 int k_need
; /* AC coefficients needed up to here */
1812 int zero_need
; /* init the block with this many zeros */
1814 int last_dc_val
= 0;
1815 int store_offs
[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1816 int restart
= p_jpeg
->restart_interval
; /* MCUs until restart marker */
1818 /* pick the IDCT we want, determine how to work with coefs */
1822 k_need
= 64; /* all */
1823 zero_need
= 63; /* all */
1825 else if (downscale
== 2)
1828 k_need
= 25; /* this far in zig-zag to cover 4*4 */
1829 zero_need
= 27; /* clear this far in linear order */
1831 else if (downscale
== 4)
1834 k_need
= 5; /* this far in zig-zag to cover 2*2 */
1835 zero_need
= 9; /* clear this far in linear order */
1837 else if (downscale
== 8)
1840 k_need
= 0; /* no AC, not needed */
1841 zero_need
= 0; /* no AC, not needed */
1843 else return -1; /* not supported */
1845 /* init bitstream, fake a restart to make it start */
1846 bs
.next_input_byte
= p_jpeg
->p_entropy_data
;
1848 bs
.input_end
= p_jpeg
->p_entropy_end
;
1850 width
= p_jpeg
->x_phys
/ downscale
;
1851 height
= p_jpeg
->y_phys
/ downscale
;
1853 skip_strip
= skip_line
* (height
/ p_jpeg
->y_mbl
);
1854 skip_mcu
= (width
/p_jpeg
->x_mbl
);
1856 /* prepare offsets about where to store the different blocks */
1857 store_offs
[p_jpeg
->store_pos
[0]] = 0;
1858 store_offs
[p_jpeg
->store_pos
[1]] = 8 / downscale
; /* to the right */
1859 store_offs
[p_jpeg
->store_pos
[2]] = width
* 8 / downscale
; /* below */
1860 store_offs
[p_jpeg
->store_pos
[3]] = store_offs
[1] + store_offs
[2]; /* r+b */
1862 for(y
=0; y
<p_jpeg
->y_mbl
&& bs
.next_input_byte
<= bs
.input_end
; y
++)
1865 p_line
+= skip_strip
;
1866 for (x
=0; x
<p_jpeg
->x_mbl
; x
++)
1870 /* Outer loop handles each block in the MCU */
1871 for (blkn
= 0; blkn
< p_jpeg
->blocks
; blkn
++)
1872 { /* Decode a single block's worth of coefficients */
1873 int k
= 1; /* coefficient index */
1874 int s
, r
; /* huffman values */
1875 int ci
= p_jpeg
->mcu_membership
[blkn
]; /* component index */
1876 int ti
= p_jpeg
->tab_membership
[blkn
]; /* table index */
1877 struct derived_tbl
* dctbl
= &p_jpeg
->dc_derived_tbls
[ti
];
1878 struct derived_tbl
* actbl
= &p_jpeg
->ac_derived_tbls
[ti
];
1880 /* Section F.2.2.1: decode the DC coefficient difference */
1881 s
= huff_decode_dc(&bs
, dctbl
);
1883 if (ci
== 0) /* only for Y component */
1886 block
[0] = last_dc_val
; /* output it (assumes zag[0] = 0) */
1888 /* coefficient buffer must be cleared */
1889 MEMSET(block
+1, 0, zero_need
*sizeof(block
[0]));
1891 /* Section F.2.2.2: decode the AC coefficients */
1892 for (; k
< k_need
; k
++)
1894 s
= huff_decode_ac(&bs
, actbl
);
1901 check_bit_buffer(&bs
, s
);
1902 r
= get_bits(&bs
, s
);
1903 block
[zag
[k
]] = HUFF_EXTEND(r
, s
);
1916 /* In this path we just discard the values */
1919 s
= huff_decode_ac(&bs
, actbl
);
1926 check_bit_buffer(&bs
, s
);
1938 { /* only for Y component */
1939 pf_idct(p_byte
+store_offs
[blkn
], block
, p_jpeg
->qt_idct
[ti
],
1944 if (p_jpeg
->restart_interval
&& --restart
== 0)
1945 { /* if a restart marker is due: */
1946 restart
= p_jpeg
->restart_interval
; /* count again */
1947 search_restart(&bs
); /* align the bitstream */
1948 last_dc_val
= 0; /* reset decoder */
1951 if (pf_progress
!= NULL
)
1952 pf_progress(y
, p_jpeg
->y_mbl
-1); /* notify about decoding progress */
1955 return 0; /* success */
1957 #endif /* !HAVE_LCD_COLOR */
1959 /**************** end JPEG code ********************/
1963 /**************** begin Application ********************/
1966 /************************* Types ***************************/
1970 #ifdef HAVE_LCD_COLOR
1971 unsigned char* bitmap
[3]; /* Y, Cr, Cb */
1974 unsigned char* bitmap
[1]; /* Y only */
1982 /************************* Globals ***************************/
1984 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1985 struct t_disp disp
[9];
1987 /* my memory pool (from the mp3 buffer) */
1988 char print
[32]; /* use a common snprintf() buffer */
1989 unsigned char* buf
; /* up to here currently used by image(s) */
1991 /* the remaining free part of the buffer for compressed+uncompressed images */
1992 unsigned char* buf_images
;
1994 ssize_t buf_size
, buf_images_size
;
1995 /* the root of the images, hereafter are decompresed ones */
1996 unsigned char* buf_root
;
1999 int ds
, ds_min
, ds_max
; /* downscaling and limits */
2000 static struct jpeg jpg
; /* too large for stack */
2002 static struct tree_context
*tree
;
2004 /* the current full file name */
2005 static char np_file
[MAX_PATH
];
2006 int curfile
= 0, direction
= DIR_NONE
, entries
= 0;
2008 /* list of the jpeg files */
2010 /* are we using the plugin buffer or the audio buffer? */
2011 bool plug_buf
= false;
2014 /************************* Implementation ***************************/
2016 #ifdef HAVE_LCD_COLOR
2018 * Conversion of full 0-255 range YCrCb to RGB:
2019 * |R| |1.000000 -0.000001 1.402000| |Y'|
2020 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
2021 * |B| |1.000000 1.772000 0.000000| |Pr|
2022 * Scaled (yields s15-bit output):
2023 * |R| |128 0 179| |Y |
2024 * |G| = |128 -43 -91| |Cb - 128|
2025 * |B| |128 227 0| |Cr - 128|
2032 #define YUV_WHITE (255*YFAC)
2033 #define NODITHER_DELTA (127*YFAC)
2034 #define COMPONENT_SHIFT 15
2035 #define MATRIX_SHIFT 7
2037 static inline int clamp_component(int x
)
2039 if ((unsigned)x
> YUV_WHITE
)
2040 x
= x
< 0 ? 0 : YUV_WHITE
;
2044 static inline int clamp_component_bits(int x
, int bits
)
2046 if ((unsigned)x
> (1u << bits
) - 1)
2047 x
= x
< 0 ? 0 : (1 << bits
) - 1;
2051 static inline int component_to_lcd(int x
, int bits
, int delta
)
2053 /* Formula used in core bitmap loader. */
2054 return (((1 << bits
) - 1)*x
+ (x
>> (8 - bits
)) + delta
) >> COMPONENT_SHIFT
;
2057 static inline int lcd_to_component(int x
, int bits
, int delta
)
2059 /* Reasonable, approximate reversal to get a full range back from the
2061 return YUV_WHITE
*x
/ ((1 << bits
) - 1);
2071 int16_t errbuf
[LCD_WIDTH
+2]; /* Error record for line below */
2072 } rgb_err_buffers
[3];
2074 fb_data rgb_linebuf
[LCD_WIDTH
]; /* Line buffer for scrolling when
2075 DITHER_DIFFUSION is set */
2079 int r
, g
, b
; /* Current pixel components in s16.0 */
2080 int inc
; /* Current line increment (-1 or 1) */
2081 int row
; /* Current row in source image */
2082 int col
; /* Current column in source image */
2083 int ce
[3]; /* Errors to apply to current pixel */
2084 struct rgb_err
*e
; /* RED, GRN, BLU */
2085 int epos
; /* Current position in error record */
2088 struct rgb_pixel
*pixel
;
2090 /** round and truncate to lcd depth **/
2091 static fb_data
pixel_to_lcd_colour(void)
2093 struct rgb_pixel
*p
= pixel
;
2096 r
= component_to_lcd(p
->r
, LCD_RED_BITS
, NODITHER_DELTA
);
2097 r
= clamp_component_bits(r
, LCD_RED_BITS
);
2099 g
= component_to_lcd(p
->g
, LCD_GREEN_BITS
, NODITHER_DELTA
);
2100 g
= clamp_component_bits(g
, LCD_GREEN_BITS
);
2102 b
= component_to_lcd(p
->b
, LCD_BLUE_BITS
, NODITHER_DELTA
);
2103 b
= clamp_component_bits(b
, LCD_BLUE_BITS
);
2105 return LCD_RGBPACK_LCD(r
, g
, b
);
2108 /** write a monochrome pixel to the colour LCD **/
2109 static fb_data
pixel_to_lcd_gray(void)
2113 g
= clamp_component(pixel
->g
);
2114 r
= component_to_lcd(g
, LCD_RED_BITS
, NODITHER_DELTA
);
2115 b
= component_to_lcd(g
, LCD_BLUE_BITS
, NODITHER_DELTA
);
2116 g
= component_to_lcd(g
, LCD_GREEN_BITS
, NODITHER_DELTA
);
2118 return LCD_RGBPACK_LCD(r
, g
, b
);
2122 * Bayer ordered dithering - swiped from the core bitmap loader.
2124 static fb_data
pixel_odither_to_lcd(void)
2126 /* canonical ordered dither matrix */
2127 static const unsigned char dither_matrix
[16][16] = {
2128 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
2129 { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
2130 { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
2131 { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
2132 { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
2133 { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
2134 { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
2135 { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
2136 { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
2137 { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
2138 { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
2139 { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
2140 { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
2141 { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
2142 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
2143 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
2146 struct rgb_pixel
*p
= pixel
;
2149 delta
= dither_matrix
[p
->col
& 15][p
->row
& 15] << MATRIX_SHIFT
;
2151 r
= component_to_lcd(p
->r
, LCD_RED_BITS
, delta
);
2152 r
= clamp_component_bits(r
, LCD_RED_BITS
);
2154 g
= component_to_lcd(p
->g
, LCD_GREEN_BITS
, delta
);
2155 g
= clamp_component_bits(g
, LCD_GREEN_BITS
);
2157 b
= component_to_lcd(p
->b
, LCD_BLUE_BITS
, delta
);
2158 b
= clamp_component_bits(b
, LCD_BLUE_BITS
);
2162 return LCD_RGBPACK_LCD(r
, g
, b
);
2166 * Floyd/Steinberg dither to lcd depth.
2168 * Apply filter to each component in serpentine pattern. Kernel shown for
2169 * L->R scan. Kernel is reversed for R->L.
2173 static inline void distribute_error(int *ce
, struct rgb_err
*e
,
2174 int err
, int epos
, int inc
)
2176 *ce
= (7*err
>> 4) + e
->errbuf
[epos
+inc
];
2177 e
->errbuf
[epos
+inc
] = err
>> 4;
2178 e
->errbuf
[epos
] += 5*err
>> 4;
2179 e
->errbuf
[epos
-inc
] += 3*err
>> 4;
2182 static fb_data
pixel_fsdither_to_lcd(void)
2184 struct rgb_pixel
*p
= pixel
;
2185 int rc
, gc
, bc
, r
, g
, b
;
2188 /* Full components with error terms */
2189 rc
= p
->r
+ p
->ce
[RED
];
2190 r
= component_to_lcd(rc
, LCD_RED_BITS
, 0);
2191 r
= clamp_component_bits(r
, LCD_RED_BITS
);
2193 gc
= p
->g
+ p
->ce
[GRN
];
2194 g
= component_to_lcd(gc
, LCD_GREEN_BITS
, 0);
2195 g
= clamp_component_bits(g
, LCD_GREEN_BITS
);
2197 bc
= p
->b
+ p
->ce
[BLU
];
2198 b
= component_to_lcd(bc
, LCD_BLUE_BITS
, 0);
2199 b
= clamp_component_bits(b
, LCD_BLUE_BITS
);
2201 /* Get pixel errors */
2202 rc
-= lcd_to_component(r
, LCD_RED_BITS
, 0);
2203 gc
-= lcd_to_component(g
, LCD_GREEN_BITS
, 0);
2204 bc
-= lcd_to_component(b
, LCD_BLUE_BITS
, 0);
2206 /* Spead error to surrounding pixels. */
2211 distribute_error(&p
->ce
[RED
], &p
->e
[RED
], rc
, epos
, inc
);
2212 distribute_error(&p
->ce
[GRN
], &p
->e
[GRN
], gc
, epos
, inc
);
2213 distribute_error(&p
->ce
[BLU
], &p
->e
[BLU
], bc
, epos
, inc
);
2215 /* Pack and return pixel */
2216 return LCD_RGBPACK_LCD(r
, g
, b
);
2219 /* Functions for each output mode, colour then grayscale. */
2220 static fb_data (* const pixel_funcs
[COLOUR_NUM_MODES
][DITHER_NUM_MODES
])(void) =
2222 [COLOURMODE_COLOUR
] =
2224 [DITHER_NONE
] = pixel_to_lcd_colour
,
2225 [DITHER_ORDERED
] = pixel_odither_to_lcd
,
2226 [DITHER_DIFFUSION
] = pixel_fsdither_to_lcd
,
2230 [DITHER_NONE
] = pixel_to_lcd_gray
,
2231 [DITHER_ORDERED
] = pixel_odither_to_lcd
,
2232 [DITHER_DIFFUSION
] = pixel_fsdither_to_lcd
,
2237 * Draw a partial YUV colour bitmap
2239 * Runs serpentine pattern when dithering is DITHER_DIFFUSION, else scan is
2242 void yuv_bitmap_part(unsigned char *src
[3], int csub_x
, int csub_y
,
2243 int src_x
, int src_y
, int stride
,
2244 int x
, int y
, int width
, int height
)
2246 fb_data
*dst
, *dst_end
;
2247 fb_data (*pixel_func
)(void);
2248 struct rgb_pixel px
;
2250 if (x
+ width
> LCD_WIDTH
)
2251 width
= LCD_WIDTH
- x
; /* Clip right */
2253 width
+= x
, x
= 0; /* Clip left */
2255 return; /* nothing left to do */
2257 if (y
+ height
> LCD_HEIGHT
)
2258 height
= LCD_HEIGHT
- y
; /* Clip bottom */
2260 height
+= y
, y
= 0; /* Clip top */
2262 return; /* nothing left to do */
2266 dst
= rb
->lcd_framebuffer
+ LCD_WIDTH
* y
+ x
;
2267 dst_end
= dst
+ LCD_WIDTH
* height
;
2269 if (jpeg_settings
.colour_mode
== COLOURMODE_GRAY
)
2270 csub_y
= 0; /* Ignore Cb, Cr */
2272 pixel_func
= pixel_funcs
[jpeg_settings
.colour_mode
]
2273 [jpeg_settings
.dither_mode
];
2275 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2277 /* Reset error terms. */
2278 px
.e
= rgb_err_buffers
;
2279 px
.ce
[RED
] = px
.ce
[GRN
] = px
.ce
[BLU
] = 0;
2280 rb
->memset(px
.e
, 0, 3*sizeof (struct rgb_err
));
2285 fb_data
*dst_row
, *row_end
;
2286 const unsigned char *ysrc
;
2289 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2291 /* Use R->L scan on odd lines */
2292 px
.inc
-= (src_y
& 1) << 1;
2296 px
.epos
+= width
- 1;
2303 row_end
= dst_row
+ width
;
2310 dst_row
= row_end
+ width
;
2311 px
.col
= src_x
+ width
- 1;
2314 ysrc
= src
[0] + stride
* src_y
+ px
.col
;
2317 /* Do one row of pixels */
2318 if (csub_y
) /* colour */
2320 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
2321 const unsigned char *usrc
, *vsrc
;
2323 usrc
= src
[1] + (stride
/csub_x
) * (src_y
/csub_y
)
2325 vsrc
= src
[2] + (stride
/csub_x
) * (src_y
/csub_y
)
2327 int xphase
= px
.col
% csub_x
;
2328 int xphase_reset
= px
.inc
* csub_x
;
2329 int y
, v
, u
, rv
, guv
, bu
;
2336 guv
= GUFAC
*u
+ GVFAC
*v
;
2347 *dst_row
= pixel_func();
2350 if (dst_row
== row_end
)
2354 if ((unsigned)xphase
< (unsigned)csub_x
)
2357 /* fetch new chromas */
2363 guv
= GUFAC
*u
+ GVFAC
*v
;
2366 xphase
-= xphase_reset
;
2369 else /* monochrome */
2373 /* Set all components the same for dithering purposes */
2374 px
.g
= px
.r
= px
.b
= YFAC
*(*ysrc
);
2375 *dst_row
= pixel_func();
2379 while (dst_row
!= row_end
);
2385 while (dst
< dst_end
);
2388 #endif /* HAVE_LCD_COLOR */
2391 /* support function for qsort() */
2392 static int compare(const void* p1
, const void* p2
)
2394 return rb
->strcasecmp(*((char **)p1
), *((char **)p2
));
2397 bool jpg_ext(const char ext
[])
2401 if(!rb
->strcasecmp(ext
,".jpg") ||
2402 !rb
->strcasecmp(ext
,".jpe") ||
2403 !rb
->strcasecmp(ext
,".jpeg"))
2409 /*Read directory contents for scrolling. */
2410 void get_pic_list(void)
2413 long int str_len
= 0;
2415 tree
= rb
->tree_get_context();
2417 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2418 file_pt
= rb
->plugin_get_buffer((size_t *)&buf_size
);
2420 file_pt
= rb
->plugin_get_audio_buffer((size_t *)&buf_size
);
2423 for(i
= 0; i
< tree
->filesindir
; i
++)
2425 if(jpg_ext(rb
->strrchr(&tree
->name_buffer
[str_len
],'.')))
2426 file_pt
[entries
++] = &tree
->name_buffer
[str_len
];
2428 str_len
+= rb
->strlen(&tree
->name_buffer
[str_len
]) + 1;
2431 rb
->qsort(file_pt
, entries
, sizeof(char**), compare
);
2433 /* Remove path and leave only the name.*/
2434 pname
= rb
->strrchr(np_file
,'/');
2437 /* Find Selected File. */
2438 for(i
= 0; i
< entries
; i
++)
2439 if(!rb
->strcmp(file_pt
[i
], pname
))
2443 int change_filename(int direct
)
2448 if(direct
== DIR_PREV
)
2454 curfile
= entries
- 1;
2457 }while(file_pt
[curfile
] == '\0' && count
< entries
);
2458 /* we "erase" the file name if we encounter
2459 * a non-supported file, so skip it now */
2461 else /* DIR_NEXT/DIR_NONE */
2466 if(curfile
== entries
- 1)
2470 }while(file_pt
[curfile
] == '\0' && count
< entries
);
2473 if(count
== entries
&& file_pt
[curfile
] == '\0')
2475 rb
->splash(HZ
, "No supported files");
2476 return PLUGIN_ERROR
;
2478 if(rb
->strlen(tree
->currdir
) > 1)
2480 rb
->strcpy(np_file
, tree
->currdir
);
2481 rb
->strcat(np_file
, "/");
2484 rb
->strcpy(np_file
, tree
->currdir
);
2486 rb
->strcat(np_file
, file_pt
[curfile
]);
2488 return PLUGIN_OTHER
;
2491 /* switch off overlay, for handling SYS_ events */
2492 void cleanup(void *parameter
)
2500 #define VSCROLL (LCD_HEIGHT/8)
2501 #define HSCROLL (LCD_WIDTH/10)
2503 #define ZOOM_IN 100 /* return codes for below function */
2504 #define ZOOM_OUT 101
2506 #ifdef HAVE_LCD_COLOR
2507 bool set_option_grayscale(void)
2509 bool gray
= jpeg_settings
.colour_mode
== COLOURMODE_GRAY
;
2510 rb
->set_bool("Grayscale", &gray
);
2511 jpeg_settings
.colour_mode
= gray
? COLOURMODE_GRAY
: COLOURMODE_COLOUR
;
2515 bool set_option_dithering(void)
2517 static const struct opt_items dithering
[DITHER_NUM_MODES
] = {
2518 [DITHER_NONE
] = { "Off", -1 },
2519 [DITHER_ORDERED
] = { "Ordered", -1 },
2520 [DITHER_DIFFUSION
] = { "Diffusion", -1 },
2523 rb
->set_option("Dithering", &jpeg_settings
.dither_mode
, INT
,
2524 dithering
, DITHER_NUM_MODES
, NULL
);
2528 static void display_options(void)
2530 static const struct menu_item items
[] = {
2531 { "Grayscale", set_option_grayscale
},
2532 { "Dithering", set_option_dithering
},
2535 int m
= menu_init(rb
, items
, ARRAYLEN(items
),
2536 NULL
, NULL
, NULL
, NULL
);
2540 #endif /* HAVE_LCD_COLOR */
2542 int show_menu(void) /* return 1 to quit */
2545 rb
->lcd_set_backdrop(old_backdrop
);
2546 #ifdef HAVE_LCD_COLOR
2547 rb
->lcd_set_foreground(rb
->global_settings
->fg_color
);
2548 rb
->lcd_set_background(rb
->global_settings
->bg_color
);
2550 rb
->lcd_set_foreground(LCD_BLACK
);
2551 rb
->lcd_set_background(LCD_WHITE
);
2560 MIID_TOGGLE_SS_MODE
,
2561 MIID_CHANGE_SS_MODE
,
2562 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2563 MIID_SHOW_PLAYBACK_MENU
,
2565 #ifdef HAVE_LCD_COLOR
2566 MIID_DISPLAY_OPTIONS
,
2571 static const struct menu_item items
[] = {
2574 [MIID_TOGGLE_SS_MODE
] =
2575 { "Toggle Slideshow Mode", NULL
},
2576 [MIID_CHANGE_SS_MODE
] =
2577 { "Change Slideshow Time", NULL
},
2578 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2579 [MIID_SHOW_PLAYBACK_MENU
] =
2580 { "Show Playback Menu", NULL
},
2582 #ifdef HAVE_LCD_COLOR
2583 [MIID_DISPLAY_OPTIONS
] =
2584 { "Display Options", NULL
},
2590 static const struct opt_items slideshow
[2] = {
2595 m
= menu_init(rb
, items
, sizeof(items
) / sizeof(*items
),
2596 NULL
, NULL
, NULL
, NULL
);
2597 result
=menu_show(m
);
2605 case MIID_TOGGLE_SS_MODE
:
2606 rb
->set_option("Toggle Slideshow", &slideshow_enabled
, INT
,
2607 slideshow
, 2, NULL
);
2609 case MIID_CHANGE_SS_MODE
:
2610 rb
->set_int("Slideshow Time", "s", UNIT_SEC
,
2611 &jpeg_settings
.ss_timeout
, NULL
, 1,
2612 SS_MIN_TIMEOUT
, SS_MAX_TIMEOUT
, NULL
);
2615 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2616 case MIID_SHOW_PLAYBACK_MENU
:
2619 playback_control(rb
, NULL
);
2623 rb
->splash(HZ
, "Cannot restart playback");
2627 #ifdef HAVE_LCD_COLOR
2628 case MIID_DISPLAY_OPTIONS
:
2636 #if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
2637 /* change ata spindown time based on slideshow time setting */
2638 immediate_ata_off
= false;
2639 rb
->ata_spindown(rb
->global_settings
->disk_spindown
);
2641 if (slideshow_enabled
)
2643 if(jpeg_settings
.ss_timeout
< 10)
2645 /* slideshow times < 10s keep disk spinning */
2646 rb
->ata_spindown(0);
2648 else if (!rb
->mp3_is_playing())
2650 /* slideshow times > 10s and not playing: ata_off after load */
2651 immediate_ata_off
= true;
2656 rb
->lcd_set_backdrop(NULL
);
2657 rb
->lcd_set_foreground(LCD_WHITE
);
2658 rb
->lcd_set_background(LCD_BLACK
);
2660 rb
->lcd_clear_display();
2664 /* interactively scroll around the image */
2665 int scroll_bmp(struct t_disp
* pdisp
)
2674 if (slideshow_enabled
)
2675 button
= rb
->button_get_w_tmo(jpeg_settings
.ss_timeout
* HZ
);
2676 else button
= rb
->button_get(true);
2678 running_slideshow
= false;
2683 if (!(ds
< ds_max
) && entries
> 0 && jpg
.x_size
<= MAX_X_SIZE
)
2684 return change_filename(DIR_PREV
);
2685 case JPEG_LEFT
| BUTTON_REPEAT
:
2686 move
= MIN(HSCROLL
, pdisp
->x
);
2689 MYXLCD(scroll_right
)(move
); /* scroll right */
2691 #ifdef HAVE_LCD_COLOR
2693 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2694 pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2695 0, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2696 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2698 MYXLCD(gray_bitmap_part
)(
2699 pdisp
->bitmap
[0], pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2700 0, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2701 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2708 if (!(ds
< ds_max
) && entries
> 0 && jpg
.x_size
<= MAX_X_SIZE
)
2709 return change_filename(DIR_NEXT
);
2710 case JPEG_RIGHT
| BUTTON_REPEAT
:
2711 move
= MIN(HSCROLL
, pdisp
->width
- pdisp
->x
- LCD_WIDTH
);
2714 MYXLCD(scroll_left
)(move
); /* scroll left */
2716 #ifdef HAVE_LCD_COLOR
2718 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2719 pdisp
->x
+ LCD_WIDTH
- move
, pdisp
->y
, pdisp
->stride
,
2720 LCD_WIDTH
- move
, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2721 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2723 MYXLCD(gray_bitmap_part
)(
2724 pdisp
->bitmap
[0], pdisp
->x
+ LCD_WIDTH
- move
,
2725 pdisp
->y
, pdisp
->stride
,
2726 LCD_WIDTH
- move
, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2727 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2734 case JPEG_UP
| BUTTON_REPEAT
:
2735 move
= MIN(VSCROLL
, pdisp
->y
);
2738 MYXLCD(scroll_down
)(move
); /* scroll down */
2740 #ifdef HAVE_LCD_COLOR
2741 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2743 /* Draw over the band at the top of the last update
2744 caused by lack of error history on line zero. */
2745 move
= MIN(move
+ 1, pdisp
->y
+ pdisp
->height
);
2749 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2750 pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2751 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), 0, /* x, y */
2752 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2754 MYXLCD(gray_bitmap_part
)(
2755 pdisp
->bitmap
[0], pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2756 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), 0, /* x, y */
2757 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2764 case JPEG_DOWN
| BUTTON_REPEAT
:
2765 move
= MIN(VSCROLL
, pdisp
->height
- pdisp
->y
- LCD_HEIGHT
);
2768 MYXLCD(scroll_up
)(move
); /* scroll up */
2770 #ifdef HAVE_LCD_COLOR
2771 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2773 /* Save the line that was on the last line of the display
2774 and draw one extra line above then recover the line with
2775 image data that had an error history when it was drawn.
2779 rb
->lcd_framebuffer
+ (LCD_HEIGHT
- move
)*LCD_WIDTH
,
2780 LCD_WIDTH
*sizeof (fb_data
));
2784 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
, pdisp
->x
,
2785 pdisp
->y
+ LCD_HEIGHT
- move
, pdisp
->stride
,
2786 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), LCD_HEIGHT
- move
, /* x, y */
2787 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2789 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2791 /* Cover the first row drawn with previous image data. */
2792 MEMCPY(rb
->lcd_framebuffer
+ (LCD_HEIGHT
- move
)*LCD_WIDTH
,
2794 LCD_WIDTH
*sizeof (fb_data
));
2798 MYXLCD(gray_bitmap_part
)(
2799 pdisp
->bitmap
[0], pdisp
->x
,
2800 pdisp
->y
+ LCD_HEIGHT
- move
, pdisp
->stride
,
2801 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), LCD_HEIGHT
- move
, /* x, y */
2802 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2808 if (!slideshow_enabled
)
2810 running_slideshow
= true;
2812 return change_filename(DIR_NEXT
);
2815 #ifdef JPEG_SLIDE_SHOW
2816 case JPEG_SLIDE_SHOW
:
2817 slideshow_enabled
= !slideshow_enabled
;
2818 running_slideshow
= slideshow_enabled
;
2822 #ifdef JPEG_NEXT_REPEAT
2823 case JPEG_NEXT_REPEAT
:
2827 return change_filename(DIR_NEXT
);
2830 #ifdef JPEG_PREVIOUS_REPEAT
2831 case JPEG_PREVIOUS_REPEAT
:
2835 return change_filename(DIR_PREV
);
2839 #ifdef JPEG_ZOOM_PRE
2840 if (lastbutton
!= JPEG_ZOOM_PRE
)
2847 #ifdef JPEG_ZOOM_PRE
2848 if (lastbutton
!= JPEG_ZOOM_PRE
)
2858 grey_show(false); /* switch off greyscale overlay */
2860 if (show_menu() == 1)
2864 grey_show(true); /* switch on greyscale overlay */
2867 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2868 pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2869 MAX(0, (LCD_WIDTH
- pdisp
->width
) / 2),
2870 MAX(0, (LCD_HEIGHT
- pdisp
->height
) / 2),
2871 MIN(LCD_WIDTH
, pdisp
->width
),
2872 MIN(LCD_HEIGHT
, pdisp
->height
));
2877 if (rb
->default_event_handler_ex(button
, cleanup
, NULL
)
2878 == SYS_USB_CONNECTED
)
2879 return PLUGIN_USB_CONNECTED
;
2884 if (button
!= BUTTON_NONE
)
2885 lastbutton
= button
;
2886 } /* while (true) */
2889 /********************* main function *************************/
2891 /* callback updating a progress meter while JPEG decoding */
2892 void cb_progess(int current
, int total
)
2894 rb
->yield(); /* be nice to the other threads */
2895 if(!running_slideshow
)
2897 rb
->gui_scrollbar_draw(rb
->screens
[SCREEN_MAIN
],0, LCD_HEIGHT
-8, LCD_WIDTH
, 8, total
, 0,
2898 current
, HORIZONTAL
);
2899 rb
->lcd_update_rect(0, LCD_HEIGHT
-8, LCD_WIDTH
, 8);
2904 /* in slideshow mode, keep gui interference to a minimum */
2905 rb
->gui_scrollbar_draw(rb
->screens
[SCREEN_MAIN
],0, LCD_HEIGHT
-4, LCD_WIDTH
, 4, total
, 0,
2906 current
, HORIZONTAL
);
2907 rb
->lcd_update_rect(0, LCD_HEIGHT
-4, LCD_WIDTH
, 4);
2912 int jpegmem(struct jpeg
*p_jpg
, int ds
)
2916 size
= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[0])
2917 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[0]);
2918 #ifdef HAVE_LCD_COLOR
2919 if (p_jpg
->blocks
> 1) /* colour, add requirements for chroma */
2921 size
+= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[1])
2922 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[1]);
2923 size
+= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[2])
2924 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[2]);
2930 /* how far can we zoom in without running out of memory */
2931 int min_downscale(struct jpeg
*p_jpg
, int bufsize
)
2935 if (jpegmem(p_jpg
, 8) > bufsize
)
2936 return 0; /* error, too large, even 1:8 doesn't fit */
2938 while (downscale
> 1 && jpegmem(p_jpg
, downscale
/2) <= bufsize
)
2945 /* how far can we zoom out, to fit image into the LCD */
2946 int max_downscale(struct jpeg
*p_jpg
)
2950 while (downscale
< 8 && (p_jpg
->x_size
> LCD_WIDTH
*downscale
2951 || p_jpg
->y_size
> LCD_HEIGHT
*downscale
))
2960 /* return decoded or cached image */
2961 struct t_disp
* get_image(struct jpeg
* p_jpg
, int ds
)
2963 int w
, h
; /* used to center output */
2964 int size
; /* decompressed image size */
2965 long time
; /* measured ticks */
2968 struct t_disp
* p_disp
= &disp
[ds
]; /* short cut */
2970 if (p_disp
->bitmap
[0] != NULL
)
2972 return p_disp
; /* we still have it */
2975 /* assign image buffer */
2977 /* physical size needed for decoding */
2978 size
= jpegmem(p_jpg
, ds
);
2979 if (buf_size
<= size
)
2980 { /* have to discard the current */
2982 for (i
=1; i
<=8; i
++)
2983 disp
[i
].bitmap
[0] = NULL
; /* invalidate all bitmaps */
2984 buf
= buf_root
; /* start again from the beginning of the buffer */
2985 buf_size
= root_size
;
2988 #ifdef HAVE_LCD_COLOR
2989 if (p_jpg
->blocks
> 1) /* colour jpeg */
2993 for (i
= 1; i
< 3; i
++)
2995 size
= (p_jpg
->x_phys
/ ds
/ p_jpg
->subsample_x
[i
])
2996 * (p_jpg
->y_phys
/ ds
/ p_jpg
->subsample_y
[i
]);
2997 p_disp
->bitmap
[i
] = buf
;
3001 p_disp
->csub_x
= p_jpg
->subsample_x
[1];
3002 p_disp
->csub_y
= p_jpg
->subsample_y
[1];
3006 p_disp
->csub_x
= p_disp
->csub_y
= 0;
3007 p_disp
->bitmap
[1] = p_disp
->bitmap
[2] = buf
;
3010 /* size may be less when decoded (if height is not block aligned) */
3011 size
= (p_jpg
->x_phys
/ds
) * (p_jpg
->y_size
/ ds
);
3012 p_disp
->bitmap
[0] = buf
;
3016 if(!running_slideshow
)
3018 rb
->snprintf(print
, sizeof(print
), "decoding %d*%d",
3019 p_jpg
->x_size
/ds
, p_jpg
->y_size
/ds
);
3020 rb
->lcd_puts(0, 3, print
);
3024 /* update image properties */
3025 p_disp
->width
= p_jpg
->x_size
/ ds
;
3026 p_disp
->stride
= p_jpg
->x_phys
/ ds
; /* use physical size for stride */
3027 p_disp
->height
= p_jpg
->y_size
/ ds
;
3029 /* the actual decoding */
3030 time
= *rb
->current_tick
;
3031 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
3032 rb
->cpu_boost(true);
3033 status
= jpeg_decode(p_jpg
, p_disp
->bitmap
, ds
, cb_progess
);
3034 rb
->cpu_boost(false);
3036 status
= jpeg_decode(p_jpg
, p_disp
->bitmap
, ds
, cb_progess
);
3040 rb
->splashf(HZ
, "decode error %d", status
);
3041 file_pt
[curfile
] = '\0';
3044 time
= *rb
->current_tick
- time
;
3046 if(!running_slideshow
)
3048 rb
->snprintf(print
, sizeof(print
), " %ld.%02ld sec ", time
/HZ
, time
%HZ
);
3049 rb
->lcd_getstringsize(print
, &w
, &h
); /* centered in progress bar */
3050 rb
->lcd_putsxy((LCD_WIDTH
- w
)/2, LCD_HEIGHT
- h
, print
);
3058 /* set the view to the given center point, limit if necessary */
3059 void set_view (struct t_disp
* p_disp
, int cx
, int cy
)
3063 /* plain center to available width/height */
3064 x
= cx
- MIN(LCD_WIDTH
, p_disp
->width
) / 2;
3065 y
= cy
- MIN(LCD_HEIGHT
, p_disp
->height
) / 2;
3067 /* limit against upper image size */
3068 x
= MIN(p_disp
->width
- LCD_WIDTH
, x
);
3069 y
= MIN(p_disp
->height
- LCD_HEIGHT
, y
);
3071 /* limit against negative side */
3075 p_disp
->x
= x
; /* set the values */
3080 /* calculate the view center based on the bitmap position */
3081 void get_view(struct t_disp
* p_disp
, int* p_cx
, int* p_cy
)
3083 *p_cx
= p_disp
->x
+ MIN(LCD_WIDTH
, p_disp
->width
) / 2;
3084 *p_cy
= p_disp
->y
+ MIN(LCD_HEIGHT
, p_disp
->height
) / 2;
3088 /* load, decode, display the image */
3089 int load_and_show(char* filename
)
3093 unsigned char* buf_jpeg
; /* compressed JPEG image */
3095 struct t_disp
* p_disp
; /* currenly displayed image */
3096 int cx
, cy
; /* view center */
3098 fd
= rb
->open(filename
, O_RDONLY
);
3101 rb
->snprintf(print
,sizeof(print
),"err opening %s:%d",filename
,fd
);
3102 rb
->splash(HZ
, print
);
3103 return PLUGIN_ERROR
;
3105 filesize
= rb
->filesize(fd
);
3106 rb
->memset(&disp
, 0, sizeof(disp
));
3108 buf
= buf_images
+ filesize
;
3109 buf_size
= buf_images_size
- filesize
;
3110 /* allocate JPEG buffer */
3111 buf_jpeg
= buf_images
;
3113 buf_root
= buf
; /* we can start the decompressed images behind it */
3114 root_size
= buf_size
;
3118 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
3122 rb
->lcd_setfont(FONT_SYSFIXED
);
3123 rb
->lcd_clear_display();
3124 rb
->snprintf(print
,sizeof(print
),"%s:",rb
->strrchr(filename
,'/')+1);
3125 rb
->lcd_puts(0,0,print
);
3126 rb
->lcd_puts(0,1,"Not enough plugin memory!");
3127 rb
->lcd_puts(0,2,"Zoom In: Stop playback.");
3129 rb
->lcd_puts(0,3,"Left/Right: Skip File.");
3130 rb
->lcd_puts(0,4,"Off: Quit.");
3132 rb
->lcd_setfont(FONT_UI
);
3134 rb
->button_clear_queue();
3138 int button
= rb
->button_get(true);
3143 buf_images
= rb
->plugin_get_audio_buffer(
3144 (size_t *)&buf_images_size
);
3145 /*try again this file, now using the audio buffer */
3146 return PLUGIN_OTHER
;
3156 rb
->lcd_clear_display();
3157 return change_filename(DIR_PREV
);
3164 rb
->lcd_clear_display();
3165 return change_filename(DIR_NEXT
);
3169 if(rb
->default_event_handler_ex(button
, cleanup
, NULL
)
3170 == SYS_USB_CONNECTED
)
3171 return PLUGIN_USB_CONNECTED
;
3179 rb
->splash(HZ
, "Out of Memory");
3181 return PLUGIN_ERROR
;
3185 if(!running_slideshow
)
3188 rb
->lcd_set_foreground(LCD_WHITE
);
3189 rb
->lcd_set_background(LCD_BLACK
);
3190 rb
->lcd_set_backdrop(NULL
);
3193 rb
->lcd_clear_display();
3194 rb
->snprintf(print
, sizeof(print
), "%s:", rb
->strrchr(filename
,'/')+1);
3195 rb
->lcd_puts(0, 0, print
);
3198 rb
->snprintf(print
, sizeof(print
), "loading %d bytes", filesize
);
3199 rb
->lcd_puts(0, 1, print
);
3203 rb
->read(fd
, buf_jpeg
, filesize
);
3206 if(!running_slideshow
)
3208 rb
->snprintf(print
, sizeof(print
), "decoding markers");
3209 rb
->lcd_puts(0, 2, print
);
3213 else if(immediate_ata_off
)
3215 /* running slideshow and time is long enough: power down disk */
3220 rb
->memset(&jpg
, 0, sizeof(jpg
)); /* clear info struct */
3221 /* process markers, unstuffing */
3222 status
= process_markers(buf_jpeg
, filesize
, &jpg
);
3224 if (status
< 0 || (status
& (DQT
| SOF0
)) != (DQT
| SOF0
))
3225 { /* bad format or minimum components not contained */
3226 rb
->splashf(HZ
, "unsupported %d", status
);
3227 file_pt
[curfile
] = '\0';
3228 return change_filename(direction
);
3231 if (!(status
& DHT
)) /* if no Huffman table present: */
3232 default_huff_tbl(&jpg
); /* use default */
3233 build_lut(&jpg
); /* derive Huffman and other lookup-tables */
3235 if(!running_slideshow
)
3237 rb
->snprintf(print
, sizeof(print
), "image %dx%d", jpg
.x_size
, jpg
.y_size
);
3238 rb
->lcd_puts(0, 2, print
);
3241 ds_max
= max_downscale(&jpg
); /* check display constraint */
3242 ds_min
= min_downscale(&jpg
, buf_size
); /* check memory constraint */
3245 rb
->splash(HZ
, "too large");
3246 file_pt
[curfile
] = '\0';
3247 return change_filename(direction
);
3250 ds
= ds_max
; /* initials setting */
3251 cx
= jpg
.x_size
/ds
/2; /* center the view */
3252 cy
= jpg
.y_size
/ds
/2;
3254 do /* loop the image prepare and decoding when zoomed */
3256 p_disp
= get_image(&jpg
, ds
); /* decode or fetch from cache */
3258 return change_filename(direction
);
3260 set_view(p_disp
, cx
, cy
);
3262 if(!running_slideshow
)
3264 rb
->snprintf(print
, sizeof(print
), "showing %dx%d",
3265 p_disp
->width
, p_disp
->height
);
3266 rb
->lcd_puts(0, 3, print
);
3269 MYLCD(clear_display
)();
3270 #ifdef HAVE_LCD_COLOR
3272 p_disp
->bitmap
, p_disp
->csub_x
, p_disp
->csub_y
,
3273 p_disp
->x
, p_disp
->y
, p_disp
->stride
,
3274 MAX(0, (LCD_WIDTH
- p_disp
->width
) / 2),
3275 MAX(0, (LCD_HEIGHT
- p_disp
->height
) / 2),
3276 MIN(LCD_WIDTH
, p_disp
->width
),
3277 MIN(LCD_HEIGHT
, p_disp
->height
));
3279 MYXLCD(gray_bitmap_part
)(
3280 p_disp
->bitmap
[0], p_disp
->x
, p_disp
->y
, p_disp
->stride
,
3281 MAX(0, (LCD_WIDTH
- p_disp
->width
) / 2),
3282 MAX(0, (LCD_HEIGHT
- p_disp
->height
) / 2),
3283 MIN(LCD_WIDTH
, p_disp
->width
),
3284 MIN(LCD_HEIGHT
, p_disp
->height
));
3289 grey_show(true); /* switch on greyscale overlay */
3292 /* drawing is now finished, play around with scrolling
3293 * until you press OFF or connect USB
3297 status
= scroll_bmp(p_disp
);
3298 if (status
== ZOOM_IN
)
3302 ds
/= 2; /* reduce downscaling to zoom in */
3303 get_view(p_disp
, &cx
, &cy
);
3304 cx
*= 2; /* prepare the position in the new image */
3311 if (status
== ZOOM_OUT
)
3315 ds
*= 2; /* increase downscaling to zoom out */
3316 get_view(p_disp
, &cx
, &cy
);
3317 cx
/= 2; /* prepare the position in the new image */
3327 grey_show(false); /* switch off overlay */
3329 rb
->lcd_clear_display();
3331 while (status
!= PLUGIN_OK
&& status
!= PLUGIN_USB_CONNECTED
3332 && status
!= PLUGIN_OTHER
);
3339 /******************** Plugin entry point *********************/
3341 enum plugin_status
plugin_start(const struct plugin_api
* api
, const void* parameter
)
3347 long greysize
; /* helper */
3350 old_backdrop
= rb
->lcd_get_backdrop();
3353 if(!parameter
) return PLUGIN_ERROR
;
3355 rb
->strcpy(np_file
, parameter
);
3358 if(!entries
) return PLUGIN_ERROR
;
3360 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
3361 if(rb
->audio_status())
3363 buf
= rb
->plugin_get_buffer((size_t *)&buf_size
) +
3364 (entries
* sizeof(char**));
3365 buf_size
-= (entries
* sizeof(char**));
3369 buf
= rb
->plugin_get_audio_buffer((size_t *)&buf_size
);
3371 buf
= rb
->plugin_get_audio_buffer(&buf_size
) +
3372 (entries
* sizeof(char**));
3373 buf_size
-= (entries
* sizeof(char**));
3377 if (!grey_init(rb
, buf
, buf_size
, GREY_ON_COP
,
3378 LCD_WIDTH
, LCD_HEIGHT
, &greysize
))
3380 rb
->splash(HZ
, "grey buf error");
3381 return PLUGIN_ERROR
;
3384 buf_size
-= greysize
;
3389 /* should be ok to just load settings since a parameter is present
3390 here and the drive should be spinning */
3391 configfile_init(rb
);
3392 configfile_load(JPEG_CONFIGFILE
, jpeg_config
,
3393 ARRAYLEN(jpeg_config
), JPEG_SETTINGS_MINVERSION
);
3394 old_settings
= jpeg_settings
;
3396 buf_images
= buf
; buf_images_size
= buf_size
;
3398 /* Turn off backlight timeout */
3399 backlight_force_on(rb
); /* backlight control in lib/helper.c */
3403 condition
= load_and_show(np_file
);
3404 }while (condition
!= PLUGIN_OK
&& condition
!= PLUGIN_USB_CONNECTED
3405 && condition
!= PLUGIN_ERROR
);
3407 if (rb
->memcmp(&jpeg_settings
, &old_settings
, sizeof (jpeg_settings
)))
3409 /* Just in case drive has to spin, keep it from looking locked */
3410 rb
->splash(0, "Saving Settings");
3411 configfile_save(JPEG_CONFIGFILE
, jpeg_config
,
3412 ARRAYLEN(jpeg_config
), JPEG_SETTINGS_VERSION
);
3415 #if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
3416 /* set back ata spindown time in case we changed it */
3417 rb
->ata_spindown(rb
->global_settings
->disk_spindown
);
3420 /* Turn on backlight timeout (revert to settings) */
3421 backlight_use_settings(rb
); /* backlight control in lib/helper.c */
3424 grey_release(); /* deinitialize */
3430 #endif /* HAVE_LCD_BITMAP */