summaryrefslogtreecommitdiff
path: root/utils/wpseditor/screenshot
diff options
context:
space:
mode:
Diffstat (limited to 'utils/wpseditor/screenshot')
-rw-r--r--utils/wpseditor/screenshot/Makefile29
-rw-r--r--utils/wpseditor/screenshot/bmp.h114
-rw-r--r--utils/wpseditor/screenshot/gd_bmp.c778
-rw-r--r--utils/wpseditor/screenshot/main.c377
4 files changed, 0 insertions, 1298 deletions
diff --git a/utils/wpseditor/screenshot/Makefile b/utils/wpseditor/screenshot/Makefile
deleted file mode 100644
index f9309f58a5..0000000000
--- a/utils/wpseditor/screenshot/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9ROOT=../../..
10
11CC = gcc
12RM = rm -f
13
14COMMON = main.c gd_bmp.c
15
16INCLUDE = -I ../libwps/src \
17 -I $(ROOT)/apps/gui \
18 -I $(ROOT)/firmware/export \
19 -I $(ROOT)/apps/recorder \
20 -I $(ROOT)/apps \
21 -I .
22
23CFLAGS = -g -Wall
24
25all:
26 $(CC) $(INCLUDE) $(CFLAGS) $(COMMON) -rdynamic -ldl -lgd -lpng -o screenshot
27
28clean:
29 $(RM) screenshot
diff --git a/utils/wpseditor/screenshot/bmp.h b/utils/wpseditor/screenshot/bmp.h
deleted file mode 100644
index 71d5a4a5bc..0000000000
--- a/utils/wpseditor/screenshot/bmp.h
+++ /dev/null
@@ -1,114 +0,0 @@
1/* $Id$ */
2#ifdef __cplusplus
3extern "C" {
4#endif
5
6/*
7 gd_bmp.c
8
9 Bitmap format support for libgd
10
11 * Written 2007, Scott MacVicar
12 ---------------------------------------------------------------------------
13
14 Todo:
15
16 RLE4, RLE8 and Bitfield encoding
17 Add full support for Windows v4 and Windows v5 header formats
18
19 ----------------------------------------------------------------------------
20 */
21
22#ifndef BMP_H
23#define BMP_H 1
24
25#define BMP_PALETTE_3 1
26#define BMP_PALETTE_4 2
27
28#define BMP_WINDOWS_V3 40
29#define BMP_OS2_V1 12
30#define BMP_OS2_V2 64
31#define BMP_WINDOWS_V4 108
32#define BMP_WINDOWS_V5 124
33
34#define BMP_BI_RGB 0
35#define BMP_BI_RLE8 1
36#define BMP_BI_RLE4 2
37#define BMP_BI_BITFIELDS 3
38#define BMP_BI_JPEG 4
39#define BMP_BI_PNG 5
40
41#define BMP_RLE_COMMAND 0
42#define BMP_RLE_ENDOFLINE 0
43#define BMP_RLE_ENDOFBITMAP 1
44#define BMP_RLE_DELTA 2
45
46#define BMP_RLE_TYPE_RAW 0
47#define BMP_RLE_TYPE_RLE 1
48
49/* BMP header. */
50typedef struct
51{
52 /* 16 bit - header identifying the type */
53 signed short int magic;
54
55 /* 32bit - size of the file */
56 int size;
57
58 /* 16bit - these two are in the spec but "reserved" */
59 signed short int reserved1;
60 signed short int reserved2;
61
62 /* 32 bit - offset of the bitmap header from data in bytes */
63 signed int off;
64
65} bmp_hdr_t;
66
67/* BMP info. */
68typedef struct
69{
70 /* 16bit - Type, ie Windows or OS/2 for the palette info */
71 signed short int type;
72 /* 32bit - The length of the bitmap information header in bytes. */
73 signed int len;
74
75 /* 32bit - The width of the bitmap in pixels. */
76 signed int width;
77
78 /* 32bit - The height of the bitmap in pixels. */
79 signed int height;
80
81 /* 8 bit - The bitmap data is specified in top-down order. */
82 signed char topdown;
83
84 /* 16 bit - The number of planes. This must be set to a value of one. */
85 signed short int numplanes;
86
87 /* 16 bit - The number of bits per pixel. */
88 signed short int depth;
89
90 /* 32bit - The type of compression used. */
91 signed int enctype;
92
93 /* 32bit - The size of the image in bytes. */
94 signed int size;
95
96 /* 32bit - The horizontal resolution in pixels/metre. */
97 signed int hres;
98
99 /* 32bit - The vertical resolution in pixels/metre. */
100 signed int vres;
101
102 /* 32bit - The number of color indices used by the bitmap. */
103 signed int numcolors;
104
105 /* 32bit - The number of color indices important for displaying the bitmap. */
106 signed int mincolors;
107
108} bmp_info_t;
109
110#endif
111
112#ifdef __cplusplus
113}
114#endif
diff --git a/utils/wpseditor/screenshot/gd_bmp.c b/utils/wpseditor/screenshot/gd_bmp.c
deleted file mode 100644
index 8fe737da03..0000000000
--- a/utils/wpseditor/screenshot/gd_bmp.c
+++ /dev/null
@@ -1,778 +0,0 @@
1/*
2 Stolen from http://cvs.php.net/viewcvs.cgi/gd/playground/gdbmp/
3*/
4
5/*
6 gd_bmp.c
7
8 Bitmap format support for libgd
9
10 * Written 2007, Scott MacVicar
11 ---------------------------------------------------------------------------
12
13 Todo:
14
15 Bitfield encoding
16
17 ----------------------------------------------------------------------------
18 */
19/* $Id$ */
20#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#include <stdio.h>
25#include <math.h>
26#include <string.h>
27#include <stdlib.h>
28#include "gd.h"
29#include "bmp.h"
30
31extern void* gdCalloc (size_t nmemb, size_t size);
32
33static int bmp_read_header(gdIOCtxPtr infile, bmp_hdr_t *hdr);
34static int bmp_read_info(gdIOCtxPtr infile, bmp_info_t *info);
35static int bmp_read_windows_v3_info(gdIOCtxPtr infile, bmp_info_t *info);
36static int bmp_read_os2_v1_info(gdIOCtxPtr infile, bmp_info_t *info);
37static int bmp_read_os2_v2_info(gdIOCtxPtr infile, bmp_info_t *info);
38
39static int bmp_read_direct(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header);
40static int bmp_read_1bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header);
41static int bmp_read_4bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header);
42static int bmp_read_8bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header);
43static int bmp_read_rle(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info);
44
45#if GD_MAJOR_VERSION == 2 && GD_MINOR_VERSION < 1
46/* Byte helper functions, since added to GD 2.1 */
47static int gdGetIntLSB(signed int *result, gdIOCtx * ctx);
48static int gdGetWordLSB(signed short int *result, gdIOCtx * ctx);
49#endif
50
51#define BMP_DEBUG(s)
52
53gdImagePtr gdImageCreateFromBmpCtx(gdIOCtxPtr infile);
54
55gdImagePtr gdImageCreateFromBmp(FILE * inFile)
56{
57 gdImagePtr im = 0;
58 gdIOCtx *in = gdNewFileCtx(inFile);
59 im = gdImageCreateFromBmpCtx(in);
60 in->gd_free(in);
61 return im;
62}
63
64gdImagePtr gdImageCreateFromBmpPtr(int size, void *data)
65{
66 gdImagePtr im;
67 gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
68 im = gdImageCreateFromBmpCtx(in);
69 in->gd_free(in);
70 return im;
71}
72
73gdImagePtr gdImageCreateFromBmpCtx(gdIOCtxPtr infile)
74{
75 bmp_hdr_t *hdr;
76 bmp_info_t *info;
77 gdImagePtr im = NULL;
78 int error = 0;
79
80 if (!(hdr= (bmp_hdr_t *)gdCalloc(1, sizeof(bmp_hdr_t)))) {
81 return NULL;
82 }
83
84 if (bmp_read_header(infile, hdr)) {
85 gdFree(hdr);
86 return NULL;
87 }
88
89 if (hdr->magic != 0x4d42) {
90 gdFree(hdr);
91 return NULL;
92 }
93
94 if (!(info = (bmp_info_t *)gdCalloc(1, sizeof(bmp_info_t)))) {
95 gdFree(hdr);
96 return NULL;
97 }
98
99 if (bmp_read_info(infile, info)) {
100 gdFree(hdr);
101 gdFree(info);
102 return NULL;
103 }
104
105 BMP_DEBUG(printf("Numcolours: %d\n", info->numcolors));
106 BMP_DEBUG(printf("Width: %d\n", info->width));
107 BMP_DEBUG(printf("Height: %d\n", info->height));
108 BMP_DEBUG(printf("Planes: %d\n", info->numplanes));
109 BMP_DEBUG(printf("Depth: %d\n", info->depth));
110 BMP_DEBUG(printf("Offset: %d\n", hdr->off));
111
112 if (info->depth >= 16) {
113 im = gdImageCreateTrueColor(info->width, info->height);
114 } else {
115 im = gdImageCreate(info->width, info->height);
116 }
117
118 if (!im) {
119 gdFree(hdr);
120 gdFree(info);
121 return NULL;
122 }
123
124 switch (info->depth) {
125 case 1:
126 BMP_DEBUG(printf("1-bit image\n"));
127 error = bmp_read_1bit(im, infile, info, hdr);
128 break;
129 case 4:
130 BMP_DEBUG(printf("4-bit image\n"));
131 error = bmp_read_4bit(im, infile, info, hdr);
132 break;
133 case 8:
134 BMP_DEBUG(printf("8-bit image\n"));
135 error = bmp_read_8bit(im, infile, info, hdr);
136 break;
137 case 16:
138 case 24:
139 case 32:
140 BMP_DEBUG(printf("Direct BMP image\n"));
141 error = bmp_read_direct(im, infile, info, hdr);
142 break;
143 default:
144 BMP_DEBUG(printf("Unknown bit count\n"));
145 error = 1;
146 }
147
148 gdFree(hdr);
149 gdFree(info);
150
151 if (error) {
152 gdImageDestroy(im);
153 return NULL;
154 }
155
156 return im;
157}
158
159static int bmp_read_header(gdIOCtx *infile, bmp_hdr_t *hdr)
160{
161 if(
162 !gdGetWordLSB(&hdr->magic, infile) ||
163 !gdGetIntLSB(&hdr->size, infile) ||
164 !gdGetWordLSB(&hdr->reserved1, infile) ||
165 !gdGetWordLSB(&hdr->reserved2 , infile) ||
166 !gdGetIntLSB(&hdr->off , infile)
167 ) {
168 return 1;
169 }
170 return 0;
171}
172
173static int bmp_read_info(gdIOCtx *infile, bmp_info_t *info)
174{
175 /* read BMP length so we can work out the version */
176 if (!gdGetIntLSB(&info->len, infile)) {
177 return 1;
178 }
179
180 switch (info->len) {
181 /* For now treat Windows v4 + v5 as v3 */
182 case BMP_WINDOWS_V3:
183 case BMP_WINDOWS_V4:
184 case BMP_WINDOWS_V5:
185 BMP_DEBUG(printf("Reading Windows Header\n"));
186 if (bmp_read_windows_v3_info(infile, info)) {
187 return 1;
188 }
189 break;
190 case BMP_OS2_V1:
191 if (bmp_read_os2_v1_info(infile, info)) {
192 return 1;
193 }
194 break;
195 case BMP_OS2_V2:
196 if (bmp_read_os2_v2_info(infile, info)) {
197 return 1;
198 }
199 break;
200 default:
201 BMP_DEBUG(printf("Unhandled bitmap\n"));
202 return 1;
203 }
204 return 0;
205}
206
207static int bmp_read_windows_v3_info(gdIOCtxPtr infile, bmp_info_t *info)
208{
209 if (
210 !gdGetIntLSB(&info->width, infile) ||
211 !gdGetIntLSB(&info->height, infile) ||
212 !gdGetWordLSB(&info->numplanes, infile) ||
213 !gdGetWordLSB(&info->depth, infile) ||
214 !gdGetIntLSB(&info->enctype, infile) ||
215 !gdGetIntLSB(&info->size, infile) ||
216 !gdGetIntLSB(&info->hres, infile) ||
217 !gdGetIntLSB(&info->vres, infile) ||
218 !gdGetIntLSB(&info->numcolors, infile) ||
219 !gdGetIntLSB(&info->mincolors, infile)
220 ) {
221 return 1;
222 }
223
224 if (info->height < 0) {
225 info->topdown = 1;
226 info->height = -info->height;
227 } else {
228 info->topdown = 0;
229 }
230
231 info->type = BMP_PALETTE_4;
232
233 if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 ||
234 info->depth <= 0 || info->numcolors < 0 || info->mincolors < 0) {
235 return 1;
236 }
237
238 return 0;
239}
240
241static int bmp_read_os2_v1_info(gdIOCtxPtr infile, bmp_info_t *info)
242{
243 if (
244 !gdGetWordLSB((signed short int *)&info->width, infile) ||
245 !gdGetWordLSB((signed short int *)&info->height, infile) ||
246 !gdGetWordLSB(&info->numplanes, infile) ||
247 !gdGetWordLSB(&info->depth, infile)
248 ) {
249 return 1;
250 }
251
252 /* OS2 v1 doesn't support topdown */
253 info->topdown = 0;
254
255 info->numcolors = 1 << info->depth;
256 info->type = BMP_PALETTE_3;
257
258 if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 ||
259 info->depth <= 0 || info->numcolors < 0) {
260 return 1;
261 }
262
263 return 0;
264}
265
266static int bmp_read_os2_v2_info(gdIOCtxPtr infile, bmp_info_t *info)
267{
268 char useless_bytes[24];
269 if (
270 !gdGetIntLSB(&info->width, infile) ||
271 !gdGetIntLSB(&info->height, infile) ||
272 !gdGetWordLSB(&info->numplanes, infile) ||
273 !gdGetWordLSB(&info->depth, infile) ||
274 !gdGetIntLSB(&info->enctype, infile) ||
275 !gdGetIntLSB(&info->size, infile) ||
276 !gdGetIntLSB(&info->hres, infile) ||
277 !gdGetIntLSB(&info->vres, infile) ||
278 !gdGetIntLSB(&info->numcolors, infile) ||
279 !gdGetIntLSB(&info->mincolors, infile)
280 ) {
281 return 1;
282 }
283
284 /* Lets seek the next 24 pointless bytes, we don't care too much about it */
285 if (!gdGetBuf(useless_bytes, 24, infile)) {
286 return 1;
287 }
288
289 if (info->height < 0) {
290 info->topdown = 1;
291 info->height = -info->height;
292 } else {
293 info->topdown = 0;
294 }
295
296 info->type = BMP_PALETTE_4;
297
298 if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 ||
299 info->depth <= 0 || info->numcolors < 0 || info->mincolors < 0) {
300 return 1;
301 }
302
303
304 return 0;
305}
306
307static int bmp_read_direct(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header)
308{
309 int ypos = 0, xpos = 0, row = 0;
310 int padding = 0, alpha = 0, red = 0, green = 0, blue = 0;
311 signed short int data = 0;
312
313 switch(info->enctype) {
314 case BMP_BI_RGB:
315 /* no-op */
316 break;
317
318 case BMP_BI_BITFIELDS:
319 if (info->depth == 24) {
320 BMP_DEBUG(printf("Bitfield compression isn't supported for 24-bit\n"));
321 return 1;
322 }
323 BMP_DEBUG(printf("Currently no bitfield support\n"));
324 return 1;
325 break;
326
327 case BMP_BI_RLE8:
328 if (info->depth != 8) {
329 BMP_DEBUG(printf("RLE is only valid for 8-bit images\n"));
330 return 1;
331 }
332 case BMP_BI_RLE4:
333 if (info->depth != 4) {
334 BMP_DEBUG(printf("RLE is only valid for 4-bit images\n"));
335 return 1;
336 }
337 case BMP_BI_JPEG:
338 case BMP_BI_PNG:
339 default:
340 BMP_DEBUG(printf("Unsupported BMP compression format\n"));
341 return 1;
342 }
343
344 /* There is a chance the data isn't until later, would be wierd but it is possible */
345 if (gdTell(infile) != header->off) {
346 /* Should make sure we don't seek past the file size */
347 gdSeek(infile, header->off);
348 }
349
350 /* The line must be divisible by 4, else its padded with NULLs */
351 padding = ((int)(info->depth / 8) * info->width) % 4;
352 if (padding) {
353 padding = 4 - padding;
354 }
355
356
357 for (ypos = 0; ypos < info->height; ++ypos) {
358 if (info->topdown) {
359 row = ypos;
360 } else {
361 row = info->height - ypos - 1;
362 }
363
364 for (xpos = 0; xpos < info->width; xpos++) {
365 if (info->depth == 16) {
366 if (!gdGetWordLSB(&data, infile)) {
367 return 1;
368 }
369 BMP_DEBUG(printf("Data: %X\n", data));
370 red = ((data & 0x7C00) >> 10) << 3;
371 green = ((data & 0x3E0) >> 5) << 3;
372 blue = (data & 0x1F) << 3;
373 BMP_DEBUG(printf("R: %d, G: %d, B: %d\n", red, green, blue));
374 } else if (info->depth == 24) {
375 if (!gdGetByte(&blue, infile) || !gdGetByte(&green, infile) || !gdGetByte(&red, infile)) {
376 return 1;
377 }
378 } else {
379 if (!gdGetByte(&blue, infile) || !gdGetByte(&green, infile) || !gdGetByte(&red, infile) || !gdGetByte(&alpha, infile)) {
380 return 1;
381 }
382 }
383 /*alpha = gdAlphaMax - (alpha >> 1);*/
384 gdImageSetPixel(im, xpos, row, gdTrueColor(red, green, blue));
385 }
386 for (xpos = padding; xpos > 0; --xpos) {
387 if (!gdGetByte(&red, infile)) {
388 return 1;
389 }
390 }
391 }
392
393 return 0;
394}
395
396static int bmp_read_palette(gdImagePtr im, gdIOCtxPtr infile, int count, int read_four)
397{
398 int i;
399 int r, g, b, z;
400
401 for (i = 0; i < count; i++) {
402 if (
403 !gdGetByte(&r, infile) ||
404 !gdGetByte(&g, infile) ||
405 !gdGetByte(&b, infile) ||
406 (read_four && !gdGetByte(&z, infile))
407 ) {
408 return 1;
409 }
410 im->red[i] = r;
411 im->green[i] = g;
412 im->blue[i] = b;
413 im->open[i] = 1;
414 }
415 return 0;
416}
417
418static int bmp_read_1bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header)
419{
420 int ypos = 0, xpos = 0, row = 0, index = 0;
421 int padding = 0, current_byte = 0, bit = 0;
422
423 if (info->enctype != BMP_BI_RGB) {
424 return 1;
425 }
426
427 if (!info->numcolors) {
428 info->numcolors = 2;
429 } else if (info->numcolors < 0 || info->numcolors > 2) {
430 return 1;
431 }
432
433 if (bmp_read_palette(im, infile, info->numcolors, (info->type == BMP_PALETTE_4))) {
434 return 1;
435 }
436
437 im->colorsTotal = info->numcolors;
438
439 /* There is a chance the data isn't until later, would be wierd but it is possible */
440 if (gdTell(infile) != header->off) {
441 /* Should make sure we don't seek past the file size */
442 gdSeek(infile, header->off);
443 }
444
445 /* The line must be divisible by 4, else its padded with NULLs */
446 padding = ((int)ceill(0.1 * info->width)) % 4;
447 if (padding) {
448 padding = 4 - padding;
449 }
450
451 for (ypos = 0; ypos < info->height; ++ypos) {
452 if (info->topdown) {
453 row = ypos;
454 } else {
455 row = info->height - ypos - 1;
456 }
457
458 for (xpos = 0; xpos < info->width; xpos += 8) {
459 /* Bitmaps are always aligned in bytes so we'll never overflow */
460 if (!gdGetByte(&current_byte, infile)) {
461 return 1;
462 }
463
464 for (bit = 0; bit < 8; bit++) {
465 index = ((current_byte & (0x80 >> bit)) != 0 ? 0x01 : 0x00);
466 if (im->open[index]) {
467 im->open[index] = 0;
468 }
469 gdImageSetPixel(im, xpos + bit, row, index);
470 /* No need to read anything extra */
471 if ((xpos + bit) >= info->width) {
472 break;
473 }
474 }
475 }
476
477 for (xpos = padding; xpos > 0; --xpos) {
478 if (!gdGetByte(&index, infile)) {
479 return 1;
480 }
481 }
482 }
483 return 0;
484}
485
486static int bmp_read_4bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header)
487{
488 int ypos = 0, xpos = 0, row = 0, index = 0;
489 int padding = 0, current_byte = 0;
490
491 if (info->enctype != BMP_BI_RGB && info->enctype != BMP_BI_RLE4) {
492 return 1;
493 }
494
495 if (!info->numcolors) {
496 info->numcolors = 16;
497 } else if (info->numcolors < 0 || info->numcolors > 16) {
498 return 1;
499 }
500
501 if (bmp_read_palette(im, infile, info->numcolors, (info->type == BMP_PALETTE_4))) {
502 return 1;
503 }
504
505 im->colorsTotal = info->numcolors;
506
507 /* There is a chance the data isn't until later, would be wierd but it is possible */
508 if (gdTell(infile) != header->off) {
509 /* Should make sure we don't seek past the file size */
510 gdSeek(infile, header->off);
511 }
512
513 /* The line must be divisible by 4, else its padded with NULLs */
514 padding = ((int)ceil(0.5 * info->width)) % 4;
515 if (padding) {
516 padding = 4 - padding;
517 }
518
519 switch (info->enctype) {
520 case BMP_BI_RGB:
521 for (ypos = 0; ypos < info->height; ++ypos) {
522 if (info->topdown) {
523 row = ypos;
524 } else {
525 row = info->height - ypos - 1;
526 }
527
528 for (xpos = 0; xpos < info->width; xpos += 2) {
529 if (!gdGetByte(&current_byte, infile)) {
530 return 1;
531 }
532
533 index = (current_byte >> 4) & 0x0f;
534 if (im->open[index]) {
535 im->open[index] = 0;
536 }
537 gdImageSetPixel(im, xpos, row, index);
538
539 /* This condition may get called often, potential optimsations */
540 if (xpos >= info->width) {
541 break;
542 }
543
544 index = current_byte & 0x0f;
545 if (im->open[index]) {
546 im->open[index] = 0;
547 }
548 gdImageSetPixel(im, xpos + 1, row, index);
549 }
550
551 for (xpos = padding; xpos > 0; --xpos) {
552 if (!gdGetByte(&index, infile)) {
553 return 1;
554 }
555 }
556 }
557 break;
558
559 case BMP_BI_RLE4:
560 if (bmp_read_rle(im, infile, info)) {
561 return 1;
562 }
563 break;
564
565 default:
566 return 1;
567 }
568 return 0;
569}
570
571static int bmp_read_8bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header)
572{
573 int ypos = 0, xpos = 0, row = 0, index = 0;
574 int padding = 0;
575
576 if (info->enctype != BMP_BI_RGB && info->enctype != BMP_BI_RLE8) {
577 return 1;
578 }
579
580 if (!info->numcolors) {
581 info->numcolors = 256;
582 } else if (info->numcolors < 0 || info->numcolors > 256) {
583 return 1;
584 }
585
586 if (bmp_read_palette(im, infile, info->numcolors, (info->type == BMP_PALETTE_4))) {
587 return 1;
588 }
589
590 im->colorsTotal = info->numcolors;
591
592 /* There is a chance the data isn't until later, would be wierd but it is possible */
593 if (gdTell(infile) != header->off) {
594 /* Should make sure we don't seek past the file size */
595 gdSeek(infile, header->off);
596 }
597
598 /* The line must be divisible by 4, else its padded with NULLs */
599 padding = (1 * info->width) % 4;
600 if (padding) {
601 padding = 4 - padding;
602 }
603
604 switch (info->enctype) {
605 case BMP_BI_RGB:
606 for (ypos = 0; ypos < info->height; ++ypos) {
607 if (info->topdown) {
608 row = ypos;
609 } else {
610 row = info->height - ypos - 1;
611 }
612
613 for (xpos = 0; xpos < info->width; ++xpos) {
614 if (!gdGetByte(&index, infile)) {
615 return 1;
616 }
617
618 if (im->open[index]) {
619 im->open[index] = 0;
620 }
621 gdImageSetPixel(im, xpos, row, index);
622 }
623 /* Could create a new variable, but it isn't really worth it */
624 for (xpos = padding; xpos > 0; --xpos) {
625 if (!gdGetByte(&index, infile)) {
626 return 1;
627 }
628 }
629 }
630 break;
631
632 case BMP_BI_RLE8:
633 if (bmp_read_rle(im, infile, info)) {
634 return 1;
635 }
636 break;
637
638 default:
639 return 1;
640 }
641 return 0;
642}
643
644static int bmp_read_rle(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info)
645{
646 int ypos = 0, xpos = 0, row = 0, index = 0;
647 int rle_length = 0, rle_data = 0;
648 int padding = 0;
649 int i = 0, j = 0;
650 int pixels_per_byte = 8 / info->depth;
651
652 for (ypos = 0; ypos < info->height && xpos <= info->width;) {
653 if (!gdGetByte(&rle_length, infile) || !gdGetByte(&rle_data, infile)) {
654 return 1;
655 }
656 row = info->height - ypos - 1;
657
658 if (rle_length != BMP_RLE_COMMAND) {
659 if (im->open[rle_data]) {
660 im->open[rle_data] = 0;
661 }
662
663 for (i = 0; (i < rle_length) && (xpos < info->width);) {
664 for (j = 1; (j <= pixels_per_byte) && (xpos < info->width) && (i < rle_length); j++, xpos++, i++) {
665 index = (rle_data & (((1 << info->depth) - 1) << (8 - (j * info->depth)))) >> (8 - (j * info->depth));
666 if (im->open[index]) {
667 im->open[index] = 0;
668 }
669 gdImageSetPixel(im, xpos, row, index);
670 }
671 }
672 } else if (rle_length == BMP_RLE_COMMAND && rle_data > 2) {
673 /* Uncompressed RLE needs to be even */
674 padding = 0;
675 for (i = 0; (i < rle_data) && (xpos < info->width); i += pixels_per_byte) {
676 int max_pixels = pixels_per_byte;
677
678 if (!gdGetByte(&index, infile)) {
679 return 1;
680 }
681 padding++;
682
683 if (rle_data - i < max_pixels) {
684 max_pixels = rle_data - i;
685 }
686
687 for (j = 1; (j <= max_pixels) && (xpos < info->width); j++, xpos++) {
688 int temp = (index >> (8 - (j * info->depth))) & ((1 << info->depth) - 1);
689 if (im->open[temp]) {
690 im->open[temp] = 0;
691 }
692 gdImageSetPixel(im, xpos, row, temp);
693 }
694 }
695
696 /* Make sure the bytes read are even */
697 if (padding % 2 && !gdGetByte(&index, infile)) {
698 return 1;
699 }
700 } else if (rle_length == BMP_RLE_COMMAND && rle_data == BMP_RLE_ENDOFLINE) {
701 /* Next Line */
702 xpos = 0;
703 ypos++;
704 } else if (rle_length == BMP_RLE_COMMAND && rle_data == BMP_RLE_DELTA) {
705 /* Delta Record, used for bmp files that contain other data*/
706 if (!gdGetByte(&rle_length, infile) || !gdGetByte(&rle_data, infile)) {
707 return 1;
708 }
709 xpos += rle_length;
710 ypos += rle_data;
711 } else if (rle_length == BMP_RLE_COMMAND && rle_data == BMP_RLE_ENDOFBITMAP) {
712 /* End of bitmap */
713 break;
714 }
715 }
716 return 0;
717}
718
719#if GD_MAJOR_VERSION == 2 && GD_MINOR_VERSION < 1
720static int gdGetWordLSB(signed short int *result, gdIOCtx * ctx)
721{
722 unsigned int high = 0, low = 0;
723 low = (ctx->getC) (ctx);
724 if (low == EOF) {
725 return 0;
726 }
727
728 high = (ctx->getC) (ctx);
729 if (high == EOF) {
730 return 0;
731 }
732
733 if (result) {
734 *result = (high << 8) | low;
735 }
736
737 return 1;
738}
739
740static int gdGetIntLSB(signed int *result, gdIOCtx * ctx)
741{
742 int c = 0;
743 unsigned int r = 0;
744
745 c = (ctx->getC) (ctx);
746 if (c == EOF) {
747 return 0;
748 }
749 r |= (c << 24);
750 r >>= 8;
751
752 c = (ctx->getC) (ctx);
753 if (c == EOF) {
754 return 0;
755 }
756 r |= (c << 24);
757 r >>= 8;
758
759 c = (ctx->getC) (ctx);
760 if (c == EOF) {
761 return 0;
762 }
763 r |= (c << 24);
764 r >>= 8;
765
766 c = (ctx->getC) (ctx);
767 if (c == EOF) {
768 return 0;
769 }
770 r |= (c << 24);
771
772 if (result) {
773 *result = (signed int)r;
774 }
775
776 return 1;
777}
778#endif
diff --git a/utils/wpseditor/screenshot/main.c b/utils/wpseditor/screenshot/main.c
deleted file mode 100644
index 72d75ab54d..0000000000
--- a/utils/wpseditor/screenshot/main.c
+++ /dev/null
@@ -1,377 +0,0 @@
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
73static bool next_nl = false;
74
75int _debug(const char* fmt,...)
76{
77 va_list ap;
78
79 va_start(ap, fmt);
80
81 if(!next_nl)
82 fprintf(stdout, "[DBG] ");
83
84 vfprintf(stdout, fmt, ap);
85
86 if(fmt[strlen(fmt)-1] != 0xa)
87 next_nl = true;
88 else
89 next_nl = false;
90
91 va_end(ap);
92
93 return 0;
94}
95
96void _putsxy(int x, int y, const unsigned char *str)
97{
98 struct viewport_api avp;
99 int black = gdImageColorAllocate(framebuffer, 0, 0, 0);
100
101 api.get_current_vp(&avp);
102
103 gdImageString(framebuffer, getFont(), x + avp.x, y + avp.y - avp.fontheight, (unsigned char*)str, black);
104}
105
106void _transparent_bitmap_part(const void *src, int src_x, int src_y,
107 int stride, int x, int y, int width, int height)
108{
109 FILE *_image;
110 gdImagePtr image;
111 int pink;
112
113 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\n", (char*)src, src_x, src_y, stride, x, y, width, height);
114
115 _image = fopen(src, "rb");
116 if(_image == NULL)
117 return;
118
119 image = gdImageCreateFromBmp(_image);
120 fclose(_image);
121
122 pink = gdTrueColor(255, 0, 255);
123 gdImageColorTransparent(image, pink);
124
125 gdImageCopy(framebuffer, image, x, y, src_x, src_y, width, height);
126
127 gdImageDestroy(image);
128}
129
130void _bitmap_part(const void *src, int src_x, int src_y,
131 int stride, int x, int y, int width, int height)
132{
133 FILE *_image;
134 gdImagePtr image;
135
136 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\n", (char*)src, src_x, src_y, stride, x, y, width, height);
137
138 _image = fopen(src, "rb");
139 if(_image == NULL)
140 return;
141
142 image = gdImageCreateFromBmp(_image);
143 fclose(_image);
144
145 gdImageCopy(framebuffer, image, x, y, src_x, src_y, width, height);
146
147 gdImageDestroy(image);
148}
149
150void _drawpixel(int x, int y)
151{
152 int black = gdImageColorAllocate(framebuffer, 0, 0, 0);
153 gdImageSetPixel(framebuffer, x, y, black);
154}
155
156void _fillrect(int x, int y, int width, int height)
157{
158 /* Don't draw this as backdrop is used */
159#if 0
160 int black = gdImageColorAllocate(framebuffer, 0, 0, 0);
161 gdImageFilledRectangle(framebuffer, x, y, x+width, y+height, black);
162#endif
163}
164
165void _hline(int x1, int x2, int y)
166{
167 int black = gdImageColorAllocate(framebuffer, 0, 0, 0);
168 gdImageLine(framebuffer, x1, y, x2, y, black);
169}
170
171void _vline(int x, int y1, int y2)
172{
173 int black = gdImageColorAllocate(framebuffer, 0, 0, 0);
174 gdImageLine(framebuffer, x, y1, x, y2, black);
175}
176
177void _clear_viewport(int x, int y, int w, int h, int color)
178{
179 if(backdrop == NULL)
180 return;
181
182 gdImageCopy(framebuffer, backdrop, x, y, x, y, w, h);
183}
184
185static bool _load_wps_backdrop(char* filename)
186{
187 FILE *image;
188 if(backdrop != NULL)
189 gdImageDestroy(backdrop);
190
191 DEBUGF2("load backdrop: %s", filename);
192
193 image = fopen(filename, "rb");
194 if(image == NULL)
195 return false;
196
197 backdrop = gdImageCreateFromBmp(image);
198 fclose(image);
199
200 return true;
201}
202
203int _read_bmp_file(const char* filename, int *width, int *height)
204{
205 FILE *_image;
206 gdImagePtr image;
207
208 DEBUGF2("load backdrop: %s", filename);
209
210 _image = fopen(filename, "rb");
211 if(_image == NULL)
212 return 0;
213
214 image = gdImageCreateFromBmp(_image);
215 fclose(_image);
216
217 *width = image->sx;
218 *height = image->sy;
219
220 gdImageDestroy(image);
221
222 return 1;
223}
224
225static void _drawBackdrop()
226{
227 if(backdrop == NULL)
228 return;
229
230 gdImageCopy(framebuffer, backdrop, 0, 0, 0, 0, backdrop->sx, backdrop->sy);
231}
232
233static int screenshot(char *model, char *wps, char *png)
234{
235 char lib[255];
236 void *handle;
237 FILE *out, *in;
238 int res;
239
240 in = fopen(wps, "rb");
241 if(in == NULL)
242 {
243 fprintf(stderr, "[ERR] Cannot open WPS: %s\n", wps);
244 return -1;
245 }
246 fclose(in);
247
248 out = fopen(png, "wb");
249 if(out == NULL)
250 {
251 fprintf(stderr, "[ERR] Cannot open PNG: %s\n", png);
252 return -2;
253 }
254
255 snprintf(lib, 255, "%s/libwps_%s.so", (char*)get_current_dir_name(), (char*)model);
256 handle = dlopen(lib, RTLD_LAZY);
257 if (!handle)
258 {
259 fprintf(stderr, "[ERR] Cannot open library: %s\n", dlerror());
260 fclose(out);
261 return -3;
262 }
263
264 wps_init = dlsym(handle, "wps_init");
265 wps_display = dlsym(handle, "wps_display");
266 wps_refresh = dlsym(handle, "wps_refresh");
267
268 if (!wps_init || !wps_display || !wps_refresh)
269 {
270 fprintf(stderr, "[ERR] Failed to resolve funcs!");
271 dlclose(handle);
272 fclose(out);
273 return -4;
274 }
275
276 memset(&api, 0, sizeof(struct proxy_api));
277
278 if(verbose)
279 api.verbose = 3;
280 else
281 api.verbose = 0;
282
283 api.putsxy = &_putsxy;
284 api.transparent_bitmap_part = &_transparent_bitmap_part;
285 api.bitmap_part = &_bitmap_part;
286 api.drawpixel = &_drawpixel;
287 api.fillrect = &_fillrect;
288 api.hline = &_hline;
289 api.vline = &_vline;
290 api.clear_viewport = &_clear_viewport;
291 api.load_wps_backdrop = &_load_wps_backdrop;
292 api.read_bmp_file = &_read_bmp_file;
293 api.debugf = &_debug;
294
295 res = wps_init(wps, &api, true);
296 if(res != 1)
297 {
298 fprintf(stderr, "[ERR] WPS wasn't correctly inited\n");
299 dlclose(handle);
300 fclose(out);
301 return -5;
302 }
303
304 framebuffer = gdImageCreateTrueColor(api.getwidth(), api.getheight());
305
306 _drawBackdrop();
307
308 fprintf(stdout, "[INFO] Model: %s\n", api.get_model_name());
309
310 wpsdata.fontheight = getFont()->h;
311 wpsdata.fontwidth = getFont()->w;
312 api.set_wpsstate(wpsdata);
313 api.set_trackstate(mp3data);
314 api.set_next_trackstate(mp3data);
315
316 _drawBackdrop();
317 wps_refresh();
318 gdImagePng(framebuffer, out);
319
320 fprintf(stdout, "[INFO] Image written\n");
321
322 dlclose(handle);
323 fclose(out);
324 gdImageDestroy(framebuffer);
325 if(backdrop != NULL)
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, "Rockbox WPS screenshot utility\n");
338 fprintf(stderr, "Made by Maurus Cuelenaere\n");
339 fprintf(stderr, "\n");
340 fprintf(stderr, "Usage: screenshot [-V] <MODEL> <WPS> <OUT>.png\n");
341 fprintf(stderr, " -> creates a PNG screenshot of the WPS for the specific MODEL\n");
342 fprintf(stderr, " -> libwps_<MODEL>.so must be present in the same directory\n");
343 fprintf(stderr, " -> -V sets verbose mode ON\n");
344 fprintf(stderr, "\n");
345 fprintf(stderr, "Example: screenshot IRIVER_H10_5GB iCatcher.wps out.png\n");
346}
347
348int main(int argc, char ** argv)
349{
350 if(argc < 4)
351 {
352 usage();
353 return -1;
354 }
355
356 if(argv[1] == NULL || argv[2] == NULL ||
357 argv[3] == NULL ||
358 (strcmp(argv[1], "-V") == 0 && argv[4] == NULL)
359 )
360 {
361 usage();
362 return -1;
363 }
364
365 if(strcmp(argv[1], "-V") == 0)
366 {
367 verbose = true;
368 return screenshot(argv[2], argv[3], argv[4]);
369 }
370 else
371 {
372 verbose = false;
373 return screenshot(argv[1], argv[2], argv[3]);
374 }
375
376 return 0;
377}