comparison gfxconv.c @ 415:d94f4bcb4be3

IFFMaster RAW output works now, at least to some extent.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 03 Nov 2012 03:50:42 +0200
parents b529b7e8ff83
children 238e6baf01a8
comparison
equal deleted inserted replaced
414:c452a459e552 415:d94f4bcb4be3
7 */ 7 */
8 #include <errno.h> 8 #include <errno.h>
9 #include "dmlib.h" 9 #include "dmlib.h"
10 #include "dmargs.h" 10 #include "dmargs.h"
11 #include "dmfile.h" 11 #include "dmfile.h"
12 #include "dmbstr.h"
12 #include "dmmutex.h" 13 #include "dmmutex.h"
13 #include "lib64gfx.h" 14 #include "lib64gfx.h"
14 15
15 //#define UNFINISHED 1 16 //#define UNFINISHED 1
16 17
75 optPlanedWidth = 1, 76 optPlanedWidth = 1,
76 optBPP = 4; 77 optBPP = 4;
77 int optInSkip = 0; 78 int optInSkip = 0;
78 BOOL optInMulticolor = FALSE, 79 BOOL optInMulticolor = FALSE,
79 optSequential = FALSE, 80 optSequential = FALSE,
80 optPaletted = FALSE; 81 optPaletted = FALSE,
82 optInterleave = FALSE;
81 int optColors[C64_MAX_COLORS]; 83 int optColors[C64_MAX_COLORS];
82 84
83 85
84 static DMOptArg optList[] = 86 static DMOptArg optList[] =
85 { 87 {
96 #ifdef UNFINISHED 98 #ifdef UNFINISHED
97 {10, 'b', "bformat", "Force input bitmap format (see below)", OPT_ARGREQ }, 99 {10, 'b', "bformat", "Force input bitmap format (see below)", OPT_ARGREQ },
98 #endif 100 #endif
99 {11, 'w', "width", "Item width (number of items per row, min 1)", OPT_ARGREQ }, 101 {11, 'w', "width", "Item width (number of items per row, min 1)", OPT_ARGREQ },
100 {12, 'P', "paletted", "Use indexed/paletted output (png, pcx output only)", OPT_NONE }, 102 {12, 'P', "paletted", "Use indexed/paletted output (png, pcx output only)", OPT_NONE },
101 {13, 'b', "bpp", "Bits per pixel (certain image output formats)", OPT_ARGREQ }, 103 {13, 'b', "bplanes", "Bits per pixel OR # of bitplanes (certain output formats)", OPT_ARGREQ },
104 {14, 'I', "interleave", "Interleave scanlines (default: output whole planes)", OPT_NONE },
102 }; 105 };
103 106
104 static const int optListN = sizeof(optList) / sizeof(optList[0]); 107 static const int optListN = sizeof(optList) / sizeof(optList[0]);
105 108
106 109
272 } 275 }
273 break; 276 break;
274 277
275 case 12: 278 case 12:
276 optPaletted = TRUE; 279 optPaletted = TRUE;
280 break;
281
282 case 13:
283 {
284 int tmp = atoi(optArg);
285 if (tmp < 1 || tmp > 8)
286 {
287 dmError("Invalid bitplanes/bpp value '%s'.\n", optArg);
288 return FALSE;
289 }
290 optBPP = tmp;
291 }
292 break;
293
294 case 14:
295 optInterleave = TRUE;
277 break; 296 break;
278 297
279 default: 298 default:
280 dmError("Unknown option '%s'.\n", currArg); 299 dmError("Unknown option '%s'.\n", currArg);
281 return FALSE; 300 return FALSE;
507 526
508 return 0; 527 return 0;
509 } 528 }
510 529
511 530
512 typedef struct 531 int dmWriteIFFMasterRAWImageFILE(FILE *fp, DMImage *img, int scale, int nplanes, BOOL interleave)
513 { 532 {
514 int bpp; 533 int xc, yc, plane, res;
515 DMImage *img; 534 DMBitStream bs;
516 FILE *fp; 535
517 } DMRawData; 536 if ((res = dmInitBitStream(&bs, fp)) != DMERR_OK)
518 537 return res;
519 538
520 static BOOL dmWriteIFFMasterRAWRow(void *cbdata, Uint8 *row, size_t len) 539 if (interleave)
521 { 540 {
522 DMRawData *raw = (DMRawData *) cbdata; 541 // Output bitplanes in interleaved format (each plane of line sequentially)
523 size_t i; 542 for (yc = 0; yc < img->height; yc++)
524 543 {
525 for (i = 0; i < len; i++) 544 for (plane = 0; plane < nplanes; plane++)
526 { 545 {
527 } 546 Uint8 *sp = img->data + yc * img->pitch;
528 547 for (xc = 0; xc < img->width; xc++)
529 return fwrite(row, sizeof(Uint8), len, raw->fp) == len; 548 {
530 } 549 if (!dmPutBits(&bs, (sp[xc] & (1 << plane)) ? 1 : 0, 1))
531 550 return DMERR_FWRITE;
532 551 }
533 int dmWriteIFFMasterRAWImageFILE(FILE *fp, DMImage *img, int scale, int bpp) 552 }
534 { 553 }
535 DMRawData raw; 554 }
536 555 else
537 raw.fp = fp; 556 {
538 raw.img = img; 557 // Output each bitplane in sequence
539 raw.bpp = bpp; 558 for (plane = 0; plane < nplanes; plane++)
540 559 {
541 return dmWriteImageData(img, (void *) &raw, dmWriteIFFMasterRAWRow, scale, DM_IFMT_PALETTE); 560 for (yc = 0; yc < img->height; yc++)
542 } 561 {
543 562 Uint8 *sp = img->data + yc * img->pitch;
544 int dmWriteIFFMasterRAWImage(const char *filename, DMImage *img, int scale, int bpp) 563 for (xc = 0; xc < img->width; xc++)
564 {
565 if (!dmPutBits(&bs, (sp[xc] & (1 << plane)) ? 1 : 0, 1))
566 return DMERR_FWRITE;
567 }
568 }
569 }
570 }
571
572 return dmFlushBitStream(&bs);
573 }
574
575 int dmWriteIFFMasterRAWImage(const char *filename, DMImage *img, int scale, int nplanes, BOOL interleave)
545 { 576 {
546 FILE *fp; 577 FILE *fp;
547 int res; 578 int res;
548 579
549 if ((fp = fopen(filename, "wb")) == NULL) 580 if ((fp = fopen(filename, "wb")) == NULL)
550 { 581 {
551 dmError("IFFMasterRAW: Could not open file '%s' for writing.\n", filename); 582 dmError("IFFMasterRAW: Could not open file '%s' for writing.\n", filename);
552 return -15; 583 return DMERR_FOPEN;
553 } 584 }
554 585
555 res = dmWriteIFFMasterRAWImageFILE(fp, img, scale, bpp); 586 res = dmWriteIFFMasterRAWImageFILE(fp, img, scale, nplanes, interleave);
556 587
557 fclose(fp); 588 fclose(fp);
558 return res; 589 return res;
559 } 590 }
560 591
584 615
585 // Create output file 616 // Create output file
586 if ((fp = fopen(filename, "wb")) == NULL) 617 if ((fp = fopen(filename, "wb")) == NULL)
587 { 618 {
588 dmError("PPM: could not open file '%s' for writing.\n", filename); 619 dmError("PPM: could not open file '%s' for writing.\n", filename);
589 return -15; 620 return DMERR_FOPEN;
590 } 621 }
591 622
592 res = dmWritePPMImageFILE(fp, img, scale); 623 res = dmWritePPMImageFILE(fp, img, scale);
593 624
594 fclose(fp); 625 fclose(fp);
614 int dmWritePNGImageFILE(FILE *fp, DMImage *img, int scale, int format) 645 int dmWritePNGImageFILE(FILE *fp, DMImage *img, int scale, int format)
615 { 646 {
616 png_structp png_ptr = NULL; 647 png_structp png_ptr = NULL;
617 png_infop info_ptr = NULL; 648 png_infop info_ptr = NULL;
618 png_colorp palette = NULL; 649 png_colorp palette = NULL;
619 int fmt; 650 int fmt, res = DMERR_OK;
620 651
621 // Create PNG structures 652 // Create PNG structures
622 png_ptr = png_create_write_struct( 653 png_ptr = png_create_write_struct(
623 PNG_LIBPNG_VER_STRING, 654 PNG_LIBPNG_VER_STRING,
624 NULL, NULL, NULL); 655 NULL, NULL, NULL);
625 656
626 if (png_ptr == NULL) 657 if (png_ptr == NULL)
627 { 658 {
628 dmError("PNG: png_create_write_struct() failed.\n"); 659 dmError("PNG: png_create_write_struct() failed.\n");
660 res = DMERR_MALLOC;
629 goto error; 661 goto error;
630 } 662 }
631 663
632 info_ptr = png_create_info_struct(png_ptr); 664 info_ptr = png_create_info_struct(png_ptr);
633 if (info_ptr == NULL) 665 if (info_ptr == NULL)
634 { 666 {
635 dmError("PNG: png_create_info_struct(%p) failed.\n", png_ptr); 667 dmError("PNG: png_create_info_struct(%p) failed.\n", png_ptr);
668 res = DMERR_INIT_FAIL;
636 goto error; 669 goto error;
637 } 670 }
638 671
639 if (setjmp(png_jmpbuf(png_ptr))) 672 if (setjmp(png_jmpbuf(png_ptr)))
640 { 673 {
641 dmError("PNG: Error during image writing..\n"); 674 dmError("PNG: Error during image writing..\n");
675 res = DMERR_INIT_FAIL;
642 goto error; 676 goto error;
643 } 677 }
644 678
645 png_init_io(png_ptr, fp); 679 png_init_io(png_ptr, fp);
646 680
697 dmWriteImageData(img, (void *) png_ptr, dmWritePNGRow, scale, format); 731 dmWriteImageData(img, (void *) png_ptr, dmWritePNGRow, scale, format);
698 732
699 // Write footer 733 // Write footer
700 png_write_end(png_ptr, NULL); 734 png_write_end(png_ptr, NULL);
701 735
702 png_free(png_ptr, palette);
703 palette = NULL;
704
705 // Deallocate shit
706 if (png_ptr && info_ptr)
707 {
708 png_destroy_write_struct(&png_ptr, &info_ptr);
709 }
710
711 return 0;
712
713 error: 736 error:
714 png_free(png_ptr, palette); 737 png_free(png_ptr, palette);
715 palette = NULL; 738 palette = NULL;
716 739
717 if (png_ptr && info_ptr) 740 if (png_ptr && info_ptr)
718 {
719 png_destroy_write_struct(&png_ptr, &info_ptr); 741 png_destroy_write_struct(&png_ptr, &info_ptr);
720 } 742
721 return -15; 743 return res;
722 } 744 }
723 745
724 746
725 int dmWritePNGImage(const char *filename, DMImage *img, int scale, int format) 747 int dmWritePNGImage(const char *filename, DMImage *img, int scale, int format)
726 { 748 {
728 FILE *fp; 750 FILE *fp;
729 751
730 if ((fp = fopen(filename, "wb")) == NULL) 752 if ((fp = fopen(filename, "wb")) == NULL)
731 { 753 {
732 dmError("PNG: could not open file '%s' for writing.\n", filename); 754 dmError("PNG: could not open file '%s' for writing.\n", filename);
733 return -15; 755 return DMERR_FOPEN;
734 } 756 }
735 757
736 res = dmWritePNGImageFILE(fp, img, scale, format); 758 res = dmWritePNGImageFILE(fp, img, scale, format);
737 759
738 fclose(fp); 760 fclose(fp);
848 870
849 return TRUE; 871 return TRUE;
850 } 872 }
851 873
852 874
853 int dmWritePCXImage(const char *filename, DMImage *img, int scale, BOOL paletted) 875 int dmWritePCXImageFILE(FILE *fp, DMImage *img, int scale, BOOL paletted)
854 { 876 {
855 DMPCXData pcx; 877 DMPCXData pcx;
856 DMPCXHeader hdr; 878 DMPCXHeader hdr;
857 int res; 879 int res;
858 880
859 // Create output file 881 // Create output file
860 pcx.buf = NULL; 882 pcx.buf = NULL;
861 pcx.format = paletted ? DM_IFMT_PALETTE : DM_IFMT_RGB_PLANE; 883 pcx.format = paletted ? DM_IFMT_PALETTE : DM_IFMT_RGB_PLANE;
862 pcx.header = &hdr; 884 pcx.header = &hdr;
863 if ((pcx.fp = fopen(filename, "wb")) == NULL) 885 pcx.fp = fp;
864 {
865 dmError("PCX: Could not open file '%s' for writing.\n", filename);
866 res = DMERR_FOPEN;
867 goto error;
868 }
869 886
870 // Create PCX header 887 // Create PCX header
871 memset(&hdr, 0, sizeof(hdr)); 888 memset(&hdr, 0, sizeof(hdr));
872 if (paletted) 889 if (paletted)
873 { 890 {
969 dm_fwrite_byte(pcx.fp, 0); 986 dm_fwrite_byte(pcx.fp, 0);
970 } 987 }
971 } 988 }
972 989
973 error: 990 error:
974 if (pcx.fp != NULL)
975 fclose(pcx.fp);
976
977 dmFree(pcx.buf); 991 dmFree(pcx.buf);
978 992 return res;
993 }
994
995
996 int dmWritePCXImage(const char *filename, DMImage *img, int scale, BOOL paletted)
997 {
998 FILE *fp;
999 int res;
1000
1001 if ((fp = fopen(filename, "wb")) == NULL)
1002 {
1003 dmError("PCX: Could not open file '%s' for writing.\n", filename);
1004 return DMERR_FOPEN;
1005 }
1006
1007 res = dmWritePCXImageFILE(fp, img, scale, paletted);
1008
1009 fclose(fp);
979 return res; 1010 return res;
980 } 1011 }
981 1012
982 1013
983 static BOOL dmPCXDecodeRLERow(FILE *fp, Uint8 *buf, const size_t bufLen) 1014 static BOOL dmPCXDecodeRLERow(FILE *fp, Uint8 *buf, const size_t bufLen)
1282 return 0; 1313 return 0;
1283 } 1314 }
1284 #endif 1315 #endif
1285 1316
1286 1317
1287 int dmWriteImage(char *filename, DMImage *image, int format, BOOL paletted, int scale, int bpp) 1318 int dmWriteImage(char *filename, DMImage *image)
1288 { 1319 {
1289 switch (format) 1320 switch (optOutFormat)
1290 { 1321 {
1291 #ifdef HAVE_LIBPNG 1322 #ifdef HAVE_LIBPNG
1292 case OUTFMT_PNG: 1323 case OUTFMT_PNG:
1293 return dmWritePNGImage(filename, image, scale, paletted ? DM_IFMT_PALETTE : DM_IFMT_RGBA); 1324 return dmWritePNGImage(filename, image, optScale, optPaletted ? DM_IFMT_PALETTE : DM_IFMT_RGBA);
1294 #endif 1325 #endif
1295 1326
1296 case OUTFMT_PPM: 1327 case OUTFMT_PPM:
1297 return dmWritePPMImage(filename, image, scale); 1328 return dmWritePPMImage(filename, image, optScale);
1298 1329
1299 case OUTFMT_PCX: 1330 case OUTFMT_PCX:
1300 return dmWritePCXImage(filename, image, scale, paletted); 1331 return dmWritePCXImage(filename, image, optScale, optPaletted);
1301 1332
1302 case OUTFMT_ARAW: 1333 case OUTFMT_ARAW:
1303 { 1334 {
1304 int res; 1335 int res;
1305 char *palFilename = dm_strdup_printf("%s.pal", filename); 1336 char *palFilename = dm_strdup_printf("%s.pal", filename);
1306 res = dmWriteIFFMasterRAWPalette(palFilename, image, 1 << bpp); 1337 res = dmWriteIFFMasterRAWPalette(palFilename, image, 1 << optBPP);
1307 dmFree(palFilename); 1338 dmFree(palFilename);
1308 if (res != DMERR_OK) 1339 if (res != DMERR_OK)
1309 return res; 1340 return res;
1310 1341
1311 return dmWriteIFFMasterRAWImage(filename, image, scale, bpp); 1342 return dmWriteIFFMasterRAWImage(filename, image, optScale, optBPP, optInterleave);
1312 } 1343 }
1313 1344
1314 default: 1345 default:
1315 return FALSE; 1346 return FALSE;
1316 } 1347 }
1466 { 1497 {
1467 dmError("Could not allocate memory for filename template?\n"); 1498 dmError("Could not allocate memory for filename template?\n");
1468 goto error; 1499 goto error;
1469 } 1500 }
1470 1501
1471 dmWriteImage(outFilename, outImage, optOutFormat, optPaletted, optScale, optBPP); 1502 dmWriteImage(outFilename, outImage);
1472 dmFree(outFilename); 1503 dmFree(outFilename);
1473 } 1504 }
1474 else 1505 else
1475 { 1506 {
1476 if (++outX >= optPlanedWidth) 1507 if (++outX >= optPlanedWidth)
1483 itemCount++; 1514 itemCount++;
1484 } 1515 }
1485 1516
1486 if (!optSequential) 1517 if (!optSequential)
1487 { 1518 {
1488 dmWriteImage(optOutFilename, outImage, optOutFormat, optPaletted, optScale, optBPP); 1519 dmWriteImage(optOutFilename, outImage);
1489 } 1520 }
1490 1521
1491 dmImageFree(outImage); 1522 dmImageFree(outImage);
1492 } 1523 }
1493 1524
1649 { 1680 {
1650 case OUTFMT_PCX: 1681 case OUTFMT_PCX:
1651 case OUTFMT_PPM: 1682 case OUTFMT_PPM:
1652 case OUTFMT_PNG: 1683 case OUTFMT_PNG:
1653 case OUTFMT_ARAW: 1684 case OUTFMT_ARAW:
1654 res = dmWriteImage(optOutFilename, img, optOutFormat, optPaletted, optScale, optBPP); 1685 res = dmWriteImage(optOutFilename, img);
1655 break; 1686 break;
1656 } 1687 }
1657 } 1688 }
1658 break; 1689 break;
1659 } 1690 }