changeset 828:c20a99411a1a

Fix a silly segfault.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 17 May 2014 01:56:04 +0300
parents c8beac5313c3
children 97700378ecd8
files tools/gfxconv.c tools/objlink.c
diffstat 2 files changed, 135 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/tools/gfxconv.c	Sat May 17 00:29:16 2014 +0300
+++ b/tools/gfxconv.c	Sat May 17 01:56:04 2014 +0300
@@ -140,7 +140,7 @@
     {  0, '?', "help",         "Show this help", OPT_NONE },
     { 15, 'v', "verbose",      "Increase verbosity", OPT_NONE },
     {  3, 'o', "output",       "Output filename", OPT_ARGREQ },
-    {  1, 'i', "informat",     "Set input format ([s]prite, [c]har, [b]itmap, [i]mage)", OPT_ARGREQ },
+    {  1, 'i', "informat",     "Set input format (sprite[:mc:sc], char[:mc|sc], bitmap[:<bformat>], image)", OPT_ARGREQ },
     {  2, 'm', "multicolor",   "Input is multicolor / output in multicolor", OPT_NONE },
     {  4, 's', "skip",         "Skip bytes in input", OPT_ARGREQ },
     {  5, 'f', "format",       "Output format (see --formats)", OPT_ARGREQ },
@@ -149,12 +149,12 @@
     {  6, 'c', "colormap",     "Color mappings (see below for information)", OPT_ARGREQ },
     {  7, 'n', "numitems",     "How many 'items' to view (default: all)", OPT_ARGREQ },
     {  9, 'S', "scale",        "Scale output by x (image output only)", OPT_ARGREQ },
-    { 10, 'b', "bformat",      "Force input bitmap format (see below)", OPT_ARGREQ },
     { 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', "bplanes",      "Bits per pixel OR # of bitplanes (certain output formats)", OPT_ARGREQ },
     { 14, 'I', "interleave",   "Interleave scanlines (default: output whole planes)", OPT_NONE },
     { 16, 'R', "remap",        "Remap output image colors (-R <(#RRGGBB|index):index>[,<..>][+remove] | -R @map.txt[+remove])", OPT_ARGREQ },
+    { 19, 'C', "crop",         "Crop intermediate -C auto|<x0>:<y0>-<x1>:<y1>|<x0>:<y0>:<w>:<h>", OPT_ARGREQ },
 };
 
 static const int optListN = sizeof(optList) / sizeof(optList[0]);
@@ -184,7 +184,7 @@
     "\n"
     "(Not all input->output combinations are actually supported.)\n"
     "\n"
-    "Available bitmap formats:\n"
+    "Available bitmap formats (-f bitmap:<bformat>):\n"
     "  Ext | Type            | Description\n"
     "------+-----------------+-------------------------------------\n"
     );
@@ -516,6 +516,38 @@
                         dmError("Invalid input format '%s'.\n", optArg);
                         return FALSE;
                 }
+            
+                char *tmp = strchr(optArg, ':');
+                if (tmp != NULL)
+                {
+                    tmp++;
+                    switch (optInFormat)
+                    {
+                        case FFMT_SPRITE:
+                        case FFMT_CHAR:
+                            if (strcasecmp(tmp, "mc") == 0)
+                                optInMulticolor = TRUE;
+                            else
+                            if (strcasecmp(tmp, "sc") == 0)
+                                optInMulticolor = FALSE;
+                            else
+                            {
+                                dmError("Invalid input subformat for sprite/char: '%s', should be 'mc' or 'sc'.\n",
+                                    tmp);
+                                return FALSE;
+                            }
+                            break;
+                        
+                        case FFMT_BITMAP:
+                            if (!dmGetC64FormatByExt(tmp, &optInFormat, &optInSubFormat))
+                            {
+                                dmError("Invalid bitmap subformat '%s', see format list for valid bformats.\n",
+                                    tmp);
+                                return FALSE;
+                            }
+                            break;
+                    }
+                }
             }
             break;
         
@@ -654,6 +686,20 @@
             optRemapColors = TRUE;
             break;
 
