1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2010 Marcin Bukat
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
24 #include <lib/pluginlib_bmp.h>
25 #include "../imageviewer.h"
26 #include "ppm_decoder.h"
29 static char print
[32]; /* use a common snprintf() buffer */
31 /* decompressed image in the possible sizes (1,2,4,8), wasting the other */
32 static unsigned char *disp
[9];
33 static unsigned char *disp_buf
;
34 static struct ppm_info ppm
;
36 #if defined(HAVE_LCD_COLOR)
37 #define resize_bitmap smooth_resize_bitmap
39 #define resize_bitmap grey_resize_bitmap
42 #if defined(USEGSLIB) && (CONFIG_PLATFORM & PLATFORM_HOSTED)
43 /* hack: fix error "undefined reference to `_grey_info'". */
47 static void draw_image_rect(struct image_info
*info
,
48 int x
, int y
, int width
, int height
)
50 unsigned char **pdisp
= (unsigned char **)info
->data
;
53 rb
->lcd_bitmap_part((fb_data
*)*pdisp
, info
->x
+ x
, info
->y
+ y
,
54 STRIDE(SCREEN_MAIN
, info
->width
, info
->height
),
55 x
+ MAX(0, (LCD_WIDTH
-info
->width
)/2),
56 y
+ MAX(0, (LCD_HEIGHT
-info
->height
)/2),
59 mylcd_ub_gray_bitmap_part(*pdisp
,
60 info
->x
+ x
, info
->y
+ y
, info
->width
,
61 x
+ MAX(0, (LCD_WIDTH
-info
->width
)/2),
62 y
+ MAX(0, (LCD_HEIGHT
-info
->height
)/2),
67 static int img_mem(int ds
)
71 return (ppm
.x
/ds
) * (ppm
.y
/ds
);
73 return (ppm
.x
/ds
) * (ppm
.y
/ds
) * FB_DATA_SZ
;
77 static int load_image(char *filename
, struct image_info
*info
,
78 unsigned char *buf
, ssize_t
*buf_size
)
82 long time
= 0; /* measured ticks */
83 int w
, h
; /* used to center output */
85 unsigned char *memory
, *memory_max
;
86 size_t memory_size
, file_size
;
89 memset(&disp
, 0, sizeof(disp
));
92 memory
= (unsigned char *)((intptr_t)(buf
+ 3) & ~3);
93 memory_max
= (unsigned char *)((intptr_t)(memory
+ *buf_size
) & ~3);
94 memory_size
= memory_max
- memory
;
96 fd
= rb
->open(filename
, O_RDONLY
);
99 rb
->splashf(HZ
, "err opening %s: %d", filename
, fd
);
103 file_size
= rb
->filesize(fd
);
104 DEBUGF("reading file '%s'\n", filename
);
106 if (!iv
->running_slideshow
)
108 rb
->lcd_puts(0, 0, rb
->strrchr(filename
,'/')+1);
109 rb
->lcd_putsf(0, 1, "loading %zu bytes", file_size
);
113 /* init decoder struct */
115 ppm
.buf_size
= memory_size
;
117 /* the actual decoding */
118 time
= *rb
->current_tick
;
119 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
121 rc
= read_ppm(fd
, &ppm
);
122 rb
->cpu_boost(false);
124 rc
= read_ppm(fd
, &ppm
);
125 #endif /*HAVE_ADJUSTABLE_CPU_FREQ*/
126 time
= *rb
->current_tick
- time
;
135 if (!iv
->running_slideshow
)
137 rb
->snprintf(print
, sizeof(print
), " %ld.%02ld sec ", time
/HZ
, time
%HZ
);
138 rb
->lcd_getstringsize(print
, &w
, &h
); /* centered in progress bar */
139 rb
->lcd_putsxy((LCD_WIDTH
- w
)/2, LCD_HEIGHT
- h
, print
);
143 info
->x_size
= ppm
.x
;
144 info
->y_size
= ppm
.y
;
146 ppm
.native_img_size
= (ppm
.native_img_size
+ 3) & ~3;
147 disp_buf
= buf
+ ppm
.native_img_size
;
148 *buf_size
= memory_max
- disp_buf
;
153 static int get_image(struct image_info
*info
, int ds
)
155 unsigned char **p_disp
= &disp
[ds
]; /* short cut */
156 struct ppm_info
*p_ppm
= &ppm
;
158 info
->width
= ppm
.x
/ ds
;
159 info
->height
= ppm
.y
/ ds
;
164 /* we still have it */
168 /* assign image buffer */
171 if (!iv
->running_slideshow
)
173 rb
->lcd_putsf(0, 3, "resizing %d*%d", info
->width
, info
->height
);
177 struct bitmap bmp_src
, bmp_dst
;
178 int size
= img_mem(ds
);
180 if (disp_buf
+ size
>= p_ppm
->buf
+ p_ppm
->buf_size
)
182 /* have to discard the current */
185 disp
[i
] = NULL
; /* invalidate all bitmaps */
187 /* start again from the beginning of the buffer */
188 disp_buf
= p_ppm
->buf
+ p_ppm
->native_img_size
;
194 bmp_src
.width
= ppm
.x
;
195 bmp_src
.height
= ppm
.y
;
196 bmp_src
.data
= ppm
.buf
;
198 bmp_dst
.width
= info
->width
;
199 bmp_dst
.height
= info
->height
;
200 bmp_dst
.data
= *p_disp
;
201 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
203 resize_bitmap(&bmp_src
, &bmp_dst
);
204 rb
->cpu_boost(false);
206 resize_bitmap(&bmp_src
, &bmp_dst
);
207 #endif /*HAVE_ADJUSTABLE_CPU_FREQ*/
211 *p_disp
= p_ppm
->buf
;
217 const struct image_decoder image_decoder
= {