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�g Hohensohn aka [IDC]Dragon
15 * Grayscale framework (C) 2004 Jens Arnold
16 * Heavily borrowed from the IJG implementation (C) Thomas G. Lane
17 * Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
19 * All files in this archive are subject to the GNU General Public License.
20 * See the file COPYING in the source tree root for full license agreement.
22 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
23 * KIND, either express or implied.
25 ****************************************************************************/
28 #include "playback_control.h"
29 #include "oldmenuapi.h"
32 #ifdef HAVE_LCD_BITMAP
37 #include "lib/configfile.h"
42 /* variable button definitions */
43 #if CONFIG_KEYPAD == RECORDER_PAD
44 #define JPEG_ZOOM_IN BUTTON_PLAY
45 #define JPEG_ZOOM_OUT BUTTON_ON
46 #define JPEG_UP BUTTON_UP
47 #define JPEG_DOWN BUTTON_DOWN
48 #define JPEG_LEFT BUTTON_LEFT
49 #define JPEG_RIGHT BUTTON_RIGHT
50 #define JPEG_NEXT BUTTON_F3
51 #define JPEG_PREVIOUS BUTTON_F2
52 #define JPEG_MENU BUTTON_OFF
54 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
55 #define JPEG_ZOOM_IN BUTTON_SELECT
56 #define JPEG_ZOOM_OUT BUTTON_ON
57 #define JPEG_UP BUTTON_UP
58 #define JPEG_DOWN BUTTON_DOWN
59 #define JPEG_LEFT BUTTON_LEFT
60 #define JPEG_RIGHT BUTTON_RIGHT
61 #define JPEG_NEXT BUTTON_F3
62 #define JPEG_PREVIOUS BUTTON_F2
63 #define JPEG_MENU BUTTON_OFF
65 #elif CONFIG_KEYPAD == ONDIO_PAD
66 #define JPEG_ZOOM_PRE BUTTON_MENU
67 #define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
68 #define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
69 #define JPEG_UP BUTTON_UP
70 #define JPEG_DOWN BUTTON_DOWN
71 #define JPEG_LEFT BUTTON_LEFT
72 #define JPEG_RIGHT BUTTON_RIGHT
73 #define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
74 #define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
75 #define JPEG_MENU BUTTON_OFF
77 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
78 (CONFIG_KEYPAD == IRIVER_H300_PAD)
79 #define JPEG_ZOOM_IN BUTTON_SELECT
80 #define JPEG_ZOOM_OUT BUTTON_MODE
81 #define JPEG_UP BUTTON_UP
82 #define JPEG_DOWN BUTTON_DOWN
83 #define JPEG_LEFT BUTTON_LEFT
84 #define JPEG_RIGHT BUTTON_RIGHT
85 #if (CONFIG_KEYPAD == IRIVER_H100_PAD)
86 #define JPEG_NEXT BUTTON_ON
87 #define JPEG_PREVIOUS BUTTON_REC
89 #define JPEG_NEXT BUTTON_REC
90 #define JPEG_PREVIOUS BUTTON_ON
92 #define JPEG_MENU BUTTON_OFF
93 #define JPEG_RC_MENU BUTTON_RC_STOP
95 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
96 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
97 #define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
98 #define JPEG_ZOOM_OUT BUTTON_SCROLL_BACK
99 #define JPEG_UP BUTTON_MENU
100 #define JPEG_DOWN BUTTON_PLAY
101 #define JPEG_LEFT BUTTON_LEFT
102 #define JPEG_RIGHT BUTTON_RIGHT
103 #define JPEG_MENU (BUTTON_SELECT | BUTTON_MENU)
104 #define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
105 #define JPEG_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
107 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
108 #define JPEG_ZOOM_PRE BUTTON_SELECT
109 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
110 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
111 #define JPEG_UP BUTTON_UP
112 #define JPEG_DOWN BUTTON_DOWN
113 #define JPEG_LEFT BUTTON_LEFT
114 #define JPEG_RIGHT BUTTON_RIGHT
115 #define JPEG_MENU BUTTON_POWER
116 #define JPEG_NEXT BUTTON_PLAY
117 #define JPEG_PREVIOUS BUTTON_REC
119 #elif CONFIG_KEYPAD == GIGABEAT_PAD
120 #define JPEG_ZOOM_IN BUTTON_VOL_UP
121 #define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
122 #define JPEG_UP BUTTON_UP
123 #define JPEG_DOWN BUTTON_DOWN
124 #define JPEG_LEFT BUTTON_LEFT
125 #define JPEG_RIGHT BUTTON_RIGHT
126 #define JPEG_MENU BUTTON_MENU
127 #define JPEG_NEXT (BUTTON_A | BUTTON_RIGHT)
128 #define JPEG_PREVIOUS (BUTTON_A | BUTTON_LEFT)
130 #elif CONFIG_KEYPAD == SANSA_E200_PAD
131 #define JPEG_ZOOM_PRE BUTTON_SELECT
132 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
133 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
134 #define JPEG_UP BUTTON_UP
135 #define JPEG_DOWN BUTTON_DOWN
136 #define JPEG_LEFT BUTTON_LEFT
137 #define JPEG_RIGHT BUTTON_RIGHT
138 #define JPEG_MENU BUTTON_POWER
139 #define JPEG_SLIDE_SHOW BUTTON_REC
140 #define JPEG_NEXT BUTTON_SCROLL_DOWN
141 #define JPEG_NEXT_REPEAT (BUTTON_SCROLL_DOWN|BUTTON_REPEAT)
142 #define JPEG_PREVIOUS BUTTON_SCROLL_UP
143 #define JPEG_PREVIOUS_REPEAT (BUTTON_SCROLL_UP|BUTTON_REPEAT)
145 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
146 #define JPEG_ZOOM_PRE BUTTON_PLAY
147 #define JPEG_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
148 #define JPEG_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
149 #define JPEG_UP BUTTON_SCROLL_UP
150 #define JPEG_DOWN BUTTON_SCROLL_DOWN
151 #define JPEG_LEFT BUTTON_LEFT
152 #define JPEG_RIGHT BUTTON_RIGHT
153 #define JPEG_MENU BUTTON_POWER
154 #define JPEG_NEXT BUTTON_FF
155 #define JPEG_PREVIOUS BUTTON_REW
159 /* different graphics libraries */
162 #define MYLCD(fn) gray_ub_ ## fn
163 #define MYLCD_UPDATE()
164 #define MYXLCD(fn) gray_ub_ ## fn
166 #define MYLCD(fn) rb->lcd_ ## fn
167 #define MYLCD_UPDATE() rb->lcd_update();
168 #define MYXLCD(fn) xlcd_ ## fn
171 #define MAX_X_SIZE LCD_WIDTH*8
173 /* Min memory allowing us to use the plugin buffer
174 * and thus not stopping the music
175 * *Very* rough estimation:
176 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
177 * + 20k code size = 60 000
178 * + 50k min for jpeg = 120 000
180 #define MIN_MEM 120000
187 #define PLUGIN_OTHER 10 /* State code for output with return. */
189 /******************************* Globals ***********************************/
191 static struct plugin_api
* rb
;
192 MEM_FUNCTION_WRAPPERS(rb
);
194 /* for portability of below JPEG code */
195 #define MEMSET(p,v,c) rb->memset(p,v,c)
196 #define MEMCPY(d,s,c) rb->memcpy(d,s,c)
197 #define INLINE static inline
198 #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
200 static int slideshow_enabled
= false; /* run slideshow */
201 static int running_slideshow
= false; /* loading image because of slideshw */
203 static int immediate_ata_off
= false; /* power down disk after loading */
205 static int button_timeout
= HZ
*5;
207 #ifdef HAVE_LCD_COLOR
209 /* Persistent configuration - only needed for color displays atm */
210 #define JPEG_CONFIGFILE "jpeg.cfg"
211 #define JPEG_SETTINGS_MINVERSION 1
212 #define JPEG_SETTINGS_VERSION 1
216 COLOURMODE_COLOUR
= 0,
223 DITHER_NONE
= 0, /* No dithering */
224 DITHER_ORDERED
, /* Bayer ordered */
225 DITHER_DIFFUSION
, /* Floyd/Steinberg error diffusion */
235 static struct jpeg_settings jpeg_settings
=
236 { COLOURMODE_COLOUR
, DITHER_NONE
};
237 static struct jpeg_settings old_settings
;
239 static struct configdata jpeg_config
[] =
241 { TYPE_ENUM
, 0, COLOUR_NUM_MODES
, &jpeg_settings
.colour_mode
,
242 "Colour Mode", (char *[]){ "Colour", "Grayscale" }, NULL
},
243 { TYPE_ENUM
, 0, DITHER_NUM_MODES
, &jpeg_settings
.dither_mode
,
244 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" }, NULL
},
247 #endif /* HAVE_LCD_COLOR */
249 fb_data
* old_backdrop
;
252 /**************** begin JPEG code ********************/
254 INLINE
unsigned range_limit(int value
)
256 #if CONFIG_CPU == SH7034
258 asm ( /* Note: Uses knowledge that only low byte of result is used */
260 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
261 "extu.b %[v],%[t] \n"
262 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
263 "bt 1f \n" /* yes: no overflow */
264 "cmp/pz %[v] \n" /* overflow: positive? */
265 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
272 #elif defined(CPU_COLDFIRE)
273 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
274 "add.l #128,%[v] \n" /* value += 128; */
275 "cmp.l #255,%[v] \n" /* overflow? */
276 "bls.b 1f \n" /* no: return value */
277 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
283 #elif defined(CPU_ARM)
284 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
285 "add %[v], %[v], #128 \n" /* value += 128 */
286 "cmp %[v], #255 \n" /* out of range 0..255? */
287 "mvnhi %[v], %[v], asr #31 \n" /* yes: set all bits to ~(sign_bit) */
295 if ((unsigned)value
<= 255)
305 /* IDCT implementation */
308 #define CONST_BITS 13
312 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
313 * causing a lot of useless floating-point operations at run time.
314 * To get around this we use the following pre-calculated constants.
315 * If you change CONST_BITS you may want to add appropriate values.
316 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
318 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
319 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
320 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
321 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
322 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
323 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
324 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
325 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
326 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
327 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
328 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
329 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
333 /* Multiply an long variable by an long constant to yield an long result.
334 * For 8-bit samples with the recommended scaling, all the variable
335 * and constant values involved are no more than 16 bits wide, so a
336 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
337 * For 12-bit samples, a full 32-bit multiplication will be needed.
339 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
342 /* Dequantize a coefficient by multiplying it by the multiplier-table
343 * entry; produce an int result. In this module, both inputs and result
344 * are 16 bits or less, so either int or short multiply will work.
346 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
347 #define DEQUANTIZE MULTIPLY16
349 /* Descale and correctly round an int value that's scaled by N bits.
350 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
351 * the fudge factor is correct for either sign of X.
353 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
358 * Perform dequantization and inverse DCT on one block of coefficients,
359 * producing a reduced-size 1x1 output block.
361 void idct1x1(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
363 (void)skip_line
; /* unused */
364 *p_byte
= range_limit(inptr
[0] * quantptr
[0] >> 3);
370 * Perform dequantization and inverse DCT on one block of coefficients,
371 * producing a reduced-size 2x2 output block.
373 void idct2x2(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
375 int tmp0
, tmp1
, tmp2
, tmp3
, tmp4
, tmp5
;
376 unsigned char* outptr
;
378 /* Pass 1: process columns from input, store into work array. */
381 tmp4
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]);
382 tmp5
= DEQUANTIZE(inptr
[8*1], quantptr
[8*1]);
388 tmp4
= DEQUANTIZE(inptr
[8*0+1], quantptr
[8*0+1]);
389 tmp5
= DEQUANTIZE(inptr
[8*1+1], quantptr
[8*1+1]);
394 /* Pass 2: process 2 rows, store into output array. */
399 outptr
[0] = range_limit((int) DESCALE(tmp0
+ tmp1
, 3));
400 outptr
[1] = range_limit((int) DESCALE(tmp0
- tmp1
, 3));
403 outptr
= p_byte
+ skip_line
;
405 outptr
[0] = range_limit((int) DESCALE(tmp2
+ tmp3
, 3));
406 outptr
[1] = range_limit((int) DESCALE(tmp2
- tmp3
, 3));
412 * Perform dequantization and inverse DCT on one block of coefficients,
413 * producing a reduced-size 4x4 output block.
415 void idct4x4(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
417 int tmp0
, tmp2
, tmp10
, tmp12
;
420 unsigned char* outptr
;
422 int workspace
[4*4]; /* buffers data between passes */
424 /* Pass 1: process columns from input, store into work array. */
427 for (ctr
= 0; ctr
< 4; ctr
++, inptr
++, quantptr
++, wsptr
++)
431 tmp0
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]);
432 tmp2
= DEQUANTIZE(inptr
[8*2], quantptr
[8*2]);
434 tmp10
= (tmp0
+ tmp2
) << PASS1_BITS
;
435 tmp12
= (tmp0
- tmp2
) << PASS1_BITS
;
438 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
440 z2
= DEQUANTIZE(inptr
[8*1], quantptr
[8*1]);
441 z3
= DEQUANTIZE(inptr
[8*3], quantptr
[8*3]);
443 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
444 tmp0
= DESCALE(z1
+ MULTIPLY16(z3
, - FIX_1_847759065
), CONST_BITS
-PASS1_BITS
);
445 tmp2
= DESCALE(z1
+ MULTIPLY16(z2
, FIX_0_765366865
), CONST_BITS
-PASS1_BITS
);
447 /* Final output stage */
449 wsptr
[4*0] = (int) (tmp10
+ tmp2
);
450 wsptr
[4*3] = (int) (tmp10
- tmp2
);
451 wsptr
[4*1] = (int) (tmp12
+ tmp0
);
452 wsptr
[4*2] = (int) (tmp12
- tmp0
);
455 /* Pass 2: process 4 rows from work array, store into output array. */
458 for (ctr
= 0; ctr
< 4; ctr
++)
460 outptr
= p_byte
+ (ctr
*skip_line
);
463 tmp0
= (int) wsptr
[0];
464 tmp2
= (int) wsptr
[2];
466 tmp10
= (tmp0
+ tmp2
) << CONST_BITS
;
467 tmp12
= (tmp0
- tmp2
) << CONST_BITS
;
470 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
475 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
476 tmp0
= z1
+ MULTIPLY16(z3
, - FIX_1_847759065
);
477 tmp2
= z1
+ MULTIPLY16(z2
, FIX_0_765366865
);
479 /* Final output stage */
481 outptr
[0] = range_limit((int) DESCALE(tmp10
+ tmp2
,
482 CONST_BITS
+PASS1_BITS
+3));
483 outptr
[3] = range_limit((int) DESCALE(tmp10
- tmp2
,
484 CONST_BITS
+PASS1_BITS
+3));
485 outptr
[1] = range_limit((int) DESCALE(tmp12
+ tmp0
,
486 CONST_BITS
+PASS1_BITS
+3));
487 outptr
[2] = range_limit((int) DESCALE(tmp12
- tmp0
,
488 CONST_BITS
+PASS1_BITS
+3));
490 wsptr
+= 4; /* advance pointer to next row */
497 * Perform dequantization and inverse DCT on one block of coefficients.
499 void idct8x8(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
501 long tmp0
, tmp1
, tmp2
, tmp3
;
502 long tmp10
, tmp11
, tmp12
, tmp13
;
503 long z1
, z2
, z3
, z4
, z5
;
505 unsigned char* outptr
;
507 int workspace
[64]; /* buffers data between passes */
509 /* Pass 1: process columns from input, store into work array. */
510 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
511 /* furthermore, we scale the results by 2**PASS1_BITS. */
514 for (ctr
= 8; ctr
> 0; ctr
--)
516 /* Due to quantization, we will usually find that many of the input
517 * coefficients are zero, especially the AC terms. We can exploit this
518 * by short-circuiting the IDCT calculation for any column in which all
519 * the AC terms are zero. In that case each output is equal to the
520 * DC coefficient (with scale factor as needed).
521 * With typical images and quantization tables, half or more of the
522 * column DCT calculations can be simplified this way.
525 if ((inptr
[8*1] | inptr
[8*2] | inptr
[8*3]
526 | inptr
[8*4] | inptr
[8*5] | inptr
[8*6] | inptr
[8*7]) == 0)
528 /* AC terms all zero */
529 int dcval
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]) << PASS1_BITS
;
531 wsptr
[8*0] = wsptr
[8*1] = wsptr
[8*2] = wsptr
[8*3] = wsptr
[8*4]
532 = wsptr
[8*5] = wsptr
[8*6] = wsptr
[8*7] = dcval
;
533 inptr
++; /* advance pointers to next column */
539 /* Even part: reverse the even part of the forward DCT. */
540 /* The rotator is sqrt(2)*c(-6). */
542 z2
= DEQUANTIZE(inptr
[8*2], quantptr
[8*2]);
543 z3
= DEQUANTIZE(inptr
[8*6], quantptr
[8*6]);
545 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
546 tmp2
= z1
+ MULTIPLY16(z3
, - FIX_1_847759065
);
547 tmp3
= z1
+ MULTIPLY16(z2
, FIX_0_765366865
);
549 z2
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]);
550 z3
= DEQUANTIZE(inptr
[8*4], quantptr
[8*4]);
552 tmp0
= (z2
+ z3
) << CONST_BITS
;
553 tmp1
= (z2
- z3
) << CONST_BITS
;
560 /* Odd part per figure 8; the matrix is unitary and hence its
561 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
563 tmp0
= DEQUANTIZE(inptr
[8*7], quantptr
[8*7]);
564 tmp1
= DEQUANTIZE(inptr
[8*5], quantptr
[8*5]);
565 tmp2
= DEQUANTIZE(inptr
[8*3], quantptr
[8*3]);
566 tmp3
= DEQUANTIZE(inptr
[8*1], quantptr
[8*1]);
572 z5
= MULTIPLY16(z3
+ z4
, FIX_1_175875602
); /* sqrt(2) * c3 */
574 tmp0
= MULTIPLY16(tmp0
, FIX_0_298631336
); /* sqrt(2) * (-c1+c3+c5-c7) */
575 tmp1
= MULTIPLY16(tmp1
, FIX_2_053119869
); /* sqrt(2) * ( c1+c3-c5+c7) */
576 tmp2
= MULTIPLY16(tmp2
, FIX_3_072711026
); /* sqrt(2) * ( c1+c3+c5-c7) */
577 tmp3
= MULTIPLY16(tmp3
, FIX_1_501321110
); /* sqrt(2) * ( c1+c3-c5-c7) */
578 z1
= MULTIPLY16(z1
, - FIX_0_899976223
); /* sqrt(2) * (c7-c3) */
579 z2
= MULTIPLY16(z2
, - FIX_2_562915447
); /* sqrt(2) * (-c1-c3) */
580 z3
= MULTIPLY16(z3
, - FIX_1_961570560
); /* sqrt(2) * (-c3-c5) */
581 z4
= MULTIPLY16(z4
, - FIX_0_390180644
); /* sqrt(2) * (c5-c3) */
591 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
593 wsptr
[8*0] = (int) DESCALE(tmp10
+ tmp3
, CONST_BITS
-PASS1_BITS
);
594 wsptr
[8*7] = (int) DESCALE(tmp10
- tmp3
, CONST_BITS
-PASS1_BITS
);
595 wsptr
[8*1] = (int) DESCALE(tmp11
+ tmp2
, CONST_BITS
-PASS1_BITS
);
596 wsptr
[8*6] = (int) DESCALE(tmp11
- tmp2
, CONST_BITS
-PASS1_BITS
);
597 wsptr
[8*2] = (int) DESCALE(tmp12
+ tmp1
, CONST_BITS
-PASS1_BITS
);
598 wsptr
[8*5] = (int) DESCALE(tmp12
- tmp1
, CONST_BITS
-PASS1_BITS
);
599 wsptr
[8*3] = (int) DESCALE(tmp13
+ tmp0
, CONST_BITS
-PASS1_BITS
);
600 wsptr
[8*4] = (int) DESCALE(tmp13
- tmp0
, CONST_BITS
-PASS1_BITS
);
602 inptr
++; /* advance pointers to next column */
607 /* Pass 2: process rows from work array, store into output array. */
608 /* Note that we must descale the results by a factor of 8 == 2**3, */
609 /* and also undo the PASS1_BITS scaling. */
612 for (ctr
= 0; ctr
< 8; ctr
++)
614 outptr
= p_byte
+ (ctr
*skip_line
);
615 /* Rows of zeroes can be exploited in the same way as we did with columns.
616 * However, the column calculation has created many nonzero AC terms, so
617 * the simplification applies less often (typically 5% to 10% of the time).
618 * On machines with very fast multiplication, it's possible that the
619 * test takes more time than it's worth. In that case this section
620 * may be commented out.
623 #ifndef NO_ZERO_ROW_TEST
624 if ((wsptr
[1] | wsptr
[2] | wsptr
[3]
625 | wsptr
[4] | wsptr
[5] | wsptr
[6] | wsptr
[7]) == 0)
627 /* AC terms all zero */
628 unsigned char dcval
= range_limit((int) DESCALE((long) wsptr
[0],
640 wsptr
+= 8; /* advance pointer to next row */
645 /* Even part: reverse the even part of the forward DCT. */
646 /* The rotator is sqrt(2)*c(-6). */
648 z2
= (long) wsptr
[2];
649 z3
= (long) wsptr
[6];
651 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
652 tmp2
= z1
+ MULTIPLY16(z3
, - FIX_1_847759065
);
653 tmp3
= z1
+ MULTIPLY16(z2
, FIX_0_765366865
);
655 tmp0
= ((long) wsptr
[0] + (long) wsptr
[4]) << CONST_BITS
;
656 tmp1
= ((long) wsptr
[0] - (long) wsptr
[4]) << CONST_BITS
;
663 /* Odd part per figure 8; the matrix is unitary and hence its
664 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
666 tmp0
= (long) wsptr
[7];
667 tmp1
= (long) wsptr
[5];
668 tmp2
= (long) wsptr
[3];
669 tmp3
= (long) wsptr
[1];
675 z5
= MULTIPLY16(z3
+ z4
, FIX_1_175875602
); /* sqrt(2) * c3 */
677 tmp0
= MULTIPLY16(tmp0
, FIX_0_298631336
); /* sqrt(2) * (-c1+c3+c5-c7) */
678 tmp1
= MULTIPLY16(tmp1
, FIX_2_053119869
); /* sqrt(2) * ( c1+c3-c5+c7) */
679 tmp2
= MULTIPLY16(tmp2
, FIX_3_072711026
); /* sqrt(2) * ( c1+c3+c5-c7) */
680 tmp3
= MULTIPLY16(tmp3
, FIX_1_501321110
); /* sqrt(2) * ( c1+c3-c5-c7) */
681 z1
= MULTIPLY16(z1
, - FIX_0_899976223
); /* sqrt(2) * (c7-c3) */
682 z2
= MULTIPLY16(z2
, - FIX_2_562915447
); /* sqrt(2) * (-c1-c3) */
683 z3
= MULTIPLY16(z3
, - FIX_1_961570560
); /* sqrt(2) * (-c3-c5) */
684 z4
= MULTIPLY16(z4
, - FIX_0_390180644
); /* sqrt(2) * (c5-c3) */
694 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
696 outptr
[0] = range_limit((int) DESCALE(tmp10
+ tmp3
,
697 CONST_BITS
+PASS1_BITS
+3));
698 outptr
[7] = range_limit((int) DESCALE(tmp10
- tmp3
,
699 CONST_BITS
+PASS1_BITS
+3));
700 outptr
[1] = range_limit((int) DESCALE(tmp11
+ tmp2
,
701 CONST_BITS
+PASS1_BITS
+3));
702 outptr
[6] = range_limit((int) DESCALE(tmp11
- tmp2
,
703 CONST_BITS
+PASS1_BITS
+3));
704 outptr
[2] = range_limit((int) DESCALE(tmp12
+ tmp1
,
705 CONST_BITS
+PASS1_BITS
+3));
706 outptr
[5] = range_limit((int) DESCALE(tmp12
- tmp1
,
707 CONST_BITS
+PASS1_BITS
+3));
708 outptr
[3] = range_limit((int) DESCALE(tmp13
+ tmp0
,
709 CONST_BITS
+PASS1_BITS
+3));
710 outptr
[4] = range_limit((int) DESCALE(tmp13
- tmp0
,
711 CONST_BITS
+PASS1_BITS
+3));
713 wsptr
+= 8; /* advance pointer to next row */
719 /* JPEG decoder implementation */
722 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
726 /* Basic tables: (element [0] of each array is unused) */
727 long mincode
[17]; /* smallest code of length k */
728 long maxcode
[18]; /* largest code of length k (-1 if none) */
729 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
730 int valptr
[17]; /* huffval[] index of 1st symbol of length k */
732 /* Back link to public Huffman table (needed only in slow_DECODE) */
735 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
736 the input data stream. If the next Huffman code is no more
737 than HUFF_LOOKAHEAD bits long, we can obtain its length and
738 the corresponding symbol directly from these tables. */
739 int look_nbits
[1<<HUFF_LOOKAHEAD
]; /* # bits, or 0 if too long */
740 unsigned char look_sym
[1<<HUFF_LOOKAHEAD
]; /* symbol, or unused */
743 #define QUANT_TABLE_LENGTH 64
745 /* for type of Huffman table */
750 { /* length and code according to JFIF format */
751 int huffmancodes_dc
[DC_LEN
];
752 int huffmancodes_ac
[AC_LEN
];
755 struct frame_component
758 int horizontal_sampling
;
759 int vertical_sampling
;
760 int quanttable_select
;
763 struct scan_component
772 unsigned long get_buffer
; /* current bit-extraction buffer */
773 int bits_left
; /* # of unused bits in it */
774 unsigned char* next_input_byte
;
775 unsigned char* input_end
; /* upper limit +1 */
780 int x_size
, y_size
; /* size of image (can be less than block boundary) */
781 int x_phys
, y_phys
; /* physical size, block aligned */
782 int x_mbl
; /* x dimension of MBL */
783 int y_mbl
; /* y dimension of MBL */
784 int blocks
; /* blocks per MB */
785 int restart_interval
; /* number of MCUs between RSTm markers */
786 int store_pos
[4]; /* for Y block ordering */
788 unsigned char* p_entropy_data
;
789 unsigned char* p_entropy_end
;
791 int quanttable
[4][QUANT_TABLE_LENGTH
]; /* raw quantization tables 0-3 */
792 int qt_idct
[2][QUANT_TABLE_LENGTH
]; /* quantization tables for IDCT */
794 struct huffman_table hufftable
[2]; /* Huffman tables */
795 struct derived_tbl dc_derived_tbls
[2]; /* Huffman-LUTs */
796 struct derived_tbl ac_derived_tbls
[2];
798 struct frame_component frameheader
[3]; /* Component descriptor */
799 struct scan_component scanheader
[3]; /* currently not used */
801 int mcu_membership
[6]; /* info per block */
802 int tab_membership
[6];
803 int subsample_x
[3]; /* info per component */
808 /* possible return flags for process_markers() */
809 #define HUFFTAB 0x0001 /* with huffman table */
810 #define QUANTTAB 0x0002 /* with quantization table */
811 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
812 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
813 #define SOF0 0x0010 /* with SOF0-Segment */
814 #define DHT 0x0020 /* with Definition of huffman tables */
815 #define SOS 0x0040 /* with Start-of-Scan segment */
816 #define DQT 0x0080 /* with definition of quantization table */
818 /* Preprocess the JPEG JFIF file */
819 int process_markers(unsigned char* p_src
, long size
, struct jpeg
* p_jpeg
)
821 unsigned char* p_bytes
= p_src
;
822 int marker_size
; /* variable length of marker segment */
824 int ret
= 0; /* returned flags */
826 p_jpeg
->p_entropy_end
= p_src
+ size
;
828 while (p_src
< p_bytes
+ size
)
830 if (*p_src
++ != 0xFF) /* no marker? */
832 p_src
--; /* it's image data, put it back */
833 p_jpeg
->p_entropy_data
= p_src
;
834 break; /* exit marker processing */
839 case 0xFF: /* Fill byte */
841 case 0x00: /* Zero stuffed byte - entropy data */
842 p_src
--; /* put it back */
845 case 0xC0: /* SOF Huff - Baseline DCT */
848 marker_size
= *p_src
++ << 8; /* Highbyte */
849 marker_size
|= *p_src
++; /* Lowbyte */
850 n
= *p_src
++; /* sample precision (= 8 or 12) */
853 return(-1); /* Unsupported sample precision */
855 p_jpeg
->y_size
= *p_src
++ << 8; /* Highbyte */
856 p_jpeg
->y_size
|= *p_src
++; /* Lowbyte */
857 p_jpeg
->x_size
= *p_src
++ << 8; /* Highbyte */
858 p_jpeg
->x_size
|= *p_src
++; /* Lowbyte */
860 n
= (marker_size
-2-6)/3;
861 if (*p_src
++ != n
|| (n
!= 1 && n
!= 3))
863 return(-2); /* Unsupported SOF0 component specification */
867 p_jpeg
->frameheader
[i
].ID
= *p_src
++; /* Component info */
868 p_jpeg
->frameheader
[i
].horizontal_sampling
= *p_src
>> 4;
869 p_jpeg
->frameheader
[i
].vertical_sampling
= *p_src
++ & 0x0F;
870 p_jpeg
->frameheader
[i
].quanttable_select
= *p_src
++;
871 if (p_jpeg
->frameheader
[i
].horizontal_sampling
> 2
872 || p_jpeg
->frameheader
[i
].vertical_sampling
> 2)
873 return -3; /* Unsupported SOF0 subsampling */
879 case 0xC1: /* SOF Huff - Extended sequential DCT*/
880 case 0xC2: /* SOF Huff - Progressive DCT*/
881 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
882 case 0xC5: /* SOF Huff - Differential sequential DCT*/
883 case 0xC6: /* SOF Huff - Differential progressive DCT*/
884 case 0xC7: /* SOF Huff - Differential spatial*/
885 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
886 case 0xC9: /* SOF Arith - Extended sequential DCT*/
887 case 0xCA: /* SOF Arith - Progressive DCT*/
888 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
889 case 0xCD: /* SOF Arith - Differential sequential DCT*/
890 case 0xCE: /* SOF Arith - Differential progressive DCT*/
891 case 0xCF: /* SOF Arith - Differential spatial*/
893 return (-4); /* other DCT model than baseline not implemented */
896 case 0xC4: /* Define Huffman Table(s) */
898 unsigned char* p_temp
;
901 marker_size
= *p_src
++ << 8; /* Highbyte */
902 marker_size
|= *p_src
++; /* Lowbyte */
905 while (p_src
< p_temp
+marker_size
-2-17) /* another table */
908 i
= *p_src
& 0x0F; /* table index */
911 return (-5); /* Huffman table index out of range */
913 else if (*p_src
++ & 0xF0) /* AC table */
918 p_jpeg
->hufftable
[i
].huffmancodes_ac
[j
] = *p_src
++;
920 if(16 + sum
> AC_LEN
)
921 return -10; /* longer than allowed */
923 for (; j
< 16 + sum
; j
++)
924 p_jpeg
->hufftable
[i
].huffmancodes_ac
[j
] = *p_src
++;
931 p_jpeg
->hufftable
[i
].huffmancodes_dc
[j
] = *p_src
++;
933 if(16 + sum
> DC_LEN
)
934 return -11; /* longer than allowed */
936 for (; j
< 16 + sum
; j
++)
937 p_jpeg
->hufftable
[i
].huffmancodes_dc
[j
] = *p_src
++;
940 p_src
= p_temp
+marker_size
- 2; /* skip possible residue */
944 case 0xCC: /* Define Arithmetic coding conditioning(s) */
945 return(-6); /* Arithmetic coding not supported */
947 case 0xD8: /* Start of Image */
948 case 0xD9: /* End of Image */
949 case 0x01: /* for temp private use arith code */
950 break; /* skip parameterless marker */
953 case 0xDA: /* Start of Scan */
956 marker_size
= *p_src
++ << 8; /* Highbyte */
957 marker_size
|= *p_src
++; /* Lowbyte */
959 n
= (marker_size
-2-1-3)/2;
960 if (*p_src
++ != n
|| (n
!= 1 && n
!= 3))
962 return (-7); /* Unsupported SOS component specification */
966 p_jpeg
->scanheader
[i
].ID
= *p_src
++;
967 p_jpeg
->scanheader
[i
].DC_select
= *p_src
>> 4;
968 p_jpeg
->scanheader
[i
].AC_select
= *p_src
++ & 0x0F;
970 p_src
+= 3; /* skip spectral information */
974 case 0xDB: /* Define quantization Table(s) */
977 marker_size
= *p_src
++ << 8; /* Highbyte */
978 marker_size
|= *p_src
++; /* Lowbyte */
979 n
= (marker_size
-2)/(QUANT_TABLE_LENGTH
+1); /* # of tables */
982 int id
= *p_src
++; /* ID */
985 return (-8); /* Unsupported quantization table */
987 /* Read Quantisation table: */
988 for (j
=0; j
<QUANT_TABLE_LENGTH
; j
++)
989 p_jpeg
->quanttable
[id
][j
] = *p_src
++;
994 case 0xDD: /* Define Restart Interval */
996 marker_size
= *p_src
++ << 8; /* Highbyte */
997 marker_size
|= *p_src
++; /* Lowbyte */
998 p_jpeg
->restart_interval
= *p_src
++ << 8; /* Highbyte */
999 p_jpeg
->restart_interval
|= *p_src
++; /* Lowbyte */
1000 p_src
+= marker_size
-4; /* skip segment */
1004 case 0xDC: /* Define Number of Lines */
1005 case 0xDE: /* Define Hierarchical progression */
1006 case 0xDF: /* Expand Reference Component(s) */
1007 case 0xE0: /* Application Field 0*/
1008 case 0xE1: /* Application Field 1*/
1009 case 0xE2: /* Application Field 2*/
1010 case 0xE3: /* Application Field 3*/
1011 case 0xE4: /* Application Field 4*/
1012 case 0xE5: /* Application Field 5*/
1013 case 0xE6: /* Application Field 6*/
1014 case 0xE7: /* Application Field 7*/
1015 case 0xE8: /* Application Field 8*/
1016 case 0xE9: /* Application Field 9*/
1017 case 0xEA: /* Application Field 10*/
1018 case 0xEB: /* Application Field 11*/
1019 case 0xEC: /* Application Field 12*/
1020 case 0xED: /* Application Field 13*/
1021 case 0xEE: /* Application Field 14*/
1022 case 0xEF: /* Application Field 15*/
1023 case 0xFE: /* Comment */
1025 marker_size
= *p_src
++ << 8; /* Highbyte */
1026 marker_size
|= *p_src
++; /* Lowbyte */
1027 p_src
+= marker_size
-2; /* skip segment */
1031 case 0xF0: /* Reserved for JPEG extensions */
1032 case 0xF1: /* Reserved for JPEG extensions */
1033 case 0xF2: /* Reserved for JPEG extensions */
1034 case 0xF3: /* Reserved for JPEG extensions */
1035 case 0xF4: /* Reserved for JPEG extensions */
1036 case 0xF5: /* Reserved for JPEG extensions */
1037 case 0xF6: /* Reserved for JPEG extensions */
1038 case 0xF7: /* Reserved for JPEG extensions */
1039 case 0xF8: /* Reserved for JPEG extensions */
1040 case 0xF9: /* Reserved for JPEG extensions */
1041 case 0xFA: /* Reserved for JPEG extensions */
1042 case 0xFB: /* Reserved for JPEG extensions */
1043 case 0xFC: /* Reserved for JPEG extensions */
1044 case 0xFD: /* Reserved for JPEG extensions */
1045 case 0x02: /* Reserved */
1047 return (-9); /* Unknown marker */
1051 return (ret
); /* return flags with seen markers */
1055 void default_huff_tbl(struct jpeg
* p_jpeg
)
1057 static const struct huffman_table luma_table
=
1060 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
1061 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1064 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
1065 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
1066 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
1067 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
1068 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
1069 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1070 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1071 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
1072 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
1073 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
1074 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1079 static const struct huffman_table chroma_table
=
1082 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
1083 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
1086 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
1087 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
1088 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1089 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1090 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1091 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1092 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1093 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1094 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1095 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1096 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1101 MEMCPY(&p_jpeg
->hufftable
[0], &luma_table
, sizeof(luma_table
));
1102 MEMCPY(&p_jpeg
->hufftable
[1], &chroma_table
, sizeof(chroma_table
));
1107 /* Compute the derived values for a Huffman table */
1108 void fix_huff_tbl(int* htbl
, struct derived_tbl
* dtbl
)
1113 unsigned int huffcode
[257];
1116 dtbl
->pub
= htbl
; /* fill in back link */
1118 /* Figure C.1: make table of Huffman code length for each symbol */
1119 /* Note that this is in code-length order. */
1122 for (l
= 1; l
<= 16; l
++)
1123 { /* all possible code length */
1124 for (i
= 1; i
<= (int) htbl
[l
-1]; i
++) /* all codes per length */
1125 huffsize
[p
++] = (char) l
;
1129 /* Figure C.2: generate the codes themselves */
1130 /* Note that this is in code-length order. */
1137 while (((int) huffsize
[p
]) == si
)
1139 huffcode
[p
++] = code
;
1146 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1149 for (l
= 1; l
<= 16; l
++)
1153 dtbl
->valptr
[l
] = p
; /* huffval[] index of 1st symbol of code length l */
1154 dtbl
->mincode
[l
] = huffcode
[p
]; /* minimum code of length l */
1156 dtbl
->maxcode
[l
] = huffcode
[p
-1]; /* maximum code of length l */
1160 dtbl
->maxcode
[l
] = -1; /* -1 if no codes of this length */
1163 dtbl
->maxcode
[17] = 0xFFFFFL
; /* ensures huff_DECODE terminates */
1165 /* Compute lookahead tables to speed up decoding.
1166 * First we set all the table entries to 0, indicating "too long";
1167 * then we iterate through the Huffman codes that are short enough and
1168 * fill in all the entries that correspond to bit sequences starting
1172 MEMSET(dtbl
->look_nbits
, 0, sizeof(dtbl
->look_nbits
));
1175 for (l
= 1; l
<= HUFF_LOOKAHEAD
; l
++)
1177 for (i
= 1; i
<= (int) htbl
[l
-1]; i
++, p
++)
1179 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1180 /* Generate left-justified code followed by all possible bit sequences */
1181 lookbits
= huffcode
[p
] << (HUFF_LOOKAHEAD
-l
);
1182 for (ctr
= 1 << (HUFF_LOOKAHEAD
-l
); ctr
> 0; ctr
--)
1184 dtbl
->look_nbits
[lookbits
] = l
;
1185 dtbl
->look_sym
[lookbits
] = htbl
[16+p
];
1193 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1194 * If the incoming data is corrupted, decode_mcu could attempt to
1195 * reference values beyond the end of the array. To avoid a wild store,
1196 * we put some extra zeroes after the real entries.
1198 static const int zag
[] =
1200 0, 1, 8, 16, 9, 2, 3, 10,
1201 17, 24, 32, 25, 18, 11, 4, 5,
1202 12, 19, 26, 33, 40, 48, 41, 34,
1203 27, 20, 13, 6, 7, 14, 21, 28,
1204 35, 42, 49, 56, 57, 50, 43, 36,
1205 29, 22, 15, 23, 30, 37, 44, 51,
1206 58, 59, 52, 45, 38, 31, 39, 46,
1207 53, 60, 61, 54, 47, 55, 62, 63,
1208 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1209 0, 0, 0, 0, 0, 0, 0, 0
1212 void build_lut(struct jpeg
* p_jpeg
)
1215 fix_huff_tbl(p_jpeg
->hufftable
[0].huffmancodes_dc
,
1216 &p_jpeg
->dc_derived_tbls
[0]);
1217 fix_huff_tbl(p_jpeg
->hufftable
[0].huffmancodes_ac
,
1218 &p_jpeg
->ac_derived_tbls
[0]);
1219 fix_huff_tbl(p_jpeg
->hufftable
[1].huffmancodes_dc
,
1220 &p_jpeg
->dc_derived_tbls
[1]);
1221 fix_huff_tbl(p_jpeg
->hufftable
[1].huffmancodes_ac
,
1222 &p_jpeg
->ac_derived_tbls
[1]);
1224 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1225 for (i
=0; i
<64; i
++)
1227 p_jpeg
->qt_idct
[0][zag
[i
]] = p_jpeg
->quanttable
[0][i
];
1228 p_jpeg
->qt_idct
[1][zag
[i
]] = p_jpeg
->quanttable
[1][i
];
1232 p_jpeg
->store_pos
[i
] = i
; /* default ordering */
1234 /* assignments for the decoding of blocks */
1235 if (p_jpeg
->frameheader
[0].horizontal_sampling
== 2
1236 && p_jpeg
->frameheader
[0].vertical_sampling
== 1)
1239 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+15) / 16;
1240 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 16;
1241 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+7) / 8;
1242 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 8;
1243 p_jpeg
->mcu_membership
[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1244 p_jpeg
->mcu_membership
[1] = 0;
1245 p_jpeg
->mcu_membership
[2] = 1;
1246 p_jpeg
->mcu_membership
[3] = 2;
1247 p_jpeg
->tab_membership
[0] = 0; /* DC, DC, AC, AC */
1248 p_jpeg
->tab_membership
[1] = 0;
1249 p_jpeg
->tab_membership
[2] = 1;
1250 p_jpeg
->tab_membership
[3] = 1;
1251 p_jpeg
->subsample_x
[0] = 1;
1252 p_jpeg
->subsample_x
[1] = 2;
1253 p_jpeg
->subsample_x
[2] = 2;
1254 p_jpeg
->subsample_y
[0] = 1;
1255 p_jpeg
->subsample_y
[1] = 1;
1256 p_jpeg
->subsample_y
[2] = 1;
1258 if (p_jpeg
->frameheader
[0].horizontal_sampling
== 1
1259 && p_jpeg
->frameheader
[0].vertical_sampling
== 2)
1260 { /* 4:2:2 vertically subsampled */
1261 p_jpeg
->store_pos
[1] = 2; /* block positions are mirrored */
1262 p_jpeg
->store_pos
[2] = 1;
1264 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+7) / 8;
1265 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 8;
1266 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+15) / 16;
1267 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 16;
1268 p_jpeg
->mcu_membership
[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1269 p_jpeg
->mcu_membership
[1] = 0;
1270 p_jpeg
->mcu_membership
[2] = 1;
1271 p_jpeg
->mcu_membership
[3] = 2;
1272 p_jpeg
->tab_membership
[0] = 0; /* DC, DC, AC, AC */
1273 p_jpeg
->tab_membership
[1] = 0;
1274 p_jpeg
->tab_membership
[2] = 1;
1275 p_jpeg
->tab_membership
[3] = 1;
1276 p_jpeg
->subsample_x
[0] = 1;
1277 p_jpeg
->subsample_x
[1] = 1;
1278 p_jpeg
->subsample_x
[2] = 1;
1279 p_jpeg
->subsample_y
[0] = 1;
1280 p_jpeg
->subsample_y
[1] = 2;
1281 p_jpeg
->subsample_y
[2] = 2;
1283 else if (p_jpeg
->frameheader
[0].horizontal_sampling
== 2
1284 && p_jpeg
->frameheader
[0].vertical_sampling
== 2)
1287 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+15) / 16;
1288 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 16;
1289 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+15) / 16;
1290 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 16;
1291 p_jpeg
->mcu_membership
[0] = 0;
1292 p_jpeg
->mcu_membership
[1] = 0;
1293 p_jpeg
->mcu_membership
[2] = 0;
1294 p_jpeg
->mcu_membership
[3] = 0;
1295 p_jpeg
->mcu_membership
[4] = 1;
1296 p_jpeg
->mcu_membership
[5] = 2;
1297 p_jpeg
->tab_membership
[0] = 0;
1298 p_jpeg
->tab_membership
[1] = 0;
1299 p_jpeg
->tab_membership
[2] = 0;
1300 p_jpeg
->tab_membership
[3] = 0;
1301 p_jpeg
->tab_membership
[4] = 1;
1302 p_jpeg
->tab_membership
[5] = 1;
1303 p_jpeg
->subsample_x
[0] = 1;
1304 p_jpeg
->subsample_x
[1] = 2;
1305 p_jpeg
->subsample_x
[2] = 2;
1306 p_jpeg
->subsample_y
[0] = 1;
1307 p_jpeg
->subsample_y
[1] = 2;
1308 p_jpeg
->subsample_y
[2] = 2;
1310 else if (p_jpeg
->frameheader
[0].horizontal_sampling
== 1
1311 && p_jpeg
->frameheader
[0].vertical_sampling
== 1)
1313 /* don't overwrite p_jpeg->blocks */
1314 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+7) / 8;
1315 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 8;
1316 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+7) / 8;
1317 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 8;
1318 p_jpeg
->mcu_membership
[0] = 0;
1319 p_jpeg
->mcu_membership
[1] = 1;
1320 p_jpeg
->mcu_membership
[2] = 2;
1321 p_jpeg
->tab_membership
[0] = 0;
1322 p_jpeg
->tab_membership
[1] = 1;
1323 p_jpeg
->tab_membership
[2] = 1;
1324 p_jpeg
->subsample_x
[0] = 1;
1325 p_jpeg
->subsample_x
[1] = 1;
1326 p_jpeg
->subsample_x
[2] = 1;
1327 p_jpeg
->subsample_y
[0] = 1;
1328 p_jpeg
->subsample_y
[1] = 1;
1329 p_jpeg
->subsample_y
[2] = 1;
1340 * These functions/macros provide the in-line portion of bit fetching.
1341 * Use check_bit_buffer to ensure there are N bits in get_buffer
1342 * before using get_bits, peek_bits, or drop_bits.
1343 * check_bit_buffer(state,n,action);
1344 * Ensure there are N bits in get_buffer; if suspend, take action.
1345 * val = get_bits(n);
1346 * Fetch next N bits.
1347 * val = peek_bits(n);
1348 * Fetch next N bits without removing them from the buffer.
1350 * Discard next N bits.
1351 * The value N should be a simple variable, not an expression, because it
1352 * is evaluated multiple times.
1355 INLINE
void check_bit_buffer(struct bitstream
* pb
, int nbits
)
1357 if (pb
->bits_left
< nbits
)
1358 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1361 byte
= *pb
->next_input_byte
++;
1362 if (byte
== 0xFF) /* legal marker can be byte stuffing or RSTm */
1363 { /* simplification: just skip the (one-byte) marker code */
1364 pb
->next_input_byte
++;
1366 pb
->get_buffer
= (pb
->get_buffer
<< 8) | byte
;
1368 byte
= *pb
->next_input_byte
++;
1369 if (byte
== 0xFF) /* legal marker can be byte stuffing or RSTm */
1370 { /* simplification: just skip the (one-byte) marker code */
1371 pb
->next_input_byte
++;
1373 pb
->get_buffer
= (pb
->get_buffer
<< 8) | byte
;
1375 pb
->bits_left
+= 16;
1379 INLINE
int get_bits(struct bitstream
* pb
, int nbits
)
1381 return ((int) (pb
->get_buffer
>> (pb
->bits_left
-= nbits
))) & ((1<<nbits
)-1);
1384 INLINE
int peek_bits(struct bitstream
* pb
, int nbits
)
1386 return ((int) (pb
->get_buffer
>> (pb
->bits_left
- nbits
))) & ((1<<nbits
)-1);
1389 INLINE
void drop_bits(struct bitstream
* pb
, int nbits
)
1391 pb
->bits_left
-= nbits
;
1394 /* re-synchronize to entropy data (skip restart marker) */
1395 void search_restart(struct bitstream
* pb
)
1397 pb
->next_input_byte
--; /* we may have overread it, taking 2 bytes */
1398 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1399 while (pb
->next_input_byte
< pb
->input_end
&&
1400 (pb
->next_input_byte
[-2] != 0xFF || pb
->next_input_byte
[-1] == 0x00))
1402 pb
->next_input_byte
++;
1407 /* Figure F.12: extend sign bit. */
1408 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1410 static const int extend_test
[16] = /* entry n is 2**(n-1) */
1412 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1413 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1416 static const int extend_offset
[16] = /* entry n is (-1 << n) + 1 */
1418 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1419 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1420 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1421 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1424 /* Decode a single value */
1425 INLINE
int huff_decode_dc(struct bitstream
* bs
, struct derived_tbl
* tbl
)
1429 check_bit_buffer(bs
, HUFF_LOOKAHEAD
);
1430 look
= peek_bits(bs
, HUFF_LOOKAHEAD
);
1431 if ((nb
= tbl
->look_nbits
[look
]) != 0)
1434 s
= tbl
->look_sym
[look
];
1435 check_bit_buffer(bs
, s
);
1436 r
= get_bits(bs
, s
);
1437 s
= HUFF_EXTEND(r
, s
);
1440 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1442 nb
=HUFF_LOOKAHEAD
+1;
1443 check_bit_buffer(bs
, nb
);
1444 code
= get_bits(bs
, nb
);
1445 while (code
> tbl
->maxcode
[nb
])
1448 check_bit_buffer(bs
, 1);
1449 code
|= get_bits(bs
, 1);
1452 if (nb
> 16) /* error in Huffman */
1454 s
=0; /* fake a zero, this is most safe */
1458 s
= tbl
->pub
[16 + tbl
->valptr
[nb
] + ((int) (code
- tbl
->mincode
[nb
])) ];
1459 check_bit_buffer(bs
, s
);
1460 r
= get_bits(bs
, s
);
1461 s
= HUFF_EXTEND(r
, s
);
1463 } /* end slow decode */
1467 INLINE
int huff_decode_ac(struct bitstream
* bs
, struct derived_tbl
* tbl
)
1471 check_bit_buffer(bs
, HUFF_LOOKAHEAD
);
1472 look
= peek_bits(bs
, HUFF_LOOKAHEAD
);
1473 if ((nb
= tbl
->look_nbits
[look
]) != 0)
1476 s
= tbl
->look_sym
[look
];
1479 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1481 nb
=HUFF_LOOKAHEAD
+1;
1482 check_bit_buffer(bs
, nb
);
1483 code
= get_bits(bs
, nb
);
1484 while (code
> tbl
->maxcode
[nb
])
1487 check_bit_buffer(bs
, 1);
1488 code
|= get_bits(bs
, 1);
1491 if (nb
> 16) /* error in Huffman */
1493 s
=0; /* fake a zero, this is most safe */
1497 s
= tbl
->pub
[16 + tbl
->valptr
[nb
] + ((int) (code
- tbl
->mincode
[nb
])) ];
1499 } /* end slow decode */
1504 #ifdef HAVE_LCD_COLOR
1506 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1507 /* Note: it keeps the original color subsampling, even if resized. */
1508 int jpeg_decode(struct jpeg
* p_jpeg
, unsigned char* p_pixel
[3],
1509 int downscale
, void (*pf_progress
)(int current
, int total
))
1511 struct bitstream bs
; /* bitstream "object" */
1512 int block
[64]; /* decoded DCT coefficients */
1515 int skip_line
[3]; /* bytes from one line to the next (skip_line) */
1516 int skip_strip
[3], skip_mcu
[3]; /* bytes to next DCT row / column */
1518 int i
, x
, y
; /* loop counter */
1520 unsigned char* p_line
[3] = {p_pixel
[0], p_pixel
[1], p_pixel
[2]};
1521 unsigned char* p_byte
[3]; /* bitmap pointer */
1523 void (*pf_idct
)(unsigned char*, int*, int*, int); /* selected IDCT */
1524 int k_need
; /* AC coefficients needed up to here */
1525 int zero_need
; /* init the block with this many zeros */
1527 int last_dc_val
[3] = {0, 0, 0}; /* or 128 for chroma? */
1528 int store_offs
[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1529 int restart
= p_jpeg
->restart_interval
; /* MCUs until restart marker */
1531 /* pick the IDCT we want, determine how to work with coefs */
1535 k_need
= 64; /* all */
1536 zero_need
= 63; /* all */
1538 else if (downscale
== 2)
1541 k_need
= 25; /* this far in zig-zag to cover 4*4 */
1542 zero_need
= 27; /* clear this far in linear order */
1544 else if (downscale
== 4)
1547 k_need
= 5; /* this far in zig-zag to cover 2*2 */
1548 zero_need
= 9; /* clear this far in linear order */
1550 else if (downscale
== 8)
1553 k_need
= 0; /* no AC, not needed */
1554 zero_need
= 0; /* no AC, not needed */
1556 else return -1; /* not supported */
1558 /* init bitstream, fake a restart to make it start */
1559 bs
.next_input_byte
= p_jpeg
->p_entropy_data
;
1561 bs
.input_end
= p_jpeg
->p_entropy_end
;
1563 width
= p_jpeg
->x_phys
/ downscale
;
1564 height
= p_jpeg
->y_phys
/ downscale
;
1565 for (i
=0; i
<3; i
++) /* calculate some strides */
1567 skip_line
[i
] = width
/ p_jpeg
->subsample_x
[i
];
1568 skip_strip
[i
] = skip_line
[i
]
1569 * (height
/ p_jpeg
->y_mbl
) / p_jpeg
->subsample_y
[i
];
1570 skip_mcu
[i
] = width
/p_jpeg
->x_mbl
/ p_jpeg
->subsample_x
[i
];
1573 /* prepare offsets about where to store the different blocks */
1574 store_offs
[p_jpeg
->store_pos
[0]] = 0;
1575 store_offs
[p_jpeg
->store_pos
[1]] = 8 / downscale
; /* to the right */
1576 store_offs
[p_jpeg
->store_pos
[2]] = width
* 8 / downscale
; /* below */
1577 store_offs
[p_jpeg
->store_pos
[3]] = store_offs
[1] + store_offs
[2]; /* r+b */
1579 for(y
=0; y
<p_jpeg
->y_mbl
&& bs
.next_input_byte
<= bs
.input_end
; y
++)
1581 for (i
=0; i
<3; i
++) /* scan line init */
1583 p_byte
[i
] = p_line
[i
];
1584 p_line
[i
] += skip_strip
[i
];
1586 for (x
=0; x
<p_jpeg
->x_mbl
; x
++)
1590 /* Outer loop handles each block in the MCU */
1591 for (blkn
= 0; blkn
< p_jpeg
->blocks
; blkn
++)
1592 { /* Decode a single block's worth of coefficients */
1593 int k
= 1; /* coefficient index */
1594 int s
, r
; /* huffman values */
1595 int ci
= p_jpeg
->mcu_membership
[blkn
]; /* component index */
1596 int ti
= p_jpeg
->tab_membership
[blkn
]; /* table index */
1597 struct derived_tbl
* dctbl
= &p_jpeg
->dc_derived_tbls
[ti
];
1598 struct derived_tbl
* actbl
= &p_jpeg
->ac_derived_tbls
[ti
];
1600 /* Section F.2.2.1: decode the DC coefficient difference */
1601 s
= huff_decode_dc(&bs
, dctbl
);
1603 last_dc_val
[ci
] += s
;
1604 block
[0] = last_dc_val
[ci
]; /* output it (assumes zag[0] = 0) */
1606 /* coefficient buffer must be cleared */
1607 MEMSET(block
+1, 0, zero_need
*sizeof(block
[0]));
1609 /* Section F.2.2.2: decode the AC coefficients */
1610 for (; k
< k_need
; k
++)
1612 s
= huff_decode_ac(&bs
, actbl
);
1619 check_bit_buffer(&bs
, s
);
1620 r
= get_bits(&bs
, s
);
1621 block
[zag
[k
]] = HUFF_EXTEND(r
, s
);
1633 /* In this path we just discard the values */
1636 s
= huff_decode_ac(&bs
, actbl
);
1643 check_bit_buffer(&bs
, s
);
1655 { /* Y component needs to bother about block store */
1656 pf_idct(p_byte
[0]+store_offs
[blkn
], block
,
1657 p_jpeg
->qt_idct
[ti
], skip_line
[0]);
1661 pf_idct(p_byte
[ci
], block
, p_jpeg
->qt_idct
[ti
],
1665 p_byte
[0] += skip_mcu
[0]; /* unrolled for (i=0; i<3; i++) loop */
1666 p_byte
[1] += skip_mcu
[1];
1667 p_byte
[2] += skip_mcu
[2];
1668 if (p_jpeg
->restart_interval
&& --restart
== 0)
1669 { /* if a restart marker is due: */
1670 restart
= p_jpeg
->restart_interval
; /* count again */
1671 search_restart(&bs
); /* align the bitstream */
1672 last_dc_val
[0] = last_dc_val
[1] =
1673 last_dc_val
[2] = 0; /* reset decoder */
1676 if (pf_progress
!= NULL
)
1677 pf_progress(y
, p_jpeg
->y_mbl
-1); /* notify about decoding progress */
1680 return 0; /* success */
1682 #else /* !HAVE_LCD_COLOR */
1684 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1685 int jpeg_decode(struct jpeg
* p_jpeg
, unsigned char* p_pixel
[1], int downscale
,
1686 void (*pf_progress
)(int current
, int total
))
1688 struct bitstream bs
; /* bitstream "object" */
1689 int block
[64]; /* decoded DCT coefficients */
1692 int skip_line
; /* bytes from one line to the next (skip_line) */
1693 int skip_strip
, skip_mcu
; /* bytes to next DCT row / column */
1695 int x
, y
; /* loop counter */
1697 unsigned char* p_line
= p_pixel
[0];
1698 unsigned char* p_byte
; /* bitmap pointer */
1700 void (*pf_idct
)(unsigned char*, int*, int*, int); /* selected IDCT */
1701 int k_need
; /* AC coefficients needed up to here */
1702 int zero_need
; /* init the block with this many zeros */
1704 int last_dc_val
= 0;
1705 int store_offs
[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1706 int restart
= p_jpeg
->restart_interval
; /* MCUs until restart marker */
1708 /* pick the IDCT we want, determine how to work with coefs */
1712 k_need
= 64; /* all */
1713 zero_need
= 63; /* all */
1715 else if (downscale
== 2)
1718 k_need
= 25; /* this far in zig-zag to cover 4*4 */
1719 zero_need
= 27; /* clear this far in linear order */
1721 else if (downscale
== 4)
1724 k_need
= 5; /* this far in zig-zag to cover 2*2 */
1725 zero_need
= 9; /* clear this far in linear order */
1727 else if (downscale
== 8)
1730 k_need
= 0; /* no AC, not needed */
1731 zero_need
= 0; /* no AC, not needed */
1733 else return -1; /* not supported */
1735 /* init bitstream, fake a restart to make it start */
1736 bs
.next_input_byte
= p_jpeg
->p_entropy_data
;
1738 bs
.input_end
= p_jpeg
->p_entropy_end
;
1740 width
= p_jpeg
->x_phys
/ downscale
;
1741 height
= p_jpeg
->y_phys
/ downscale
;
1743 skip_strip
= skip_line
* (height
/ p_jpeg
->y_mbl
);
1744 skip_mcu
= (width
/p_jpeg
->x_mbl
);
1746 /* prepare offsets about where to store the different blocks */
1747 store_offs
[p_jpeg
->store_pos
[0]] = 0;
1748 store_offs
[p_jpeg
->store_pos
[1]] = 8 / downscale
; /* to the right */
1749 store_offs
[p_jpeg
->store_pos
[2]] = width
* 8 / downscale
; /* below */
1750 store_offs
[p_jpeg
->store_pos
[3]] = store_offs
[1] + store_offs
[2]; /* r+b */
1752 for(y
=0; y
<p_jpeg
->y_mbl
&& bs
.next_input_byte
<= bs
.input_end
; y
++)
1755 p_line
+= skip_strip
;
1756 for (x
=0; x
<p_jpeg
->x_mbl
; x
++)
1760 /* Outer loop handles each block in the MCU */
1761 for (blkn
= 0; blkn
< p_jpeg
->blocks
; blkn
++)
1762 { /* Decode a single block's worth of coefficients */
1763 int k
= 1; /* coefficient index */
1764 int s
, r
; /* huffman values */
1765 int ci
= p_jpeg
->mcu_membership
[blkn
]; /* component index */
1766 int ti
= p_jpeg
->tab_membership
[blkn
]; /* table index */
1767 struct derived_tbl
* dctbl
= &p_jpeg
->dc_derived_tbls
[ti
];
1768 struct derived_tbl
* actbl
= &p_jpeg
->ac_derived_tbls
[ti
];
1770 /* Section F.2.2.1: decode the DC coefficient difference */
1771 s
= huff_decode_dc(&bs
, dctbl
);
1773 if (ci
== 0) /* only for Y component */
1776 block
[0] = last_dc_val
; /* output it (assumes zag[0] = 0) */
1778 /* coefficient buffer must be cleared */
1779 MEMSET(block
+1, 0, zero_need
*sizeof(block
[0]));
1781 /* Section F.2.2.2: decode the AC coefficients */
1782 for (; k
< k_need
; k
++)
1784 s
= huff_decode_ac(&bs
, actbl
);
1791 check_bit_buffer(&bs
, s
);
1792 r
= get_bits(&bs
, s
);
1793 block
[zag
[k
]] = HUFF_EXTEND(r
, s
);
1806 /* In this path we just discard the values */
1809 s
= huff_decode_ac(&bs
, actbl
);
1816 check_bit_buffer(&bs
, s
);
1828 { /* only for Y component */
1829 pf_idct(p_byte
+store_offs
[blkn
], block
, p_jpeg
->qt_idct
[ti
],
1834 if (p_jpeg
->restart_interval
&& --restart
== 0)
1835 { /* if a restart marker is due: */
1836 restart
= p_jpeg
->restart_interval
; /* count again */
1837 search_restart(&bs
); /* align the bitstream */
1838 last_dc_val
= 0; /* reset decoder */
1841 if (pf_progress
!= NULL
)
1842 pf_progress(y
, p_jpeg
->y_mbl
-1); /* notify about decoding progress */
1845 return 0; /* success */
1847 #endif /* !HAVE_LCD_COLOR */
1849 /**************** end JPEG code ********************/
1853 /**************** begin Application ********************/
1856 /************************* Types ***************************/
1860 #ifdef HAVE_LCD_COLOR
1861 unsigned char* bitmap
[3]; /* Y, Cr, Cb */
1864 unsigned char* bitmap
[1]; /* Y only */
1872 /************************* Globals ***************************/
1874 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1875 struct t_disp disp
[9];
1877 /* my memory pool (from the mp3 buffer) */
1878 char print
[32]; /* use a common snprintf() buffer */
1879 unsigned char* buf
; /* up to here currently used by image(s) */
1881 /* the remaining free part of the buffer for compressed+uncompressed images */
1882 unsigned char* buf_images
;
1884 ssize_t buf_size
, buf_images_size
;
1885 /* the root of the images, hereafter are decompresed ones */
1886 unsigned char* buf_root
;
1889 int ds
, ds_min
, ds_max
; /* downscaling and limits */
1890 static struct jpeg jpg
; /* too large for stack */
1892 static struct tree_context
*tree
;
1894 /* the current full file name */
1895 static char np_file
[MAX_PATH
];
1896 int curfile
= 0, direction
= DIR_NONE
, entries
= 0;
1898 /* list of the jpeg files */
1900 /* are we using the plugin buffer or the audio buffer? */
1901 bool plug_buf
= false;
1904 /************************* Implementation ***************************/
1906 #ifdef HAVE_LCD_COLOR
1908 * Conversion of full 0-255 range YCrCb to RGB:
1909 * |R| |1.000000 -0.000001 1.402000| |Y'|
1910 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
1911 * |B| |1.000000 1.772000 0.000000| |Pr|
1912 * Scaled (yields s15-bit output):
1913 * |R| |128 0 179| |Y |
1914 * |G| = |128 -43 -91| |Cb - 128|
1915 * |B| |128 227 0| |Cr - 128|
1922 #define YUV_WHITE (255*YFAC)
1923 #define NODITHER_DELTA (127*YFAC)
1924 #define COMPONENT_SHIFT 15
1925 #define MATRIX_SHIFT 7
1927 static inline int clamp_component(int x
)
1929 if ((unsigned)x
> YUV_WHITE
)
1930 x
= x
< 0 ? 0 : YUV_WHITE
;
1934 static inline int clamp_component_bits(int x
, int bits
)
1936 if ((unsigned)x
> (1u << bits
) - 1)
1937 x
= x
< 0 ? 0 : (1 << bits
) - 1;
1941 static inline int component_to_lcd(int x
, int bits
, int delta
)
1943 /* Formula used in core bitmap loader. */
1944 return (((1 << bits
) - 1)*x
+ (x
>> (8 - bits
)) + delta
) >> COMPONENT_SHIFT
;
1947 static inline int lcd_to_component(int x
, int bits
, int delta
)
1949 /* Reasonable, approximate reversal to get a full range back from the
1951 return YUV_WHITE
*x
/ ((1 << bits
) - 1);
1961 int16_t errbuf
[LCD_WIDTH
+2]; /* Error record for line below */
1962 } rgb_err_buffers
[3];
1964 fb_data rgb_linebuf
[LCD_WIDTH
]; /* Line buffer for scrolling when
1965 DITHER_DIFFUSION is set */
1969 int r
, g
, b
; /* Current pixel components in s16.0 */
1970 int inc
; /* Current line increment (-1 or 1) */
1971 int row
; /* Current row in source image */
1972 int col
; /* Current column in source image */
1973 int ce
[3]; /* Errors to apply to current pixel */
1974 struct rgb_err
*e
; /* RED, GRN, BLU */
1975 int epos
; /* Current position in error record */
1978 struct rgb_pixel
*pixel
;
1980 /** round and truncate to lcd depth **/
1981 static fb_data
pixel_to_lcd_colour(void)
1983 struct rgb_pixel
*p
= pixel
;
1986 r
= component_to_lcd(p
->r
, LCD_RED_BITS
, NODITHER_DELTA
);
1987 r
= clamp_component_bits(r
, LCD_RED_BITS
);
1989 g
= component_to_lcd(p
->g
, LCD_GREEN_BITS
, NODITHER_DELTA
);
1990 g
= clamp_component_bits(g
, LCD_GREEN_BITS
);
1992 b
= component_to_lcd(p
->b
, LCD_BLUE_BITS
, NODITHER_DELTA
);
1993 b
= clamp_component_bits(b
, LCD_BLUE_BITS
);
1995 return LCD_RGBPACK_LCD(r
, g
, b
);
1998 /** write a monochrome pixel to the colour LCD **/
1999 static fb_data
pixel_to_lcd_gray(void)
2003 g
= clamp_component(pixel
->g
);
2004 r
= component_to_lcd(g
, LCD_RED_BITS
, NODITHER_DELTA
);
2005 b
= component_to_lcd(g
, LCD_BLUE_BITS
, NODITHER_DELTA
);
2006 g
= component_to_lcd(g
, LCD_GREEN_BITS
, NODITHER_DELTA
);
2008 return LCD_RGBPACK_LCD(r
, g
, b
);
2012 * Bayer ordered dithering - swiped from the core bitmap loader.
2014 static fb_data
pixel_odither_to_lcd(void)
2016 /* canonical ordered dither matrix */
2017 static const unsigned char dither_matrix
[16][16] = {
2018 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
2019 { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
2020 { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
2021 { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
2022 { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
2023 { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
2024 { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
2025 { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
2026 { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
2027 { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
2028 { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
2029 { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
2030 { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
2031 { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
2032 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
2033 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
2036 struct rgb_pixel
*p
= pixel
;
2039 delta
= dither_matrix
[p
->col
& 15][p
->row
& 15] << MATRIX_SHIFT
;
2041 r
= component_to_lcd(p
->r
, LCD_RED_BITS
, delta
);
2042 r
= clamp_component_bits(r
, LCD_RED_BITS
);
2044 g
= component_to_lcd(p
->g
, LCD_GREEN_BITS
, delta
);
2045 g
= clamp_component_bits(g
, LCD_GREEN_BITS
);
2047 b
= component_to_lcd(p
->b
, LCD_BLUE_BITS
, delta
);
2048 b
= clamp_component_bits(b
, LCD_BLUE_BITS
);
2052 return LCD_RGBPACK_LCD(r
, g
, b
);
2056 * Floyd/Steinberg dither to lcd depth.
2058 * Apply filter to each component in serpentine pattern. Kernel shown for
2059 * L->R scan. Kernel is reversed for R->L.
2063 static inline void distribute_error(int *ce
, struct rgb_err
*e
,
2064 int err
, int epos
, int inc
)
2066 *ce
= (7*err
>> 4) + e
->errbuf
[epos
+inc
];
2067 e
->errbuf
[epos
+inc
] = err
>> 4;
2068 e
->errbuf
[epos
] += 5*err
>> 4;
2069 e
->errbuf
[epos
-inc
] += 3*err
>> 4;
2072 static fb_data
pixel_fsdither_to_lcd(void)
2074 struct rgb_pixel
*p
= pixel
;
2075 int rc
, gc
, bc
, r
, g
, b
;
2078 /* Full components with error terms */
2079 rc
= p
->r
+ p
->ce
[RED
];
2080 r
= component_to_lcd(rc
, LCD_RED_BITS
, 0);
2081 r
= clamp_component_bits(r
, LCD_RED_BITS
);
2083 gc
= p
->g
+ p
->ce
[GRN
];
2084 g
= component_to_lcd(gc
, LCD_GREEN_BITS
, 0);
2085 g
= clamp_component_bits(g
, LCD_GREEN_BITS
);
2087 bc
= p
->b
+ p
->ce
[BLU
];
2088 b
= component_to_lcd(bc
, LCD_BLUE_BITS
, 0);
2089 b
= clamp_component_bits(b
, LCD_BLUE_BITS
);
2091 /* Get pixel errors */
2092 rc
-= lcd_to_component(r
, LCD_RED_BITS
, 0);
2093 gc
-= lcd_to_component(g
, LCD_GREEN_BITS
, 0);
2094 bc
-= lcd_to_component(b
, LCD_BLUE_BITS
, 0);
2096 /* Spead error to surrounding pixels. */
2101 distribute_error(&p
->ce
[RED
], &p
->e
[RED
], rc
, epos
, inc
);
2102 distribute_error(&p
->ce
[GRN
], &p
->e
[GRN
], gc
, epos
, inc
);
2103 distribute_error(&p
->ce
[BLU
], &p
->e
[BLU
], bc
, epos
, inc
);
2105 /* Pack and return pixel */
2106 return LCD_RGBPACK_LCD(r
, g
, b
);
2109 /* Functions for each output mode, colour then grayscale. */
2110 static fb_data (* const pixel_funcs
[COLOUR_NUM_MODES
][DITHER_NUM_MODES
])(void) =
2112 [COLOURMODE_COLOUR
] =
2114 [DITHER_NONE
] = pixel_to_lcd_colour
,
2115 [DITHER_ORDERED
] = pixel_odither_to_lcd
,
2116 [DITHER_DIFFUSION
] = pixel_fsdither_to_lcd
,
2120 [DITHER_NONE
] = pixel_to_lcd_gray
,
2121 [DITHER_ORDERED
] = pixel_odither_to_lcd
,
2122 [DITHER_DIFFUSION
] = pixel_fsdither_to_lcd
,
2127 * Draw a partial YUV colour bitmap
2129 * Runs serpentine pattern when dithering is DITHER_DIFFUSION, else scan is
2132 void yuv_bitmap_part(unsigned char *src
[3], int csub_x
, int csub_y
,
2133 int src_x
, int src_y
, int stride
,
2134 int x
, int y
, int width
, int height
)
2136 fb_data
*dst
, *dst_end
;
2137 fb_data (*pixel_func
)(void);
2138 struct rgb_pixel px
;
2140 if (x
+ width
> LCD_WIDTH
)
2141 width
= LCD_WIDTH
- x
; /* Clip right */
2143 width
+= x
, x
= 0; /* Clip left */
2145 return; /* nothing left to do */
2147 if (y
+ height
> LCD_HEIGHT
)
2148 height
= LCD_HEIGHT
- y
; /* Clip bottom */
2150 height
+= y
, y
= 0; /* Clip top */
2152 return; /* nothing left to do */
2156 dst
= rb
->lcd_framebuffer
+ LCD_WIDTH
* y
+ x
;
2157 dst_end
= dst
+ LCD_WIDTH
* height
;
2159 if (jpeg_settings
.colour_mode
== COLOURMODE_GRAY
)
2160 csub_y
= 0; /* Ignore Cb, Cr */
2162 pixel_func
= pixel_funcs
[jpeg_settings
.colour_mode
]
2163 [jpeg_settings
.dither_mode
];
2165 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2167 /* Reset error terms. */
2168 px
.e
= rgb_err_buffers
;
2169 px
.ce
[RED
] = px
.ce
[GRN
] = px
.ce
[BLU
] = 0;
2170 rb
->memset(px
.e
, 0, 3*sizeof (struct rgb_err
));
2175 fb_data
*dst_row
, *row_end
;
2176 const unsigned char *ysrc
;
2179 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2181 /* Use R->L scan on odd lines */
2182 px
.inc
-= (src_y
& 1) << 1;
2186 px
.epos
+= width
- 1;
2193 row_end
= dst_row
+ width
;
2200 dst_row
= row_end
+ width
;
2201 px
.col
= src_x
+ width
- 1;
2204 ysrc
= src
[0] + stride
* src_y
+ px
.col
;
2207 /* Do one row of pixels */
2208 if (csub_y
) /* colour */
2210 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
2211 const unsigned char *usrc
, *vsrc
;
2213 usrc
= src
[1] + (stride
/csub_x
) * (src_y
/csub_y
)
2215 vsrc
= src
[2] + (stride
/csub_x
) * (src_y
/csub_y
)
2217 int xphase
= px
.col
% csub_x
;
2218 int xphase_reset
= px
.inc
* csub_x
;
2219 int y
, v
, u
, rv
, guv
, bu
;
2226 guv
= GUFAC
*u
+ GVFAC
*v
;
2237 *dst_row
= pixel_func();
2240 if (dst_row
== row_end
)
2244 if ((unsigned)xphase
< (unsigned)csub_x
)
2247 /* fetch new chromas */
2253 guv
= GUFAC
*u
+ GVFAC
*v
;
2256 xphase
-= xphase_reset
;
2259 else /* monochrome */
2263 /* Set all components the same for dithering purposes */
2264 px
.g
= px
.r
= px
.b
= YFAC
*(*ysrc
);
2265 *dst_row
= pixel_func();
2269 while (dst_row
!= row_end
);
2275 while (dst
< dst_end
);
2278 #endif /* HAVE_LCD_COLOR */
2281 /* support function for qsort() */
2282 static int compare(const void* p1
, const void* p2
)
2284 return rb
->strcasecmp(*((char **)p1
), *((char **)p2
));
2287 bool jpg_ext(const char ext
[])
2291 if(!rb
->strcasecmp(ext
,".jpg") ||
2292 !rb
->strcasecmp(ext
,".jpe") ||
2293 !rb
->strcasecmp(ext
,".jpeg"))
2299 /*Read directory contents for scrolling. */
2300 void get_pic_list(void)
2303 long int str_len
= 0;
2305 tree
= rb
->tree_get_context();
2307 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2308 file_pt
= rb
->plugin_get_buffer((size_t *)&buf_size
);
2310 file_pt
= rb
->plugin_get_audio_buffer((size_t *)&buf_size
);
2313 for(i
= 0; i
< tree
->filesindir
; i
++)
2315 if(jpg_ext(rb
->strrchr(&tree
->name_buffer
[str_len
],'.')))
2316 file_pt
[entries
++] = &tree
->name_buffer
[str_len
];
2318 str_len
+= rb
->strlen(&tree
->name_buffer
[str_len
]) + 1;
2321 rb
->qsort(file_pt
, entries
, sizeof(char**), compare
);
2323 /* Remove path and leave only the name.*/
2324 pname
= rb
->strrchr(np_file
,'/');
2327 /* Find Selected File. */
2328 for(i
= 0; i
< entries
; i
++)
2329 if(!rb
->strcmp(file_pt
[i
], pname
))
2333 int change_filename(int direct
)
2338 if(direct
== DIR_PREV
)
2344 curfile
= entries
- 1;
2347 }while(file_pt
[curfile
] == '\0' && count
< entries
);
2348 /* we "erase" the file name if we encounter
2349 * a non-supported file, so skip it now */
2351 else /* DIR_NEXT/DIR_NONE */
2356 if(curfile
== entries
- 1)
2360 }while(file_pt
[curfile
] == '\0' && count
< entries
);
2363 if(count
== entries
&& file_pt
[curfile
] == '\0')
2365 rb
->splash(HZ
, "No supported files");
2366 return PLUGIN_ERROR
;
2368 if(rb
->strlen(tree
->currdir
) > 1)
2370 rb
->strcpy(np_file
, tree
->currdir
);
2371 rb
->strcat(np_file
, "/");
2374 rb
->strcpy(np_file
, tree
->currdir
);
2376 rb
->strcat(np_file
, file_pt
[curfile
]);
2378 return PLUGIN_OTHER
;
2381 /* switch off overlay, for handling SYS_ events */
2382 void cleanup(void *parameter
)
2390 #define VSCROLL (LCD_HEIGHT/8)
2391 #define HSCROLL (LCD_WIDTH/10)
2393 #define ZOOM_IN 100 /* return codes for below function */
2394 #define ZOOM_OUT 101
2396 #ifdef HAVE_LCD_COLOR
2397 bool set_option_grayscale(void)
2399 bool gray
= jpeg_settings
.colour_mode
== COLOURMODE_GRAY
;
2400 rb
->set_bool("Grayscale", &gray
);
2401 jpeg_settings
.colour_mode
= gray
? COLOURMODE_GRAY
: COLOURMODE_COLOUR
;
2405 bool set_option_dithering(void)
2407 static const struct opt_items dithering
[DITHER_NUM_MODES
] = {
2408 [DITHER_NONE
] = { "Off", -1 },
2409 [DITHER_ORDERED
] = { "Ordered", -1 },
2410 [DITHER_DIFFUSION
] = { "Diffusion", -1 },
2413 rb
->set_option("Dithering", &jpeg_settings
.dither_mode
, INT
,
2414 dithering
, DITHER_NUM_MODES
, NULL
);
2418 static void display_options(void)
2420 static const struct menu_item items
[] = {
2421 { "Grayscale", set_option_grayscale
},
2422 { "Dithering", set_option_dithering
},
2425 int m
= menu_init(rb
, items
, ARRAYLEN(items
),
2426 NULL
, NULL
, NULL
, NULL
);
2430 #endif /* HAVE_LCD_COLOR */
2432 int show_menu(void) /* return 1 to quit */
2435 rb
->lcd_set_backdrop(old_backdrop
);
2436 #ifdef HAVE_LCD_COLOR
2437 rb
->lcd_set_foreground(rb
->global_settings
->fg_color
);
2438 rb
->lcd_set_background(rb
->global_settings
->bg_color
);
2440 rb
->lcd_set_foreground(LCD_BLACK
);
2441 rb
->lcd_set_background(LCD_WHITE
);
2450 MIID_TOGGLE_SS_MODE
,
2451 MIID_CHANGE_SS_MODE
,
2452 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2453 MIID_SHOW_PLAYBACK_MENU
,
2455 #ifdef HAVE_LCD_COLOR
2456 MIID_DISPLAY_OPTIONS
,
2461 static const struct menu_item items
[] = {
2464 [MIID_TOGGLE_SS_MODE
] =
2465 { "Toggle Slideshow Mode", NULL
},
2466 [MIID_CHANGE_SS_MODE
] =
2467 { "Change Slideshow Time", NULL
},
2468 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2469 [MIID_SHOW_PLAYBACK_MENU
] =
2470 { "Show Playback Menu", NULL
},
2472 #ifdef HAVE_LCD_COLOR
2473 [MIID_DISPLAY_OPTIONS
] =
2474 { "Display Options", NULL
},
2480 static const struct opt_items slideshow
[2] = {
2485 static const struct opt_items timeout
[12] = {
2487 { "2 seconds", -1 },
2488 { "3 seconds", -1 },
2489 { "4 seconds", -1 },
2490 { "5 seconds", -1 },
2491 { "6 seconds", -1 },
2492 { "7 seconds", -1 },
2493 { "8 seconds", -1 },
2494 { "9 seconds", -1 },
2495 { "10 seconds", -1 },
2496 { "15 seconds", -1 },
2497 { "20 seconds", -1 },
2500 m
= menu_init(rb
, items
, sizeof(items
) / sizeof(*items
),
2501 NULL
, NULL
, NULL
, NULL
);
2502 result
=menu_show(m
);
2510 case MIID_TOGGLE_SS_MODE
:
2511 rb
->set_option("Toggle Slideshow", &slideshow_enabled
, INT
,
2512 slideshow
, 2, NULL
);
2514 case MIID_CHANGE_SS_MODE
:
2515 switch (button_timeout
/HZ
)
2517 case 10: result
= 9; break;
2518 case 15: result
= 10; break;
2519 case 20: result
= 11; break;
2520 default: result
= (button_timeout
/HZ
)-1; break;
2522 rb
->set_option("Slideshow Time", &result
, INT
,
2523 timeout
, 12, NULL
);
2526 case 9: button_timeout
= 10*HZ
; break;
2527 case 10: button_timeout
= 15*HZ
; break;
2528 case 11: button_timeout
= 20*HZ
; break;
2529 default: button_timeout
= (result
+1)*HZ
; break;
2532 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2533 case MIID_SHOW_PLAYBACK_MENU
:
2534 playback_control(rb
);
2537 #ifdef HAVE_LCD_COLOR
2538 case MIID_DISPLAY_OPTIONS
:
2546 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
2547 /* change ata spindown time based on slideshow time setting */
2548 immediate_ata_off
= false;
2549 rb
->ata_spindown(rb
->global_settings
->disk_spindown
);
2551 if (slideshow_enabled
)
2553 if(button_timeout
/HZ
< 10)
2555 /* slideshow times < 10s keep disk spinning */
2556 rb
->ata_spindown(0);
2558 else if (!rb
->mp3_is_playing())
2560 /* slideshow times > 10s and not playing: ata_off after load */
2561 immediate_ata_off
= true;
2566 rb
->lcd_set_backdrop(NULL
);
2567 rb
->lcd_set_foreground(LCD_WHITE
);
2568 rb
->lcd_set_background(LCD_BLACK
);
2570 rb
->lcd_clear_display();
2574 /* interactively scroll around the image */
2575 int scroll_bmp(struct t_disp
* pdisp
)
2584 if (slideshow_enabled
)
2585 button
= rb
->button_get_w_tmo(button_timeout
);
2586 else button
= rb
->button_get(true);
2588 running_slideshow
= false;
2593 if (!(ds
< ds_max
) && entries
> 0 && jpg
.x_size
<= MAX_X_SIZE
)
2594 return change_filename(DIR_PREV
);
2595 case JPEG_LEFT
| BUTTON_REPEAT
:
2596 move
= MIN(HSCROLL
, pdisp
->x
);
2599 MYXLCD(scroll_right
)(move
); /* scroll right */
2601 #ifdef HAVE_LCD_COLOR
2603 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2604 pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2605 0, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2606 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2608 MYXLCD(gray_bitmap_part
)(
2609 pdisp
->bitmap
[0], pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2610 0, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2611 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2618 if (!(ds
< ds_max
) && entries
> 0 && jpg
.x_size
<= MAX_X_SIZE
)
2619 return change_filename(DIR_NEXT
);
2620 case JPEG_RIGHT
| BUTTON_REPEAT
:
2621 move
= MIN(HSCROLL
, pdisp
->width
- pdisp
->x
- LCD_WIDTH
);
2624 MYXLCD(scroll_left
)(move
); /* scroll left */
2626 #ifdef HAVE_LCD_COLOR
2628 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2629 pdisp
->x
+ LCD_WIDTH
- move
, pdisp
->y
, pdisp
->stride
,
2630 LCD_WIDTH
- move
, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2631 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2633 MYXLCD(gray_bitmap_part
)(
2634 pdisp
->bitmap
[0], pdisp
->x
+ LCD_WIDTH
- move
,
2635 pdisp
->y
, pdisp
->stride
,
2636 LCD_WIDTH
- move
, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2637 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2644 case JPEG_UP
| BUTTON_REPEAT
:
2645 move
= MIN(VSCROLL
, pdisp
->y
);
2648 MYXLCD(scroll_down
)(move
); /* scroll down */
2650 #ifdef HAVE_LCD_COLOR
2651 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2653 /* Draw over the band at the top of the last update
2654 caused by lack of error history on line zero. */
2655 move
= MIN(move
+ 1, pdisp
->y
+ pdisp
->height
);
2659 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2660 pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2661 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), 0, /* x, y */
2662 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2664 MYXLCD(gray_bitmap_part
)(
2665 pdisp
->bitmap
[0], pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2666 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), 0, /* x, y */
2667 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2674 case JPEG_DOWN
| BUTTON_REPEAT
:
2675 move
= MIN(VSCROLL
, pdisp
->height
- pdisp
->y
- LCD_HEIGHT
);
2678 MYXLCD(scroll_up
)(move
); /* scroll up */
2680 #ifdef HAVE_LCD_COLOR
2681 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2683 /* Save the line that was on the last line of the display
2684 and draw one extra line above then recover the line with
2685 image data that had an error history when it was drawn.
2689 rb
->lcd_framebuffer
+ (LCD_HEIGHT
- move
)*LCD_WIDTH
,
2690 LCD_WIDTH
*sizeof (fb_data
));
2694 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
, pdisp
->x
,
2695 pdisp
->y
+ LCD_HEIGHT
- move
, pdisp
->stride
,
2696 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), LCD_HEIGHT
- move
, /* x, y */
2697 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2699 if (jpeg_settings
.dither_mode
== DITHER_DIFFUSION
)
2701 /* Cover the first row drawn with previous image data. */
2702 MEMCPY(rb
->lcd_framebuffer
+ (LCD_HEIGHT
- move
)*LCD_WIDTH
,
2704 LCD_WIDTH
*sizeof (fb_data
));
2708 MYXLCD(gray_bitmap_part
)(
2709 pdisp
->bitmap
[0], pdisp
->x
,
2710 pdisp
->y
+ LCD_HEIGHT
- move
, pdisp
->stride
,
2711 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), LCD_HEIGHT
- move
, /* x, y */
2712 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2718 if (!slideshow_enabled
)
2720 running_slideshow
= true;
2722 return change_filename(DIR_NEXT
);
2725 #ifdef JPEG_SLIDE_SHOW
2726 case JPEG_SLIDE_SHOW
:
2727 slideshow_enabled
= !slideshow_enabled
;
2728 running_slideshow
= slideshow_enabled
;
2732 #ifdef JPEG_NEXT_REPEAT
2733 case JPEG_NEXT_REPEAT
:
2737 return change_filename(DIR_NEXT
);
2740 #ifdef JPEG_PREVIOUS_REPEAT
2741 case JPEG_PREVIOUS_REPEAT
:
2745 return change_filename(DIR_PREV
);
2749 #ifdef JPEG_ZOOM_PRE
2750 if (lastbutton
!= JPEG_ZOOM_PRE
)
2757 #ifdef JPEG_ZOOM_PRE
2758 if (lastbutton
!= JPEG_ZOOM_PRE
)
2768 gray_show(false); /* switch off grayscale overlay */
2770 if (show_menu() == 1)
2774 gray_show(true); /* switch on grayscale overlay */
2777 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2778 pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2779 MAX(0, (LCD_WIDTH
- pdisp
->width
) / 2),
2780 MAX(0, (LCD_HEIGHT
- pdisp
->height
) / 2),
2781 MIN(LCD_WIDTH
, pdisp
->width
),
2782 MIN(LCD_HEIGHT
, pdisp
->height
));
2787 if (rb
->default_event_handler_ex(button
, cleanup
, NULL
)
2788 == SYS_USB_CONNECTED
)
2789 return PLUGIN_USB_CONNECTED
;
2794 if (button
!= BUTTON_NONE
)
2795 lastbutton
= button
;
2796 } /* while (true) */
2799 /********************* main function *************************/
2801 /* callback updating a progress meter while JPEG decoding */
2802 void cb_progess(int current
, int total
)
2804 rb
->yield(); /* be nice to the other threads */
2805 if(!running_slideshow
)
2807 rb
->gui_scrollbar_draw(rb
->screens
[SCREEN_MAIN
],0, LCD_HEIGHT
-8, LCD_WIDTH
, 8, total
, 0,
2808 current
, HORIZONTAL
);
2809 rb
->lcd_update_rect(0, LCD_HEIGHT
-8, LCD_WIDTH
, 8);
2814 /* in slideshow mode, keep gui interference to a minimum */
2815 rb
->gui_scrollbar_draw(rb
->screens
[SCREEN_MAIN
],0, LCD_HEIGHT
-4, LCD_WIDTH
, 4, total
, 0,
2816 current
, HORIZONTAL
);
2817 rb
->lcd_update_rect(0, LCD_HEIGHT
-4, LCD_WIDTH
, 4);
2822 int jpegmem(struct jpeg
*p_jpg
, int ds
)
2826 size
= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[0])
2827 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[0]);
2828 #ifdef HAVE_LCD_COLOR
2829 if (p_jpg
->blocks
> 1) /* colour, add requirements for chroma */
2831 size
+= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[1])
2832 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[1]);
2833 size
+= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[2])
2834 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[2]);
2840 /* how far can we zoom in without running out of memory */
2841 int min_downscale(struct jpeg
*p_jpg
, int bufsize
)
2845 if (jpegmem(p_jpg
, 8) > bufsize
)
2846 return 0; /* error, too large, even 1:8 doesn't fit */
2848 while (downscale
> 1 && jpegmem(p_jpg
, downscale
/2) <= bufsize
)
2855 /* how far can we zoom out, to fit image into the LCD */
2856 int max_downscale(struct jpeg
*p_jpg
)
2860 while (downscale
< 8 && (p_jpg
->x_size
> LCD_WIDTH
*downscale
2861 || p_jpg
->y_size
> LCD_HEIGHT
*downscale
))
2870 /* return decoded or cached image */
2871 struct t_disp
* get_image(struct jpeg
* p_jpg
, int ds
)
2873 int w
, h
; /* used to center output */
2874 int size
; /* decompressed image size */
2875 long time
; /* measured ticks */
2878 struct t_disp
* p_disp
= &disp
[ds
]; /* short cut */
2880 if (p_disp
->bitmap
[0] != NULL
)
2882 return p_disp
; /* we still have it */
2885 /* assign image buffer */
2887 /* physical size needed for decoding */
2888 size
= jpegmem(p_jpg
, ds
);
2889 if (buf_size
<= size
)
2890 { /* have to discard the current */
2892 for (i
=1; i
<=8; i
++)
2893 disp
[i
].bitmap
[0] = NULL
; /* invalidate all bitmaps */
2894 buf
= buf_root
; /* start again from the beginning of the buffer */
2895 buf_size
= root_size
;
2898 #ifdef HAVE_LCD_COLOR
2899 if (p_jpg
->blocks
> 1) /* colour jpeg */
2903 for (i
= 1; i
< 3; i
++)
2905 size
= (p_jpg
->x_phys
/ ds
/ p_jpg
->subsample_x
[i
])
2906 * (p_jpg
->y_phys
/ ds
/ p_jpg
->subsample_y
[i
]);
2907 p_disp
->bitmap
[i
] = buf
;
2911 p_disp
->csub_x
= p_jpg
->subsample_x
[1];
2912 p_disp
->csub_y
= p_jpg
->subsample_y
[1];
2916 p_disp
->csub_x
= p_disp
->csub_y
= 0;
2917 p_disp
->bitmap
[1] = p_disp
->bitmap
[2] = buf
;
2920 /* size may be less when decoded (if height is not block aligned) */
2921 size
= (p_jpg
->x_phys
/ds
) * (p_jpg
->y_size
/ ds
);
2922 p_disp
->bitmap
[0] = buf
;
2926 if(!running_slideshow
)
2928 rb
->snprintf(print
, sizeof(print
), "decoding %d*%d",
2929 p_jpg
->x_size
/ds
, p_jpg
->y_size
/ds
);
2930 rb
->lcd_puts(0, 3, print
);
2934 /* update image properties */
2935 p_disp
->width
= p_jpg
->x_size
/ ds
;
2936 p_disp
->stride
= p_jpg
->x_phys
/ ds
; /* use physical size for stride */
2937 p_disp
->height
= p_jpg
->y_size
/ ds
;
2939 /* the actual decoding */
2940 time
= *rb
->current_tick
;
2941 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2942 rb
->cpu_boost(true);
2943 status
= jpeg_decode(p_jpg
, p_disp
->bitmap
, ds
, cb_progess
);
2944 rb
->cpu_boost(false);
2946 status
= jpeg_decode(p_jpg
, p_disp
->bitmap
, ds
, cb_progess
);
2950 rb
->splash(HZ
, "decode error %d", status
);
2951 file_pt
[curfile
] = '\0';
2954 time
= *rb
->current_tick
- time
;
2956 if(!running_slideshow
)
2958 rb
->snprintf(print
, sizeof(print
), " %ld.%02ld sec ", time
/HZ
, time
%HZ
);
2959 rb
->lcd_getstringsize(print
, &w
, &h
); /* centered in progress bar */
2960 rb
->lcd_putsxy((LCD_WIDTH
- w
)/2, LCD_HEIGHT
- h
, print
);
2968 /* set the view to the given center point, limit if necessary */
2969 void set_view (struct t_disp
* p_disp
, int cx
, int cy
)
2973 /* plain center to available width/height */
2974 x
= cx
- MIN(LCD_WIDTH
, p_disp
->width
) / 2;
2975 y
= cy
- MIN(LCD_HEIGHT
, p_disp
->height
) / 2;
2977 /* limit against upper image size */
2978 x
= MIN(p_disp
->width
- LCD_WIDTH
, x
);
2979 y
= MIN(p_disp
->height
- LCD_HEIGHT
, y
);
2981 /* limit against negative side */
2985 p_disp
->x
= x
; /* set the values */
2990 /* calculate the view center based on the bitmap position */
2991 void get_view(struct t_disp
* p_disp
, int* p_cx
, int* p_cy
)
2993 *p_cx
= p_disp
->x
+ MIN(LCD_WIDTH
, p_disp
->width
) / 2;
2994 *p_cy
= p_disp
->y
+ MIN(LCD_HEIGHT
, p_disp
->height
) / 2;
2998 /* load, decode, display the image */
2999 int load_and_show(char* filename
)
3003 unsigned char* buf_jpeg
; /* compressed JPEG image */
3005 struct t_disp
* p_disp
; /* currenly displayed image */
3006 int cx
, cy
; /* view center */
3008 fd
= rb
->open(filename
, O_RDONLY
);
3011 rb
->snprintf(print
,sizeof(print
),"err opening %s:%d",filename
,fd
);
3012 rb
->splash(HZ
, print
);
3013 return PLUGIN_ERROR
;
3015 filesize
= rb
->filesize(fd
);
3016 rb
->memset(&disp
, 0, sizeof(disp
));
3018 buf
= buf_images
+ filesize
;
3019 buf_size
= buf_images_size
- filesize
;
3020 /* allocate JPEG buffer */
3021 buf_jpeg
= buf_images
;
3023 buf_root
= buf
; /* we can start the decompressed images behind it */
3024 root_size
= buf_size
;
3028 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
3032 rb
->lcd_setfont(FONT_SYSFIXED
);
3033 rb
->lcd_clear_display();
3034 rb
->snprintf(print
,sizeof(print
),"%s:",rb
->strrchr(filename
,'/')+1);
3035 rb
->lcd_puts(0,0,print
);
3036 rb
->lcd_puts(0,1,"Not enough plugin memory!");
3037 rb
->lcd_puts(0,2,"Zoom In: Stop playback.");
3039 rb
->lcd_puts(0,3,"Left/Right: Skip File.");
3040 rb
->lcd_puts(0,4,"Off: Quit.");
3042 rb
->lcd_setfont(FONT_UI
);
3044 rb
->button_clear_queue();
3048 int button
= rb
->button_get(true);
3053 buf_images
= rb
->plugin_get_audio_buffer(
3054 (size_t *)&buf_images_size
);
3055 /*try again this file, now using the audio buffer */
3056 return PLUGIN_OTHER
;
3066 rb
->lcd_clear_display();
3067 return change_filename(DIR_PREV
);
3074 rb
->lcd_clear_display();
3075 return change_filename(DIR_NEXT
);
3079 if(rb
->default_event_handler_ex(button
, cleanup
, NULL
)
3080 == SYS_USB_CONNECTED
)
3081 return PLUGIN_USB_CONNECTED
;
3089 rb
->splash(HZ
, "Out of Memory");
3091 return PLUGIN_ERROR
;
3095 if(!running_slideshow
)
3098 rb
->lcd_set_foreground(LCD_WHITE
);
3099 rb
->lcd_set_background(LCD_BLACK
);
3100 rb
->lcd_set_backdrop(NULL
);
3103 rb
->lcd_clear_display();
3104 rb
->snprintf(print
, sizeof(print
), "%s:", rb
->strrchr(filename
,'/')+1);
3105 rb
->lcd_puts(0, 0, print
);
3108 rb
->snprintf(print
, sizeof(print
), "loading %d bytes", filesize
);
3109 rb
->lcd_puts(0, 1, print
);
3113 rb
->read(fd
, buf_jpeg
, filesize
);
3116 if(!running_slideshow
)
3118 rb
->snprintf(print
, sizeof(print
), "decoding markers");
3119 rb
->lcd_puts(0, 2, print
);
3123 else if(immediate_ata_off
)
3125 /* running slideshow and time is long enough: power down disk */
3130 rb
->memset(&jpg
, 0, sizeof(jpg
)); /* clear info struct */
3131 /* process markers, unstuffing */
3132 status
= process_markers(buf_jpeg
, filesize
, &jpg
);
3134 if (status
< 0 || (status
& (DQT
| SOF0
)) != (DQT
| SOF0
))
3135 { /* bad format or minimum components not contained */
3136 rb
->splash(HZ
, "unsupported %d", status
);
3137 file_pt
[curfile
] = '\0';
3138 return change_filename(direction
);
3141 if (!(status
& DHT
)) /* if no Huffman table present: */
3142 default_huff_tbl(&jpg
); /* use default */
3143 build_lut(&jpg
); /* derive Huffman and other lookup-tables */
3145 if(!running_slideshow
)
3147 rb
->snprintf(print
, sizeof(print
), "image %dx%d", jpg
.x_size
, jpg
.y_size
);
3148 rb
->lcd_puts(0, 2, print
);
3151 ds_max
= max_downscale(&jpg
); /* check display constraint */
3152 ds_min
= min_downscale(&jpg
, buf_size
); /* check memory constraint */
3155 rb
->splash(HZ
, "too large");
3156 file_pt
[curfile
] = '\0';
3157 return change_filename(direction
);
3160 ds
= ds_max
; /* initials setting */
3161 cx
= jpg
.x_size
/ds
/2; /* center the view */
3162 cy
= jpg
.y_size
/ds
/2;
3164 do /* loop the image prepare and decoding when zoomed */
3166 p_disp
= get_image(&jpg
, ds
); /* decode or fetch from cache */
3168 return change_filename(direction
);
3170 set_view(p_disp
, cx
, cy
);
3172 if(!running_slideshow
)
3174 rb
->snprintf(print
, sizeof(print
), "showing %dx%d",
3175 p_disp
->width
, p_disp
->height
);
3176 rb
->lcd_puts(0, 3, print
);
3179 MYLCD(clear_display
)();
3180 #ifdef HAVE_LCD_COLOR
3182 p_disp
->bitmap
, p_disp
->csub_x
, p_disp
->csub_y
,
3183 p_disp
->x
, p_disp
->y
, p_disp
->stride
,
3184 MAX(0, (LCD_WIDTH
- p_disp
->width
) / 2),
3185 MAX(0, (LCD_HEIGHT
- p_disp
->height
) / 2),
3186 MIN(LCD_WIDTH
, p_disp
->width
),
3187 MIN(LCD_HEIGHT
, p_disp
->height
));
3189 MYXLCD(gray_bitmap_part
)(
3190 p_disp
->bitmap
[0], p_disp
->x
, p_disp
->y
, p_disp
->stride
,
3191 MAX(0, (LCD_WIDTH
- p_disp
->width
) / 2),
3192 MAX(0, (LCD_HEIGHT
- p_disp
->height
) / 2),
3193 MIN(LCD_WIDTH
, p_disp
->width
),
3194 MIN(LCD_HEIGHT
, p_disp
->height
));
3199 gray_show(true); /* switch on grayscale overlay */
3202 /* drawing is now finished, play around with scrolling
3203 * until you press OFF or connect USB
3207 status
= scroll_bmp(p_disp
);
3208 if (status
== ZOOM_IN
)
3212 ds
/= 2; /* reduce downscaling to zoom in */
3213 get_view(p_disp
, &cx
, &cy
);
3214 cx
*= 2; /* prepare the position in the new image */
3221 if (status
== ZOOM_OUT
)
3225 ds
*= 2; /* increase downscaling to zoom out */
3226 get_view(p_disp
, &cx
, &cy
);
3227 cx
/= 2; /* prepare the position in the new image */
3237 gray_show(false); /* switch off overlay */
3239 rb
->lcd_clear_display();
3241 while (status
!= PLUGIN_OK
&& status
!= PLUGIN_USB_CONNECTED
3242 && status
!= PLUGIN_OTHER
);
3249 /******************** Plugin entry point *********************/
3251 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
3258 long graysize
; /* helper */
3261 old_backdrop
= rb
->lcd_get_backdrop();
3264 if(!parameter
) return PLUGIN_ERROR
;
3266 rb
->strcpy(np_file
, parameter
);
3269 if(!entries
) return PLUGIN_ERROR
;
3271 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
3272 if(rb
->audio_status())
3274 buf
= rb
->plugin_get_buffer((size_t *)&buf_size
) +
3275 (entries
* sizeof(char**));
3276 buf_size
-= (entries
* sizeof(char**));
3280 buf
= rb
->plugin_get_audio_buffer((size_t *)&buf_size
);
3282 buf
= rb
->plugin_get_audio_buffer(&buf_size
) +
3283 (entries
* sizeof(char**));
3284 buf_size
-= (entries
* sizeof(char**));
3288 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */
3289 grayscales
= gray_init(rb
, buf
, buf_size
, false, LCD_WIDTH
, LCD_HEIGHT
,
3290 32, 2<<8, &graysize
) + 1;
3292 buf_size
-= graysize
;
3293 if (grayscales
< 33 || buf_size
<= 0)
3295 rb
->splash(HZ
, "gray buf error");
3296 return PLUGIN_ERROR
;
3302 #ifdef HAVE_LCD_COLOR
3303 /* should be ok to just load settings since a parameter is present
3304 here and the drive should be spinning */
3305 configfile_init(rb
);
3306 configfile_load(JPEG_CONFIGFILE
, jpeg_config
,
3307 ARRAYLEN(jpeg_config
), JPEG_SETTINGS_MINVERSION
);
3308 old_settings
= jpeg_settings
;
3311 buf_images
= buf
; buf_images_size
= buf_size
;
3313 /* Turn off backlight timeout */
3314 backlight_force_on(); /* backlight control in lib/helper.c */
3318 condition
= load_and_show(np_file
);
3319 }while (condition
!= PLUGIN_OK
&& condition
!= PLUGIN_USB_CONNECTED
3320 && condition
!= PLUGIN_ERROR
);
3322 #ifdef HAVE_LCD_COLOR
3323 if (rb
->memcmp(&jpeg_settings
, &old_settings
, sizeof (jpeg_settings
)))
3325 /* Just in case drive has to spin, keep it from looking locked */
3326 rb
->splash(0, "Saving Settings");
3327 configfile_save(JPEG_CONFIGFILE
, jpeg_config
,
3328 ARRAYLEN(jpeg_config
), JPEG_SETTINGS_VERSION
);
3332 #if !defined(SIMULATOR) && !defined(HAVE_FLASH_STORAGE)
3333 /* set back ata spindown time in case we changed it */
3334 rb
->ata_spindown(rb
->global_settings
->disk_spindown
);
3337 /* Turn on backlight timeout (revert to settings) */
3338 backlight_use_settings(); /* backlight control in lib/helper.c */
3341 gray_release(); /* deinitialize */
3347 #endif /* HAVE_LCD_BITMAP */