diff options
Diffstat (limited to 'utils/wpseditor/screenshot/main.c')
-rw-r--r-- | utils/wpseditor/screenshot/main.c | 361 |
1 files changed, 361 insertions, 0 deletions
diff --git a/utils/wpseditor/screenshot/main.c b/utils/wpseditor/screenshot/main.c new file mode 100644 index 0000000000..fb81e069b0 --- /dev/null +++ b/utils/wpseditor/screenshot/main.c | |||
@@ -0,0 +1,361 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Maurus Cuelenaere | ||
11 | * | ||
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. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include <stdio.h> | ||
23 | #include <stdarg.h> | ||
24 | #include <string.h> | ||
25 | #include <dlfcn.h> | ||
26 | #include <unistd.h> | ||
27 | #include "gd.h" | ||
28 | #include "gdfonts.h" | ||
29 | #include "api.h" | ||
30 | |||
31 | #define DEBUGF1 _debug | ||
32 | #define DEBUGF2 if(verbose) _debug | ||
33 | |||
34 | #define getFont() gdFontGetSmall() | ||
35 | |||
36 | static struct trackstate mp3data = | ||
37 | { | ||
38 | (char*)"Test title", | ||
39 | (char*)"Test artist", | ||
40 | (char*)"Test album", | ||
41 | (char*)"Test genre", | ||
42 | (char*)"Test disc", | ||
43 | (char*)"Test track", | ||
44 | (char*)"Test year", | ||
45 | (char*)"Test composer", | ||
46 | (char*)"Test comment", | ||
47 | (char*)"Test album artist", | ||
48 | (char*)"Test grouping", | ||
49 | 1, /* int discnum */ | ||
50 | 1, /* int tracknum */ | ||
51 | 1, /* int version */ | ||
52 | 1, /* int layer */ | ||
53 | 2008, /* int year */ | ||
54 | |||
55 | 100, /* int length */ | ||
56 | 70 /* int elapsed */ | ||
57 | }; | ||
58 | |||
59 | static struct wpsstate wpsdata = {-20, -1, -1, 70, API_STATUS_FASTFORWARD}; | ||
60 | /* volume, fontheight, fontwidth, battery_level, audio_status */ | ||
61 | |||
62 | static struct proxy_api api; | ||
63 | static bool verbose = false; | ||
64 | static int (*wps_init)(const char* buff, struct proxy_api *api, bool isfile); | ||
65 | static int (*wps_display)(); | ||
66 | static int (*wps_refresh)(); | ||
67 | static gdImagePtr framebuffer; | ||
68 | static gdImagePtr backdrop; | ||
69 | |||
70 | extern gdImagePtr gdImageCreateFromBmp(FILE * inFile); | ||
71 | extern char *get_current_dir_name (void) __THROW; | ||
72 | |||
73 | int _debug(const char* fmt,...) | ||
74 | { | ||
75 | #if 0 /* Doesn't want to compile ?? */ | ||
76 | struct va_list ap; | ||
77 | |||
78 | va_start(ap, fmt); | ||
79 | |||
80 | fprintf(stdout, "[DBG] "); | ||
81 | vfprintf(stdout, fmt, ap); | ||
82 | fprintf(stdout, "\n"); | ||
83 | |||
84 | va_end(ap); | ||
85 | |||
86 | return 0; | ||
87 | #else | ||
88 | return -1; | ||
89 | #endif | ||
90 | } | ||
91 | |||
92 | void _putsxy(int x, int y, const unsigned char *str) | ||
93 | { | ||
94 | struct viewport_api avp; | ||
95 | int black = gdImageColorAllocate(framebuffer, 0, 0, 0); | ||
96 | |||
97 | api.get_current_vp(&avp); | ||
98 | |||
99 | gdImageString(framebuffer, getFont(), x + avp.x, y + avp.y - avp.fontheight, (unsigned char*)str, black); | ||
100 | } | ||
101 | |||
102 | void _transparent_bitmap_part(const void *src, int src_x, int src_y, | ||
103 | int stride, int x, int y, int width, int height) | ||
104 | { | ||
105 | FILE *_image; | ||
106 | gdImagePtr image; | ||
107 | int pink; | ||
108 | |||
109 | DEBUGF2("transparent_bitmap_part(const void *src=%s, int src_x=%d, int src_y=%d, int stride=%d, int x=%d, int y=%d, int width=%d, int height=%d", (char*)src, src_x, src_y, stride, x, y, width, height); | ||
110 | |||
111 | _image = fopen(src, "rb"); | ||
112 | if(_image == NULL) | ||
113 | return; | ||
114 | |||
115 | image = gdImageCreateFromBmp(_image); | ||
116 | fclose(_image); | ||
117 | |||
118 | pink = gdTrueColor(255, 0, 255); | ||
119 | gdImageColorTransparent(image, pink); | ||
120 | |||
121 | gdImageCopy(framebuffer, image, x, y, src_x, src_y, width, height); | ||
122 | |||
123 | gdImageDestroy(image); | ||
124 | } | ||
125 | |||
126 | void _bitmap_part(const void *src, int src_x, int src_y, | ||
127 | int stride, int x, int y, int width, int height) | ||
128 | { | ||
129 | FILE *_image; | ||
130 | gdImagePtr image; | ||
131 | |||
132 | DEBUGF2("bitmap_part(const void *src=%s, int src_x=%d, int src_y=%d, int stride=%d, int x=%d, int y=%d, int width=%d, int height=%d", (char*)src, src_x, src_y, stride, x, y, width, height); | ||
133 | |||
134 | _image = fopen(src, "rb"); | ||
135 | if(_image == NULL) | ||
136 | return; | ||
137 | |||
138 | image = gdImageCreateFromBmp(_image); | ||
139 | fclose(_image); | ||
140 | |||
141 | gdImageCopy(framebuffer, image, x, y, src_x, src_y, width, height); | ||
142 | |||
143 | gdImageDestroy(image); | ||
144 | } | ||
145 | |||
146 | void _drawpixel(int x, int y) | ||
147 | { | ||
148 | int black = gdImageColorAllocate(framebuffer, 0, 0, 0); | ||
149 | gdImageSetPixel(framebuffer, x, y, black); | ||
150 | } | ||
151 | |||
152 | void _fillrect(int x, int y, int width, int height) | ||
153 | { | ||
154 | /* Don't draw this as backdrop is used */ | ||
155 | #if 0 | ||
156 | int black = gdImageColorAllocate(framebuffer, 0, 0, 0); | ||
157 | gdImageFilledRectangle(framebuffer, x, y, x+width, y+height, black); | ||
158 | #endif | ||
159 | } | ||
160 | |||
161 | void _hline(int x1, int x2, int y) | ||
162 | { | ||
163 | int black = gdImageColorAllocate(framebuffer, 0, 0, 0); | ||
164 | gdImageLine(framebuffer, x1, y, x2, y, black); | ||
165 | } | ||
166 | |||
167 | void _vline(int x, int y1, int y2) | ||
168 | { | ||
169 | int black = gdImageColorAllocate(framebuffer, 0, 0, 0); | ||
170 | gdImageLine(framebuffer, x, y1, x, y2, black); | ||
171 | } | ||
172 | |||
173 | void _clear_viewport(int x, int y, int w, int h, int color) | ||
174 | { | ||
175 | if(backdrop == NULL) | ||
176 | return; | ||
177 | |||
178 | gdImageCopy(framebuffer, backdrop, x, y, x, y, w, h); | ||
179 | } | ||
180 | |||
181 | static bool _load_wps_backdrop(char* filename) | ||
182 | { | ||
183 | FILE *image; | ||
184 | if(backdrop != NULL) | ||
185 | gdImageDestroy(backdrop); | ||
186 | |||
187 | DEBUGF2("load backdrop: %s", filename); | ||
188 | |||
189 | image = fopen(filename, "rb"); | ||
190 | if(image == NULL) | ||
191 | return false; | ||
192 | |||
193 | backdrop = gdImageCreateFromBmp(image); | ||
194 | fclose(image); | ||
195 | |||
196 | return true; | ||
197 | } | ||
198 | |||
199 | int _read_bmp_file(const char* filename, int *width, int *height) | ||
200 | { | ||
201 | FILE *_image; | ||
202 | gdImagePtr image; | ||
203 | |||
204 | DEBUGF2("load backdrop: %s", filename); | ||
205 | |||
206 | _image = fopen(filename, "rb"); | ||
207 | if(_image == NULL) | ||
208 | return 0; | ||
209 | |||
210 | image = gdImageCreateFromBmp(_image); | ||
211 | fclose(_image); | ||
212 | |||
213 | *width = image->sx; | ||
214 | *height = image->sy; | ||
215 | |||
216 | gdImageDestroy(image); | ||
217 | |||
218 | return 1; | ||
219 | } | ||
220 | |||
221 | static void _drawBackdrop() | ||
222 | { | ||
223 | if(backdrop == NULL) | ||
224 | return; | ||
225 | |||
226 | gdImageCopy(framebuffer, backdrop, 0, 0, 0, 0, backdrop->sx, backdrop->sy); | ||
227 | } | ||
228 | |||
229 | static int screenshot(char *model, char *wps, char *png) | ||
230 | { | ||
231 | char lib[255]; | ||
232 | void *handle; | ||
233 | FILE *out, *in; | ||
234 | |||
235 | in = fopen(wps, "rb"); | ||
236 | if(in == NULL) | ||
237 | { | ||
238 | fprintf(stderr, "[ERR] Cannot open WPS: %s\n", wps); | ||
239 | return -1; | ||
240 | } | ||
241 | fclose(in); | ||
242 | |||
243 | out = fopen(png, "wb"); | ||
244 | if(out == NULL) | ||
245 | { | ||
246 | fprintf(stderr, "[ERR] Cannot open PNG: %s\n", png); | ||
247 | return -2; | ||
248 | } | ||
249 | |||
250 | snprintf(lib, 255, "%s/libwps_%s.so", (char*)get_current_dir_name(), (char*)model); | ||
251 | handle = dlopen(lib, RTLD_LAZY); | ||
252 | if (!handle) | ||
253 | { | ||
254 | fprintf(stderr, "[ERR] Cannot open library: %s\n", dlerror()); | ||
255 | fclose(out); | ||
256 | return -3; | ||
257 | } | ||
258 | |||
259 | wps_init = dlsym(handle, "wps_init"); | ||
260 | wps_display = dlsym(handle, "wps_display"); | ||
261 | wps_refresh = dlsym(handle, "wps_refresh"); | ||
262 | |||
263 | if (!wps_init || !wps_display || !wps_refresh) | ||
264 | { | ||
265 | fprintf(stderr, "[ERR] Failed to resolve funcs!"); | ||
266 | dlclose(handle); | ||
267 | fclose(out); | ||
268 | return -4; | ||
269 | } | ||
270 | |||
271 | memset(&api, 0, sizeof(struct proxy_api)); | ||
272 | |||
273 | if(verbose) | ||
274 | api.verbose = 3; | ||
275 | else | ||
276 | api.verbose = 0; | ||
277 | |||
278 | api.putsxy = &_putsxy; | ||
279 | api.transparent_bitmap_part = &_transparent_bitmap_part; | ||
280 | api.bitmap_part = &_bitmap_part; | ||
281 | api.drawpixel = &_drawpixel; | ||
282 | api.fillrect = &_fillrect; | ||
283 | api.hline = &_hline; | ||
284 | api.vline = &_vline; | ||
285 | api.clear_viewport = &_clear_viewport; | ||
286 | api.load_wps_backdrop = &_load_wps_backdrop; | ||
287 | api.read_bmp_file = &_read_bmp_file; | ||
288 | api.debugf = &_debug; | ||
289 | |||
290 | wps_init(wps, &api, true); | ||
291 | |||
292 | framebuffer = gdImageCreateTrueColor(api.getwidth(), api.getheight()); | ||
293 | |||
294 | _drawBackdrop(); | ||
295 | |||
296 | if(strcmp(api.get_model_name(), model) != 0) | ||
297 | { | ||
298 | fprintf(stderr, "[ERR] Model name doesn't match the one supplied by the library\n"); | ||
299 | fprintf(stderr, " %s <-> %s\n", model, api.get_model_name()); | ||
300 | dlclose(handle); | ||
301 | fclose(out); | ||
302 | gdImageDestroy(framebuffer); | ||
303 | gdImageDestroy(backdrop); | ||
304 | wps_init = NULL; | ||
305 | wps_display = NULL; | ||
306 | wps_refresh = NULL; | ||
307 | return -5; | ||
308 | } | ||
309 | fprintf(stdout, "[INFO] Model: %s\n", api.get_model_name()); | ||
310 | |||
311 | wpsdata.fontheight = getFont()->h; | ||
312 | wpsdata.fontwidth = getFont()->w; | ||
313 | api.set_wpsstate(wpsdata); | ||
314 | api.set_trackstate(mp3data); | ||
315 | api.set_next_trackstate(mp3data); | ||
316 | |||
317 | _drawBackdrop(); | ||
318 | wps_refresh(); | ||
319 | gdImagePng(framebuffer, out); | ||
320 | |||
321 | fprintf(stdout, "[INFO] Image written\n"); | ||
322 | |||
323 | dlclose(handle); | ||
324 | fclose(out); | ||
325 | gdImageDestroy(framebuffer); | ||
326 | gdImageDestroy(backdrop); | ||
327 | |||
328 | wps_init = NULL; | ||
329 | wps_display = NULL; | ||
330 | wps_refresh = NULL; | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static void usage(void) | ||
336 | { | ||
337 | fprintf(stderr, "Usage: screenshot [-V] <MODEL> <WPS_FILE> <OUT_PNG>\n"); | ||
338 | fprintf(stderr, "Example: screenshot h10_5gb iCatcher.wps out.png\n"); | ||
339 | } | ||
340 | |||
341 | int main(int argc, char ** argv) | ||
342 | { | ||
343 | if(argc < 4) | ||
344 | { | ||
345 | usage(); | ||
346 | return -1; | ||
347 | } | ||
348 | |||
349 | if(strcmp(argv[1], "-V") == 0) | ||
350 | { | ||
351 | verbose = true; | ||
352 | return screenshot(argv[2], argv[3], argv[4]); | ||
353 | } | ||
354 | else | ||
355 | { | ||
356 | verbose = false; | ||
357 | return screenshot(argv[1], argv[2], argv[3]); | ||
358 | } | ||
359 | |||
360 | return 0; | ||
361 | } | ||