summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2013-09-07 11:00:16 +0200
committerThomas Martitz <kugel@rockbox.org>2013-09-07 11:00:16 +0200
commitcd741b7c7e8efb155598e30fba9c96d961972bd4 (patch)
tree48977ff255374d60ba39789f200a389b025abd13
parent90007da3e997a3bb585dca2b58b2337a178b3f53 (diff)
downloadrockbox-cd741b7c7e8efb155598e30fba9c96d961972bd4.tar.gz
rockbox-cd741b7c7e8efb155598e30fba9c96d961972bd4.zip
bmp2rb: Support generating 24bit BMP raw data.
This will be required by the R0 port. Generating C source with 24bit data is not supported yet because Rockbox doesn't support this depth yet (and has no data type for it). Change-Id: I6474a6d32bb7942661bac833bb3348073335e25c
-rw-r--r--tools/bmp2rb.c94
1 files changed, 68 insertions, 26 deletions
diff --git a/tools/bmp2rb.c b/tools/bmp2rb.c
index 7fee1e6177..8651815804 100644
--- a/tools/bmp2rb.c
+++ b/tools/bmp2rb.c
@@ -77,6 +77,12 @@ struct RGBQUAD
77 unsigned char rgbReserved; 77 unsigned char rgbReserved;
78} STRUCT_PACKED; 78} STRUCT_PACKED;
79 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};
85
80short readshort(void* value) 86short readshort(void* value)
81{ 87{
82 unsigned char* bytes = (unsigned char*) value; 88 unsigned char* bytes = (unsigned char*) value;
@@ -285,11 +291,13 @@ int read_bmp_file(char* filename,
285 ****************************************************************************/ 291 ****************************************************************************/
286 292
287int transform_bitmap(const struct RGBQUAD *src, int width, int height, 293int transform_bitmap(const struct RGBQUAD *src, int width, int height,
288 int format, unsigned short **dest, int *dst_width, 294 int format, union RAWDATA *dst, int *dst_width,
289 int *dst_height, int *dst_depth) 295 int *dst_height, int *dst_depth)
290{ 296{
291 int row, col; 297 int row, col;
292 int dst_w, dst_h, dst_d; 298 int dst_w, dst_h, dst_d;
299 int alloc_size;
300 union RAWDATA dest;
293 301
294 switch (format) 302 switch (format)
295 { 303 {
@@ -337,21 +345,32 @@ int transform_bitmap(const struct RGBQUAD *src, int width, int height,
337 dst_d = 16; 345 dst_d = 16;
338 break; 346 break;
339 347
348 case 9: /* greyscale X5 remote 4-grey */
349 dst_w = width;
350 dst_h = height;
351 dst_d = 24;
352 break;
353
340 default: /* unknown */ 354 default: /* unknown */
341 debugf("error - Undefined destination format\n"); 355 debugf("error - Undefined destination format\n");
342 return 1; 356 return 1;
343 } 357 }
344 358
345 *dest = (unsigned short *)malloc(dst_w * dst_h * sizeof(short)); 359 if (dst_d <= 16)
346 if (*dest == NULL) 360 alloc_size = sizeof(dest.d16[0]);
361 else /* 24 bit */
362 alloc_size = sizeof(dest.d24[0]);
363 dest.d = calloc(dst_w * dst_h, alloc_size);
364
365 if (dest.d == NULL)
347 { 366 {
348 debugf("error - Out of memory.\n"); 367 debugf("error - Out of memory.\n");
349 return 2; 368 return 2;
350 } 369 }
351 memset(*dest, 0, dst_w * dst_h * sizeof(short));
352 *dst_width = dst_w; 370 *dst_width = dst_w;
353 *dst_height = dst_h; 371 *dst_height = dst_h;
354 *dst_depth = dst_d; 372 *dst_depth = dst_d;
373 *dst = dest;
355 374
356 switch (format) 375 switch (format)
357 { 376 {
@@ -359,7 +378,7 @@ int transform_bitmap(const struct RGBQUAD *src, int width, int height,
359 for (row = 0; row < height; row++) 378 for (row = 0; row < height; row++)
360 for (col = 0; col < width; col++) 379 for (col = 0; col < width; col++)
361 { 380 {
362 (*dest)[(row/8) * dst_w + col] |= 381 dest.d16[(row/8) * dst_w + col] |=
363 (~brightness(src[row * width + col]) & 0x80) >> (~row & 7); 382 (~brightness(src[row * width + col]) & 0x80) >> (~row & 7);
364 } 383 }
365 break; 384 break;
@@ -368,7 +387,7 @@ int transform_bitmap(const struct RGBQUAD *src, int width, int height,
368 for (row = 0; row < height; row++) 387 for (row = 0; row < height; row++)
369 for (col = 0; col < width; col++) 388 for (col = 0; col < width; col++)
370 { 389 {
371 (*dest)[row * dst_w + (col/8)] |= 390 dest.d16[row * dst_w + (col/8)] |=
372 (~brightness(src[row * width + col]) & 0x80) >> (col & 7); 391 (~brightness(src[row * width + col]) & 0x80) >> (col & 7);
373 } 392 }
374 break; 393 break;
@@ -377,7 +396,7 @@ int transform_bitmap(const struct RGBQUAD *src, int width, int height,
377 for (row = 0; row < height; row++) 396 for (row = 0; row < height; row++)
378 for (col = 0; col < width; col++) 397 for (col = 0; col < width; col++)
379 { 398 {
380 (*dest)[(row/4) * dst_w + col] |= 399 dest.d16[(row/4) * dst_w + col] |=
381 (~brightness(src[row * width + col]) & 0xC0) >> (2 * (~row & 3)); 400 (~brightness(src[row * width + col]) & 0xC0) >> (2 * (~row & 3));
382 } 401 }
383 break; 402 break;
@@ -386,7 +405,7 @@ int transform_bitmap(const struct RGBQUAD *src, int width, int height,
386 for (row = 0; row < height; row++) 405 for (row = 0; row < height; row++)
387 for (col = 0; col < width; col++) 406 for (col = 0; col < width; col++)
388 { 407 {
389 (*dest)[row * dst_w + col] = brightness(src[row * width + col]); 408 dest.d16[row * dst_w + col] = brightness(src[row * width + col]);
390 } 409 }
391 break; 410 break;
392 411
@@ -401,9 +420,9 @@ int transform_bitmap(const struct RGBQUAD *src, int width, int height,
401 ((src[row * width + col].rgbBlue >> 3))); 420 ((src[row * width + col].rgbBlue >> 3)));
402 421
403 if (format == 4) 422 if (format == 4)
404 (*dest)[row * dst_w + col] = rgb; 423 dest.d16[row * dst_w + col] = rgb;
405 else 424 else
406 (*dest)[row * dst_w + col] = ((rgb&0xff00)>>8)|((rgb&0x00ff)<<8); 425 dest.d16[row * dst_w + col] = ((rgb&0xff00)>>8)|((rgb&0x00ff)<<8);
407 } 426 }
408 break; 427 break;
409 428
@@ -411,7 +430,7 @@ int transform_bitmap(const struct RGBQUAD *src, int width, int height,
411 for (row = 0; row < height; row++) 430 for (row = 0; row < height; row++)
412 for (col = 0; col < width; col++) 431 for (col = 0; col < width; col++)
413 { 432 {
414 (*dest)[row * dst_w + (col/4)] |= 433 dest.d16[row * dst_w + (col/4)] |=
415 (~brightness(src[row * width + col]) & 0xC0) >> (2 * (col & 3)); 434 (~brightness(src[row * width + col]) & 0xC0) >> (2 * (col & 3));
416 } 435 }
417 break; 436 break;
@@ -423,7 +442,7 @@ int transform_bitmap(const struct RGBQUAD *src, int width, int height,
423 unsigned short data = (~brightness(src[row * width + col]) & 0xC0) >> 6; 442 unsigned short data = (~brightness(src[row * width + col]) & 0xC0) >> 6;
424 443
425 data = (data | (data << 7)) & 0x0101; 444 data = (data | (data << 7)) & 0x0101;
426 (*dest)[(row/8) * dst_w + col] |= data << (row & 7); 445 dest.d16[(row/8) * dst_w + col] |= data << (row & 7);
427 } 446 }
428 break; 447 break;
429 448
@@ -436,7 +455,17 @@ int transform_bitmap(const struct RGBQUAD *src, int width, int height,
436 ((src[row * width + col].rgbGreen >> 2) << 5) | 455 ((src[row * width + col].rgbGreen >> 2) << 5) |
437 ((src[row * width + col].rgbBlue >> 3))); 456 ((src[row * width + col].rgbBlue >> 3)));
438 457
439 (*dest)[col * dst_h + row] = rgb; 458 dest.d16[col * dst_h + row] = rgb;
459 }
460 break;
461
462 case 9: /* 24-bit RGB */
463 for (row = 0; row < height; row++)
464 for (col = 0; col < width; col++)
465 {
466 dest.d24[row * width + col].r = src[row * width + col].rgbRed;
467 dest.d24[row * width + col].g = src[row * width + col].rgbGreen;
468 dest.d24[row * width + col].b = src[row * width + col].rgbBlue;
440 } 469 }
441 break; 470 break;
442 } 471 }
@@ -452,7 +481,7 @@ int transform_bitmap(const struct RGBQUAD *src, int width, int height,
452 ****************************************************************************/ 481 ****************************************************************************/
453 482
454void generate_c_source(char *id, char* header_dir, int width, int height, 483void generate_c_source(char *id, char* header_dir, int width, int height,
455 const unsigned short *t_bitmap, int t_width, 484 const union RAWDATA *t_bitmap, int t_width,
456 int t_height, int t_depth, bool t_mono, bool create_bm) 485 int t_height, int t_depth, bool t_mono, bool create_bm)
457{ 486{
458 FILE *f; 487 FILE *f;
@@ -462,6 +491,14 @@ void generate_c_source(char *id, char* header_dir, int width, int height,
462 bool have_header = header_dir && header_dir[0]; 491 bool have_header = header_dir && header_dir[0];
463 create_bm = have_header && create_bm; 492 create_bm = have_header && create_bm;
464 493
494 if (t_depth > 16)
495 {
496 fprintf(stderr, "Generating C source not supported for this format\n");
497 fprintf(stderr, "because Rockbox does not support this display depth yet.\n");
498 fprintf(stderr, "However you are welcome to fix this!\n");
499 return;
500 }
501
465 if (!id || !id[0]) 502 if (!id || !id[0])
466 id = "bitmap"; 503 id = "bitmap";
467 504
@@ -513,10 +550,10 @@ void generate_c_source(char *id, char* header_dir, int width, int height,
513 for (a = 0; a < t_width; a++) 550 for (a = 0; a < t_width; a++)
514 { 551 {
515 if (t_depth <= 8) 552 if (t_depth <= 8)
516 fprintf(f, "0x%02x,%c", t_bitmap[i * t_width + a], 553 fprintf(f, "0x%02x,%c", t_bitmap->d16[i * t_width + a],
517 (a + 1) % 13 ? ' ' : '\n'); 554 (a + 1) % 13 ? ' ' : '\n');
518 else 555 else if (t_depth == 16)
519 fprintf(f, "0x%04x,%c", t_bitmap[i * t_width + a], 556 fprintf(f, "0x%04x,%c", t_bitmap->d16[i * t_width + a],
520 (a + 1) % 10 ? ' ' : '\n'); 557 (a + 1) % 10 ? ' ' : '\n');
521 } 558 }
522 fprintf(f, "\n"); 559 fprintf(f, "\n");
@@ -538,7 +575,7 @@ void generate_c_source(char *id, char* header_dir, int width, int height,
538 } 575 }
539} 576}
540 577
541void generate_raw_file(const unsigned short *t_bitmap, 578void generate_raw_file(const union RAWDATA *t_bitmap,
542 int t_width, int t_height, int t_depth) 579 int t_width, int t_height, int t_depth)
543{ 580{
544 FILE *f; 581 FILE *f;
@@ -553,16 +590,20 @@ void generate_raw_file(const unsigned short *t_bitmap,
553 { 590 {
554 if (t_depth <= 8) 591 if (t_depth <= 8)
555 { 592 {
556 lo = (t_bitmap[i * t_width + a] & 0x00ff); 593 lo = (t_bitmap->d16[i * t_width + a] & 0x00ff);
557 fwrite(&lo, 1, 1, f); 594 fwrite(&lo, 1, 1, f);
558 } 595 }
559 else 596 else if (t_depth == 16)
560 { 597 {
561 lo = (t_bitmap[i * t_width + a] & 0x00ff); 598 lo = (t_bitmap->d16[i * t_width + a] & 0x00ff);
562 hi = (t_bitmap[i * t_width + a] & 0xff00) >> 8; 599 hi = (t_bitmap->d16[i * t_width + a] & 0xff00) >> 8;
563 fwrite(&lo, 1, 1, f); 600 fwrite(&lo, 1, 1, f);
564 fwrite(&hi, 1, 1, f); 601 fwrite(&hi, 1, 1, f);
565 } 602 }
603 else /* 24 */
604 {
605 fwrite(&t_bitmap->d24[i * t_width + a].b, 3, 1, f);
606 }
566 } 607 }
567 } 608 }
568} 609}
@@ -609,7 +650,8 @@ void print_usage(void)
609 "\t 5 16-bit packed and byte-swapped 5-6-5 RGB (iPod, Fuzev2)\n" 650 "\t 5 16-bit packed and byte-swapped 5-6-5 RGB (iPod, Fuzev2)\n"
610 "\t 6 Greyscale iPod 4-grey\n" 651 "\t 6 Greyscale iPod 4-grey\n"
611 "\t 7 Greyscale X5 remote 4-grey\n" 652 "\t 7 Greyscale X5 remote 4-grey\n"
612 "\t 8 16-bit packed 5-6-5 RGB with a vertical stride\n"); 653 "\t 8 16-bit packed 5-6-5 RGB with a vertical stride\n"
654 "\t 9 24-bit BGR (raw only for now)\n");
613 printf("build date: " __DATE__ "\n\n"); 655 printf("build date: " __DATE__ "\n\n");
614} 656}
615 657
@@ -622,7 +664,7 @@ int main(int argc, char **argv)
622 int ascii = false; 664 int ascii = false;
623 int format = 0; 665 int format = 0;
624 struct RGBQUAD *bitmap = NULL; 666 struct RGBQUAD *bitmap = NULL;
625 unsigned short *t_bitmap = NULL; 667 union RAWDATA t_bitmap = { NULL };
626 int width, height; 668 int width, height;
627 int t_width, t_height, t_depth; 669 int t_width, t_height, t_depth;
628 bool raw = false; 670 bool raw = false;
@@ -751,9 +793,9 @@ int main(int argc, char **argv)
751 &t_width, &t_height, &t_depth)) 793 &t_width, &t_height, &t_depth))
752 exit(1); 794 exit(1);
753 if(raw) 795 if(raw)
754 generate_raw_file(t_bitmap, t_width, t_height, t_depth); 796 generate_raw_file(&t_bitmap, t_width, t_height, t_depth);
755 else 797 else
756 generate_c_source(id, header_dir, width, height, t_bitmap, 798 generate_c_source(id, header_dir, width, height, &t_bitmap,
757 t_width, t_height, t_depth, 799 t_width, t_height, t_depth,
758 format <= 1, create_bm); 800 format <= 1, create_bm);
759 } 801 }