comparison tools/gfxconv.c @ 829:97700378ecd8

Oops, accidentally committed unfinished code :S
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 17 May 2014 15:31:40 +0300
parents c20a99411a1a
children 5333dd4a99e4
comparison
equal deleted inserted replaced
828:c20a99411a1a 829:97700378ecd8
138 static DMOptArg optList[] = 138 static DMOptArg optList[] =
139 { 139 {
140 { 0, '?', "help", "Show this help", OPT_NONE }, 140 { 0, '?', "help", "Show this help", OPT_NONE },
141 { 15, 'v', "verbose", "Increase verbosity", OPT_NONE }, 141 { 15, 'v', "verbose", "Increase verbosity", OPT_NONE },
142 { 3, 'o', "output", "Output filename", OPT_ARGREQ }, 142 { 3, 'o', "output", "Output filename", OPT_ARGREQ },
143 { 1, 'i', "informat", "Set input format (sprite[:mc:sc], char[:mc|sc], bitmap[:<bformat>], image)", OPT_ARGREQ }, 143 { 1, 'i', "informat", "Set input format ([s]prite, [c]har, [b]itmap, [i]mage)", OPT_ARGREQ },
144 { 2, 'm', "multicolor", "Input is multicolor / output in multicolor", OPT_NONE }, 144 { 2, 'm', "multicolor", "Input is multicolor / output in multicolor", OPT_NONE },
145 { 4, 's', "skip", "Skip bytes in input", OPT_ARGREQ }, 145 { 4, 's', "skip", "Skip bytes in input", OPT_ARGREQ },
146 { 5, 'f', "format", "Output format (see --formats)", OPT_ARGREQ }, 146 { 5, 'f', "format", "Output format (see --formats)", OPT_ARGREQ },
147 { 17, 0 , "formats", "List available input/output formats", OPT_NONE }, 147 { 17, 0 , "formats", "List available input/output formats", OPT_NONE },
148 { 8, 'q', "sequential", "Output sequential files (image output only)", OPT_NONE }, 148 { 8, 'q', "sequential", "Output sequential files (image output only)", OPT_NONE },
149 { 6, 'c', "colormap", "Color mappings (see below for information)", OPT_ARGREQ }, 149 { 6, 'c', "colormap", "Color mappings (see below for information)", OPT_ARGREQ },
150 { 7, 'n', "numitems", "How many 'items' to view (default: all)", OPT_ARGREQ }, 150 { 7, 'n', "numitems", "How many 'items' to view (default: all)", OPT_ARGREQ },
151 { 9, 'S', "scale", "Scale output by x (image output only)", OPT_ARGREQ }, 151 { 9, 'S', "scale", "Scale output by x (image output only)", OPT_ARGREQ },
152 { 10, 'b', "bformat", "Force input bitmap format (see below)", OPT_ARGREQ },
152 { 11, 'w', "width", "Item width (number of items per row, min 1)", OPT_ARGREQ }, 153 { 11, 'w', "width", "Item width (number of items per row, min 1)", OPT_ARGREQ },
153 { 12, 'P', "paletted", "Use indexed/paletted output (png, pcx output only)", OPT_NONE }, 154 { 12, 'P', "paletted", "Use indexed/paletted output (png, pcx output only)", OPT_NONE },
154 { 13, 'B', "bplanes", "Bits per pixel OR # of bitplanes (certain output formats)", OPT_ARGREQ }, 155 { 13, 'B', "bplanes", "Bits per pixel OR # of bitplanes (certain output formats)", OPT_ARGREQ },
155 { 14, 'I', "interleave", "Interleave scanlines (default: output whole planes)", OPT_NONE }, 156 { 14, 'I', "interleave", "Interleave scanlines (default: output whole planes)", OPT_NONE },
156 { 16, 'R', "remap", "Remap output image colors (-R <(#RRGGBB|index):index>[,<..>][+remove] | -R @map.txt[+remove])", OPT_ARGREQ }, 157 { 16, 'R', "remap", "Remap output image colors (-R <(#RRGGBB|index):index>[,<..>][+remove] | -R @map.txt[+remove])", OPT_ARGREQ },
157 { 19, 'C', "crop", "Crop intermediate -C auto|<x0>:<y0>-<x1>:<y1>|<x0>:<y0>:<w>:<h>", OPT_ARGREQ },
158 }; 158 };
159 159
160 static const int optListN = sizeof(optList) / sizeof(optList[0]); 160 static const int optListN = sizeof(optList) / sizeof(optList[0]);
161 161
162 162
182 182
183 printf( 183 printf(
184 "\n" 184 "\n"
185 "(Not all input->output combinations are actually supported.)\n" 185 "(Not all input->output combinations are actually supported.)\n"
186 "\n" 186 "\n"
187 "Available bitmap formats (-f bitmap:<bformat>):\n" 187 "Available bitmap formats:\n"
188 " Ext | Type | Description\n" 188 " Ext | Type | Description\n"
189 "------+-----------------+-------------------------------------\n" 189 "------+-----------------+-------------------------------------\n"
190 ); 190 );
191 191
192 for (i = 0; i < ndmC64ImageFormats; i++) 192 for (i = 0; i < ndmC64ImageFormats; i++)
514 case 'i': optInFormat = FFMT_IMAGE; break; 514 case 'i': optInFormat = FFMT_IMAGE; break;
515 default: 515 default:
516 dmError("Invalid input format '%s'.\n", optArg); 516 dmError("Invalid input format '%s'.\n", optArg);
517 return FALSE; 517 return FALSE;
518 } 518 }
519
520 char *tmp = strchr(optArg, ':');
521 if (tmp != NULL)
522 {
523 tmp++;
524 switch (optInFormat)
525 {
526 case FFMT_SPRITE:
527 case FFMT_CHAR:
528 if (strcasecmp(tmp, "mc") == 0)
529 optInMulticolor = TRUE;
530 else
531 if (strcasecmp(tmp, "sc") == 0)
532 optInMulticolor = FALSE;
533 else
534 {
535 dmError("Invalid input subformat for sprite/char: '%s', should be 'mc' or 'sc'.\n",
536 tmp);
537 return FALSE;
538 }
539 break;
540
541 case FFMT_BITMAP:
542 if (!dmGetC64FormatByExt(tmp, &optInFormat, &optInSubFormat))
543 {
544 dmError("Invalid bitmap subformat '%s', see format list for valid bformats.\n",
545 tmp);
546 return FALSE;
547 }
548 break;
549 }
550 }
551 } 519 }
552 break; 520 break;
553 521
554 case 2: 522 case 2:
555 optInMulticolor = TRUE; 523 optInMulticolor = TRUE;
682 return FALSE; 650 return FALSE;
683 } 651 }
684 } 652 }
685 653
686 optRemapColors = TRUE; 654 optRemapColors = TRUE;
687 break;
688
689 case 19:
690 {
691 if (strcasecmp(optArg, "auto") == 0)
692 {
693 }
694 else
695 if (sscanf(optArg, "%d:%d-%d:%d", ) == 4)
696 {
697 }
698 else
699 if (sscanf(optArg, "%d:%d
700 }
701 break; 655 break;
702 656
703 default: 657 default:
704 dmError("Unknown option '%s'.\n", currArg); 658 dmError("Unknown option '%s'.\n", currArg);
705 return FALSE; 659 return FALSE;
1200 } 1154 }
1201 1155
1202 1156
1203 int dmWriteSpritesAndChars(const char *filename, DMImage *image, int outFormat, BOOL multicolor) 1157 int dmWriteSpritesAndChars(const char *filename, DMImage *image, int outFormat, BOOL multicolor)
1204 { 1158 {
1205 int ret = DMERR_OK; 1159 int outBlockW, outBlockH, bx, by;
1206 int outBlockW, outBlockH, bx, by, index;
1207 FILE *outFile = NULL; 1160 FILE *outFile = NULL;
1208 Uint8 **outBuf = NULL; 1161 Uint8 *buf = NULL;
1209 int *outScreen = NULL; 1162 size_t bufSize;
1210 size_t outBufSize; 1163 char *outType;
1211 char *outType, *tmpFilename;
1212 1164
1213 switch (outFormat) 1165 switch (outFormat)
1214 { 1166 {
1215 case FFMT_CHAR: 1167 case FFMT_CHAR:
1216 outBufSize = C64_CHR_SIZE; 1168 bufSize = C64_CHR_SIZE;
1217 outBlockW = image->width / C64_CHR_WIDTH_PX; 1169 outBlockW = image->width / C64_CHR_WIDTH_PX;
1218 outBlockH = image->height / C64_CHR_HEIGHT; 1170 outBlockH = image->height / C64_CHR_HEIGHT;
1219 outType = "char"; 1171 outType = "char";
1220 break; 1172 break;
1221 1173
1222 case FFMT_SPRITE: 1174 case FFMT_SPRITE:
1223 outBufSize = C64_SPR_SIZE; 1175 bufSize = C64_SPR_SIZE;
1224 outBlockW = image->width / C64_SPR_WIDTH_PX; 1176 outBlockW = image->width / C64_SPR_WIDTH_PX;
1225 outBlockH = image->height / C64_SPR_HEIGHT; 1177 outBlockH = image->height / C64_SPR_HEIGHT;
1226 outType = "sprite"; 1178 outType = "sprite";
1227 break; 1179 break;
1228 1180
1229 default: 1181 default:
1230 dmError("Invalid output format %d, internal error.\n", outFormat); 1182 dmError("Invalid output format %d, internal error.\n", outFormat);
1231 goto error; 1183 goto error;
1232 } 1184 }
1233 1185
1234 if (outBlockW < 1 || outBlockH < 1) 1186 if (outBlockW <= 0 || outBlockH <= 0)
1235 { 1187 {
1236 ret = DMERR_INVALID_ARGS;
1237 dmError("Source image dimensions too small for conversion, block dimensions %d x %d.\n", 1188 dmError("Source image dimensions too small for conversion, block dimensions %d x %d.\n",
1238 outBlockW, outBlockH); 1189 outBlockW, outBlockH);
1239 goto error; 1190 goto error;
1240 } 1191 }
1241 1192
1242 dmMsg(1, "Converting %d x %d = %d blocks of %s data...\n", 1193 if ((outFile = fopen(filename, "wb")) == NULL)
1194 {
1195 int err = dmGetErrno();
1196 dmError("Could not open '%s' for writing, %d: %s.\n",
1197 filename, err, dmErrorStr(err));
1198 goto error;
1199 }
1200
1201 if ((buf = dmMalloc(bufSize)) == NULL)
1202 {
1203 dmError("Could not allocate %d bytes for conversion buffer.\n",
1204 bufSize);
1205 goto error;
1206 }
1207
1208 dmMsg(1, "Writing %d x %d = %d blocks of %s data...\n",
1243 outBlockW, outBlockH, outBlockW * outBlockH, outType); 1209 outBlockW, outBlockH, outBlockW * outBlockH, outType);
1244 1210
1245
1246 // Allocate screen buffer
1247 if ((outScreen = dmMalloc(outBlockW * outBlockH * sizeof(int))) == NULL)
1248 {
1249 ret = DMERR_MALLOC;
1250 dmError("Could not allocate %d bytes for screen conversion buffer.\n",
1251 outBlockW * outBlockH * sizeof(int));
1252 goto error;
1253 }
1254
1255 // Allocate char buffers
1256 if ((outBuf = dmMalloc0(outBlockW * outBlockH * sizeof(Uint8 *))) == NULL)
1257 {
1258 ret = DMERR_MALLOC;
1259 dmError("Could not allocate character data index.\n");
1260 goto error;
1261 }
1262
1263 for (index = 0; index < outBlockW * outBlockH; index++)
1264 {
1265 if ((outBuf[index] = dmMalloc(outBufSize)) == NULL)
1266 {
1267 ret = DMERR_MALLOC;
1268 dmError("Could not allocate %d bytes for character data buffer.\n",
1269 outBufSize);
1270 goto error;
1271 }
1272 }
1273
1274 if ((tmpBuf = dmMalloc(outBufSize)) == NULL)
1275 {
1276 err = DMERR_MALLOC;
1277 dmError("Could not allocate %d bytes for character data buffer.\n",
1278 outBufSize);
1279 goto error;
1280 }
1281
1282 // Chop input image into char blocks
1283 index = 0;
1284 for (by = 0; by < outBlockH; by++) 1211 for (by = 0; by < outBlockH; by++)
1285 for (bx = 0; bx < outBlockW; bx++) 1212 for (bx = 0; bx < outBlockW; bx++)
1286 { 1213 {
1287 outScreen[index] = index;
1288 switch (outFormat) 1214 switch (outFormat)
1289 { 1215 {
1290 case FFMT_CHAR: 1216 case FFMT_CHAR:
1291 if (!dmConvertImage2Char(tmpBuf, image, 1217 if (!dmConvertImage2Char(buf, image,
1292 bx * C64_CHR_WIDTH_PX, by * C64_CHR_HEIGHT, 1218 bx * C64_CHR_WIDTH_PX, by * C64_CHR_HEIGHT,
1293 multicolor)) 1219 multicolor))
1294 goto error; 1220 goto error;
1295 break; 1221 break;
1296 1222
1297 case FFMT_SPRITE: 1223 case FFMT_SPRITE:
1298 if (!dmConvertImage2Sprite(tmpBuf, image, 1224 if (!dmConvertImage2Sprite(buf, image,
1299 bx * C64_SPR_WIDTH_PX, by * C64_SPR_HEIGHT, 1225 bx * C64_SPR_WIDTH_PX, by * C64_SPR_HEIGHT,
1300 multicolor)) 1226 multicolor))
1301 goto error; 1227 goto error;
1302 break; 1228 }
1303 }
1304 index++;
1305 }
1306
1307 // Eliminate duplicates
1308
1309
1310
1311 // Write out character data
1312 tmpFilename = dm_strdup_fext(filename, "%s.chr");
1313 if ((outFile = fopen(filename, "wb")) == NULL)
1314 {
1315 err = dmGetErrno();
1316 dmError("Could not open '%s' for writing, %d: %s.\n",
1317 filename, err, dmErrorStr(err));
1318 goto error;
1319 }
1320
1321 1229
1322 if (!dm_fwrite_str(outFile, buf, bufSize)) 1230 if (!dm_fwrite_str(outFile, buf, bufSize))
1323 { 1231 {
1324 err = dmGetErrno(); 1232 int err = dmGetErrno();
1325 dmError("Error writing data block %d,%d to '%s', %d: %s\n", 1233 dmError("Error writing data block %d,%d to '%s', %d: %s\n",
1326 bx, by, filename, err, dmErrorStr(err)); 1234 bx, by, filename, err, dmErrorStr(err));
1327 goto error; 1235 goto error;
1328 } 1236 }
1237 }
1238
1239 fclose(outFile);
1240 dmFree(buf);
1241 return 0;
1329 1242
1330 error: 1243 error:
1331 // Cleanup
1332 if (outFile != NULL) 1244 if (outFile != NULL)
1333 fclose(outFile); 1245 fclose(outFile);
1334 1246 dmFree(buf);
1335 if (outBuf != NULL) 1247 return -1;
1336 {
1337 for (index = 0; index < outBlockW * outBlockH; index++)
1338 dmFree(outBuf[i]);
1339 }
1340
1341 dmFree(tmpFilename);
1342 dmFree(outBuf);
1343 dmFree(tmpBuf);
1344 dmFree(outScreen);
1345
1346 return err;
1347 } 1248 }
1348 1249
1349 1250
1350 int dmDumpSpritesAndChars(FILE *inFile) 1251 int dmDumpSpritesAndChars(FILE *inFile)
1351 { 1252 {