summaryrefslogtreecommitdiff
path: root/utils/wpseditor/screenshot/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/wpseditor/screenshot/main.c')
-rw-r--r--utils/wpseditor/screenshot/main.c361
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
36static 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",
491, /* int discnum */
501, /* int tracknum */
511, /* int version */
521, /* int layer */
532008, /* int year */
54
55100, /* int length */
5670 /* int elapsed */
57};
58
59static struct wpsstate wpsdata = {-20, -1, -1, 70, API_STATUS_FASTFORWARD};
60 /* volume, fontheight, fontwidth, battery_level, audio_status */
61
62static struct proxy_api api;
63static bool verbose = false;
64static int (*wps_init)(const char* buff, struct proxy_api *api, bool isfile);
65static int (*wps_display)();
66static int (*wps_refresh)();
67static gdImagePtr framebuffer;
68static gdImagePtr backdrop;
69
70extern gdImagePtr gdImageCreateFromBmp(FILE * inFile);
71extern char *get_current_dir_name (void) __THROW;
72
73int _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
92void _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
102void _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
126void _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
146void _drawpixel(int x, int y)
147{
148 int black = gdImageColorAllocate(framebuffer, 0, 0, 0);
149 gdImageSetPixel(framebuffer, x, y, black);
150}
151
152void _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
161void _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
167void _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
173void _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
181static 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
199int _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
221static void _drawBackdrop()
222{
223 if(backdrop == NULL)
224 return;
225
226 gdImageCopy(framebuffer, backdrop, 0, 0, 0, 0, backdrop->sx, backdrop->sy);
227}
228
229static 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
335static 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
341int 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}