Mercurial > hg > dmlib
changeset 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 | c452a459e552 |
children | 238e6baf01a8 |
files | gfxconv.c |
diffstat | 1 files changed, 99 insertions(+), 68 deletions(-) [+] |
line wrap: on
line diff
--- a/gfxconv.c Sat Nov 03 03:50:26 2012 +0200 +++ b/gfxconv.c Sat Nov 03 03:50:42 2012 +0200 @@ -9,6 +9,7 @@ #include "dmlib.h" #include "dmargs.h" #include "dmfile.h" +#include "dmbstr.h" #include "dmmutex.h" #include "lib64gfx.h" @@ -77,7 +78,8 @@ int optInSkip = 0; BOOL optInMulticolor = FALSE, optSequential = FALSE, - optPaletted = FALSE; + optPaletted = FALSE, + optInterleave = FALSE; int optColors[C64_MAX_COLORS]; @@ -98,7 +100,8 @@ #endif {11, 'w', "width", "Item width (number of items per row, min 1)", OPT_ARGREQ }, {12, 'P', "paletted", "Use indexed/paletted output (png, pcx output only)", OPT_NONE }, - {13, 'b', "bpp", "Bits per pixel (certain image output formats)", OPT_ARGREQ }, + {13, 'b', "bplanes", "Bits per pixel OR # of bitplanes (certain output formats)", OPT_ARGREQ }, + {14, 'I', "interleave", "Interleave scanlines (default: output whole planes)", OPT_NONE }, }; static const int optListN = sizeof(optList) / sizeof(optList[0]); @@ -276,6 +279,22 @@ optPaletted = TRUE; break; + case 13: + { + int tmp = atoi(optArg); + if (tmp < 1 || tmp > 8) + { + dmError("Invalid bitplanes/bpp value '%s'.\n", optArg); + return FALSE; + } + optBPP = tmp; + } + break; + + case 14: + optInterleave = TRUE; + break; + default: dmError("Unknown option '%s'.\n", currArg); return FALSE; @@ -509,39 +528,51 @@ } -typedef struct +int dmWriteIFFMasterRAWImageFILE(FILE *fp, DMImage *img, int scale, int nplanes, BOOL interleave) { - int bpp; - DMImage *img; - FILE *fp; -} DMRawData; - + int xc, yc, plane, res; + DMBitStream bs; + + if ((res = dmInitBitStream(&bs, fp)) != DMERR_OK) + return res; -static BOOL dmWriteIFFMasterRAWRow(void *cbdata, Uint8 *row, size_t len) -{ - DMRawData *raw = (DMRawData *) cbdata; - size_t i; - - for (i = 0; i < len; i++) + if (interleave) { + // Output bitplanes in interleaved format (each plane of line sequentially) + for (yc = 0; yc < img->height; yc++) + { + for (plane = 0; plane < nplanes; plane++) + { + Uint8 *sp = img->data + yc * img->pitch; + for (xc = 0; xc < img->width; xc++) + { + if (!dmPutBits(&bs, (sp[xc] & (1 << plane)) ? 1 : 0, 1)) + return DMERR_FWRITE; + } + } + } } - - return fwrite(row, sizeof(Uint8), len, raw->fp) == len; + else + { + // Output each bitplane in sequence + for (plane = 0; plane < nplanes; plane++) + { + for (yc = 0; yc < img->height; yc++) + { + Uint8 *sp = img->data + yc * img->pitch; + for (xc = 0; xc < img->width; xc++) + { + if (!dmPutBits(&bs, (sp[xc] & (1 << plane)) ? 1 : 0, 1)) + return DMERR_FWRITE; + } + } + } + } + + return dmFlushBitStream(&bs); } - -int dmWriteIFFMasterRAWImageFILE(FILE *fp, DMImage *img, int scale, int bpp) -{ - DMRawData raw; - - raw.fp = fp; - raw.img = img; - raw.bpp = bpp; - - return dmWriteImageData(img, (void *) &raw, dmWriteIFFMasterRAWRow, scale, DM_IFMT_PALETTE); -} - -int dmWriteIFFMasterRAWImage(const char *filename, DMImage *img, int scale, int bpp) +int dmWriteIFFMasterRAWImage(const char *filename, DMImage *img, int scale, int nplanes, BOOL interleave) { FILE *fp; int res; @@ -549,10 +580,10 @@ if ((fp = fopen(filename, "wb")) == NULL) { dmError("IFFMasterRAW: Could not open file '%s' for writing.\n", filename); - return -15; + return DMERR_FOPEN; } - res = dmWriteIFFMasterRAWImageFILE(fp, img, scale, bpp); + res = dmWriteIFFMasterRAWImageFILE(fp, img, scale, nplanes, interleave); fclose(fp); return res; @@ -586,7 +617,7 @@ if ((fp = fopen(filename, "wb")) == NULL) { dmError("PPM: could not open file '%s' for writing.\n", filename); - return -15; + return DMERR_FOPEN; } res = dmWritePPMImageFILE(fp, img, scale); @@ -616,7 +647,7 @@ png_structp png_ptr = NULL; png_infop info_ptr = NULL; png_colorp palette = NULL; - int fmt; + int fmt, res = DMERR_OK; // Create PNG structures png_ptr = png_create_write_struct( @@ -626,6 +657,7 @@ if (png_ptr == NULL) { dmError("PNG: png_create_write_struct() failed.\n"); + res = DMERR_MALLOC; goto error; } @@ -633,12 +665,14 @@ if (info_ptr == NULL) { dmError("PNG: png_create_info_struct(%p) failed.\n", png_ptr); + res = DMERR_INIT_FAIL; goto error; } if (setjmp(png_jmpbuf(png_ptr))) { dmError("PNG: Error during image writing..\n"); + res = DMERR_INIT_FAIL; goto error; } @@ -699,26 +733,14 @@ // Write footer png_write_end(png_ptr, NULL); - png_free(png_ptr, palette); - palette = NULL; - - // Deallocate shit - if (png_ptr && info_ptr) - { - png_destroy_write_struct(&png_ptr, &info_ptr); - } - - return 0; - error: png_free(png_ptr, palette); palette = NULL; if (png_ptr && info_ptr) - { png_destroy_write_struct(&png_ptr, &info_ptr); - } - return -15; + + return res; } @@ -730,7 +752,7 @@ if ((fp = fopen(filename, "wb")) == NULL) { dmError("PNG: could not open file '%s' for writing.\n", filename); - return -15; + return DMERR_FOPEN; } res = dmWritePNGImageFILE(fp, img, scale, format); @@ -850,7 +872,7 @@ } -int dmWritePCXImage(const char *filename, DMImage *img, int scale, BOOL paletted) +int dmWritePCXImageFILE(FILE *fp, DMImage *img, int scale, BOOL paletted) { DMPCXData pcx; DMPCXHeader hdr; @@ -860,12 +882,7 @@ pcx.buf = NULL; pcx.format = paletted ? DM_IFMT_PALETTE : DM_IFMT_RGB_PLANE; pcx.header = &hdr; - if ((pcx.fp = fopen(filename, "wb")) == NULL) - { - dmError("PCX: Could not open file '%s' for writing.\n", filename); - res = DMERR_FOPEN; - goto error; - } + pcx.fp = fp; // Create PCX header memset(&hdr, 0, sizeof(hdr)); @@ -971,11 +988,25 @@ } error: - if (pcx.fp != NULL) - fclose(pcx.fp); + dmFree(pcx.buf); + return res; +} + + +int dmWritePCXImage(const char *filename, DMImage *img, int scale, BOOL paletted) +{ + FILE *fp; + int res; - dmFree(pcx.buf); + if ((fp = fopen(filename, "wb")) == NULL) + { + dmError("PCX: Could not open file '%s' for writing.\n", filename); + return DMERR_FOPEN; + } + res = dmWritePCXImageFILE(fp, img, scale, paletted); + + fclose(fp); return res; } @@ -1284,31 +1315,31 @@ #endif -int dmWriteImage(char *filename, DMImage *image, int format, BOOL paletted, int scale, int bpp) +int dmWriteImage(char *filename, DMImage *image) { - switch (format) + switch (optOutFormat) { #ifdef HAVE_LIBPNG case OUTFMT_PNG: - return dmWritePNGImage(filename, image, scale, paletted ? DM_IFMT_PALETTE : DM_IFMT_RGBA); + return dmWritePNGImage(filename, image, optScale, optPaletted ? DM_IFMT_PALETTE : DM_IFMT_RGBA); #endif case OUTFMT_PPM: - return dmWritePPMImage(filename, image, scale); + return dmWritePPMImage(filename, image, optScale); case OUTFMT_PCX: - return dmWritePCXImage(filename, image, scale, paletted); + return dmWritePCXImage(filename, image, optScale, optPaletted); case OUTFMT_ARAW: { int res; char *palFilename = dm_strdup_printf("%s.pal", filename); - res = dmWriteIFFMasterRAWPalette(palFilename, image, 1 << bpp); + res = dmWriteIFFMasterRAWPalette(palFilename, image, 1 << optBPP); dmFree(palFilename); if (res != DMERR_OK) return res; - return dmWriteIFFMasterRAWImage(filename, image, scale, bpp); + return dmWriteIFFMasterRAWImage(filename, image, optScale, optBPP, optInterleave); } default: @@ -1468,7 +1499,7 @@ goto error; } - dmWriteImage(outFilename, outImage, optOutFormat, optPaletted, optScale, optBPP); + dmWriteImage(outFilename, outImage); dmFree(outFilename); } else @@ -1485,7 +1516,7 @@ if (!optSequential) { - dmWriteImage(optOutFilename, outImage, optOutFormat, optPaletted, optScale, optBPP); + dmWriteImage(optOutFilename, outImage); } dmImageFree(outImage); @@ -1651,7 +1682,7 @@ case OUTFMT_PPM: case OUTFMT_PNG: case OUTFMT_ARAW: - res = dmWriteImage(optOutFilename, img, optOutFormat, optPaletted, optScale, optBPP); + res = dmWriteImage(optOutFilename, img); break; } }