+        case 19:
+            {
+                if (strcasecmp(optArg, "auto") == 0)
+                {
+                }
+                else
+                if (sscanf(optArg, "%d:%d-%d:%d", ) == 4)
+                {
+                }
+                else
+                if (sscanf(optArg, "%d:%d
+            }
+            break;
+
         default:
             dmError("Unknown option '%s'.\n", currArg);
             return FALSE;
@@ -1156,23 +1202,25 @@
 
 int dmWriteSpritesAndChars(const char *filename, DMImage *image, int outFormat, BOOL multicolor)
 {
-    int outBlockW, outBlockH, bx, by;
+    int ret = DMERR_OK;
+    int outBlockW, outBlockH, bx, by, index;
     FILE *outFile = NULL;
-    Uint8 *buf = NULL;
-    size_t bufSize;
-    char *outType;
+    Uint8 **outBuf = NULL;
+    int *outScreen = NULL;
+    size_t outBufSize;
+    char *outType, *tmpFilename;
 
     switch (outFormat)
     {
         case FFMT_CHAR:
-            bufSize = C64_CHR_SIZE;
+            outBufSize = C64_CHR_SIZE;
             outBlockW = image->width / C64_CHR_WIDTH_PX;
             outBlockH = image->height / C64_CHR_HEIGHT;
             outType = "char";
             break;
 
         case FFMT_SPRITE:
-            bufSize = C64_SPR_SIZE;
+            outBufSize = C64_SPR_SIZE;
             outBlockW = image->width / C64_SPR_WIDTH_PX;
             outBlockH = image->height / C64_SPR_HEIGHT;
             outType = "sprite";
@@ -1183,68 +1231,119 @@
             goto error;
     }
 
-    if (outBlockW <= 0 || outBlockH <= 0)
+    if (outBlockW < 1 || outBlockH < 1)
     {
+        ret = DMERR_INVALID_ARGS;
         dmError("Source image dimensions too small for conversion, block dimensions %d x %d.\n",
             outBlockW, outBlockH);
         goto error;
     }
 
-    if ((outFile = fopen(filename, "wb")) == NULL)
+    dmMsg(1, "Converting %d x %d = %d blocks of %s data...\n",
+        outBlockW, outBlockH, outBlockW * outBlockH, outType);
+
+
+    // Allocate screen buffer
+    if ((outScreen = dmMalloc(outBlockW * outBlockH * sizeof(int))) == NULL)
     {
-        int err = dmGetErrno();
-        dmError("Could not open '%s' for writing, %d: %s.\n",
-            filename, err, dmErrorStr(err));
+        ret = DMERR_MALLOC;
+        dmError("Could not allocate %d bytes for screen conversion buffer.\n",
+            outBlockW * outBlockH * sizeof(int));
+        goto error;
+    }
+
+    // Allocate char buffers
+    if ((outBuf = dmMalloc0(outBlockW * outBlockH * sizeof(Uint8 *))) == NULL)
+    {
+        ret = DMERR_MALLOC;
+        dmError("Could not allocate character data index.\n");
         goto error;
     }
 
-    if ((buf = dmMalloc(bufSize)) == NULL)
+    for (index = 0; index < outBlockW * outBlockH; index++)
     {
-        dmError("Could not allocate %d bytes for conversion buffer.\n",
-            bufSize);
+        if ((outBuf[index] = dmMalloc(outBufSize)) == NULL)
+        {
+            ret = DMERR_MALLOC;
+            dmError("Could not allocate %d bytes for character data buffer.\n",
+                outBufSize);
+            goto error;
+        }
+    }
+
+    if ((tmpBuf = dmMalloc(outBufSize)) == NULL)
+    {
+        err = DMERR_MALLOC;
+        dmError("Could not allocate %d bytes for character data buffer.\n",
+            outBufSize);
         goto error;
     }
 
-    dmMsg(1, "Writing %d x %d = %d blocks of %s data...\n",
-        outBlockW, outBlockH, outBlockW * outBlockH, outType);
-
+    // Chop input image into char blocks
+    index = 0;
     for (by = 0; by < outBlockH; by++)
     for (bx = 0; bx < outBlockW; bx++)
     {
+        outScreen[index] = index;
         switch (outFormat)
         {
             case FFMT_CHAR:
-                if (!dmConvertImage2Char(buf, image,
+                if (!dmConvertImage2Char(tmpBuf, image,
                     bx * C64_CHR_WIDTH_PX, by * C64_CHR_HEIGHT,
                     multicolor))
                     goto error;
                 break;
 
             case FFMT_SPRITE:
-                if (!dmConvertImage2Sprite(buf, image,
+                if (!dmConvertImage2Sprite(tmpBuf, image,
                     bx * C64_SPR_WIDTH_PX, by * C64_SPR_HEIGHT,
                     multicolor))
                     goto error;
+                break;
         }
+        index++;
+    }
+
+    // Eliminate duplicates
+    
+    
+
+    // Write out character data
+    tmpFilename = dm_strdup_fext(filename, "%s.chr");
+    if ((outFile = fopen(filename, "wb")) == NULL)
+    {
+        err = dmGetErrno();
+        dmError("Could not open '%s' for writing, %d: %s.\n",
+            filename, err, dmErrorStr(err));
+        goto error;
+    }
+
 
         if (!dm_fwrite_str(outFile, buf, bufSize))
         {
-            int err = dmGetErrno();
+            err = dmGetErrno();
             dmError("Error writing data block %d,%d to '%s', %d: %s\n",
                 bx, by, filename, err, dmErrorStr(err));
             goto error;
         }
+
+error:
+    // Cleanup
+    if (outFile != NULL)
+        fclose(outFile);
+
+    if (outBuf != NULL)
+    {
+        for (index = 0; index < outBlockW * outBlockH; index++)
+            dmFree(outBuf[i]);
     }
 
-    fclose(outFile);
-    dmFree(buf);
-    return 0;
+    dmFree(tmpFilename);
+    dmFree(outBuf);
+    dmFree(tmpBuf);
+    dmFree(outScreen);
 
-error:
-    if (outFile != NULL)
-        fclose(outFile);
-    dmFree(buf);
-    return -1;
+    return err;
 }
 
 
--- a/tools/objlink.c	Sat May 17 00:29:16 2014 +0300
+++ b/tools/objlink.c	Sat May 17 01:56:04 2014 +0300
@@ -703,7 +703,11 @@
         ssize_t siz, kz;
 
         // Check for empty, unreserved areas
-        siz = (curr->start - 1) - (prev->end + 1) + 1;
+        if (prev != NULL)
+            siz = (curr->start - 1) - (prev->end + 1) + 1;
+        else
+            siz = 0;
+        
         if (prev != NULL && siz > 1)
         {
             kz = siz / (1024 * 2);