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;
                 }
             }