1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
11 * (This is a real mess if it has to be coded in one single C file)
13 * File scrolling addition (C) 2005 Alexander Spyridakis
14 * Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon
15 * Heavily borrowed from the IJG implementation (C) Thomas G. Lane
16 * Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
26 ****************************************************************************/
30 #include "../imageviewer.h"
31 #include "jpeg_decoder.h"
37 /**************** begin Application ********************/
39 /************************* Types ***************************/
44 unsigned char* bitmap
[3]; /* Y, Cr, Cb */
47 unsigned char* bitmap
[1]; /* Y only */
52 /************************* Globals ***************************/
54 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
55 static struct t_disp disp
[9];
57 /* my memory pool (from the mp3 buffer) */
58 static char print
[32]; /* use a common snprintf() buffer */
60 /* the root of the images, hereafter are decompresed ones */
61 static unsigned char* buf_root
;
64 /* up to here currently used by image(s) */
65 static unsigned char* buf_images
;
66 static ssize_t buf_images_size
;
68 static struct jpeg jpg
; /* too large for stack */
70 /************************* Implementation ***************************/
72 bool img_ext(const char *ext
)
76 if(!rb
->strcasecmp(ext
,".jpg") ||
77 !rb
->strcasecmp(ext
,".jpe") ||
78 !rb
->strcasecmp(ext
,".jpeg"))
84 void draw_image_rect(struct image_info
*info
,
85 int x
, int y
, int width
, int height
)
87 struct t_disp
* pdisp
= (struct t_disp
*)info
->data
;
90 pdisp
->bitmap
, pdisp
->csub_x
, pdisp
->csub_y
,
91 info
->x
+ x
, info
->y
+ y
, pdisp
->stride
,
92 x
+ MAX(0, (LCD_WIDTH
- info
->width
) / 2),
93 y
+ MAX(0, (LCD_HEIGHT
- info
->height
) / 2),
95 settings
.jpeg_colour_mode
, settings
.jpeg_dither_mode
);
97 MYXLCD(gray_bitmap_part
)(
98 pdisp
->bitmap
[0], info
->x
+ x
, info
->y
+ y
, pdisp
->stride
,
99 x
+ MAX(0, (LCD_WIDTH
-info
->width
)/2),
100 y
+ MAX(0, (LCD_HEIGHT
-info
->height
)/2),
108 struct jpeg
*p_jpg
= &jpg
;
110 size
= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[0])
111 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[0]);
112 #ifdef HAVE_LCD_COLOR
113 if (p_jpg
->blocks
> 1) /* colour, add requirements for chroma */
115 size
+= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[1])
116 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[1]);
117 size
+= (p_jpg
->x_phys
/ds
/p_jpg
->subsample_x
[2])
118 * (p_jpg
->y_phys
/ds
/p_jpg
->subsample_y
[2]);
124 int load_image(char *filename
, struct image_info
*info
,
125 unsigned char *buf
, ssize_t
*buf_size
)
129 unsigned char* buf_jpeg
; /* compressed JPEG image */
131 struct jpeg
*p_jpg
= &jpg
;
133 rb
->memset(&disp
, 0, sizeof(disp
));
134 rb
->memset(&jpg
, 0, sizeof(jpg
));
136 fd
= rb
->open(filename
, O_RDONLY
);
139 rb
->splashf(HZ
, "err opening %s:%d", filename
, fd
);
142 filesize
= rb
->filesize(fd
);
144 /* allocate JPEG buffer */
147 /* we can start the decompressed images behind it */
148 buf_images
= buf_root
= buf
+ filesize
;
149 buf_images_size
= root_size
= *buf_size
- filesize
;
151 if (buf_images_size
<= 0)
154 return PLUGIN_OUTOFMEM
;
157 if(!running_slideshow
)
159 rb
->snprintf(print
, sizeof(print
), "%s:", rb
->strrchr(filename
,'/')+1);
160 rb
->lcd_puts(0, 0, print
);
163 rb
->snprintf(print
, sizeof(print
), "loading %d bytes", filesize
);
164 rb
->lcd_puts(0, 1, print
);
168 rb
->read(fd
, buf_jpeg
, filesize
);
171 if(!running_slideshow
)
173 rb
->snprintf(print
, sizeof(print
), "decoding markers");
174 rb
->lcd_puts(0, 2, print
);
178 else if(immediate_ata_off
)
180 /* running slideshow and time is long enough: power down disk */
185 /* process markers, unstuffing */
186 status
= process_markers(buf_jpeg
, filesize
, p_jpg
);
188 if (status
< 0 || (status
& (DQT
| SOF0
)) != (DQT
| SOF0
))
189 { /* bad format or minimum components not contained */
190 rb
->splashf(HZ
, "unsupported %d", status
);
194 if (!(status
& DHT
)) /* if no Huffman table present: */
195 default_huff_tbl(p_jpg
); /* use default */
196 build_lut(p_jpg
); /* derive Huffman and other lookup-tables */
198 if(!running_slideshow
)
200 rb
->snprintf(print
, sizeof(print
), "image %dx%d",
201 p_jpg
->x_size
, p_jpg
->y_size
);
202 rb
->lcd_puts(0, 2, print
);
206 info
->x_size
= p_jpg
->x_size
;
207 info
->y_size
= p_jpg
->y_size
;
208 *buf_size
= buf_images_size
;
212 int get_image(struct image_info
*info
, int ds
)
214 int w
, h
; /* used to center output */
215 int size
; /* decompressed image size */
216 long time
; /* measured ticks */
218 struct jpeg
* p_jpg
= &jpg
;
219 struct t_disp
* p_disp
= &disp
[ds
]; /* short cut */
221 info
->width
= p_jpg
->x_size
/ ds
;
222 info
->height
= p_jpg
->y_size
/ ds
;
225 if (p_disp
->bitmap
[0] != NULL
)
227 /* we still have it */
231 /* assign image buffer */
233 /* physical size needed for decoding */
235 if (buf_images_size
<= size
)
236 { /* have to discard the current */
239 disp
[i
].bitmap
[0] = NULL
; /* invalidate all bitmaps */
240 buf_images
= buf_root
; /* start again from the beginning of the buffer */
241 buf_images_size
= root_size
;
244 #ifdef HAVE_LCD_COLOR
245 if (p_jpg
->blocks
> 1) /* colour jpeg */
249 for (i
= 1; i
< 3; i
++)
251 size
= (p_jpg
->x_phys
/ ds
/ p_jpg
->subsample_x
[i
])
252 * (p_jpg
->y_phys
/ ds
/ p_jpg
->subsample_y
[i
]);
253 p_disp
->bitmap
[i
] = buf_images
;
255 buf_images_size
-= size
;
257 p_disp
->csub_x
= p_jpg
->subsample_x
[1];
258 p_disp
->csub_y
= p_jpg
->subsample_y
[1];
262 p_disp
->csub_x
= p_disp
->csub_y
= 0;
263 p_disp
->bitmap
[1] = p_disp
->bitmap
[2] = buf_images
;
266 /* size may be less when decoded (if height is not block aligned) */
267 size
= (p_jpg
->x_phys
/ds
) * (p_jpg
->y_size
/ds
);
268 p_disp
->bitmap
[0] = buf_images
;
270 buf_images_size
-= size
;
272 if(!running_slideshow
)
274 rb
->snprintf(print
, sizeof(print
), "decoding %d*%d",
275 p_jpg
->x_size
/ds
, p_jpg
->y_size
/ds
);
276 rb
->lcd_puts(0, 3, print
);
280 /* update image properties */
281 p_disp
->stride
= p_jpg
->x_phys
/ ds
; /* use physical size for stride */
283 /* the actual decoding */
284 time
= *rb
->current_tick
;
285 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
287 status
= jpeg_decode(p_jpg
, p_disp
->bitmap
, ds
, cb_progress
);
288 rb
->cpu_boost(false);
290 status
= jpeg_decode(p_jpg
, p_disp
->bitmap
, ds
, cb_progress
);
294 rb
->splashf(HZ
, "decode error %d", status
);
297 time
= *rb
->current_tick
- time
;
299 if(!running_slideshow
)
301 rb
->snprintf(print
, sizeof(print
), " %ld.%02ld sec ", time
/HZ
, time
%HZ
);
302 rb
->lcd_getstringsize(print
, &w
, &h
); /* centered in progress bar */
303 rb
->lcd_putsxy((LCD_WIDTH
- w
)/2, LCD_HEIGHT
- h
, print
);