Mercurial > hg > dmlib
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 { |