Mercurial > hg > dmlib
diff gfxconv.c @ 435:e4a3f183e463
Modularize some more.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 03 Nov 2012 16:08:30 +0200 |
parents | b583a682f12d |
children | 2a4de5fe4003 |
line wrap: on
line diff
--- a/gfxconv.c Sat Nov 03 14:52:52 2012 +0200 +++ b/gfxconv.c Sat Nov 03 16:08:30 2012 +0200 @@ -9,34 +9,12 @@ #include "dmlib.h" #include "dmargs.h" #include "dmfile.h" -#include "dmbstr.h" #include "dmmutex.h" +#include "libgfx.h" #include "lib64gfx.h" //#define UNFINISHED 1 -#ifdef DM_USE_LIBPNG -#include <png.h> -#endif - -enum -{ - IMGFMT_PNG, - IMGFMT_PPM, - IMGFMT_PCX, - IMGFMT_ARAW, - - IMGFMT_LAST -}; - -static const char *imageFormatList[IMGFMT_LAST] = -{ - "PNG", - "PPM", - "PCX", - "ARAW", -}; - enum { FFMT_AUTO = 0, @@ -120,17 +98,21 @@ optInSubFormat = IMGFMT_PNG, optOutSubFormat = IMGFMT_PNG, optItemCount = -1, - optScale = 2, optPlanedWidth = 1, - optForcedFormat = -1, - optBPP = 4; + optForcedFormat = -1; int optInSkip = 0; BOOL optInMulticolor = FALSE, - optSequential = FALSE, - optPaletted = FALSE, - optInterleave = FALSE; + optSequential = FALSE; int optColors[C64_MAX_COLORS]; +DMImageSpec optSpec = +{ + .scale = 2, + .nplanes = 4, + .interleave = FALSE, + .paletted = FALSE, + .format = 0, +}; static DMOptArg optList[] = { @@ -344,7 +326,7 @@ dmError("Invalid scale value '%s'.\n", optArg); return FALSE; } - optScale = tmp; + optSpec.scale = tmp; } break; @@ -361,7 +343,7 @@ break; case 12: - optPaletted = TRUE; + optSpec.paletted = TRUE; break; case 13: @@ -372,12 +354,12 @@ dmError("Invalid bitplanes/bpp value '%s'.\n", optArg); return FALSE; } - optBPP = tmp; + optSpec.nplanes = tmp; } break; case 14: - optInterleave = TRUE; + optSpec.interleave = TRUE; break; default: @@ -489,875 +471,6 @@ } -int dmWriteImageData(DMImage *img, void *cbdata, BOOL (*writeRowCB)(void *, Uint8 *, size_t), int scale, int format) -{ - int x, y, yscale, xscale, res = 0, rowSize, rowWidth; - Uint8 *row = NULL; - - // Allocate memory for row buffer - rowWidth = img->width * scale; - rowSize = rowWidth * dmImageGetBytesPerPixel(format); - - if ((row = dmMalloc(rowSize + 16)) == NULL) - { - res = DMERR_MALLOC; - goto done; - } - - // Generate the image - for (y = 0; y < img->height; y++) - { - Uint8 *ptr = row, - *ptr1 = row, - *ptr2 = ptr1 + rowWidth, - *ptr3 = ptr2 + rowWidth; - - for (x = 0; x < img->width; x++) - { - Uint8 c = img->data[(y * img->pitch) + x], qr, qg, qb, qa; - switch (format) - { - case DM_IFMT_PALETTE: - for (xscale = 0; xscale < scale; xscale++) - *ptr++ = c; - break; - - case DM_IFMT_RGBA: - qr = img->pal[c].r; - qg = img->pal[c].g; - qb = img->pal[c].b; - qa = (c == img->ctrans) ? 0 : 255; - - for (xscale = 0; xscale < scale; xscale++) - { - *ptr++ = qr; - *ptr++ = qg; - *ptr++ = qb; - *ptr++ = qa; - } - break; - - case DM_IFMT_RGB: - qr = img->pal[c].r; - qg = img->pal[c].g; - qb = img->pal[c].b; - - for (xscale = 0; xscale < scale; xscale++) - { - *ptr++ = qr; - *ptr++ = qg; - *ptr++ = qb; - } - break; - - case DM_IFMT_RGB_PLANE: - qr = img->pal[c].r; - qg = img->pal[c].g; - qb = img->pal[c].b; - - for (xscale = 0; xscale < scale; xscale++) - { - *ptr1++ = qr; - *ptr2++ = qg; - *ptr3++ = qb; - } - break; - } - } - - for (yscale = 0; yscale < scale; yscale++) - { - if (!writeRowCB(cbdata, row, rowSize)) - { - res = DMERR_FWRITE; - goto done; - } - } - } - -done: - dmFree(row); - return res; -} - - -#define DMCOL(x) (((x) >> 4) & 0xf) - -int dmWriteIFFMasterRAWPalette(const char *filename, DMImage *img, int ncolors) -{ - FILE *fp; - int i; - - if ((fp = fopen(filename, "w")) == NULL) - { - dmError("IFFMasterRAW: Could not open file '%s' for writing.\n", filename); - return -15; - } - - for (i = 0; i < ncolors; i++) - { - int color; - if (i < img->ncolors) - { - color = (DMCOL(img->pal[i].r) << 8) | - (DMCOL(img->pal[i].g) << 4) | - (DMCOL(img->pal[i].b)); - } - else - color = 0; - - fprintf(fp, "\tdc.w $%04X\n", color); - } - - return 0; -} - - -int dmWriteIFFMasterRAWImageFILE(FILE *fp, DMImage *img, int scale, int nplanes, BOOL interleave) -{ - int xc, yc, plane, res; - DMBitStream bs; - - if ((res = dmInitBitStream(&bs, fp)) != DMERR_OK) - return res; - - 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; - } - } - } - } - 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 dmWriteIFFMasterRAWImage(const char *filename, DMImage *img, int scale, int nplanes, BOOL interleave) -{ - FILE *fp; - int res; - - if ((fp = fopen(filename, "wb")) == NULL) - { - dmError("IFFMasterRAW: Could not open file '%s' for writing.\n", filename); - return DMERR_FOPEN; - } - - res = dmWriteIFFMasterRAWImageFILE(fp, img, scale, nplanes, interleave); - - fclose(fp); - return res; -} - - -static BOOL dmWritePPMRow(void *cbdata, Uint8 *row, size_t len) -{ - return fwrite(row, sizeof(Uint8), len, (FILE *) cbdata) == len; -} - - -int dmWritePPMImageFILE(FILE *fp, DMImage *img, int scale) -{ - // Write PPM header - fprintf(fp, - "P6\n%d %d\n255\n", - img->width * scale, img->height * scale); - - // Write image data - return dmWriteImageData(img, (void *) fp, dmWritePPMRow, scale, DM_IFMT_RGB); -} - - -int dmWritePPMImage(const char *filename, DMImage *img, int scale) -{ - FILE *fp; - int res; - - // Create output file - if ((fp = fopen(filename, "wb")) == NULL) - { - dmError("PPM: could not open file '%s' for writing.\n", filename); - return DMERR_FOPEN; - } - - res = dmWritePPMImageFILE(fp, img, scale); - - fclose(fp); - return res; -} - - -#ifdef DM_USE_LIBPNG -static BOOL dmWritePNGRow(void *cbdata, Uint8 *row, size_t len) -{ - png_structp png_ptr = cbdata; - (void) len; - - if (setjmp(png_jmpbuf(png_ptr))) - return FALSE; - - png_write_row(png_ptr, row); - - return TRUE; -} - - -int dmWritePNGImageFILE(FILE *fp, DMImage *img, int scale, int format) -{ - png_structp png_ptr = NULL; - png_infop info_ptr = NULL; - png_colorp palette = NULL; - int fmt, res = DMERR_OK; - - // Create PNG structures - png_ptr = png_create_write_struct( - PNG_LIBPNG_VER_STRING, - NULL, NULL, NULL); - - if (png_ptr == NULL) - { - dmError("PNG: png_create_write_struct() failed.\n"); - res = DMERR_MALLOC; - goto error; - } - - info_ptr = png_create_info_struct(png_ptr); - 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; - } - - png_init_io(png_ptr, fp); - - // Write PNG header info - switch (format) - { - case DM_IFMT_PALETTE: fmt = PNG_COLOR_TYPE_PALETTE; break; - case DM_IFMT_RGB : fmt = PNG_COLOR_TYPE_RGB; break; - case DM_IFMT_RGBA : fmt = PNG_COLOR_TYPE_RGB_ALPHA; break; - default: - dmError("PNG: Internal error, unsupported image format %d.\n", format); - goto error; - } - - png_set_IHDR(png_ptr, info_ptr, - img->width * scale, - img->height * scale, - 8, /* bits per component */ - fmt, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - - // Palette - if (format == DM_IFMT_PALETTE) - { - int i; - - palette = png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * sizeof(png_color)); - if (palette == NULL) - { - dmError("PNG: Could not allocate palette structure."); - goto error; - } - - memset(palette, 0, PNG_MAX_PALETTE_LENGTH * sizeof(png_color)); - - for (i = 0; i < img->ncolors; i++) - { - palette[i].red = img->pal[i].r; - palette[i].green = img->pal[i].g; - palette[i].blue = img->pal[i].b; - } - - png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH); - } - -// png_set_gAMA(png_ptr, info_ptr, 2.2); - - png_write_info(png_ptr, info_ptr); - - - // Write compressed image data - dmWriteImageData(img, (void *) png_ptr, dmWritePNGRow, scale, format); - - // Write footer - png_write_end(png_ptr, NULL); - -error: - png_free(png_ptr, palette); - palette = NULL; - - if (png_ptr && info_ptr) - png_destroy_write_struct(&png_ptr, &info_ptr); - - return res; -} - - -int dmWritePNGImage(const char *filename, DMImage *img, int scale, int format) -{ - int res; - FILE *fp; - - if ((fp = fopen(filename, "wb")) == NULL) - { - dmError("PNG: could not open file '%s' for writing.\n", filename); - return DMERR_FOPEN; - } - - res = dmWritePNGImageFILE(fp, img, scale, format); - - fclose(fp); - return res; -} -#endif - - -typedef struct -{ - Uint8 r,g,b; -} DMPCXColor; - - -typedef struct -{ - Uint8 manufacturer, - version, - encoding, - bpp; - Uint16 xmin, ymin, xmax, ymax; - Uint16 hres, vres; - DMPCXColor colormap[16]; - Uint8 reserved; - Uint8 nplanes; - Uint16 bpl; - Uint16 palinfo; - Uint8 filler[58]; -} DMPCXHeader; - -typedef struct -{ - DMPCXHeader *header; - Uint8 *buf; - size_t bufLen, bufOffs; - int format; - FILE *fp; -} DMPCXData; - - -static inline Uint8 dmPCXGetByte(Uint8 *row, const size_t len, const size_t soffs) -{ - return (soffs < len) ? row[soffs] : 0; -} - -static BOOL dmPCXFlush(DMPCXData *pcx) -{ - BOOL ret = fwrite(pcx->buf, sizeof(Uint8), pcx->bufOffs, pcx->fp) == pcx->bufOffs; - pcx->bufOffs = 0; - return ret; -} - -static inline BOOL dmPCXPutByte(DMPCXData *pcx, const Uint8 val) -{ - if (pcx->bufOffs < pcx->bufLen) - { - pcx->buf[pcx->bufOffs++] = val; - return TRUE; - } - else - return dmPCXFlush(pcx); -} - -BOOL dmWritePCXRow(void *cbdata, Uint8 *row, size_t len) -{ - DMPCXData *pcx = (DMPCXData *) cbdata; - int plane; - - for (plane = 0; plane < pcx->header->nplanes; plane++) - { - size_t soffs = 0; - Uint8 data = dmPCXGetByte(row, len, soffs++), - count = 1; - - pcx->bufOffs = 0; - - while (soffs < pcx->header->bpl) - { - if (data == dmPCXGetByte(row, len, soffs) && count < 63) - { - count++; - soffs++; - } - else - { - if (count == 1 && (data & 0xC0) != 0xC0) - { - if (!dmPCXPutByte(pcx, data)) - return FALSE; - } - else - { - if (!dmPCXPutByte(pcx, 0xC0 | count) || - !dmPCXPutByte(pcx, data)) - return FALSE; - } - - data = dmPCXGetByte(row, len, soffs++); - count = 1; - } - } - - if (count > 1) - { - if (!dmPCXPutByte(pcx, 0xC0 | count) || - !dmPCXPutByte(pcx, data)) - return FALSE; - } - - if (!dmPCXFlush(pcx)) - return FALSE; - } - - return TRUE; -} - - -int dmWritePCXImageFILE(FILE *fp, DMImage *img, int scale, BOOL paletted) -{ - DMPCXData pcx; - DMPCXHeader hdr; - int res; - - // Create output file - pcx.buf = NULL; - pcx.format = paletted ? DM_IFMT_PALETTE : DM_IFMT_RGB_PLANE; - pcx.header = &hdr; - pcx.fp = fp; - - // Create PCX header - memset(&hdr, 0, sizeof(hdr)); - if (paletted) - { - int i; - for (i = 0; i < (img->ncolors > 16 ? 16 : img->ncolors); i++) - { - hdr.colormap[i].r = img->pal[i].r; - hdr.colormap[i].g = img->pal[i].g; - hdr.colormap[i].b = img->pal[i].b; - } - } - hdr.manufacturer = 10; - hdr.version = 5; - hdr.encoding = 1; - hdr.bpp = 8; - hdr.hres = img->width * scale; - hdr.vres = img->height * scale; - hdr.xmin = hdr.ymin = 0; - hdr.xmax = hdr.hres - 1; - hdr.ymax = hdr.vres - 1; - hdr.nplanes = dmImageGetBytesPerPixel(pcx.format); - hdr.palinfo = 1; - res = (img->width * scale); - hdr.bpl = res / 2; - if (res % 2) hdr.bpl++; - hdr.bpl *= 2; - - dmMsg(2, "PCX: paletted=%d, nplanes=%d, bpp=%d, bpl=%d\n", - paletted, hdr.nplanes, hdr.bpp, hdr.bpl); - - pcx.bufLen = hdr.bpl * 4; - if ((pcx.buf = dmMalloc(pcx.bufLen)) == NULL) - { - dmError("PCX: Could not allocate %d bytes for RLE compression buffer.\n", - pcx.bufLen); - res = DMERR_MALLOC; - goto error; - } - - // Write PCX header - if (!dm_fwrite_byte(pcx.fp, hdr.manufacturer) || - !dm_fwrite_byte(pcx.fp, hdr.version) || - !dm_fwrite_byte(pcx.fp, hdr.encoding) || - !dm_fwrite_byte(pcx.fp, hdr.bpp)) - { - dmError("PCX: Could not write basic header data.\n"); - res = DMERR_FWRITE; - goto error; - } - - if (!dm_fwrite_le16(pcx.fp, hdr.xmin) || - !dm_fwrite_le16(pcx.fp, hdr.ymin) || - !dm_fwrite_le16(pcx.fp, hdr.xmax) || - !dm_fwrite_le16(pcx.fp, hdr.ymax) || - !dm_fwrite_le16(pcx.fp, hdr.hres) || - !dm_fwrite_le16(pcx.fp, hdr.vres)) - { - dmError("PCX: Could not write image dimensions.\n"); - res = DMERR_FWRITE; - goto error; - } - - if (!dm_fwrite_str(pcx.fp, (Uint8 *) &hdr.colormap, sizeof(hdr.colormap))) - { - dmError("PCX: Could not write colormap.\n"); - res = DMERR_FWRITE; - goto error; - } - - if (!dm_fwrite_byte(pcx.fp, hdr.reserved) || - !dm_fwrite_byte(pcx.fp, hdr.nplanes) || - !dm_fwrite_le16(pcx.fp, hdr.bpl) || - !dm_fwrite_le16(pcx.fp, hdr.palinfo) || - !dm_fwrite_str(pcx.fp, (Uint8 *) &hdr.filler, sizeof(hdr.filler))) - { - dmError("PCX: Could not write header remainder.\n"); - res = DMERR_FWRITE; - goto error; - } - - // Write image data - res = dmWriteImageData(img, (void *) &pcx, dmWritePCXRow, scale, pcx.format); - - // Write VGA palette - if (paletted) - { - int i; - dm_fwrite_byte(pcx.fp, 0x0C); - dmMsg(2, "PCX: Writing palette of %d active entries.\n", img->ncolors); - - for (i = 0; i < img->ncolors; i++) - { - dm_fwrite_byte(pcx.fp, img->pal[i].r); - dm_fwrite_byte(pcx.fp, img->pal[i].g); - dm_fwrite_byte(pcx.fp, img->pal[i].b); - } - - // Pad the palette, if necessary - for (; i < 256; i++) - { - dm_fwrite_byte(pcx.fp, 0); - dm_fwrite_byte(pcx.fp, 0); - dm_fwrite_byte(pcx.fp, 0); - } - } - -error: - dmFree(pcx.buf); - return res; -} - - -int dmWritePCXImage(const char *filename, DMImage *img, int scale, BOOL paletted) -{ - FILE *fp; - int res; - - 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; -} - - -static BOOL dmPCXDecodeRLERow(FILE *fp, Uint8 *buf, const size_t bufLen) -{ - size_t offs = 0; - do - { - int count; - Uint8 data; - - if (!dm_fread_byte(fp, &data)) - return FALSE; - - if ((data & 0xC0) == 0xC0) - { - count = data & 0x3F; - if (!dm_fread_byte(fp, &data)) - return FALSE; - } - else - count = 1; - - while (count-- && offs < bufLen) - buf[offs++] = data; - - } while (offs < bufLen); - - return TRUE; -} - - -int dmReadPCXImageFILE(FILE *fp, DMImage **pimg) -{ - DMImage *img; - DMPCXData pcx; - DMPCXHeader hdr; - BOOL paletted; - int res = 0, yc, xc; - Uint8 *dp; - - pcx.buf = NULL; - - // Read PCX header - if (!dm_fread_byte(fp, &hdr.manufacturer) || - !dm_fread_byte(fp, &hdr.version) || - !dm_fread_byte(fp, &hdr.encoding) || - !dm_fread_byte(fp, &hdr.bpp)) - { - dmError("PCX: Could not read basic header data.\n"); - res = DMERR_FREAD; - goto error; - } - - if (hdr.manufacturer != 10 || - hdr.version != 5 || - hdr.encoding != 1 || - hdr.bpp != 8) - { - dmError("PCX: Not a PCX file, or unsupported variant.\n"); - res = DMERR_FREAD; - goto error; - } - - if (!dm_fread_le16(fp, &hdr.xmin) || - !dm_fread_le16(fp, &hdr.ymin) || - !dm_fread_le16(fp, &hdr.xmax) || - !dm_fread_le16(fp, &hdr.ymax) || - !dm_fread_le16(fp, &hdr.hres) || - !dm_fread_le16(fp, &hdr.vres)) - { - dmError("PCX: Could not read image dimensions.\n"); - res = DMERR_FREAD; - goto error; - } - - if (!dm_fread_str(fp, (Uint8 *) &hdr.colormap, sizeof(hdr.colormap))) - { - dmError("PCX: Could not read colormap.\n"); - res = DMERR_FREAD; - goto error; - } - - if (!dm_fread_byte(fp, &hdr.reserved) || - !dm_fread_byte(fp, &hdr.nplanes) || - !dm_fread_le16(fp, &hdr.bpl) || - !dm_fread_le16(fp, &hdr.palinfo) || - !dm_fread_str(fp, (Uint8 *) &hdr.filler, sizeof(hdr.filler))) - { - dmError("PCX: Could not read header remainder.\n"); - res = DMERR_FREAD; - goto error; - } - - if (hdr.nplanes != 3 && hdr.nplanes != 1) - { - dmError("PCX: Unsupported number of bitplanes %d.\n", hdr.nplanes); - res = DMERR_FREAD; - goto error; - } - - // Allocate image - if ((*pimg = img = dmImageAlloc(hdr.xmax - hdr.xmin + 1, hdr.ymax - hdr.ymin + 1)) == NULL) - { - dmError("PCX: Could not allocate image structure.\n"); - res = DMERR_MALLOC; - goto error; - } - - paletted = hdr.nplanes == 1; - pcx.bufLen = hdr.nplanes * hdr.bpl; - if ((pcx.buf = dmMalloc(pcx.bufLen)) == NULL) - { - dmError("PCX: Could not allocate RLE buffer.\n"); - res = DMERR_MALLOC; - goto error; - } - - // Read image data - dp = img->data; - for (yc = 0; yc < img->height; yc++) - { - // Decode row of RLE'd data - if (!dmPCXDecodeRLERow(fp, pcx.buf, pcx.bufLen)) - { - dmError("PCX: Error decoding RLE data.\n"); - res = DMERR_INVALID_DATA; - goto error; - } - - // Decode bitplanes - switch (hdr.nplanes) - { - case 1: - memcpy(dp, pcx.buf, img->width); - break; - - case 3: - { - Uint8 *dptr = dp, - *sptr1 = pcx.buf, - *sptr2 = sptr1 + hdr.bpl, - *sptr3 = sptr2 + hdr.bpl; - - for (xc = 0; xc < img->width; xc++) - { - *dptr++ = *sptr1++; - *dptr++ = *sptr2++; - *dptr++ = *sptr3++; - } - } - break; - } - - dp += img->pitch; - } - - // Read VGA palette - if (paletted) - { - int i; - Uint8 tmpb; - BOOL read; - - if (!dm_fread_byte(fp, &tmpb) || tmpb != 0x0C) - { - read = FALSE; - img->ncolors = 16; - } - else - { - read = TRUE; - img->ncolors = 256; - } - - if ((img->pal = dmCalloc(img->ncolors, sizeof(DMColor))) == NULL) - { - dmError("PCX: Could not allocate palette data!\n"); - res = DMERR_MALLOC; - goto error; - } - - if (read) - { - for (i = 0; i < img->ncolors; i++) - { - Uint8 tmpR, tmpG, tmpB; - if (!dm_fread_byte(fp, &tmpR) || - !dm_fread_byte(fp, &tmpG) || - !dm_fread_byte(fp, &tmpB)) - goto error; - - img->pal[i].r = tmpR; - img->pal[i].g = tmpG; - img->pal[i].b = tmpB; - } - } - else - { - for (i = 0; i < img->ncolors; i++) - { - if (i < 16) - { - img->pal[i].r = hdr.colormap[i].r; - img->pal[i].g = hdr.colormap[i].g; - img->pal[i].b = hdr.colormap[i].b; - } - } - } - - - } - -error: - dmFree(pcx.buf); - return res; -} - - -int dmReadPCXImage(const char *filename, DMImage **pimg) -{ - FILE *fp; - int res; - - if ((fp = fopen(filename, "rb")) == NULL) - { - dmError("PCX: Could not open file '%s' for reading.\n", filename); - return -15; - } - - res = dmReadPCXImageFILE(fp, pimg); - - fclose(fp); - return res; -} - - -static int fmtProbePNG(const Uint8 *buf, const size_t len) -{ - if (len > 64 && buf[0] == 0x89 && - buf[1] == 'P' && buf[2] == 'N' && buf[3] == 'G' && - buf[4] == 0x0d && buf[5] == 0x0a) - return DM_PROBE_SCORE_GOOD; - - return DM_PROBE_SCORE_FALSE; -} - - -static int fmtProbePCX(const Uint8 *buf, const size_t len) -{ - if (len > 128 + 64 && - buf[0] == 10 && - buf[1] == 5 && - buf[2] == 1 && - buf[3] == 8) - return DM_PROBE_SCORE_GOOD; - - return DM_PROBE_SCORE_FALSE; -} - - #ifdef UNFINISHED int dmConvertBMP2(DMImage *screen, const DM64Image *img) { @@ -1400,43 +513,46 @@ #endif -int dmWriteImage(char *filename, DMImage *image, BOOL info) +int dmWriteImage(const char *filename, DMImage *image, DMImageSpec *spec, int iformat, BOOL info) { if (info) { dmMsg(1, "Outputting %s image %d x %d -> %d x %d [%d]\n", - imageFormatList[optOutSubFormat], + dmImageFormatList[iformat], image->width, image->height, - image->width * optScale, image->height * optScale, optScale); + image->width * spec->scale, image->height * spec->scale, + spec->scale); } - - switch (optOutSubFormat) + + switch (iformat) { #ifdef DM_USE_LIBPNG case IMGFMT_PNG: - if (info) dmMsg(2, "%s output.\n", optPaletted ? "Indexed 8bpp" : "32bit RGBA"); - return dmWritePNGImage(filename, image, optScale, optPaletted ? DM_IFMT_PALETTE : DM_IFMT_RGBA); + if (info) dmMsg(2, "%s output.\n", spec->paletted ? "Indexed 8bpp" : "32bit RGBA"); + spec->format = spec->paletted ? DM_IFMT_PALETTE : DM_IFMT_RGBA; + return dmWritePNGImage(filename, image, spec); #endif case IMGFMT_PPM: if (info) dmMsg(2, "24bit RGB output.\n"); - return dmWritePPMImage(filename, image, optScale); + spec->format = DM_IFMT_RGB; + return dmWritePPMImage(filename, image, spec); case IMGFMT_PCX: - if (info) dmMsg(2, "%s output.\n", optPaletted ? "Indexed 8bpp" : "24bit RGB"); - return dmWritePCXImage(filename, image, optScale, optPaletted); + if (info) dmMsg(2, "%s output.\n", spec->paletted ? "Indexed 8bpp" : "24bit RGB"); + return dmWritePCXImage(filename, image, spec); case IMGFMT_ARAW: { int res; char *palFilename = dm_strdup_printf("%s.pal", filename); - res = dmWriteIFFMasterRAWPalette(palFilename, image, 1 << optBPP); + res = dmWriteIFFMasterRAWPalette(palFilename, image, 1 << optSpec.nplanes); dmFree(palFilename); if (res != DMERR_OK) return res; - if (info) dmMsg(2, "%d bitplanes, %s interleave.\n", optBPP, optInterleave ? "with" : "without"); - return dmWriteIFFMasterRAWImage(filename, image, optScale, optBPP, optInterleave); + if (info) dmMsg(2, "%d bitplanes, %s interleave.\n", spec->nplanes, spec->interleave ? "with" : "without"); + return dmWriteIFFMasterRAWImage(filename, image, spec); } default: @@ -1544,7 +660,7 @@ dmMsg(1, "Outputting sequence of %d images @ %d x %d -> %d x %d.\n", optItemCount, outImage->width, outImage->height, - outImage->width * optScale, outImage->height * optScale); + outImage->width * optSpec.scale, outImage->height * optSpec.scale); } else { @@ -1595,7 +711,7 @@ goto error; } - dmWriteImage(outFilename, outImage, FALSE); + dmWriteImage(optOutFilename, outImage, &optSpec, optOutSubFormat, TRUE); dmFree(outFilename); } else @@ -1612,7 +728,7 @@ if (!optSequential) { - dmWriteImage(optOutFilename, outImage, TRUE); + dmWriteImage(optOutFilename, outImage, &optSpec, optOutSubFormat, TRUE); } dmImageFree(outImage); @@ -1712,17 +828,12 @@ if (optInFormat == FFMT_AUTO) { - // XXX, needs a proper probe loop - if (fmtProbePNG(dataBuf + optInSkip, dataSize - optInSkip)) + DMImageFormat *ifmt = NULL; + int index; + if (dmImageProbeGeneric(dataBuf + optInSkip, dataSize - optInSkip, &ifmt, &index) > 0) { optInFormat = FFMT_IMAGE; - optInSubFormat = IMGFMT_PNG; - } - else - if (fmtProbePCX(dataBuf + optInSkip, dataSize - optInSkip)) - { - optInFormat = FFMT_IMAGE; - optInSubFormat = IMGFMT_PCX; + optInSubFormat = index; } } @@ -1767,7 +878,7 @@ case FFMT_BITMAP: { - DMImage *img = NULL; + DMImage *outImage = NULL; int res = DMERR_OK; if (optOutFilename == NULL) @@ -1779,29 +890,29 @@ switch (optOutFormat) { case FFMT_IMAGE: - if ((img = dmImageAlloc(C64_SCR_WIDTH, C64_SCR_HEIGHT)) == NULL) + if ((outImage = dmImageAlloc(C64_SCR_WIDTH, C64_SCR_HEIGHT)) == NULL) { dmError("Could not allocate output image surface %d x %d.\n", C64_SCR_WIDTH, C64_SCR_HEIGHT); goto error; } - img->pal = (DMColor *) &dmC64Palette; - img->ncolors = C64_NCOLORS; - img->constpal = TRUE; + outImage->pal = (DMColor *) &dmC64Palette; + outImage->ncolors = C64_NCOLORS; + outImage->constpal = TRUE; if (cfmt->convert != NULL) - res = cfmt->convert(img, &cimage); + res = cfmt->convert(outImage, &cimage); else - res = dmC64ConvertGenericBMP2Image(img, &cimage); + res = dmC64ConvertGenericBMP2Image(outImage, &cimage); - if (res != DMERR_OK || img == NULL) + if (res != DMERR_OK || outImage == NULL) { dmError("Error in bitmap to image conversion.\n"); goto error; } - res = dmWriteImage(optOutFilename, img, TRUE); + res = dmWriteImage(optOutFilename, outImage, &optSpec, optOutSubFormat, TRUE); break; default: @@ -1809,13 +920,13 @@ break; } - dmImageFree(img); + dmImageFree(outImage); } break; case FFMT_IMAGE: { - DMImage *img; + DMImage *outImage; int res = DMERR_OK; if (optOutFilename == NULL) @@ -1827,22 +938,22 @@ // Read input switch (optInSubFormat) { - case IMGFMT_PCX: res = dmReadPCXImageFILE(inFile, &img); break; -// case IMGFMT_PNG: res = dmReadPNGImageFILE(inFile, &img); break; -// case IMGFMT_ARAW: res = dmReadARAWImageFILE(inFile, &img, optBPP); break; + case IMGFMT_PCX: res = dmReadPCXImageFILE(inFile, &outImage); break; +// case IMGFMT_PNG: res = dmReadPNGImageFILE(inFile, &outImage); break; +// case IMGFMT_ARAW: res = dmReadARAWImageFILE(inFile, &outImage, optSpec.nplanes); break; default: dmError("Unsupported input image format for bitmap/image conversion.\n"); break; } - if (res != DMERR_OK || img == NULL) + if (res != DMERR_OK || outImage == NULL) break; switch (optOutFormat) { case FFMT_IMAGE: - res = dmWriteImage(optOutFilename, img, TRUE); + res = dmWriteImage(optOutFilename, outImage, &optSpec, optOutSubFormat, TRUE); break; default: @@ -1850,7 +961,7 @@ break; } - dmImageFree(img); + dmImageFree(outImage); } break; }