# HG changeset patch # User Matti Hamalainen # Date 1586947948 -10800 # Node ID 11151bc8d0561e33925b915f2057b72bf76c130a # Parent 0fdc14005e436a6500341e8c5fda8904e11f1c0e Implement functionality for converting the supported palette formats to another. This is quite simplistic currently. diff -r 0fdc14005e43 -r 11151bc8d056 tools/gfxconv.c --- a/tools/gfxconv.c Wed Apr 15 13:51:22 2020 +0300 +++ b/tools/gfxconv.c Wed Apr 15 13:52:28 2020 +0300 @@ -34,6 +34,7 @@ FFMT_IMAGE, FFMT_DUMP, + FFMT_PALETTE, FFMT_LAST }; @@ -56,6 +57,7 @@ "C64 sprite data", "Image", "CDump", + "Palette", }; @@ -88,12 +90,13 @@ static const DMConvFormat baseFormatList[] = { - { "ASCII text" , "asc" , DM_FMT_WR , FFMT_ASCII , 0 , NULL }, - { "ANSI colored text" , "ansi" , DM_FMT_WR , FFMT_ANSI , 0 , NULL }, - { "C64 bitmap image" , "bitmap", DM_FMT_RDWR , FFMT_BITMAP , -1 , NULL }, - { "C64 character/font data" , "chr" , DM_FMT_RDWR , FFMT_CHAR , 0 , " (chr:mc/chr:sc for multi/singlecolor)" }, - { "C64 sprite data" , "spr" , DM_FMT_RDWR , FFMT_SPRITE , 0 , " (spr:mc/spr:sc for multi/singlecolor)" }, - { "C64 bitmap image dump" , "dump" , DM_FMT_WR , FFMT_DUMP , 0 , NULL }, + { "ASCII text" , "asc" , DM_FMT_WR , FFMT_ASCII , 0 , NULL }, + { "ANSI colored text" , "ansi" , DM_FMT_WR , FFMT_ANSI , 0 , NULL }, + { "C64 bitmap image" , "bitmap", DM_FMT_RDWR , FFMT_BITMAP , -1 , NULL }, + { "C64 character/font data" , "chr" , DM_FMT_RDWR , FFMT_CHAR , 0 , " (chr:mc/chr:sc for multi/singlecolor)" }, + { "C64 sprite data" , "spr" , DM_FMT_RDWR , FFMT_SPRITE , 0 , " (spr:mc/spr:sc for multi/singlecolor)" }, + { "C64 bitmap image dump" , "dump" , DM_FMT_WR , FFMT_DUMP , 0 , NULL }, + { "Palette data" , "pal" , DM_FMT_RDWR , FFMT_PALETTE , -1 , NULL }, }; static const int nbaseFormatList = sizeof(baseFormatList) / sizeof(baseFormatList[0]); @@ -141,6 +144,7 @@ char *optCharROMFilename = NULL; DMC64Palette *optC64Palette = NULL; char *optPaletteFile = NULL; +DMPalette *optPaletteData = NULL; DMImageWriteSpec optSpec = @@ -1605,6 +1609,38 @@ } +int dmWritePalette(const char *filename, const DMPalette *palette, const DMPaletteFormat *fmt) +{ + DMResource *fp = NULL; + int res; + + // Check if writing is even supported + if (fmt->write == NULL || (fmt->flags & DM_FMT_WR) == 0) + { + return dmError(DMERR_NOT_SUPPORTED, + "Writing of '%s' format is not supported.\n", + fmt->name); + } + + dmMsg(1, "Outputting '%s' format palette of %d entries.\n", + fmt->name, palette->ncolors); + + if ((res = dmf_open_stdio(filename, "wb", &fp)) != DMERR_OK) + { + dmErrorMsg("Could not open file '%s' for writing.\n", + filename); + goto err; + } + + res = fmt->write(fp, palette); + +err: + dmf_close(fp); + + return res; +} + + static Uint8 dmConvertByte(const Uint8 *sp, const BOOL multicolor) { Uint8 byte = 0; @@ -1987,7 +2023,7 @@ goto exit; } - nconvFormatList = ndmImageFormatList + nbaseFormatList; + nconvFormatList = ndmImageFormatList + ndmPaletteFormatList + nbaseFormatList; convFormatList = dmCalloc(nconvFormatList, sizeof(DMConvFormat)); for (n = i = 0; i < ndmImageFormatList; i++) @@ -2001,6 +2037,18 @@ dfmt->format = sfmt->fmtid; } + for (i = 0; i < ndmPaletteFormatList; i++) + { + const DMPaletteFormat *sfmt = &dmPaletteFormatList[i]; + DMConvFormat *dfmt = &convFormatList[n++]; + dfmt->name = sfmt->name; + dfmt->fext = sfmt->fext; + dfmt->flags = sfmt->flags; + dfmt->type = FFMT_PALETTE; + dfmt->format = sfmt->fmtid; + } + + for (i = 0; i < nbaseFormatList; i++) memcpy(&convFormatList[n++], &baseFormatList[i], sizeof(DMConvFormat)); @@ -2160,6 +2208,20 @@ } } + if (optInType == FFMT_AUTO || optInType == FFMT_PALETTE) + { + const DMPaletteFormat *pfmt = NULL; + int index; + dmMsg(4, "Trying to probe palette formats.\n"); + if (dmPaletteProbeGeneric(dataBuf, dataSize, &pfmt, &index) > 0 && + pfmt->read != NULL) + { + optInType = FFMT_PALETTE; + optInFormat = index; + dmMsg(1, "Probed '%s' format palette.\n", pfmt->name); + } + } + if (optInType == FFMT_AUTO) { dmErrorMsg("No input format specified, and could not be determined automatically.\n"); @@ -2199,35 +2261,48 @@ } } - if (optPaletteFile != NULL) - { - if ((res = dmHandleExternalPalette(optPaletteFile, &optC64Spec.pal)) != DMERR_OK) - goto exit; - - if (optC64Spec.pal->ncolors < D64_NCOLORS) - { - dmErrorMsg("Palette does not have enough colors (%d < %d)\n", - optC64Spec.pal->ncolors, D64_NCOLORS); - goto exit; - } - } - else + // Handle palette stuff that is generic for different operation modes + if (optPaletteFile != NULL && + (res = dmHandleExternalPalette(optPaletteFile, &optPaletteData)) != DMERR_OK) + goto exit; + + switch (optInType) { - // No palette file specified, use internal palette - if (optC64Palette == NULL) - optC64Palette = &dmC64DefaultPalettes[0]; - - dmMsg(1, "Using internal palette '%s' (%s).\n", - optC64Palette->name, optC64Palette->desc); - - optC64Spec.cpal = optC64Palette; - - if ((res = dmC64PaletteFromC64Palette(&optC64Spec.pal, optC64Palette, FALSE)) != DMERR_OK) - { - dmErrorMsg("Could not setup palette: %s.\n", - dmErrorStr(res)); - goto exit; - } + case FFMT_SPRITE: + case FFMT_CHAR: + case FFMT_BITMAP: + if (optPaletteData == NULL) + { + // No palette file specified, use internal palette + if (optC64Palette == NULL) + optC64Palette = &dmC64DefaultPalettes[0]; + + dmMsg(1, "Using internal palette '%s' (%s).\n", + optC64Palette->name, optC64Palette->desc); + + if ((res = dmC64PaletteFromC64Palette(&optPaletteData, optC64Palette, FALSE)) != DMERR_OK) + { + dmErrorMsg("Could not set up palette: %s.\n", + dmErrorStr(res)); + goto exit; + } + } + + if (optPaletteData->ncolors < D64_NCOLORS) + { + dmErrorMsg("Palette does not have enough colors (%d < %d)\n", + optPaletteData->ncolors, D64_NCOLORS); + goto exit; + } + + if (optPaletteData->ncolors > D64_NCOLORS) + { + dmMsg(1, "Palette has %d colors, using only first %d.\n", + optPaletteData->ncolors, D64_NCOLORS); + } + + optC64Spec.pal = optPaletteData; + break; } switch (optInType) @@ -2237,6 +2312,39 @@ dmDumpSpritesAndChars(dataBuf, dataSize, dataRealOffs); break; + case FFMT_PALETTE: + { + const DMPaletteFormat *pfmt = &dmPaletteFormatList[optInFormat]; + DMResource *fp; + + if (optOutFilename == NULL) + { + dmErrorMsg("Output filename not set, required for palette formats.\n"); + goto exit; + } + + // Read palette file + if ((res = dmf_open_memio(NULL, optInFilename, dataBuf, dataSize, &fp)) != DMERR_OK) + { + dmErrorMsg("Could not create MemIO handle for input.\n"); + goto exit; + } + + // Read input + if (pfmt->read != NULL) + res = pfmt->read(fp, &optPaletteData); + else + dmErrorMsg("Unsupported input palette format.\n"); + + dmf_close(fp); + + if (res != DMERR_OK || optPaletteData == NULL) + goto exit; + + res = dmWritePalette(optOutFilename, optPaletteData, &dmPaletteFormatList[optOutFormat]); + } + break; + case FFMT_BITMAP: if (optOutFilename == NULL) { @@ -2296,6 +2404,10 @@ } break; + case FFMT_PALETTE: + res = dmWritePalette(optOutFilename, optPaletteData, &dmPaletteFormatList[optOutFormat]); + break; + case FFMT_DUMP: dmDumpC64Bitmap(optOutFilename, inC64Image); break; @@ -2356,6 +2468,10 @@ &dmImageFormatList[optOutFormat], TRUE); break; + case FFMT_PALETTE: + res = dmWritePalette(optOutFilename, inImage->pal, &dmPaletteFormatList[optOutFormat]); + break; + case FFMT_CHAR: case FFMT_SPRITE: res = dmWriteSpritesAndChars(optOutFilename, inImage,