# HG changeset patch # User Matti Hamalainen # Date 1400280964 -10800 # Node ID c20a99411a1a44f36d8d538ab347fd94dacba949 # Parent c8beac5313c32b537476b0709b61f755c80e8afb Fix a silly segfault. diff -r c8beac5313c3 -r c20a99411a1a tools/gfxconv.c --- 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[:], 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|:-:|:::", 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:):\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; } diff -r c8beac5313c3 -r c20a99411a1a tools/objlink.c --- 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);