A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
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 *
23 * Converts BMP files to Rockbox bitmap format
24 *
25 * 1999-05-03 Linus Nielsen Feltzing
26 *
27 * 2005-07-06 Jens Arnold
28 * added reading of 4, 16, 24 and 32 bit bmps
29 * added 2 new target formats (playergfx and iriver 4-grey)
30 *
31 ****************************************************************************/
32
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <stdbool.h>
37#include <unistd.h>
38
39#include <sys/types.h>
40#include <sys/stat.h>
41#include <fcntl.h>
42
43#define debugf printf
44
45#ifdef __GNUC__
46#define STRUCT_PACKED __attribute__((packed))
47#else
48#define STRUCT_PACKED
49#pragma pack (push, 2)
50#endif
51
52struct Fileheader
53{
54 unsigned short Type; /* signature - 'BM' */
55 unsigned int Size; /* file size in bytes */
56 unsigned short Reserved1; /* 0 */
57 unsigned short Reserved2; /* 0 */
58 unsigned int OffBits; /* offset to bitmap */
59 unsigned int StructSize; /* size of this struct (40) */
60 unsigned int Width; /* bmap width in pixels */
61 unsigned int Height; /* bmap height in pixels */
62 unsigned short Planes; /* num planes - always 1 */
63 unsigned short BitCount; /* bits per pixel */
64 unsigned int Compression; /* compression flag */
65 unsigned int SizeImage; /* image size in bytes */
66 int XPelsPerMeter; /* horz resolution */
67 int YPelsPerMeter; /* vert resolution */
68 unsigned int ClrUsed; /* 0 -> color table size */
69 unsigned int ClrImportant; /* important color count */
70} STRUCT_PACKED;
71
72struct RGBQUAD
73{
74 unsigned char rgbBlue;
75 unsigned char rgbGreen;
76 unsigned char rgbRed;
77 unsigned char rgbReserved;
78} STRUCT_PACKED;
79
80union RAWDATA {
81 void *d; /* unspecified */
82 unsigned short *d16; /* depth <= 16 */
83 struct { unsigned char b, g, r; } *d24; /* depth = 24 BGR */
84 struct { unsigned char b, g, r, x; } *d32;
85};
86
87short readshort(void* value)
88{
89 unsigned char* bytes = (unsigned char*) value;
90 return bytes[0] | (bytes[1] << 8);
91}
92
93int readint(void* value)
94{
95 unsigned char* bytes = (unsigned char*) value;
96 return bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
97}
98
99unsigned char brightness(struct RGBQUAD color)
100{
101 return (3 * (unsigned int)color.rgbRed + 6 * (unsigned int)color.rgbGreen
102 + (unsigned int)color.rgbBlue) / 10;
103}
104
105#ifndef O_BINARY
106#define O_BINARY 0 /* systems that don't have O_BINARY won't make a difference
107 on text and binary files */
108#endif
109
110/****************************************************************************
111 * read_bmp_file()
112 *
113 * Reads an uncompressed BMP file and puts the data in a 4-byte-per-pixel
114 * (RGBQUAD) array. Returns 0 on success.
115 *
116 ***************************************************************************/
117
118int read_bmp_file(char* filename,
119 int *get_width, /* in pixels */
120 int *get_height, /* in pixels */
121 struct RGBQUAD **bitmap)
122{
123 struct Fileheader fh;
124 struct RGBQUAD palette[256];
125
126 int fd = open(filename, O_RDONLY| O_BINARY);
127 unsigned short data;
128 unsigned char *bmp;
129 int width, height;
130 int padded_width;
131 int size;
132 int row, col, i;
133 int numcolors, compression;
134 int depth;
135
136 if (fd == -1)
137 {
138 debugf("error - can't open '%s'\n", filename);
139 return 1;
140 }
141 if (read(fd, &fh, sizeof(struct Fileheader)) !=
142 sizeof(struct Fileheader))
143 {
144 debugf("error - can't Read Fileheader Stucture\n");
145 close(fd);
146 return 2;
147 }
148
149 compression = readint(&fh.Compression);
150
151 if (compression != 0)
152 {
153 debugf("error - Unsupported compression %d\n", compression);
154 close(fd);
155 return 3;
156 }
157
158 depth = readshort(&fh.BitCount);
159
160 if (depth <= 8)
161 {
162 numcolors = readint(&fh.ClrUsed);
163 if (numcolors == 0)
164 numcolors = 1 << depth;
165
166 if (read(fd, &palette[0], numcolors * sizeof(struct RGBQUAD))
167 != (int)(numcolors * sizeof(struct RGBQUAD)))
168 {
169 debugf("error - Can't read bitmap's color palette\n");
170 close(fd);
171 return 4;
172 }
173 }
174
175 width = readint(&fh.Width);
176 height = readint(&fh.Height);
177 padded_width = ((width * depth + 31) / 8) & ~3; /* aligned 4-bytes boundaries */
178
179 size = padded_width * height; /* read this many bytes */
180 bmp = (unsigned char *)malloc(size);
181 *bitmap = (struct RGBQUAD *)malloc(width * height * sizeof(struct RGBQUAD));
182
183 if ((bmp == NULL) || (*bitmap == NULL))
184 {
185 debugf("error - Out of memory\n");
186 close(fd);
187 return 5;
188 }
189
190 if (lseek(fd, (off_t)readint(&fh.OffBits), SEEK_SET) < 0)
191 {
192 debugf("error - Can't seek to start of image data\n");
193 close(fd);
194 return 6;
195 }
196 if (read(fd, (unsigned char*)bmp, (int)size) != size)
197 {
198 debugf("error - Can't read image\n");
199 close(fd);
200 return 7;
201 }
202
203 close(fd);
204 *get_width = width;
205 *get_height = height;
206
207 switch (depth)
208 {
209 case 1:
210 for (row = 0; row < height; row++)
211 for (col = 0; col < width; col++)
212 {
213 data = (bmp[(height - 1 - row) * padded_width + col / 8]
214 >> (~col & 7)) & 1;
215 (*bitmap)[row * width + col] = palette[data];
216 }
217 break;
218
219 case 4:
220 for (row = 0; row < height; row++)
221 for (col = 0; col < width; col++)
222 {
223 data = (bmp[(height - 1 - row) * padded_width + col / 2]
224 >> (4 * (~col & 1))) & 0x0F;
225 (*bitmap)[row * width + col] = palette[data];
226 }
227 break;
228
229 case 8:
230 for (row = 0; row < height; row++)
231 for (col = 0; col < width; col++)
232 {
233 data = bmp[(height - 1 - row) * padded_width + col];
234 (*bitmap)[row * width + col] = palette[data];
235 }
236 break;
237
238 case 16:
239 for (row = 0; row < height; row++)
240 for (col = 0; col < width; col++)
241 {
242 data = readshort(&bmp[(height - 1 - row) * padded_width + 2 * col]);
243 (*bitmap)[row * width + col].rgbRed =
244 ((data >> 7) & 0xF8) | ((data >> 12) & 0x07);
245 (*bitmap)[row * width + col].rgbGreen =
246 ((data >> 2) & 0xF8) | ((data >> 7) & 0x07);
247 (*bitmap)[row * width + col].rgbBlue =
248 ((data << 3) & 0xF8) | ((data >> 2) & 0x07);
249 (*bitmap)[row * width + col].rgbReserved = 0;
250 }
251 break;
252
253 case 24:
254 for (row = 0; row < height; row++)
255 for (col = 0; col < width; col++)
256 {
257 i = (height - 1 - row) * padded_width + 3 * col;
258 (*bitmap)[row * width + col].rgbRed = bmp[i+2];
259 (*bitmap)[row * width + col].rgbGreen = bmp[i+1];
260 (*bitmap)[row * width + col].rgbBlue = bmp[i];
261 (*bitmap)[row * width + col].rgbReserved = 0;
262 }
263 break;
264
265 case 32:
266 for (row = 0; row < height; row++)
267 for (col = 0; col < width; col++)
268 {
269 i = (height - 1 - row) * padded_width + 4 * col;
270 (*bitmap)[row * width + col].rgbRed = bmp[i+2];
271 (*bitmap)[row * width + col].rgbGreen = bmp[i+1];
272 (*bitmap)[row * width + col].rgbBlue = bmp[i];
273 (*bitmap)[row * width + col].rgbReserved = 0;
274 }
275 break;
276
277 default: /* should never happen */
278 debugf("error - Unsupported bitmap depth %d.\n", depth);
279 return 8;
280 }
281
282 free(bmp);
283
284 return 0; /* success */
285}
286
287/****************************************************************************
288 * transform_bitmap()
289 *
290 * Transform a 4-byte-per-pixel bitmap (RGBQUAD) into one of the supported
291 * destination formats
292 ****************************************************************************/
293
294int transform_bitmap(const struct RGBQUAD *src, int width, int height,
295 int format, union RAWDATA *dst, int *dst_width,
296 int *dst_height, int *dst_depth)
297{
298 int row, col;
299 int dst_w, dst_h, dst_d;
300 int alloc_size;
301 union RAWDATA dest;
302
303 switch (format)
304 {
305 case 0: /* Archos recorders, Ondio, Iriver H1x0 monochrome */
306 dst_w = width;
307 dst_h = (height + 7) / 8;
308 dst_d = 8;
309 break;
310
311 case 1: /* Archos player graphics library */
312 dst_w = (width + 7) / 8;
313 dst_h = height;
314 dst_d = 8;
315 break;
316
317 case 2: /* Iriver H1x0 4-grey */
318 dst_w = width;
319 dst_h = (height + 3) / 4;
320 dst_d = 8;
321 break;
322
323 case 3: /* Canonical 8-bit grayscale */
324 dst_w = width;
325 dst_h = height;
326 dst_d = 8;
327 break;
328
329 case 4: /* 16-bit packed RGB (5-6-5) */
330 case 5: /* 16-bit packed and byte-swapped RGB (5-6-5) */
331 case 8: /* 16-bit packed RGB (5-6-5) vertical stride*/
332 dst_w = width;
333 dst_h = height;
334 dst_d = 16;
335 break;
336
337 case 6: /* greyscale iPods 4-grey */
338 dst_w = (width + 3) / 4;
339 dst_h = height;
340 dst_d = 8;
341 break;
342
343 case 7: /* greyscale X5 remote 4-grey */
344 dst_w = width;
345 dst_h = (height + 7) / 8;
346 dst_d = 16;
347 break;
348
349 case 9: /* 24-bit BGR */
350 dst_w = width;
351 dst_h = height;
352 dst_d = 24;
353 break;
354
355 case 10: /* 32-bit XRGB */
356 dst_w = width;
357 dst_h = height;
358 dst_d = 32;
359 break;
360
361 default: /* unknown */
362 debugf("error - Undefined destination format\n");
363 return 1;
364 }
365
366 if (dst_d <= 16)
367 alloc_size = sizeof(dest.d16[0]);
368 else if (dst_d <= 24)
369 alloc_size = sizeof(dest.d24[0]);
370 else
371 alloc_size = sizeof(dest.d32[0]);
372 dest.d = calloc(dst_w * dst_h, alloc_size);
373
374 if (dest.d == NULL)
375 {
376 debugf("error - Out of memory.\n");
377 return 2;
378 }
379 *dst_width = dst_w;
380 *dst_height = dst_h;
381 *dst_depth = dst_d;
382 *dst = dest;
383
384 switch (format)
385 {
386 case 0: /* Archos recorders, Ondio, Iriver H1x0 b&w */
387 for (row = 0; row < height; row++)
388 for (col = 0; col < width; col++)
389 {
390 dest.d16[(row/8) * dst_w + col] |=
391 (~brightness(src[row * width + col]) & 0x80) >> (~row & 7);
392 }
393 break;
394
395 case 1: /* Archos player graphics library */
396 for (row = 0; row < height; row++)
397 for (col = 0; col < width; col++)
398 {
399 dest.d16[row * dst_w + (col/8)] |=
400 (~brightness(src[row * width + col]) & 0x80) >> (col & 7);
401 }
402 break;
403
404 case 2: /* Iriver H1x0 4-grey */
405 for (row = 0; row < height; row++)
406 for (col = 0; col < width; col++)
407 {
408 dest.d16[(row/4) * dst_w + col] |=
409 (~brightness(src[row * width + col]) & 0xC0) >> (2 * (~row & 3));
410 }
411 break;
412
413 case 3: /* Canonical 8-bit grayscale */
414 for (row = 0; row < height; row++)
415 for (col = 0; col < width; col++)
416 {
417 dest.d16[row * dst_w + col] = brightness(src[row * width + col]);
418 }
419 break;
420
421 case 4: /* 16-bit packed RGB (5-6-5) */
422 case 5: /* 16-bit packed and byte-swapped RGB (5-6-5) */
423 for (row = 0; row < height; row++)
424 for (col = 0; col < width; col++)
425 {
426 unsigned short rgb =
427 (((src[row * width + col].rgbRed >> 3) << 11) |
428 ((src[row * width + col].rgbGreen >> 2) << 5) |
429 ((src[row * width + col].rgbBlue >> 3)));
430
431 if (format == 4)
432 dest.d16[row * dst_w + col] = rgb;
433 else
434 dest.d16[row * dst_w + col] = ((rgb&0xff00)>>8)|((rgb&0x00ff)<<8);
435 }
436 break;
437
438 case 6: /* greyscale iPods 4-grey */
439 for (row = 0; row < height; row++)
440 for (col = 0; col < width; col++)
441 {
442 dest.d16[row * dst_w + (col/4)] |=
443 (~brightness(src[row * width + col]) & 0xC0) >> (2 * (col & 3));
444 }
445 break;
446
447 case 7: /* greyscale X5 remote 4-grey */
448 for (row = 0; row < height; row++)
449 for (col = 0; col < width; col++)
450 {
451 unsigned short data = (~brightness(src[row * width + col]) & 0xC0) >> 6;
452
453 data = (data | (data << 7)) & 0x0101;
454 dest.d16[(row/8) * dst_w + col] |= data << (row & 7);
455 }
456 break;
457
458 case 8: /* 16-bit packed RGB (5-6-5) vertical stride*/
459 for (row = 0; row < height; row++)
460 for (col = 0; col < width; col++)
461 {
462 unsigned short rgb =
463 (((src[row * width + col].rgbRed >> 3) << 11) |
464 ((src[row * width + col].rgbGreen >> 2) << 5) |
465 ((src[row * width + col].rgbBlue >> 3)));
466
467 dest.d16[col * dst_h + row] = rgb;
468 }
469 break;
470
471 case 9: /* 24-bit RGB */
472 for (row = 0; row < height; row++)
473 for (col = 0; col < width; col++)
474 {
475 dest.d24[row * width + col].r = src[row * width + col].rgbRed;
476 dest.d24[row * width + col].g = src[row * width + col].rgbGreen;
477 dest.d24[row * width + col].b = src[row * width + col].rgbBlue;
478 }
479 break;
480
481 case 10: /* 32-bit XRGB */
482 for (row = 0; row < height; row++)
483 for (col = 0; col < width; col++)
484 {
485 dest.d32[row * width + col].r = src[row * width + col].rgbRed;
486 dest.d32[row * width + col].g = src[row * width + col].rgbGreen;
487 dest.d32[row * width + col].b = src[row * width + col].rgbBlue;
488 }
489 }
490
491 return 0;
492}
493
494/****************************************************************************
495 * generate_c_source()
496 *
497 * Outputs a C source code with the bitmap in an array, accompanied by
498 * some #define's
499 ****************************************************************************/
500
501void generate_c_source(char *id, char* header_dir, int width, int height,
502 const union RAWDATA *t_bitmap, int t_width,
503 int t_height, int t_depth, bool t_mono, bool create_bm)
504{
505 FILE *f;
506 FILE *fh;
507 int i, a;
508 char header_name[1024];
509 bool have_header = header_dir && header_dir[0];
510 create_bm = have_header && create_bm;
511
512 if (!id || !id[0])
513 id = "bitmap";
514
515 bool initdata = create_bm && ((strcmp(id,"rockboxlogo") == 0)
516 || (strcmp(id,"remote_rockboxlogo") == 0));
517
518 f = stdout;
519
520 if (have_header)
521 {
522 snprintf(header_name,sizeof(header_name),"%s/%s.h",header_dir,id);
523 fh = fopen(header_name,"w+");
524
525 if (fh == NULL)
526 {
527 debugf("error - can't open '%s'\n", header_name);
528 return;
529 }
530 fprintf(fh,
531 "#define BMPHEIGHT_%s %d\n"
532 "#define BMPWIDTH_%s %d\n",
533 id, height, id, width);
534
535 if (t_depth <= 8)
536 fprintf(fh, "extern const unsigned char %s[]%s;\n", id,
537 initdata ? " INITDATA_ATTR":"");
538 else if (t_depth <= 16)
539 fprintf(fh, "extern const unsigned short %s[]%s;\n", id,
540 initdata ? " INITDATA_ATTR":"");
541 else
542 fprintf(fh, "extern const fb_data %s[]%s;\n", id,
543 initdata ? " INITDATA_ATTR":"");
544
545
546 if (create_bm)
547 {
548 fprintf(f, "#include \"lcd.h\"\n");
549 fprintf(fh, "extern const struct bitmap bm_%s%s;\n", id,
550 initdata ? " INITDATA_ATTR":"");
551 }
552 fclose(fh);
553 } else {
554 fprintf(f,
555 "#define BMPHEIGHT_%s %d\n"
556 "#define BMPWIDTH_%s %d\n",
557 id, height, id, width);
558 }
559
560 if (create_bm) {
561 fprintf(f, "#include \"%s\"\n", header_name);
562 }
563
564 if (t_depth <= 8)
565 fprintf(f, "const unsigned char %s[] = {\n", id);
566 else if (t_depth <= 16)
567 fprintf(f, "const unsigned short %s[] = {\n", id);
568 else
569 fprintf(f, "const fb_data %s[] = {\n", id);
570
571 for (i = 0; i < t_height; i++)
572 {
573 for (a = 0; a < t_width; a++)
574 {
575 if (t_depth <= 8)
576 fprintf(f, "0x%02x,%c", t_bitmap->d16[i * t_width + a],
577 (a + 1) % 13 ? ' ' : '\n');
578 else if (t_depth == 16)
579 fprintf(f, "0x%04x,%c", t_bitmap->d16[i * t_width + a],
580 (a + 1) % 10 ? ' ' : '\n');
581 else if (t_depth == 24)
582 fprintf(f, "{ .r = 0x%02x, .g = 0x%02x, .b = 0x%02x },%c",
583 t_bitmap->d24[i * t_width + a].r,
584 t_bitmap->d24[i * t_width + a].g,
585 t_bitmap->d24[i * t_width + a].b,
586 (a + 1) % 4 ? ' ' : '\n');
587 else if (t_depth == 32)
588 fprintf(f, "{ .r = 0x%02x, .g = 0x%02x, .b = 0x%02x, .x = 0x00 },%c",
589 t_bitmap->d32[i * t_width + a].r,
590 t_bitmap->d32[i * t_width + a].g,
591 t_bitmap->d32[i * t_width + a].b,
592 (a + 1) % 4 ? ' ' : '\n');
593 }
594 fprintf(f, "\n");
595 }
596
597 fprintf(f, "\n};\n\n");
598
599 if (create_bm) {
600 char format_line[] = " .format = FORMAT_NATIVE, \n";
601 fprintf(f, "const struct bitmap bm_%s = { \n"
602 " .width = BMPWIDTH_%s, \n"
603 " .height = BMPHEIGHT_%s, \n"
604 "%s"
605 " .data = (unsigned char*)%s,\n"
606 "};\n",
607 id, id, id,
608 t_mono ? "" : format_line,
609 id);
610 }
611}
612
613void generate_raw_file(const union RAWDATA *t_bitmap,
614 int t_width, int t_height, int t_depth)
615{
616 FILE *f;
617 int i, a;
618 unsigned char lo,hi;
619
620 f = stdout;
621
622 for (i = 0; i < t_height; i++)
623 {
624 for (a = 0; a < t_width; a++)
625 {
626 if (t_depth <= 8)
627 {
628 lo = (t_bitmap->d16[i * t_width + a] & 0x00ff);
629 fwrite(&lo, 1, 1, f);
630 }
631 else if (t_depth == 16)
632 {
633 lo = (t_bitmap->d16[i * t_width + a] & 0x00ff);
634 hi = (t_bitmap->d16[i * t_width + a] & 0xff00) >> 8;
635 fwrite(&lo, 1, 1, f);
636 fwrite(&hi, 1, 1, f);
637 }
638 else if (t_depth == 24)
639 {
640 fwrite(&t_bitmap->d24[i * t_width + a], 3, 1, f);
641 }
642 else /* 32 */
643 {
644 fwrite(&t_bitmap->d32[i * t_width + a], 4, 1, f);
645 }
646 }
647 }
648}
649
650/****************************************************************************
651 * generate_ascii()
652 *
653 * Outputs an ascii picture of the bitmap
654 ****************************************************************************/
655
656void generate_ascii(int width, int height, struct RGBQUAD *bitmap)
657{
658 FILE *f;
659 int x, y;
660
661 f = stdout;
662
663 /* for screen output debugging */
664 for (y = 0; y < height; y++)
665 {
666 for (x = 0; x < width; x++)
667 {
668 fprintf(f, (brightness(bitmap[y * width + x]) & 0x80) ? " " : "*");
669 }
670 fprintf(f, "\n");
671 }
672}
673
674void print_usage(void)
675{
676 printf("Usage: %s [-i <id>] [-a] <bitmap file>\n"
677 "\t-i <id> Bitmap name (default is filename without extension)\n"
678 "\t-h <dir> Create header file in <dir>/<id>.h\n"
679 "\t-a Show ascii picture of bitmap\n"
680 "\t-b Create bitmap struct along with pixel array\n"
681 "\t-r Generate RAW file (little-endian)\n"
682 "\t-f <n> Generate destination format n, default = 0\n"
683 "\t 0 Archos recorder, Ondio, Iriver H1x0 mono\n"
684 , APPLICATION_NAME);
685 printf("\t 1 Archos player graphics library\n"
686 "\t 2 Iriver H1x0 4-grey\n"
687 "\t 3 Canonical 8-bit greyscale\n"
688 "\t 4 16-bit packed 5-6-5 RGB (iriver H300)\n"
689 "\t 5 16-bit packed and byte-swapped 5-6-5 RGB (iPod, Fuzev2)\n"
690 "\t 6 Greyscale iPod 4-grey\n"
691 "\t 7 Greyscale X5 remote 4-grey\n"
692 "\t 8 16-bit packed 5-6-5 RGB with a vertical stride\n"
693 "\t 9 24-bit BGR\n"
694 "\t 10 32-bit XRGB8888\n");
695 printf("build date: " __DATE__ "\n\n");
696}
697
698int main(int argc, char **argv)
699{
700 char *bmp_filename = NULL;
701 char *id = NULL;
702 char* header_dir = NULL;
703 int i;
704 int ascii = false;
705 int format = 0;
706 struct RGBQUAD *bitmap = NULL;
707 union RAWDATA t_bitmap = { NULL };
708 int width, height;
709 int t_width, t_height, t_depth;
710 bool raw = false;
711 bool create_bm = false;
712
713
714 for (i = 1;i < argc;i++)
715 {
716 if (argv[i][0] == '-')
717 {
718 switch (argv[i][1])
719 {
720 case 'h': /* .h filename */
721 if (argv[i][2])
722 {
723 header_dir = &argv[i][2];
724 }
725 else if (argc > i+1)
726 {
727 header_dir = argv[i+1];
728 i++;
729 }
730 else
731 {
732 print_usage();
733 exit(1);
734 }
735 break;
736
737 case 'i': /* ID */
738 if (argv[i][2])
739 {
740 id = &argv[i][2];
741 }
742 else if (argc > i+1)
743 {
744 id = argv[i+1];
745 i++;
746 }
747 else
748 {
749 print_usage();
750 exit(1);
751 }
752 break;
753
754 case 'a': /* Ascii art */
755 ascii = true;
756 break;
757
758 case 'b':
759 create_bm = true;
760 break;
761
762 case 'r': /* Raw File */
763 raw = true;
764 break;
765
766 case 'f':
767 if (argv[i][2])
768 {
769 format = atoi(&argv[i][2]);
770 }
771 else if (argc > i+1)
772 {
773 format = atoi(argv[i+1]);
774 i++;
775 }
776 else
777 {
778 print_usage();
779 exit(1);
780 }
781 break;
782
783 default:
784 print_usage();
785 exit(1);
786 break;
787 }
788 }
789 else
790 {
791 if (!bmp_filename)
792 {
793 bmp_filename = argv[i];
794 }
795 else
796 {
797 print_usage();
798 exit(1);
799 }
800 }
801 }
802
803 if (!bmp_filename)
804 {
805 print_usage();
806 exit(1);
807 }
808
809 if (!id)
810 {
811 char *ptr=strrchr(bmp_filename, '/');
812 if (ptr)
813 ptr++;
814 else
815 ptr = bmp_filename;
816 id = strdup(ptr);
817 for (i = 0; id[i]; i++)
818 if (id[i] == '.')
819 id[i] = '\0';
820 }
821
822 if (read_bmp_file(bmp_filename, &width, &height, &bitmap))
823 exit(1);
824
825
826 if (ascii)
827 {
828 generate_ascii(width, height, bitmap);
829 }
830 else
831 {
832 if (transform_bitmap(bitmap, width, height, format, &t_bitmap,
833 &t_width, &t_height, &t_depth))
834 exit(1);
835 if(raw)
836 generate_raw_file(&t_bitmap, t_width, t_height, t_depth);
837 else
838 generate_c_source(id, header_dir, width, height, &t_bitmap,
839 t_width, t_height, t_depth,
840 format <= 1, create_bm);
841 }
842
843 return 0;
844}