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"
30 #ifdef HAVE_LCD_BITMAP
36 /* variable button definitions */
37 #if CONFIG_KEYPAD == RECORDER_PAD
38 #define JPEG_ZOOM_IN BUTTON_PLAY
39 #define JPEG_ZOOM_OUT BUTTON_ON
40 #define JPEG_UP BUTTON_UP
41 #define JPEG_DOWN BUTTON_DOWN
42 #define JPEG_LEFT BUTTON_LEFT
43 #define JPEG_RIGHT BUTTON_RIGHT
44 #define JPEG_NEXT BUTTON_F3
45 #define JPEG_PREVIOUS BUTTON_F2
46 #define JPEG_MENU BUTTON_OFF
49 #elif CONFIG_KEYPAD == ONDIO_PAD
50 #define JPEG_ZOOM_PRE BUTTON_MENU
51 #define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
52 #define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
53 #define JPEG_UP BUTTON_UP
54 #define JPEG_DOWN BUTTON_DOWN
55 #define JPEG_LEFT BUTTON_LEFT
56 #define JPEG_RIGHT BUTTON_RIGHT
57 #define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
58 #define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
59 #define JPEG_MENU BUTTON_OFF
61 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
62 (CONFIG_KEYPAD == IRIVER_H300_PAD)
63 #define JPEG_ZOOM_IN BUTTON_SELECT
64 #define JPEG_ZOOM_OUT BUTTON_MODE
65 #define JPEG_UP BUTTON_UP
66 #define JPEG_DOWN BUTTON_DOWN
67 #define JPEG_LEFT BUTTON_LEFT
68 #define JPEG_RIGHT BUTTON_RIGHT
69 #if (CONFIG_KEYPAD == IRIVER_H100_PAD)
70 #define JPEG_NEXT BUTTON_ON
71 #define JPEG_PREVIOUS BUTTON_REC
73 #define JPEG_NEXT BUTTON_REC
74 #define JPEG_PREVIOUS BUTTON_ON
76 #define JPEG_MENU BUTTON_OFF
78 #elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
79 #define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
80 #define JPEG_ZOOM_OUT BUTTON_SCROLL_BACK
81 #define JPEG_UP BUTTON_MENU
82 #define JPEG_DOWN BUTTON_PLAY
83 #define JPEG_LEFT BUTTON_LEFT
84 #define JPEG_RIGHT BUTTON_RIGHT
85 #define JPEG_MENU (BUTTON_SELECT | BUTTON_MENU)
86 #define JPEG_NEXT_PRE (BUTTON_SELECT | BUTTON_RIGHT)
87 #define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT | BUTTON_REL)
88 #define JPEG_TOGGLE_SLIDESHOW (BUTTON_SELECT | BUTTON_RIGHT | BUTTON_REPEAT)
89 #define JPEG_PREVIOUS (BUTTON_SELECT |BUTTON_LEFT)
91 #elif CONFIG_KEYPAD == IAUDIO_X5_PAD
92 #define JPEG_ZOOM_IN_PRE BUTTON_SELECT
93 #define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
94 #define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
95 #define JPEG_UP BUTTON_UP
96 #define JPEG_DOWN BUTTON_DOWN
97 #define JPEG_LEFT BUTTON_LEFT
98 #define JPEG_RIGHT BUTTON_RIGHT
99 #define JPEG_MENU BUTTON_POWER
100 #define JPEG_NEXT_PRE BUTTON_PLAY
101 #define JPEG_NEXT (BUTTON_PLAY|BUTTON_REL)
102 #define JPEG_TOGGLE_SLIDESHOW (BUTTON_PLAY|BUTTON_REPEAT)
103 #define JPEG_PREVIOUS BUTTON_REC
105 #elif CONFIG_KEYPAD == GIGABEAT_PAD
106 #define JPEG_ZOOM_IN_PRE BUTTON_MENU
107 #define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
108 #define JPEG_ZOOM_OUT (BUTTON_MENU | 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_A
114 #define JPEG_NEXT (BUTTON_POWER | BUTTON_RIGHT)
115 #define JPEG_PREVIOUS (BUTTON_POWER | BUTTON_LEFT)
119 /* different graphics libraries */
122 #define MYLCD(fn) gray_ub_ ## fn
123 #define MYLCD_UPDATE()
124 #define MYXLCD(fn) gray_ub_ ## fn
126 #define MYLCD(fn) rb->lcd_ ## fn
127 #define MYLCD_UPDATE() rb->lcd_update();
128 #define MYXLCD(fn) xlcd_ ## fn
131 #define MAX_X_SIZE LCD_WIDTH*8
133 /* Min memory allowing us to use the plugin buffer
134 * and thus not stopping the music
135 * *Very* rough estimation:
136 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
137 * + 20k code size = 60 000
138 * + 50k min for jpeg = 120 000
140 #define MIN_MEM 120000
147 #define PLUGIN_OTHER 10 /* State code for output with return. */
149 /******************************* Globals ***********************************/
151 static struct plugin_api
* rb
;
153 /* for portability of below JPEG code */
154 #define MEMSET(p,v,c) rb->memset(p,v,c)
155 #define MEMCPY(d,s,c) rb->memcpy(d,s,c)
156 #define INLINE static inline
157 #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
159 static int slideshow_enabled
= false;
160 static int button_timeout
= HZ
*5;
162 /**************** begin JPEG code ********************/
164 INLINE
unsigned range_limit(int value
)
166 #if CONFIG_CPU == SH7034
168 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
170 "sub %[t],%[v] \n" /* value -= -128; equals value += 128; */
171 "extu.b %[v],%[t] \n"
172 "cmp/eq %[v],%[t] \n" /* low byte == whole number ? */
173 "bt 1f \n" /* yes: no overflow */
174 "cmp/pz %[v] \n" /* overflow: positive? */
175 "subc %[v],%[v] \n" /* %[r] now either 0 or 0xffffffff */
182 #elif defined(CPU_COLDFIRE)
183 asm ( /* Note: Uses knowledge that only the low byte of the result is used */
184 "add.l #128,%[v] \n" /* value += 128; */
185 "cmp.l #255,%[v] \n" /* overflow? */
186 "bls.b 1f \n" /* no: return value */
187 "spl.b %[v] \n" /* yes: set low byte to appropriate boundary */
193 #elif defined(CPU_ARM)
195 "adds %[v], %[v], #128\n" /* value += 128 */
196 "movmi %[v], #0 \n" /* clip to 0 if negative result */
197 "cmp %[v], #255 \n" /* did we exceed 255? */
198 "movgt %[v], #255 \n" /* yes, clip to limit */
206 if ((unsigned)value
<= 255)
216 /* IDCT implementation */
219 #define CONST_BITS 13
223 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
224 * causing a lot of useless floating-point operations at run time.
225 * To get around this we use the following pre-calculated constants.
226 * If you change CONST_BITS you may want to add appropriate values.
227 * (With a reasonable C compiler, you can just rely on the FIX() macro...)
229 #define FIX_0_298631336 2446 /* FIX(0.298631336) */
230 #define FIX_0_390180644 3196 /* FIX(0.390180644) */
231 #define FIX_0_541196100 4433 /* FIX(0.541196100) */
232 #define FIX_0_765366865 6270 /* FIX(0.765366865) */
233 #define FIX_0_899976223 7373 /* FIX(0.899976223) */
234 #define FIX_1_175875602 9633 /* FIX(1.175875602) */
235 #define FIX_1_501321110 12299 /* FIX(1.501321110) */
236 #define FIX_1_847759065 15137 /* FIX(1.847759065) */
237 #define FIX_1_961570560 16069 /* FIX(1.961570560) */
238 #define FIX_2_053119869 16819 /* FIX(2.053119869) */
239 #define FIX_2_562915447 20995 /* FIX(2.562915447) */
240 #define FIX_3_072711026 25172 /* FIX(3.072711026) */
244 /* Multiply an long variable by an long constant to yield an long result.
245 * For 8-bit samples with the recommended scaling, all the variable
246 * and constant values involved are no more than 16 bits wide, so a
247 * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
248 * For 12-bit samples, a full 32-bit multiplication will be needed.
250 #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const)))
253 /* Dequantize a coefficient by multiplying it by the multiplier-table
254 * entry; produce an int result. In this module, both inputs and result
255 * are 16 bits or less, so either int or short multiply will work.
257 /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */
258 #define DEQUANTIZE MULTIPLY16
260 /* Descale and correctly round an int value that's scaled by N bits.
261 * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
262 * the fudge factor is correct for either sign of X.
264 #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n))
269 * Perform dequantization and inverse DCT on one block of coefficients,
270 * producing a reduced-size 1x1 output block.
272 void idct1x1(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
274 (void)skip_line
; /* unused */
275 *p_byte
= range_limit(inptr
[0] * quantptr
[0] >> 3);
281 * Perform dequantization and inverse DCT on one block of coefficients,
282 * producing a reduced-size 2x2 output block.
284 void idct2x2(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
286 int tmp0
, tmp1
, tmp2
, tmp3
, tmp4
, tmp5
;
287 unsigned char* outptr
;
289 /* Pass 1: process columns from input, store into work array. */
292 tmp4
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]);
293 tmp5
= DEQUANTIZE(inptr
[8*1], quantptr
[8*1]);
299 tmp4
= DEQUANTIZE(inptr
[8*0+1], quantptr
[8*0+1]);
300 tmp5
= DEQUANTIZE(inptr
[8*1+1], quantptr
[8*1+1]);
305 /* Pass 2: process 2 rows, store into output array. */
310 outptr
[0] = range_limit((int) DESCALE(tmp0
+ tmp1
, 3));
311 outptr
[1] = range_limit((int) DESCALE(tmp0
- tmp1
, 3));
314 outptr
= p_byte
+ skip_line
;
316 outptr
[0] = range_limit((int) DESCALE(tmp2
+ tmp3
, 3));
317 outptr
[1] = range_limit((int) DESCALE(tmp2
- tmp3
, 3));
323 * Perform dequantization and inverse DCT on one block of coefficients,
324 * producing a reduced-size 4x4 output block.
326 void idct4x4(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
328 int tmp0
, tmp2
, tmp10
, tmp12
;
331 unsigned char* outptr
;
333 int workspace
[4*4]; /* buffers data between passes */
335 /* Pass 1: process columns from input, store into work array. */
338 for (ctr
= 0; ctr
< 4; ctr
++, inptr
++, quantptr
++, wsptr
++)
342 tmp0
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]);
343 tmp2
= DEQUANTIZE(inptr
[8*2], quantptr
[8*2]);
345 tmp10
= (tmp0
+ tmp2
) << PASS1_BITS
;
346 tmp12
= (tmp0
- tmp2
) << PASS1_BITS
;
349 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
351 z2
= DEQUANTIZE(inptr
[8*1], quantptr
[8*1]);
352 z3
= DEQUANTIZE(inptr
[8*3], quantptr
[8*3]);
354 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
355 tmp0
= DESCALE(z1
+ MULTIPLY16(z3
, - FIX_1_847759065
), CONST_BITS
-PASS1_BITS
);
356 tmp2
= DESCALE(z1
+ MULTIPLY16(z2
, FIX_0_765366865
), CONST_BITS
-PASS1_BITS
);
358 /* Final output stage */
360 wsptr
[4*0] = (int) (tmp10
+ tmp2
);
361 wsptr
[4*3] = (int) (tmp10
- tmp2
);
362 wsptr
[4*1] = (int) (tmp12
+ tmp0
);
363 wsptr
[4*2] = (int) (tmp12
- tmp0
);
366 /* Pass 2: process 4 rows from work array, store into output array. */
369 for (ctr
= 0; ctr
< 4; ctr
++)
371 outptr
= p_byte
+ (ctr
*skip_line
);
374 tmp0
= (int) wsptr
[0];
375 tmp2
= (int) wsptr
[2];
377 tmp10
= (tmp0
+ tmp2
) << CONST_BITS
;
378 tmp12
= (tmp0
- tmp2
) << CONST_BITS
;
381 /* Same rotation as in the even part of the 8x8 LL&M IDCT */
386 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
387 tmp0
= z1
+ MULTIPLY16(z3
, - FIX_1_847759065
);
388 tmp2
= z1
+ MULTIPLY16(z2
, FIX_0_765366865
);
390 /* Final output stage */
392 outptr
[0] = range_limit((int) DESCALE(tmp10
+ tmp2
,
393 CONST_BITS
+PASS1_BITS
+3));
394 outptr
[3] = range_limit((int) DESCALE(tmp10
- tmp2
,
395 CONST_BITS
+PASS1_BITS
+3));
396 outptr
[1] = range_limit((int) DESCALE(tmp12
+ tmp0
,
397 CONST_BITS
+PASS1_BITS
+3));
398 outptr
[2] = range_limit((int) DESCALE(tmp12
- tmp0
,
399 CONST_BITS
+PASS1_BITS
+3));
401 wsptr
+= 4; /* advance pointer to next row */
408 * Perform dequantization and inverse DCT on one block of coefficients.
410 void idct8x8(unsigned char* p_byte
, int* inptr
, int* quantptr
, int skip_line
)
412 long tmp0
, tmp1
, tmp2
, tmp3
;
413 long tmp10
, tmp11
, tmp12
, tmp13
;
414 long z1
, z2
, z3
, z4
, z5
;
416 unsigned char* outptr
;
418 int workspace
[64]; /* buffers data between passes */
420 /* Pass 1: process columns from input, store into work array. */
421 /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
422 /* furthermore, we scale the results by 2**PASS1_BITS. */
425 for (ctr
= 8; ctr
> 0; ctr
--)
427 /* Due to quantization, we will usually find that many of the input
428 * coefficients are zero, especially the AC terms. We can exploit this
429 * by short-circuiting the IDCT calculation for any column in which all
430 * the AC terms are zero. In that case each output is equal to the
431 * DC coefficient (with scale factor as needed).
432 * With typical images and quantization tables, half or more of the
433 * column DCT calculations can be simplified this way.
436 if ((inptr
[8*1] | inptr
[8*2] | inptr
[8*3]
437 | inptr
[8*4] | inptr
[8*5] | inptr
[8*6] | inptr
[8*7]) == 0)
439 /* AC terms all zero */
440 int dcval
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]) << PASS1_BITS
;
442 wsptr
[8*0] = wsptr
[8*1] = wsptr
[8*2] = wsptr
[8*3] = wsptr
[8*4]
443 = wsptr
[8*5] = wsptr
[8*6] = wsptr
[8*7] = dcval
;
444 inptr
++; /* advance pointers to next column */
450 /* Even part: reverse the even part of the forward DCT. */
451 /* The rotator is sqrt(2)*c(-6). */
453 z2
= DEQUANTIZE(inptr
[8*2], quantptr
[8*2]);
454 z3
= DEQUANTIZE(inptr
[8*6], quantptr
[8*6]);
456 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
457 tmp2
= z1
+ MULTIPLY16(z3
, - FIX_1_847759065
);
458 tmp3
= z1
+ MULTIPLY16(z2
, FIX_0_765366865
);
460 z2
= DEQUANTIZE(inptr
[8*0], quantptr
[8*0]);
461 z3
= DEQUANTIZE(inptr
[8*4], quantptr
[8*4]);
463 tmp0
= (z2
+ z3
) << CONST_BITS
;
464 tmp1
= (z2
- z3
) << CONST_BITS
;
471 /* Odd part per figure 8; the matrix is unitary and hence its
472 transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
474 tmp0
= DEQUANTIZE(inptr
[8*7], quantptr
[8*7]);
475 tmp1
= DEQUANTIZE(inptr
[8*5], quantptr
[8*5]);
476 tmp2
= DEQUANTIZE(inptr
[8*3], quantptr
[8*3]);
477 tmp3
= DEQUANTIZE(inptr
[8*1], quantptr
[8*1]);
483 z5
= MULTIPLY16(z3
+ z4
, FIX_1_175875602
); /* sqrt(2) * c3 */
485 tmp0
= MULTIPLY16(tmp0
, FIX_0_298631336
); /* sqrt(2) * (-c1+c3+c5-c7) */
486 tmp1
= MULTIPLY16(tmp1
, FIX_2_053119869
); /* sqrt(2) * ( c1+c3-c5+c7) */
487 tmp2
= MULTIPLY16(tmp2
, FIX_3_072711026
); /* sqrt(2) * ( c1+c3+c5-c7) */
488 tmp3
= MULTIPLY16(tmp3
, FIX_1_501321110
); /* sqrt(2) * ( c1+c3-c5-c7) */
489 z1
= MULTIPLY16(z1
, - FIX_0_899976223
); /* sqrt(2) * (c7-c3) */
490 z2
= MULTIPLY16(z2
, - FIX_2_562915447
); /* sqrt(2) * (-c1-c3) */
491 z3
= MULTIPLY16(z3
, - FIX_1_961570560
); /* sqrt(2) * (-c3-c5) */
492 z4
= MULTIPLY16(z4
, - FIX_0_390180644
); /* sqrt(2) * (c5-c3) */
502 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
504 wsptr
[8*0] = (int) DESCALE(tmp10
+ tmp3
, CONST_BITS
-PASS1_BITS
);
505 wsptr
[8*7] = (int) DESCALE(tmp10
- tmp3
, CONST_BITS
-PASS1_BITS
);
506 wsptr
[8*1] = (int) DESCALE(tmp11
+ tmp2
, CONST_BITS
-PASS1_BITS
);
507 wsptr
[8*6] = (int) DESCALE(tmp11
- tmp2
, CONST_BITS
-PASS1_BITS
);
508 wsptr
[8*2] = (int) DESCALE(tmp12
+ tmp1
, CONST_BITS
-PASS1_BITS
);
509 wsptr
[8*5] = (int) DESCALE(tmp12
- tmp1
, CONST_BITS
-PASS1_BITS
);
510 wsptr
[8*3] = (int) DESCALE(tmp13
+ tmp0
, CONST_BITS
-PASS1_BITS
);
511 wsptr
[8*4] = (int) DESCALE(tmp13
- tmp0
, CONST_BITS
-PASS1_BITS
);
513 inptr
++; /* advance pointers to next column */
518 /* Pass 2: process rows from work array, store into output array. */
519 /* Note that we must descale the results by a factor of 8 == 2**3, */
520 /* and also undo the PASS1_BITS scaling. */
523 for (ctr
= 0; ctr
< 8; ctr
++)
525 outptr
= p_byte
+ (ctr
*skip_line
);
526 /* Rows of zeroes can be exploited in the same way as we did with columns.
527 * However, the column calculation has created many nonzero AC terms, so
528 * the simplification applies less often (typically 5% to 10% of the time).
529 * On machines with very fast multiplication, it's possible that the
530 * test takes more time than it's worth. In that case this section
531 * may be commented out.
534 #ifndef NO_ZERO_ROW_TEST
535 if ((wsptr
[1] | wsptr
[2] | wsptr
[3]
536 | wsptr
[4] | wsptr
[5] | wsptr
[6] | wsptr
[7]) == 0)
538 /* AC terms all zero */
539 unsigned char dcval
= range_limit((int) DESCALE((long) wsptr
[0],
551 wsptr
+= 8; /* advance pointer to next row */
556 /* Even part: reverse the even part of the forward DCT. */
557 /* The rotator is sqrt(2)*c(-6). */
559 z2
= (long) wsptr
[2];
560 z3
= (long) wsptr
[6];
562 z1
= MULTIPLY16(z2
+ z3
, FIX_0_541196100
);
563 tmp2
= z1
+ MULTIPLY16(z3
, - FIX_1_847759065
);
564 tmp3
= z1
+ MULTIPLY16(z2
, FIX_0_765366865
);
566 tmp0
= ((long) wsptr
[0] + (long) wsptr
[4]) << CONST_BITS
;
567 tmp1
= ((long) wsptr
[0] - (long) wsptr
[4]) << CONST_BITS
;
574 /* Odd part per figure 8; the matrix is unitary and hence its
575 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */
577 tmp0
= (long) wsptr
[7];
578 tmp1
= (long) wsptr
[5];
579 tmp2
= (long) wsptr
[3];
580 tmp3
= (long) wsptr
[1];
586 z5
= MULTIPLY16(z3
+ z4
, FIX_1_175875602
); /* sqrt(2) * c3 */
588 tmp0
= MULTIPLY16(tmp0
, FIX_0_298631336
); /* sqrt(2) * (-c1+c3+c5-c7) */
589 tmp1
= MULTIPLY16(tmp1
, FIX_2_053119869
); /* sqrt(2) * ( c1+c3-c5+c7) */
590 tmp2
= MULTIPLY16(tmp2
, FIX_3_072711026
); /* sqrt(2) * ( c1+c3+c5-c7) */
591 tmp3
= MULTIPLY16(tmp3
, FIX_1_501321110
); /* sqrt(2) * ( c1+c3-c5-c7) */
592 z1
= MULTIPLY16(z1
, - FIX_0_899976223
); /* sqrt(2) * (c7-c3) */
593 z2
= MULTIPLY16(z2
, - FIX_2_562915447
); /* sqrt(2) * (-c1-c3) */
594 z3
= MULTIPLY16(z3
, - FIX_1_961570560
); /* sqrt(2) * (-c3-c5) */
595 z4
= MULTIPLY16(z4
, - FIX_0_390180644
); /* sqrt(2) * (c5-c3) */
605 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
607 outptr
[0] = range_limit((int) DESCALE(tmp10
+ tmp3
,
608 CONST_BITS
+PASS1_BITS
+3));
609 outptr
[7] = range_limit((int) DESCALE(tmp10
- tmp3
,
610 CONST_BITS
+PASS1_BITS
+3));
611 outptr
[1] = range_limit((int) DESCALE(tmp11
+ tmp2
,
612 CONST_BITS
+PASS1_BITS
+3));
613 outptr
[6] = range_limit((int) DESCALE(tmp11
- tmp2
,
614 CONST_BITS
+PASS1_BITS
+3));
615 outptr
[2] = range_limit((int) DESCALE(tmp12
+ tmp1
,
616 CONST_BITS
+PASS1_BITS
+3));
617 outptr
[5] = range_limit((int) DESCALE(tmp12
- tmp1
,
618 CONST_BITS
+PASS1_BITS
+3));
619 outptr
[3] = range_limit((int) DESCALE(tmp13
+ tmp0
,
620 CONST_BITS
+PASS1_BITS
+3));
621 outptr
[4] = range_limit((int) DESCALE(tmp13
- tmp0
,
622 CONST_BITS
+PASS1_BITS
+3));
624 wsptr
+= 8; /* advance pointer to next row */
630 /* JPEG decoder implementation */
633 #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
637 /* Basic tables: (element [0] of each array is unused) */
638 long mincode
[17]; /* smallest code of length k */
639 long maxcode
[18]; /* largest code of length k (-1 if none) */
640 /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
641 int valptr
[17]; /* huffval[] index of 1st symbol of length k */
643 /* Back link to public Huffman table (needed only in slow_DECODE) */
646 /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
647 the input data stream. If the next Huffman code is no more
648 than HUFF_LOOKAHEAD bits long, we can obtain its length and
649 the corresponding symbol directly from these tables. */
650 int look_nbits
[1<<HUFF_LOOKAHEAD
]; /* # bits, or 0 if too long */
651 unsigned char look_sym
[1<<HUFF_LOOKAHEAD
]; /* symbol, or unused */
654 #define QUANT_TABLE_LENGTH 64
656 /* for type of Huffman table */
661 { /* length and code according to JFIF format */
662 int huffmancodes_dc
[DC_LEN
];
663 int huffmancodes_ac
[AC_LEN
];
666 struct frame_component
669 int horizontal_sampling
;
670 int vertical_sampling
;
671 int quanttable_select
;
674 struct scan_component
683 unsigned long get_buffer
; /* current bit-extraction buffer */
684 int bits_left
; /* # of unused bits in it */
685 unsigned char* next_input_byte
;
686 unsigned char* input_end
; /* upper limit +1 */
691 int x_size
, y_size
; /* size of image (can be less than block boundary) */
692 int x_phys
, y_phys
; /* physical size, block aligned */
693 int x_mbl
; /* x dimension of MBL */
694 int y_mbl
; /* y dimension of MBL */
695 int blocks
; /* blocks per MB */
696 int restart_interval
; /* number of MCUs between RSTm markers */
697 int store_pos
[4]; /* for Y block ordering */
699 unsigned char* p_entropy_data
;
700 unsigned char* p_entropy_end
;
702 int quanttable
[4][QUANT_TABLE_LENGTH
]; /* raw quantization tables 0-3 */
703 int qt_idct
[2][QUANT_TABLE_LENGTH
]; /* quantization tables for IDCT */
705 struct huffman_table hufftable
[2]; /* Huffman tables */
706 struct derived_tbl dc_derived_tbls
[2]; /* Huffman-LUTs */
707 struct derived_tbl ac_derived_tbls
[2];
709 struct frame_component frameheader
[3]; /* Component descriptor */
710 struct scan_component scanheader
[3]; /* currently not used */
712 int mcu_membership
[6]; /* info per block */
713 int tab_membership
[6];
714 int subsample_x
[3]; /* info per component */
719 /* possible return flags for process_markers() */
720 #define HUFFTAB 0x0001 /* with huffman table */
721 #define QUANTTAB 0x0002 /* with quantization table */
722 #define APP0_JFIF 0x0004 /* with APP0 segment following JFIF standard */
723 #define FILL_FF 0x0008 /* with 0xFF padding bytes at begin/end */
724 #define SOF0 0x0010 /* with SOF0-Segment */
725 #define DHT 0x0020 /* with Definition of huffman tables */
726 #define SOS 0x0040 /* with Start-of-Scan segment */
727 #define DQT 0x0080 /* with definition of quantization table */
729 /* Preprocess the JPEG JFIF file */
730 int process_markers(unsigned char* p_src
, long size
, struct jpeg
* p_jpeg
)
732 unsigned char* p_bytes
= p_src
;
733 int marker_size
; /* variable length of marker segment */
735 int ret
= 0; /* returned flags */
737 p_jpeg
->p_entropy_end
= p_src
+ size
;
739 while (p_src
< p_bytes
+ size
)
741 if (*p_src
++ != 0xFF) /* no marker? */
743 p_src
--; /* it's image data, put it back */
744 p_jpeg
->p_entropy_data
= p_src
;
745 break; /* exit marker processing */
750 case 0xFF: /* Fill byte */
752 case 0x00: /* Zero stuffed byte - entropy data */
753 p_src
--; /* put it back */
756 case 0xC0: /* SOF Huff - Baseline DCT */
759 marker_size
= *p_src
++ << 8; /* Highbyte */
760 marker_size
|= *p_src
++; /* Lowbyte */
761 n
= *p_src
++; /* sample precision (= 8 or 12) */
764 return(-1); /* Unsupported sample precision */
766 p_jpeg
->y_size
= *p_src
++ << 8; /* Highbyte */
767 p_jpeg
->y_size
|= *p_src
++; /* Lowbyte */
768 p_jpeg
->x_size
= *p_src
++ << 8; /* Highbyte */
769 p_jpeg
->x_size
|= *p_src
++; /* Lowbyte */
771 n
= (marker_size
-2-6)/3;
772 if (*p_src
++ != n
|| (n
!= 1 && n
!= 3))
774 return(-2); /* Unsupported SOF0 component specification */
778 p_jpeg
->frameheader
[i
].ID
= *p_src
++; /* Component info */
779 p_jpeg
->frameheader
[i
].horizontal_sampling
= *p_src
>> 4;
780 p_jpeg
->frameheader
[i
].vertical_sampling
= *p_src
++ & 0x0F;
781 p_jpeg
->frameheader
[i
].quanttable_select
= *p_src
++;
782 if (p_jpeg
->frameheader
[i
].horizontal_sampling
> 2
783 || p_jpeg
->frameheader
[i
].vertical_sampling
> 2)
784 return -3; /* Unsupported SOF0 subsampling */
790 case 0xC1: /* SOF Huff - Extended sequential DCT*/
791 case 0xC2: /* SOF Huff - Progressive DCT*/
792 case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
793 case 0xC5: /* SOF Huff - Differential sequential DCT*/
794 case 0xC6: /* SOF Huff - Differential progressive DCT*/
795 case 0xC7: /* SOF Huff - Differential spatial*/
796 case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/
797 case 0xC9: /* SOF Arith - Extended sequential DCT*/
798 case 0xCA: /* SOF Arith - Progressive DCT*/
799 case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/
800 case 0xCD: /* SOF Arith - Differential sequential DCT*/
801 case 0xCE: /* SOF Arith - Differential progressive DCT*/
802 case 0xCF: /* SOF Arith - Differential spatial*/
804 return (-4); /* other DCT model than baseline not implemented */
807 case 0xC4: /* Define Huffman Table(s) */
809 unsigned char* p_temp
;
812 marker_size
= *p_src
++ << 8; /* Highbyte */
813 marker_size
|= *p_src
++; /* Lowbyte */
816 while (p_src
< p_temp
+marker_size
-2-17) /* another table */
819 i
= *p_src
& 0x0F; /* table index */
822 return (-5); /* Huffman table index out of range */
824 else if (*p_src
++ & 0xF0) /* AC table */
829 p_jpeg
->hufftable
[i
].huffmancodes_ac
[j
] = *p_src
++;
831 if(16 + sum
> AC_LEN
)
832 return -10; /* longer than allowed */
834 for (; j
< 16 + sum
; j
++)
835 p_jpeg
->hufftable
[i
].huffmancodes_ac
[j
] = *p_src
++;
842 p_jpeg
->hufftable
[i
].huffmancodes_dc
[j
] = *p_src
++;
844 if(16 + sum
> DC_LEN
)
845 return -11; /* longer than allowed */
847 for (; j
< 16 + sum
; j
++)
848 p_jpeg
->hufftable
[i
].huffmancodes_dc
[j
] = *p_src
++;
851 p_src
= p_temp
+marker_size
- 2; /* skip possible residue */
855 case 0xCC: /* Define Arithmetic coding conditioning(s) */
856 return(-6); /* Arithmetic coding not supported */
858 case 0xD8: /* Start of Image */
859 case 0xD9: /* End of Image */
860 case 0x01: /* for temp private use arith code */
861 break; /* skip parameterless marker */
864 case 0xDA: /* Start of Scan */
867 marker_size
= *p_src
++ << 8; /* Highbyte */
868 marker_size
|= *p_src
++; /* Lowbyte */
870 n
= (marker_size
-2-1-3)/2;
871 if (*p_src
++ != n
|| (n
!= 1 && n
!= 3))
873 return (-7); /* Unsupported SOS component specification */
877 p_jpeg
->scanheader
[i
].ID
= *p_src
++;
878 p_jpeg
->scanheader
[i
].DC_select
= *p_src
>> 4;
879 p_jpeg
->scanheader
[i
].AC_select
= *p_src
++ & 0x0F;
881 p_src
+= 3; /* skip spectral information */
885 case 0xDB: /* Define quantization Table(s) */
888 marker_size
= *p_src
++ << 8; /* Highbyte */
889 marker_size
|= *p_src
++; /* Lowbyte */
890 n
= (marker_size
-2)/(QUANT_TABLE_LENGTH
+1); /* # of tables */
893 int id
= *p_src
++; /* ID */
896 return (-8); /* Unsupported quantization table */
898 /* Read Quantisation table: */
899 for (j
=0; j
<QUANT_TABLE_LENGTH
; j
++)
900 p_jpeg
->quanttable
[id
][j
] = *p_src
++;
905 case 0xDD: /* Define Restart Interval */
907 marker_size
= *p_src
++ << 8; /* Highbyte */
908 marker_size
|= *p_src
++; /* Lowbyte */
909 p_jpeg
->restart_interval
= *p_src
++ << 8; /* Highbyte */
910 p_jpeg
->restart_interval
|= *p_src
++; /* Lowbyte */
911 p_src
+= marker_size
-4; /* skip segment */
915 case 0xDC: /* Define Number of Lines */
916 case 0xDE: /* Define Hierarchical progression */
917 case 0xDF: /* Expand Reference Component(s) */
918 case 0xE0: /* Application Field 0*/
919 case 0xE1: /* Application Field 1*/
920 case 0xE2: /* Application Field 2*/
921 case 0xE3: /* Application Field 3*/
922 case 0xE4: /* Application Field 4*/
923 case 0xE5: /* Application Field 5*/
924 case 0xE6: /* Application Field 6*/
925 case 0xE7: /* Application Field 7*/
926 case 0xE8: /* Application Field 8*/
927 case 0xE9: /* Application Field 9*/
928 case 0xEA: /* Application Field 10*/
929 case 0xEB: /* Application Field 11*/
930 case 0xEC: /* Application Field 12*/
931 case 0xED: /* Application Field 13*/
932 case 0xEE: /* Application Field 14*/
933 case 0xEF: /* Application Field 15*/
934 case 0xFE: /* Comment */
936 marker_size
= *p_src
++ << 8; /* Highbyte */
937 marker_size
|= *p_src
++; /* Lowbyte */
938 p_src
+= marker_size
-2; /* skip segment */
942 case 0xF0: /* Reserved for JPEG extensions */
943 case 0xF1: /* Reserved for JPEG extensions */
944 case 0xF2: /* Reserved for JPEG extensions */
945 case 0xF3: /* Reserved for JPEG extensions */
946 case 0xF4: /* Reserved for JPEG extensions */
947 case 0xF5: /* Reserved for JPEG extensions */
948 case 0xF6: /* Reserved for JPEG extensions */
949 case 0xF7: /* Reserved for JPEG extensions */
950 case 0xF8: /* Reserved for JPEG extensions */
951 case 0xF9: /* Reserved for JPEG extensions */
952 case 0xFA: /* Reserved for JPEG extensions */
953 case 0xFB: /* Reserved for JPEG extensions */
954 case 0xFC: /* Reserved for JPEG extensions */
955 case 0xFD: /* Reserved for JPEG extensions */
956 case 0x02: /* Reserved */
958 return (-9); /* Unknown marker */
962 return (ret
); /* return flags with seen markers */
966 void default_huff_tbl(struct jpeg
* p_jpeg
)
968 static const struct huffman_table luma_table
=
971 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
972 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
975 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,
976 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
977 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,
978 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,
979 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
980 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
981 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
982 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
983 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,
984 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,
985 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
990 static const struct huffman_table chroma_table
=
993 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
994 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B
997 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,
998 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
999 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,
1000 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,
1001 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,
1002 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,
1003 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,
1004 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,
1005 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,
1006 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,
1007 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
1012 MEMCPY(&p_jpeg
->hufftable
[0], &luma_table
, sizeof(luma_table
));
1013 MEMCPY(&p_jpeg
->hufftable
[1], &chroma_table
, sizeof(chroma_table
));
1018 /* Compute the derived values for a Huffman table */
1019 void fix_huff_tbl(int* htbl
, struct derived_tbl
* dtbl
)
1024 unsigned int huffcode
[257];
1027 dtbl
->pub
= htbl
; /* fill in back link */
1029 /* Figure C.1: make table of Huffman code length for each symbol */
1030 /* Note that this is in code-length order. */
1033 for (l
= 1; l
<= 16; l
++)
1034 { /* all possible code length */
1035 for (i
= 1; i
<= (int) htbl
[l
-1]; i
++) /* all codes per length */
1036 huffsize
[p
++] = (char) l
;
1040 /* Figure C.2: generate the codes themselves */
1041 /* Note that this is in code-length order. */
1048 while (((int) huffsize
[p
]) == si
)
1050 huffcode
[p
++] = code
;
1057 /* Figure F.15: generate decoding tables for bit-sequential decoding */
1060 for (l
= 1; l
<= 16; l
++)
1064 dtbl
->valptr
[l
] = p
; /* huffval[] index of 1st symbol of code length l */
1065 dtbl
->mincode
[l
] = huffcode
[p
]; /* minimum code of length l */
1067 dtbl
->maxcode
[l
] = huffcode
[p
-1]; /* maximum code of length l */
1071 dtbl
->maxcode
[l
] = -1; /* -1 if no codes of this length */
1074 dtbl
->maxcode
[17] = 0xFFFFFL
; /* ensures huff_DECODE terminates */
1076 /* Compute lookahead tables to speed up decoding.
1077 * First we set all the table entries to 0, indicating "too long";
1078 * then we iterate through the Huffman codes that are short enough and
1079 * fill in all the entries that correspond to bit sequences starting
1083 MEMSET(dtbl
->look_nbits
, 0, sizeof(dtbl
->look_nbits
));
1086 for (l
= 1; l
<= HUFF_LOOKAHEAD
; l
++)
1088 for (i
= 1; i
<= (int) htbl
[l
-1]; i
++, p
++)
1090 /* l = current code's length, p = its index in huffcode[] & huffval[]. */
1091 /* Generate left-justified code followed by all possible bit sequences */
1092 lookbits
= huffcode
[p
] << (HUFF_LOOKAHEAD
-l
);
1093 for (ctr
= 1 << (HUFF_LOOKAHEAD
-l
); ctr
> 0; ctr
--)
1095 dtbl
->look_nbits
[lookbits
] = l
;
1096 dtbl
->look_sym
[lookbits
] = htbl
[16+p
];
1104 /* zag[i] is the natural-order position of the i'th element of zigzag order.
1105 * If the incoming data is corrupted, decode_mcu could attempt to
1106 * reference values beyond the end of the array. To avoid a wild store,
1107 * we put some extra zeroes after the real entries.
1109 static const int zag
[] =
1111 0, 1, 8, 16, 9, 2, 3, 10,
1112 17, 24, 32, 25, 18, 11, 4, 5,
1113 12, 19, 26, 33, 40, 48, 41, 34,
1114 27, 20, 13, 6, 7, 14, 21, 28,
1115 35, 42, 49, 56, 57, 50, 43, 36,
1116 29, 22, 15, 23, 30, 37, 44, 51,
1117 58, 59, 52, 45, 38, 31, 39, 46,
1118 53, 60, 61, 54, 47, 55, 62, 63,
1119 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */
1120 0, 0, 0, 0, 0, 0, 0, 0
1123 void build_lut(struct jpeg
* p_jpeg
)
1126 fix_huff_tbl(p_jpeg
->hufftable
[0].huffmancodes_dc
,
1127 &p_jpeg
->dc_derived_tbls
[0]);
1128 fix_huff_tbl(p_jpeg
->hufftable
[0].huffmancodes_ac
,
1129 &p_jpeg
->ac_derived_tbls
[0]);
1130 fix_huff_tbl(p_jpeg
->hufftable
[1].huffmancodes_dc
,
1131 &p_jpeg
->dc_derived_tbls
[1]);
1132 fix_huff_tbl(p_jpeg
->hufftable
[1].huffmancodes_ac
,
1133 &p_jpeg
->ac_derived_tbls
[1]);
1135 /* build the dequantization tables for the IDCT (De-ZiZagged) */
1136 for (i
=0; i
<64; i
++)
1138 p_jpeg
->qt_idct
[0][zag
[i
]] = p_jpeg
->quanttable
[0][i
];
1139 p_jpeg
->qt_idct
[1][zag
[i
]] = p_jpeg
->quanttable
[1][i
];
1143 p_jpeg
->store_pos
[i
] = i
; /* default ordering */
1145 /* assignments for the decoding of blocks */
1146 if (p_jpeg
->frameheader
[0].horizontal_sampling
== 2
1147 && p_jpeg
->frameheader
[0].vertical_sampling
== 1)
1150 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+15) / 16;
1151 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 16;
1152 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+7) / 8;
1153 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 8;
1154 p_jpeg
->mcu_membership
[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1155 p_jpeg
->mcu_membership
[1] = 0;
1156 p_jpeg
->mcu_membership
[2] = 1;
1157 p_jpeg
->mcu_membership
[3] = 2;
1158 p_jpeg
->tab_membership
[0] = 0; /* DC, DC, AC, AC */
1159 p_jpeg
->tab_membership
[1] = 0;
1160 p_jpeg
->tab_membership
[2] = 1;
1161 p_jpeg
->tab_membership
[3] = 1;
1162 p_jpeg
->subsample_x
[0] = 1;
1163 p_jpeg
->subsample_x
[1] = 2;
1164 p_jpeg
->subsample_x
[2] = 2;
1165 p_jpeg
->subsample_y
[0] = 1;
1166 p_jpeg
->subsample_y
[1] = 1;
1167 p_jpeg
->subsample_y
[2] = 1;
1169 if (p_jpeg
->frameheader
[0].horizontal_sampling
== 1
1170 && p_jpeg
->frameheader
[0].vertical_sampling
== 2)
1171 { /* 4:2:2 vertically subsampled */
1172 p_jpeg
->store_pos
[1] = 2; /* block positions are mirrored */
1173 p_jpeg
->store_pos
[2] = 1;
1175 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+7) / 8;
1176 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 8;
1177 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+15) / 16;
1178 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 16;
1179 p_jpeg
->mcu_membership
[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1180 p_jpeg
->mcu_membership
[1] = 0;
1181 p_jpeg
->mcu_membership
[2] = 1;
1182 p_jpeg
->mcu_membership
[3] = 2;
1183 p_jpeg
->tab_membership
[0] = 0; /* DC, DC, AC, AC */
1184 p_jpeg
->tab_membership
[1] = 0;
1185 p_jpeg
->tab_membership
[2] = 1;
1186 p_jpeg
->tab_membership
[3] = 1;
1187 p_jpeg
->subsample_x
[0] = 1;
1188 p_jpeg
->subsample_x
[1] = 1;
1189 p_jpeg
->subsample_x
[2] = 1;
1190 p_jpeg
->subsample_y
[0] = 1;
1191 p_jpeg
->subsample_y
[1] = 2;
1192 p_jpeg
->subsample_y
[2] = 2;
1194 else if (p_jpeg
->frameheader
[0].horizontal_sampling
== 2
1195 && p_jpeg
->frameheader
[0].vertical_sampling
== 2)
1198 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+15) / 16;
1199 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 16;
1200 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+15) / 16;
1201 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 16;
1202 p_jpeg
->mcu_membership
[0] = 0;
1203 p_jpeg
->mcu_membership
[1] = 0;
1204 p_jpeg
->mcu_membership
[2] = 0;
1205 p_jpeg
->mcu_membership
[3] = 0;
1206 p_jpeg
->mcu_membership
[4] = 1;
1207 p_jpeg
->mcu_membership
[5] = 2;
1208 p_jpeg
->tab_membership
[0] = 0;
1209 p_jpeg
->tab_membership
[1] = 0;
1210 p_jpeg
->tab_membership
[2] = 0;
1211 p_jpeg
->tab_membership
[3] = 0;
1212 p_jpeg
->tab_membership
[4] = 1;
1213 p_jpeg
->tab_membership
[5] = 1;
1214 p_jpeg
->subsample_x
[0] = 1;
1215 p_jpeg
->subsample_x
[1] = 2;
1216 p_jpeg
->subsample_x
[2] = 2;
1217 p_jpeg
->subsample_y
[0] = 1;
1218 p_jpeg
->subsample_y
[1] = 2;
1219 p_jpeg
->subsample_y
[2] = 2;
1221 else if (p_jpeg
->frameheader
[0].horizontal_sampling
== 1
1222 && p_jpeg
->frameheader
[0].vertical_sampling
== 1)
1224 /* don't overwrite p_jpeg->blocks */
1225 p_jpeg
->x_mbl
= (p_jpeg
->x_size
+7) / 8;
1226 p_jpeg
->x_phys
= p_jpeg
->x_mbl
* 8;
1227 p_jpeg
->y_mbl
= (p_jpeg
->y_size
+7) / 8;
1228 p_jpeg
->y_phys
= p_jpeg
->y_mbl
* 8;
1229 p_jpeg
->mcu_membership
[0] = 0;
1230 p_jpeg
->mcu_membership
[1] = 1;
1231 p_jpeg
->mcu_membership
[2] = 2;
1232 p_jpeg
->tab_membership
[0] = 0;
1233 p_jpeg
->tab_membership
[1] = 1;
1234 p_jpeg
->tab_membership
[2] = 1;
1235 p_jpeg
->subsample_x
[0] = 1;
1236 p_jpeg
->subsample_x
[1] = 1;
1237 p_jpeg
->subsample_x
[2] = 1;
1238 p_jpeg
->subsample_y
[0] = 1;
1239 p_jpeg
->subsample_y
[1] = 1;
1240 p_jpeg
->subsample_y
[2] = 1;
1251 * These functions/macros provide the in-line portion of bit fetching.
1252 * Use check_bit_buffer to ensure there are N bits in get_buffer
1253 * before using get_bits, peek_bits, or drop_bits.
1254 * check_bit_buffer(state,n,action);
1255 * Ensure there are N bits in get_buffer; if suspend, take action.
1256 * val = get_bits(n);
1257 * Fetch next N bits.
1258 * val = peek_bits(n);
1259 * Fetch next N bits without removing them from the buffer.
1261 * Discard next N bits.
1262 * The value N should be a simple variable, not an expression, because it
1263 * is evaluated multiple times.
1266 INLINE
void check_bit_buffer(struct bitstream
* pb
, int nbits
)
1268 if (pb
->bits_left
< nbits
)
1269 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1272 byte
= *pb
->next_input_byte
++;
1273 if (byte
== 0xFF) /* legal marker can be byte stuffing or RSTm */
1274 { /* simplification: just skip the (one-byte) marker code */
1275 pb
->next_input_byte
++;
1277 pb
->get_buffer
= (pb
->get_buffer
<< 8) | byte
;
1279 byte
= *pb
->next_input_byte
++;
1280 if (byte
== 0xFF) /* legal marker can be byte stuffing or RSTm */
1281 { /* simplification: just skip the (one-byte) marker code */
1282 pb
->next_input_byte
++;
1284 pb
->get_buffer
= (pb
->get_buffer
<< 8) | byte
;
1286 pb
->bits_left
+= 16;
1290 INLINE
int get_bits(struct bitstream
* pb
, int nbits
)
1292 return ((int) (pb
->get_buffer
>> (pb
->bits_left
-= nbits
))) & ((1<<nbits
)-1);
1295 INLINE
int peek_bits(struct bitstream
* pb
, int nbits
)
1297 return ((int) (pb
->get_buffer
>> (pb
->bits_left
- nbits
))) & ((1<<nbits
)-1);
1300 INLINE
void drop_bits(struct bitstream
* pb
, int nbits
)
1302 pb
->bits_left
-= nbits
;
1305 /* re-synchronize to entropy data (skip restart marker) */
1306 void search_restart(struct bitstream
* pb
)
1308 pb
->next_input_byte
--; /* we may have overread it, taking 2 bytes */
1309 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1310 while (pb
->next_input_byte
< pb
->input_end
&&
1311 (pb
->next_input_byte
[-2] != 0xFF || pb
->next_input_byte
[-1] == 0x00))
1313 pb
->next_input_byte
++;
1318 /* Figure F.12: extend sign bit. */
1319 #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1321 static const int extend_test
[16] = /* entry n is 2**(n-1) */
1323 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
1324 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000
1327 static const int extend_offset
[16] = /* entry n is (-1 << n) + 1 */
1329 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
1330 ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
1331 ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
1332 ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1
1335 /* Decode a single value */
1336 INLINE
int huff_decode_dc(struct bitstream
* bs
, struct derived_tbl
* tbl
)
1340 check_bit_buffer(bs
, HUFF_LOOKAHEAD
);
1341 look
= peek_bits(bs
, HUFF_LOOKAHEAD
);
1342 if ((nb
= tbl
->look_nbits
[look
]) != 0)
1345 s
= tbl
->look_sym
[look
];
1346 check_bit_buffer(bs
, s
);
1347 r
= get_bits(bs
, s
);
1348 s
= HUFF_EXTEND(r
, s
);
1351 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1353 nb
=HUFF_LOOKAHEAD
+1;
1354 check_bit_buffer(bs
, nb
);
1355 code
= get_bits(bs
, nb
);
1356 while (code
> tbl
->maxcode
[nb
])
1359 check_bit_buffer(bs
, 1);
1360 code
|= get_bits(bs
, 1);
1363 if (nb
> 16) /* error in Huffman */
1365 s
=0; /* fake a zero, this is most safe */
1369 s
= tbl
->pub
[16 + tbl
->valptr
[nb
] + ((int) (code
- tbl
->mincode
[nb
])) ];
1370 check_bit_buffer(bs
, s
);
1371 r
= get_bits(bs
, s
);
1372 s
= HUFF_EXTEND(r
, s
);
1374 } /* end slow decode */
1378 INLINE
int huff_decode_ac(struct bitstream
* bs
, struct derived_tbl
* tbl
)
1382 check_bit_buffer(bs
, HUFF_LOOKAHEAD
);
1383 look
= peek_bits(bs
, HUFF_LOOKAHEAD
);
1384 if ((nb
= tbl
->look_nbits
[look
]) != 0)
1387 s
= tbl
->look_sym
[look
];
1390 { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */
1392 nb
=HUFF_LOOKAHEAD
+1;
1393 check_bit_buffer(bs
, nb
);
1394 code
= get_bits(bs
, nb
);
1395 while (code
> tbl
->maxcode
[nb
])
1398 check_bit_buffer(bs
, 1);
1399 code
|= get_bits(bs
, 1);
1402 if (nb
> 16) /* error in Huffman */
1404 s
=0; /* fake a zero, this is most safe */
1408 s
= tbl
->pub
[16 + tbl
->valptr
[nb
] + ((int) (code
- tbl
->mincode
[nb
])) ];
1410 } /* end slow decode */
1415 #ifdef HAVE_LCD_COLOR
1417 /* JPEG decoder variant for YUV decoding, into 3 different planes */
1418 /* Note: it keeps the original color subsampling, even if resized. */
1419 int jpeg_decode(struct jpeg
* p_jpeg
, unsigned char* p_pixel
[3],
1420 int downscale
, void (*pf_progress
)(int current
, int total
))
1422 struct bitstream bs
; /* bitstream "object" */
1423 int block
[64]; /* decoded DCT coefficients */
1426 int skip_line
[3]; /* bytes from one line to the next (skip_line) */
1427 int skip_strip
[3], skip_mcu
[3]; /* bytes to next DCT row / column */
1429 int i
, x
, y
; /* loop counter */
1431 unsigned char* p_line
[3] = {p_pixel
[0], p_pixel
[1], p_pixel
[2]};
1432 unsigned char* p_byte
[3]; /* bitmap pointer */
1434 void (*pf_idct
)(unsigned char*, int*, int*, int); /* selected IDCT */
1435 int k_need
; /* AC coefficients needed up to here */
1436 int zero_need
; /* init the block with this many zeros */
1438 int last_dc_val
[3] = {0, 0, 0}; /* or 128 for chroma? */
1439 int store_offs
[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1440 int restart
= p_jpeg
->restart_interval
; /* MCUs until restart marker */
1442 /* pick the IDCT we want, determine how to work with coefs */
1446 k_need
= 64; /* all */
1447 zero_need
= 63; /* all */
1449 else if (downscale
== 2)
1452 k_need
= 25; /* this far in zig-zag to cover 4*4 */
1453 zero_need
= 27; /* clear this far in linear order */
1455 else if (downscale
== 4)
1458 k_need
= 5; /* this far in zig-zag to cover 2*2 */
1459 zero_need
= 9; /* clear this far in linear order */
1461 else if (downscale
== 8)
1464 k_need
= 0; /* no AC, not needed */
1465 zero_need
= 0; /* no AC, not needed */
1467 else return -1; /* not supported */
1469 /* init bitstream, fake a restart to make it start */
1470 bs
.next_input_byte
= p_jpeg
->p_entropy_data
;
1472 bs
.input_end
= p_jpeg
->p_entropy_end
;
1474 width
= p_jpeg
->x_phys
/ downscale
;
1475 height
= p_jpeg
->y_phys
/ downscale
;
1476 for (i
=0; i
<3; i
++) /* calculate some strides */
1478 skip_line
[i
] = width
/ p_jpeg
->subsample_x
[i
];
1479 skip_strip
[i
] = skip_line
[i
]
1480 * (height
/ p_jpeg
->y_mbl
) / p_jpeg
->subsample_y
[i
];
1481 skip_mcu
[i
] = width
/p_jpeg
->x_mbl
/ p_jpeg
->subsample_x
[i
];
1484 /* prepare offsets about where to store the different blocks */
1485 store_offs
[p_jpeg
->store_pos
[0]] = 0;
1486 store_offs
[p_jpeg
->store_pos
[1]] = 8 / downscale
; /* to the right */
1487 store_offs
[p_jpeg
->store_pos
[2]] = width
* 8 / downscale
; /* below */
1488 store_offs
[p_jpeg
->store_pos
[3]] = store_offs
[1] + store_offs
[2]; /* r+b */
1490 for(y
=0; y
<p_jpeg
->y_mbl
&& bs
.next_input_byte
<= bs
.input_end
; y
++)
1492 for (i
=0; i
<3; i
++) /* scan line init */
1494 p_byte
[i
] = p_line
[i
];
1495 p_line
[i
] += skip_strip
[i
];
1497 for (x
=0; x
<p_jpeg
->x_mbl
; x
++)
1501 /* Outer loop handles each block in the MCU */
1502 for (blkn
= 0; blkn
< p_jpeg
->blocks
; blkn
++)
1503 { /* Decode a single block's worth of coefficients */
1504 int k
= 1; /* coefficient index */
1505 int s
, r
; /* huffman values */
1506 int ci
= p_jpeg
->mcu_membership
[blkn
]; /* component index */
1507 int ti
= p_jpeg
->tab_membership
[blkn
]; /* table index */
1508 struct derived_tbl
* dctbl
= &p_jpeg
->dc_derived_tbls
[ti
];
1509 struct derived_tbl
* actbl
= &p_jpeg
->ac_derived_tbls
[ti
];
1511 /* Section F.2.2.1: decode the DC coefficient difference */
1512 s
= huff_decode_dc(&bs
, dctbl
);
1514 last_dc_val
[ci
] += s
;
1515 block
[0] = last_dc_val
[ci
]; /* output it (assumes zag[0] = 0) */
1517 /* coefficient buffer must be cleared */
1518 MEMSET(block
+1, 0, zero_need
*sizeof(block
[0]));
1520 /* Section F.2.2.2: decode the AC coefficients */
1521 for (; k
< k_need
; k
++)
1523 s
= huff_decode_ac(&bs
, actbl
);
1530 check_bit_buffer(&bs
, s
);
1531 r
= get_bits(&bs
, s
);
1532 block
[zag
[k
]] = HUFF_EXTEND(r
, s
);
1544 /* In this path we just discard the values */
1547 s
= huff_decode_ac(&bs
, actbl
);
1554 check_bit_buffer(&bs
, s
);
1566 { /* Y component needs to bother about block store */
1567 pf_idct(p_byte
[0]+store_offs
[blkn
], block
,
1568 p_jpeg
->qt_idct
[ti
], skip_line
[0]);
1572 pf_idct(p_byte
[ci
], block
, p_jpeg
->qt_idct
[ti
],
1576 p_byte
[0] += skip_mcu
[0]; /* unrolled for (i=0; i<3; i++) loop */
1577 p_byte
[1] += skip_mcu
[1];
1578 p_byte
[2] += skip_mcu
[2];
1579 if (p_jpeg
->restart_interval
&& --restart
== 0)
1580 { /* if a restart marker is due: */
1581 restart
= p_jpeg
->restart_interval
; /* count again */
1582 search_restart(&bs
); /* align the bitstream */
1583 last_dc_val
[0] = last_dc_val
[1] =
1584 last_dc_val
[2] = 0; /* reset decoder */
1587 if (pf_progress
!= NULL
)
1588 pf_progress(y
, p_jpeg
->y_mbl
-1); /* notify about decoding progress */
1591 return 0; /* success */
1593 #else /* !HAVE_LCD_COLOR */
1595 /* a JPEG decoder specialized in decoding only the luminance (b&w) */
1596 int jpeg_decode(struct jpeg
* p_jpeg
, unsigned char* p_pixel
[1], int downscale
,
1597 void (*pf_progress
)(int current
, int total
))
1599 struct bitstream bs
; /* bitstream "object" */
1600 int block
[64]; /* decoded DCT coefficients */
1603 int skip_line
; /* bytes from one line to the next (skip_line) */
1604 int skip_strip
, skip_mcu
; /* bytes to next DCT row / column */
1606 int x
, y
; /* loop counter */
1608 unsigned char* p_line
= p_pixel
[0];
1609 unsigned char* p_byte
; /* bitmap pointer */
1611 void (*pf_idct
)(unsigned char*, int*, int*, int); /* selected IDCT */
1612 int k_need
; /* AC coefficients needed up to here */
1613 int zero_need
; /* init the block with this many zeros */
1615 int last_dc_val
= 0;
1616 int store_offs
[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1617 int restart
= p_jpeg
->restart_interval
; /* MCUs until restart marker */
1619 /* pick the IDCT we want, determine how to work with coefs */
1623 k_need
= 64; /* all */
1624 zero_need
= 63; /* all */
1626 else if (downscale
== 2)
1629 k_need
= 25; /* this far in zig-zag to cover 4*4 */
1630 zero_need
= 27; /* clear this far in linear order */
1632 else if (downscale
== 4)
1635 k_need
= 5; /* this far in zig-zag to cover 2*2 */
1636 zero_need
= 9; /* clear this far in linear order */
1638 else if (downscale
== 8)
1641 k_need
= 0; /* no AC, not needed */
1642 zero_need
= 0; /* no AC, not needed */
1644 else return -1; /* not supported */
1646 /* init bitstream, fake a restart to make it start */
1647 bs
.next_input_byte
= p_jpeg
->p_entropy_data
;
1649 bs
.input_end
= p_jpeg
->p_entropy_end
;
1651 width
= p_jpeg
->x_phys
/ downscale
;
1652 height
= p_jpeg
->y_phys
/ downscale
;
1654 skip_strip
= skip_line
* (height
/ p_jpeg
->y_mbl
);
1655 skip_mcu
= (width
/p_jpeg
->x_mbl
);
1657 /* prepare offsets about where to store the different blocks */
1658 store_offs
[p_jpeg
->store_pos
[0]] = 0;
1659 store_offs
[p_jpeg
->store_pos
[1]] = 8 / downscale
; /* to the right */
1660 store_offs
[p_jpeg
->store_pos
[2]] = width
* 8 / downscale
; /* below */
1661 store_offs
[p_jpeg
->store_pos
[3]] = store_offs
[1] + store_offs
[2]; /* r+b */
1663 for(y
=0; y
<p_jpeg
->y_mbl
&& bs
.next_input_byte
<= bs
.input_end
; y
++)
1666 p_line
+= skip_strip
;
1667 for (x
=0; x
<p_jpeg
->x_mbl
; x
++)
1671 /* Outer loop handles each block in the MCU */
1672 for (blkn
= 0; blkn
< p_jpeg
->blocks
; blkn
++)
1673 { /* Decode a single block's worth of coefficients */
1674 int k
= 1; /* coefficient index */
1675 int s
, r
; /* huffman values */
1676 int ci
= p_jpeg
->mcu_membership
[blkn
]; /* component index */
1677 int ti
= p_jpeg
->tab_membership
[blkn
]; /* table index */
1678 struct derived_tbl
* dctbl
= &p_jpeg
->dc_derived_tbls
[ti
];
1679 struct derived_tbl
* actbl
= &p_jpeg
->ac_derived_tbls
[ti
];
1681 /* Section F.2.2.1: decode the DC coefficient difference */
1682 s
= huff_decode_dc(&bs
, dctbl
);
1684 if (ci
== 0) /* only for Y component */
1687 block
[0] = last_dc_val
; /* output it (assumes zag[0] = 0) */
1689 /* coefficient buffer must be cleared */
1690 MEMSET(block
+1, 0, zero_need
*sizeof(block
[0]));
1692 /* Section F.2.2.2: decode the AC coefficients */
1693 for (; k
< k_need
; k
++)
1695 s
= huff_decode_ac(&bs
, actbl
);
1702 check_bit_buffer(&bs
, s
);
1703 r
= get_bits(&bs
, s
);
1704 block
[zag
[k
]] = HUFF_EXTEND(r
, s
);
1717 /* In this path we just discard the values */
1720 s
= huff_decode_ac(&bs
, actbl
);
1727 check_bit_buffer(&bs
, s
);
1739 { /* only for Y component */
1740 pf_idct(p_byte
+store_offs
[blkn
], block
, p_jpeg
->qt_idct
[ti
],
1745 if (p_jpeg
->restart_interval
&& --restart
== 0)
1746 { /* if a restart marker is due: */
1747 restart
= p_jpeg
->restart_interval
; /* count again */
1748 search_restart(&bs
); /* align the bitstream */
1749 last_dc_val
= 0; /* reset decoder */
1752 if (pf_progress
!= NULL
)
1753 pf_progress(y
, p_jpeg
->y_mbl
-1); /* notify about decoding progress */
1756 return 0; /* success */
1758 #endif /* !HAVE_LCD_COLOR */
1760 /**************** end JPEG code ********************/
1764 /**************** begin Application ********************/
1767 /************************* Types ***************************/
1771 #ifdef HAVE_LCD_COLOR
1772 unsigned char* bitmap
[3]; /* Y, Cr, Cb */
1775 unsigned char* bitmap
[1]; /* Y only */
1783 /************************* Globals ***************************/
1785 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
1786 struct t_disp disp
[9];
1788 /* my memory pool (from the mp3 buffer) */
1789 char print
[32]; /* use a common snprintf() buffer */
1790 unsigned char* buf
; /* up to here currently used by image(s) */
1792 /* the remaining free part of the buffer for compressed+uncompressed images */
1793 unsigned char* buf_images
;
1795 int buf_size
, buf_images_size
;
1796 /* the root of the images, hereafter are decompresed ones */
1797 unsigned char* buf_root
;
1800 int ds
, ds_min
, ds_max
; /* downscaling and limits */
1801 static struct jpeg jpg
; /* too large for stack */
1803 static struct tree_context
*tree
;
1805 /* the current full file name */
1806 static char np_file
[MAX_PATH
];
1807 int curfile
= 0, direction
= DIR_NONE
, entries
= 0;
1809 /* list of the jpeg files */
1811 /* are we using the plugin buffer or the audio buffer? */
1812 bool plug_buf
= false;
1815 /************************* Implementation ***************************/
1817 #ifdef HAVE_LCD_COLOR
1819 #if (LCD_DEPTH == 16) && \
1820 ((LCD_PIXELFORMAT == RGB565) || (LCD_PIXELFORMAT == RGB565SWAPPED))
1821 #define RYFAC (31*257)
1822 #define GYFAC (63*257)
1823 #define BYFAC (31*257)
1824 #define RVFAC 11170 /* 31 * 257 * 1.402 */
1825 #define GVFAC (-11563) /* 63 * 257 * -0.714136 */
1826 #define GUFAC (-5572) /* 63 * 257 * -0.344136 */
1827 #define BUFAC 14118 /* 31 * 257 * 1.772 */
1830 #define ROUNDOFFS (127*257)
1832 /* Draw a partial YUV colour bitmap */
1833 void yuv_bitmap_part(unsigned char *src
[3], int csub_x
, int csub_y
,
1834 int src_x
, int src_y
, int stride
,
1835 int x
, int y
, int width
, int height
)
1837 fb_data
*dst
, *dst_end
;
1839 /* nothing to draw? */
1840 if ((width
<= 0) || (height
<= 0) || (x
>= LCD_WIDTH
) || (y
>= LCD_HEIGHT
)
1841 || (x
+ width
<= 0) || (y
+ height
<= 0))
1857 if (x
+ width
> LCD_WIDTH
)
1858 width
= LCD_WIDTH
- x
;
1859 if (y
+ height
> LCD_HEIGHT
)
1860 height
= LCD_HEIGHT
- y
;
1862 dst
= rb
->lcd_framebuffer
+ LCD_WIDTH
* y
+ x
;
1863 dst_end
= dst
+ LCD_WIDTH
* height
;
1867 fb_data
*dst_row
= dst
;
1868 fb_data
*row_end
= dst_row
+ width
;
1869 const unsigned char *ysrc
= src
[0] + stride
* src_y
+ src_x
;
1871 int red
, green
, blue
;
1872 unsigned rbits
, gbits
, bbits
;
1874 if (csub_y
) /* colour */
1876 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
1877 const unsigned char *usrc
= src
[1] + (stride
/csub_x
) * (src_y
/csub_y
)
1879 const unsigned char *vsrc
= src
[2] + (stride
/csub_x
) * (src_y
/csub_y
)
1881 int xphase
= src_x
% csub_x
;
1886 rc
= RVFAC
* v
+ ROUNDOFFS
;
1887 gc
= GVFAC
* v
+ GUFAC
* u
+ ROUNDOFFS
;
1888 bc
= BUFAC
* u
+ ROUNDOFFS
;
1893 red
= RYFAC
* y
+ rc
;
1894 green
= GYFAC
* y
+ gc
;
1895 blue
= BYFAC
* y
+ bc
;
1897 if ((unsigned)red
> (RYFAC
*255+ROUNDOFFS
))
1902 red
= (RYFAC
*255+ROUNDOFFS
);
1904 if ((unsigned)green
> (GYFAC
*255+ROUNDOFFS
))
1909 green
= (GYFAC
*255+ROUNDOFFS
);
1911 if ((unsigned)blue
> (BYFAC
*255+ROUNDOFFS
))
1916 blue
= (BYFAC
*255+ROUNDOFFS
);
1918 rbits
= ((unsigned)red
) >> 16 ;
1919 gbits
= ((unsigned)green
) >> 16 ;
1920 bbits
= ((unsigned)blue
) >> 16 ;
1921 #if LCD_PIXELFORMAT == RGB565
1922 *dst_row
++ = (rbits
<< 11) | (gbits
<< 5) | bbits
;
1923 #elif LCD_PIXELFORMAT == RGB565SWAPPED
1924 *dst_row
++ = swap16((rbits
<< 11) | (gbits
<< 5) | bbits
);
1927 if (++xphase
>= csub_x
)
1931 rc
= RVFAC
* v
+ ROUNDOFFS
;
1932 gc
= GVFAC
* v
+ GUFAC
* u
+ ROUNDOFFS
;
1933 bc
= BUFAC
* u
+ ROUNDOFFS
;
1937 while (dst_row
< row_end
);
1939 else /* monochrome */
1944 red
= RYFAC
* y
+ ROUNDOFFS
; /* blue == red */
1945 green
= GYFAC
* y
+ ROUNDOFFS
;
1946 rbits
= ((unsigned)red
) >> 16;
1947 gbits
= ((unsigned)green
) >> 16;
1948 #if LCD_PIXELFORMAT == RGB565
1949 *dst_row
++ = (rbits
<< 11) | (gbits
<< 5) | rbits
;
1950 #elif LCD_PIXELFORMAT == RGB565SWAPPED
1951 *dst_row
++ = swap16((rbits
<< 11) | (gbits
<< 5) | rbits
);
1954 while (dst_row
< row_end
);
1960 while (dst
< dst_end
);
1965 /* support function for qsort() */
1966 static int compare(const void* p1
, const void* p2
)
1968 return rb
->strcasecmp(*((char **)p1
), *((char **)p2
));
1971 bool jpg_ext(const char ext
[])
1973 if(!rb
->strcasecmp(ext
,".jpg") ||
1974 !rb
->strcasecmp(ext
,".jpe") ||
1975 !rb
->strcasecmp(ext
,".jpeg"))
1981 /*Read directory contents for scrolling. */
1982 void get_pic_list(void)
1985 long int str_len
= 0;
1987 tree
= rb
->tree_get_context();
1989 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
1990 file_pt
= rb
->plugin_get_buffer(&buf_size
);
1992 file_pt
= rb
->plugin_get_audio_buffer(&buf_size
);
1995 for(i
= 0; i
< tree
->filesindir
; i
++)
1997 if(jpg_ext(rb
->strrchr(&tree
->name_buffer
[str_len
],'.')))
1998 file_pt
[entries
++] = &tree
->name_buffer
[str_len
];
2000 str_len
+= rb
->strlen(&tree
->name_buffer
[str_len
]) + 1;
2003 rb
->qsort(file_pt
, entries
, sizeof(char**), compare
);
2005 /* Remove path and leave only the name.*/
2006 pname
= rb
->strrchr(np_file
,'/');
2009 /* Find Selected File. */
2010 for(i
= 0; i
< entries
; i
++)
2011 if(!rb
->strcmp(file_pt
[i
], pname
))
2015 int change_filename(int direct
)
2020 if(direct
== DIR_PREV
)
2026 curfile
= entries
- 1;
2029 }while(file_pt
[curfile
] == '\0' && count
< entries
);
2030 /* we "erase" the file name if we encounter
2031 * a non-supported file, so skip it now */
2033 else /* DIR_NEXT/DIR_NONE */
2038 if(curfile
== entries
- 1)
2042 }while(file_pt
[curfile
] == '\0' && count
< entries
);
2045 if(count
== entries
&& file_pt
[curfile
] == '\0')
2047 rb
->splash(HZ
,true,"No supported files");
2048 return PLUGIN_ERROR
;
2050 if(rb
->strlen(tree
->currdir
) > 1)
2052 rb
->strcpy(np_file
, tree
->currdir
);
2053 rb
->strcat(np_file
, "/");
2056 rb
->strcpy(np_file
, tree
->currdir
);
2058 rb
->strcat(np_file
, file_pt
[curfile
]);
2060 return PLUGIN_OTHER
;
2063 /* switch off overlay, for handling SYS_ events */
2064 void cleanup(void *parameter
)
2072 #define VSCROLL (LCD_HEIGHT/8)
2073 #define HSCROLL (LCD_WIDTH/10)
2075 #define ZOOM_IN 100 /* return codes for below function */
2076 #define ZOOM_OUT 101
2078 int show_menu() /* return 1 to quit */
2082 static const struct menu_item items
[] = {
2084 { "Toggle Slideshow Mode", NULL
},
2085 { "Change Slideshow Timeout", NULL
},
2086 { "Show Playback Menu", NULL
},
2089 static const struct opt_items slideshow
[2] = {
2093 static const struct opt_items timeout
[12] = {
2094 { "1 second", NULL
},
2095 { "2 seconds", NULL
},
2096 { "3 seconds", NULL
},
2097 { "4 seconds", NULL
},
2098 { "5 seconds", NULL
},
2099 { "6 seconds", NULL
},
2100 { "7 seconds", NULL
},
2101 { "8 seconds", NULL
},
2102 { "9 seconds", NULL
},
2103 { "10 seconds", NULL
},
2104 { "15 seconds", NULL
},
2105 { "20 seconds", NULL
},
2107 m
= rb
->menu_init(items
, sizeof(items
) / sizeof(*items
),
2108 NULL
, NULL
, NULL
, NULL
);
2109 result
=rb
->menu_show(m
);
2116 case 1: //toggle slideshow
2117 rb
->set_option("Toggle Slideshow", &slideshow_enabled
, INT
,
2118 slideshow
, 2, NULL
);
2121 switch (button_timeout
/HZ
)
2123 case 10: result
= 9; break;
2124 case 15: result
= 10; break;
2125 case 20: result
= 11; break;
2126 default: result
= (button_timeout
/HZ
)-1; break;
2128 rb
->set_option("Slideshow Timeout", &result
, INT
,
2129 timeout
, 12, NULL
);
2132 case 9: button_timeout
= 10*HZ
; break;
2133 case 10: button_timeout
= 15*HZ
; break;
2134 case 11: button_timeout
= 20*HZ
; break;
2135 default: button_timeout
= (result
+1)*HZ
; break;
2139 playback_control(rb
);
2142 MYLCD(clear_display
)();
2148 /* interactively scroll around the image */
2149 int scroll_bmp(struct t_disp
* pdisp
)
2158 if (slideshow_enabled
)
2159 button
= rb
->button_get_w_tmo(button_timeout
);
2160 else button
= rb
->button_get(true);
2165 if (!(ds
< ds_max
) && entries
> 0 && jpg
.x_size
<= MAX_X_SIZE
)
2166 return change_filename(DIR_PREV
);
2167 case JPEG_LEFT
| BUTTON_REPEAT
:
2168 move
= MIN(HSCROLL
, pdisp
->x
);
2171 MYXLCD(scroll_right
)(move
); /* scroll right */
2173 #ifdef HAVE_LCD_COLOR
2175 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2176 pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2177 0, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2178 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2180 MYXLCD(gray_bitmap_part
)(
2181 pdisp
->bitmap
[0], pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2182 0, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2183 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2190 if (!(ds
< ds_max
) && entries
> 0 && jpg
.x_size
<= MAX_X_SIZE
)
2191 return change_filename(DIR_NEXT
);
2192 case JPEG_RIGHT
| BUTTON_REPEAT
:
2193 move
= MIN(HSCROLL
, pdisp
->width
- pdisp
->x
- LCD_WIDTH
);
2196 MYXLCD(scroll_left
)(move
); /* scroll left */
2198 #ifdef HAVE_LCD_COLOR
2200 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2201 pdisp
->x
+ LCD_WIDTH
- move
, pdisp
->y
, pdisp
->stride
,
2202 LCD_WIDTH
- move
, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2203 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2205 MYXLCD(gray_bitmap_part
)(
2206 pdisp
->bitmap
[0], pdisp
->x
+ LCD_WIDTH
- move
,
2207 pdisp
->y
, pdisp
->stride
,
2208 LCD_WIDTH
- move
, MAX(0, (LCD_HEIGHT
-pdisp
->height
)/2), /* x, y */
2209 move
, MIN(LCD_HEIGHT
, pdisp
->height
)); /* w, h */
2216 case JPEG_UP
| BUTTON_REPEAT
:
2217 move
= MIN(VSCROLL
, pdisp
->y
);
2220 MYXLCD(scroll_down
)(move
); /* scroll down */
2222 #ifdef HAVE_LCD_COLOR
2224 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2225 pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2226 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), 0, /* x, y */
2227 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2229 MYXLCD(gray_bitmap_part
)(
2230 pdisp
->bitmap
[0], pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2231 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), 0, /* x, y */
2232 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2239 case JPEG_DOWN
| BUTTON_REPEAT
:
2240 move
= MIN(VSCROLL
, pdisp
->height
- pdisp
->y
- LCD_HEIGHT
);
2243 MYXLCD(scroll_up
)(move
); /* scroll up */
2245 #ifdef HAVE_LCD_COLOR
2247 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
, pdisp
->x
,
2248 pdisp
->y
+ LCD_HEIGHT
- move
, pdisp
->stride
,
2249 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), LCD_HEIGHT
- move
, /* x, y */
2250 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2252 MYXLCD(gray_bitmap_part
)(
2253 pdisp
->bitmap
[0], pdisp
->x
,
2254 pdisp
->y
+ LCD_HEIGHT
- move
, pdisp
->stride
,
2255 MAX(0, (LCD_WIDTH
-pdisp
->width
)/2), LCD_HEIGHT
- move
, /* x, y */
2256 MIN(LCD_WIDTH
, pdisp
->width
), move
); /* w, h */
2262 if (!slideshow_enabled
)
2265 return change_filename(DIR_NEXT
);
2268 #ifdef JPEG_NEXT_PRE
2269 if (lastbutton
!= JPEG_NEXT_PRE
)
2273 return change_filename(DIR_NEXT
);
2278 return change_filename(DIR_PREV
);
2282 #ifdef JPEG_ZOOM_PRE
2283 if (lastbutton
!= JPEG_ZOOM_PRE
)
2290 #ifdef JPEG_ZOOM_PRE
2291 if (lastbutton
!= JPEG_ZOOM_PRE
)
2299 gray_show(false); /* switch off grayscale overlay */
2301 if (show_menu() == 1)
2304 gray_show(true); /* switch on grayscale overlay */
2307 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
2308 pdisp
->x
, pdisp
->y
, pdisp
->stride
,
2309 MAX(0, (LCD_WIDTH
- pdisp
->width
) / 2),
2310 MAX(0, (LCD_HEIGHT
- pdisp
->height
) / 2),
2311 MIN(LCD_WIDTH
, pdisp
->width
),
2312 MIN(LCD_HEIGHT
, pdisp
->height
));
2317 if (rb
->default_event_handler_ex(button
, cleanup
, NULL
)
2318 == SYS_USB_CONNECTED
)
2319 return PLUGIN_USB_CONNECTED
;
2324 if (button
!= BUTTON_NONE
)
2325 lastbutton
= button
;
2326 } /* while (true) */
2329 /********************* main function *************************/
2331 /* callback updating a progress meter while JPEG decoding */
2332 void cb_progess(int current
, int total
)
2334 rb
->yield(); /* be nice to the other threads */
2335 rb
->scrollbar(0, LCD_HEIGHT
-8, LCD_WIDTH
, 8, total
, 0,
2336 current
, HORIZONTAL
);
2337 rb
->lcd_update_rect(0, LCD_HEIGHT
-8, LCD_WIDTH
, 8);
2340 int jpegmem(struct jpeg
*p_jpg
, int ds
)
2344 size
= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[0])
2345 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[0]);
2346 #ifdef HAVE_LCD_COLOR
2347 if (p_jpg
->blocks
> 1) /* colour, add requirements for chroma */
2349 size
+= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[1])
2350 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[1]);
2351 size
+= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[2])
2352 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[2]);
2358 /* how far can we zoom in without running out of memory */
2359 int min_downscale(struct jpeg
*p_jpg
, int bufsize
)
2363 if (jpegmem(p_jpg
, 8) > bufsize
)
2364 return 0; /* error, too large, even 1:8 doesn't fit */
2366 while (downscale
> 1 && jpegmem(p_jpg
, downscale
/2) <= bufsize
)
2373 /* how far can we zoom out, to fit image into the LCD */
2374 int max_downscale(struct jpeg
*p_jpg
)
2378 while (downscale
< 8 && (p_jpg
->x_size
> LCD_WIDTH
*downscale
2379 || p_jpg
->y_size
> LCD_HEIGHT
*downscale
))
2388 /* return decoded or cached image */
2389 struct t_disp
* get_image(struct jpeg
* p_jpg
, int ds
)
2391 int w
, h
; /* used to center output */
2392 int size
; /* decompressed image size */
2393 long time
; /* measured ticks */
2396 struct t_disp
* p_disp
= &disp
[ds
]; /* short cut */
2398 if (p_disp
->bitmap
[0] != NULL
)
2400 return p_disp
; /* we still have it */
2403 /* assign image buffer */
2405 /* physical size needed for decoding */
2406 size
= jpegmem(p_jpg
, ds
);
2407 if (buf_size
<= size
)
2408 { /* have to discard the current */
2410 for (i
=1; i
<=8; i
++)
2411 disp
[i
].bitmap
[0] = NULL
; /* invalidate all bitmaps */
2412 buf
= buf_root
; /* start again from the beginning of the buffer */
2413 buf_size
= root_size
;
2416 #ifdef HAVE_LCD_COLOR
2417 if (p_jpg
->blocks
> 1) /* colour jpeg */
2421 for (i
= 1; i
< 3; i
++)
2423 size
= (p_jpg
->x_phys
/ ds
/ p_jpg
->subsample_x
[i
])
2424 * (p_jpg
->y_phys
/ ds
/ p_jpg
->subsample_y
[i
]);
2425 p_disp
->bitmap
[i
] = buf
;
2429 p_disp
->csub_x
= p_jpg
->subsample_x
[1];
2430 p_disp
->csub_y
= p_jpg
->subsample_y
[1];
2434 p_disp
->csub_x
= p_disp
->csub_y
= 0;
2435 p_disp
->bitmap
[1] = p_disp
->bitmap
[2] = buf
;
2438 /* size may be less when decoded (if height is not block aligned) */
2439 size
= (p_jpg
->x_phys
/ds
) * (p_jpg
->y_size
/ ds
);
2440 p_disp
->bitmap
[0] = buf
;
2444 rb
->snprintf(print
, sizeof(print
), "decoding %d*%d",
2445 p_jpg
->x_size
/ds
, p_jpg
->y_size
/ds
);
2446 rb
->lcd_puts(0, 3, print
);
2449 /* update image properties */
2450 p_disp
->width
= p_jpg
->x_size
/ ds
;
2451 p_disp
->stride
= p_jpg
->x_phys
/ ds
; /* use physical size for stride */
2452 p_disp
->height
= p_jpg
->y_size
/ ds
;
2454 /* the actual decoding */
2455 time
= *rb
->current_tick
;
2456 #if !defined(SIMULATOR) && defined(HAVE_ADJUSTABLE_CPU_FREQ)
2457 rb
->cpu_boost(true);
2458 status
= jpeg_decode(p_jpg
, p_disp
->bitmap
, ds
, cb_progess
);
2459 rb
->cpu_boost(false);
2461 status
= jpeg_decode(p_jpg
, p_disp
->bitmap
, ds
, cb_progess
);
2465 rb
->splash(HZ
, true, "decode error %d", status
);
2466 file_pt
[curfile
] = '\0';
2469 time
= *rb
->current_tick
- time
;
2470 rb
->snprintf(print
, sizeof(print
), " %d.%02d sec ", time
/HZ
, time
%HZ
);
2471 rb
->lcd_getstringsize(print
, &w
, &h
); /* centered in progress bar */
2472 rb
->lcd_putsxy((LCD_WIDTH
- w
)/2, LCD_HEIGHT
- h
, print
);
2479 /* set the view to the given center point, limit if necessary */
2480 void set_view (struct t_disp
* p_disp
, int cx
, int cy
)
2484 /* plain center to available width/height */
2485 x
= cx
- MIN(LCD_WIDTH
, p_disp
->width
) / 2;
2486 y
= cy
- MIN(LCD_HEIGHT
, p_disp
->height
) / 2;
2488 /* limit against upper image size */
2489 x
= MIN(p_disp
->width
- LCD_WIDTH
, x
);
2490 y
= MIN(p_disp
->height
- LCD_HEIGHT
, y
);
2492 /* limit against negative side */
2496 p_disp
->x
= x
; /* set the values */
2501 /* calculate the view center based on the bitmap position */
2502 void get_view(struct t_disp
* p_disp
, int* p_cx
, int* p_cy
)
2504 *p_cx
= p_disp
->x
+ MIN(LCD_WIDTH
, p_disp
->width
) / 2;
2505 *p_cy
= p_disp
->y
+ MIN(LCD_HEIGHT
, p_disp
->height
) / 2;
2509 /* load, decode, display the image */
2510 int load_and_show(char* filename
)
2514 unsigned char* buf_jpeg
; /* compressed JPEG image */
2516 struct t_disp
* p_disp
; /* currenly displayed image */
2517 int cx
, cy
; /* view center */
2519 fd
= rb
->open(filename
, O_RDONLY
);
2522 rb
->snprintf(print
,sizeof(print
),"err opening %s:%d",filename
,fd
);
2523 rb
->splash(HZ
, true, print
);
2524 return PLUGIN_ERROR
;
2526 filesize
= rb
->filesize(fd
);
2527 rb
->memset(&disp
, 0, sizeof(disp
));
2529 buf
= buf_images
+ filesize
;
2530 buf_size
= buf_images_size
- filesize
;
2531 /* allocate JPEG buffer */
2532 buf_jpeg
= buf_images
;
2534 buf_root
= buf
; /* we can start the decompressed images behind it */
2535 root_size
= buf_size
;
2539 #if PLUGIN_BUFFER_SIZE >= MIN_MEM
2543 rb
->lcd_setfont(FONT_SYSFIXED
);
2544 rb
->lcd_clear_display();
2545 rb
->snprintf(print
,sizeof(print
),"%s:",rb
->strrchr(filename
,'/')+1);
2546 rb
->lcd_puts(0,0,print
);
2547 rb
->lcd_puts(0,1,"Not enough plugin memory!");
2548 rb
->lcd_puts(0,2,"Zoom In: Stop playback.");
2550 rb
->lcd_puts(0,3,"Left/Right: Skip File.");
2551 rb
->lcd_puts(0,4,"Off: Quit.");
2553 rb
->lcd_setfont(FONT_UI
);
2555 rb
->button_clear_queue();
2559 int button
= rb
->button_get(true);
2565 rb
->plugin_get_audio_buffer(&buf_images_size
);
2566 /*try again this file, now using the audio buffer */
2567 return PLUGIN_OTHER
;
2575 rb
->lcd_clear_display();
2576 return change_filename(DIR_PREV
);
2583 rb
->lcd_clear_display();
2584 return change_filename(DIR_NEXT
);
2588 if(rb
->default_event_handler_ex(button
, cleanup
, NULL
)
2589 == SYS_USB_CONNECTED
)
2590 return PLUGIN_USB_CONNECTED
;
2598 rb
->splash(HZ
, true, "Out of Memory");
2600 return PLUGIN_ERROR
;
2604 #ifdef HAVE_LCD_COLOR
2605 rb
->lcd_set_foreground(LCD_WHITE
);
2606 rb
->lcd_set_background(LCD_BLACK
);
2609 rb
->lcd_clear_display();
2610 rb
->snprintf(print
, sizeof(print
), "%s:", rb
->strrchr(filename
,'/')+1);
2611 rb
->lcd_puts(0, 0, print
);
2614 rb
->snprintf(print
, sizeof(print
), "loading %d bytes", filesize
);
2615 rb
->lcd_puts(0, 1, print
);
2618 rb
->read(fd
, buf_jpeg
, filesize
);
2621 rb
->snprintf(print
, sizeof(print
), "decoding markers");
2622 rb
->lcd_puts(0, 2, print
);
2627 rb
->memset(&jpg
, 0, sizeof(jpg
)); /* clear info struct */
2628 /* process markers, unstuffing */
2629 status
= process_markers(buf_jpeg
, filesize
, &jpg
);
2631 if (status
< 0 || (status
& (DQT
| SOF0
)) != (DQT
| SOF0
))
2632 { /* bad format or minimum components not contained */
2633 rb
->splash(HZ
, true, "unsupported %d", status
);
2634 file_pt
[curfile
] = '\0';
2635 return change_filename(direction
);
2638 if (!(status
& DHT
)) /* if no Huffman table present: */
2639 default_huff_tbl(&jpg
); /* use default */
2640 build_lut(&jpg
); /* derive Huffman and other lookup-tables */
2642 rb
->snprintf(print
, sizeof(print
), "image %dx%d", jpg
.x_size
, jpg
.y_size
);
2643 rb
->lcd_puts(0, 2, print
);
2646 ds_max
= max_downscale(&jpg
); /* check display constraint */
2647 ds_min
= min_downscale(&jpg
, buf_size
); /* check memory constraint */
2650 rb
->splash(HZ
, true, "too large");
2651 file_pt
[curfile
] = '\0';
2652 return change_filename(direction
);
2655 ds
= ds_max
; /* initials setting */
2656 cx
= jpg
.x_size
/ds
/2; /* center the view */
2657 cy
= jpg
.y_size
/ds
/2;
2659 do /* loop the image prepare and decoding when zoomed */
2661 p_disp
= get_image(&jpg
, ds
); /* decode or fetch from cache */
2663 return change_filename(direction
);
2665 set_view(p_disp
, cx
, cy
);
2667 rb
->snprintf(print
, sizeof(print
), "showing %dx%d",
2668 p_disp
->width
, p_disp
->height
);
2669 rb
->lcd_puts(0, 3, print
);
2672 MYLCD(clear_display
)();
2673 #ifdef HAVE_LCD_COLOR
2675 p_disp
->bitmap
, p_disp
->csub_x
, p_disp
->csub_y
,
2676 p_disp
->x
, p_disp
->y
, p_disp
->stride
,
2677 MAX(0, (LCD_WIDTH
- p_disp
->width
) / 2),
2678 MAX(0, (LCD_HEIGHT
- p_disp
->height
) / 2),
2679 MIN(LCD_WIDTH
, p_disp
->width
),
2680 MIN(LCD_HEIGHT
, p_disp
->height
));
2682 MYXLCD(gray_bitmap_part
)(
2683 p_disp
->bitmap
[0], p_disp
->x
, p_disp
->y
, p_disp
->stride
,
2684 MAX(0, (LCD_WIDTH
- p_disp
->width
) / 2),
2685 MAX(0, (LCD_HEIGHT
- p_disp
->height
) / 2),
2686 MIN(LCD_WIDTH
, p_disp
->width
),
2687 MIN(LCD_HEIGHT
, p_disp
->height
));
2692 gray_show(true); /* switch on grayscale overlay */
2695 /* drawing is now finished, play around with scrolling
2696 * until you press OFF or connect USB
2700 status
= scroll_bmp(p_disp
);
2701 if (status
== ZOOM_IN
)
2705 ds
/= 2; /* reduce downscaling to zoom in */
2706 get_view(p_disp
, &cx
, &cy
);
2707 cx
*= 2; /* prepare the position in the new image */
2714 if (status
== ZOOM_OUT
)
2718 ds
*= 2; /* increase downscaling to zoom out */
2719 get_view(p_disp
, &cx
, &cy
);
2720 cx
/= 2; /* prepare the position in the new image */
2730 gray_show(false); /* switch off overlay */
2732 rb
->lcd_clear_display();
2736 while (status
!= PLUGIN_OK
&& status
!= PLUGIN_USB_CONNECTED
2737 && status
!= PLUGIN_OTHER
);
2741 /******************** Plugin entry point *********************/
2743 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
2750 long graysize
; /* helper */
2753 rb
->strcpy(np_file
, parameter
);
2756 #if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
2757 #if CONFIG_CODEC == SWCODEC
2758 if(rb
->pcm_is_playing())
2760 if(rb
->mp3_is_playing())
2763 buf
= rb
->plugin_get_buffer(&buf_size
) +
2764 (entries
* sizeof(char**));
2765 buf_size
-= (entries
* sizeof(char**));
2769 buf
= rb
->plugin_get_audio_buffer(&buf_size
);
2771 buf
= rb
->plugin_get_audio_buffer(&buf_size
) +
2772 (entries
* sizeof(char**));
2773 buf_size
-= (entries
* sizeof(char**));
2777 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */
2778 grayscales
= gray_init(rb
, buf
, buf_size
, false, LCD_WIDTH
, LCD_HEIGHT
/8,
2781 buf_size
-= graysize
;
2782 if (grayscales
< 33 || buf_size
<= 0)
2784 rb
->splash(HZ
, true, "gray buf error");
2785 return PLUGIN_ERROR
;
2791 buf_images
= buf
; buf_images_size
= buf_size
;
2795 condition
= load_and_show(np_file
);
2796 }while (condition
!= PLUGIN_OK
&& condition
!= PLUGIN_USB_CONNECTED
2797 && condition
!= PLUGIN_ERROR
);
2800 gray_release(); /* deinitialize */
2806 #endif /* HAVE_LCD_BITMAP */