gbagfx: Various fixes and improvements

Fix num_colors exceeding amount of colors in palette leading to use of uninitialized colors

Handle png -> pal conversion (aka extracting JASC palettes from png

Allow using only file extension as output to reuse entire path from input before extension
This commit is contained in:
Sierraffinity 2020-04-22 14:39:20 -07:00
parent 922a8de78d
commit 21e9ed6615
3 changed files with 69 additions and 11 deletions

View File

@ -26,8 +26,18 @@ void ConvertGbaToPng(char *inputPath, char *outputPath, struct GbaToPngOptions *
struct Image image; struct Image image;
if (options->paletteFilePath != NULL) if (options->paletteFilePath != NULL)
{
char *paletteFileExtension = GetFileExtensionAfterDot(options->paletteFilePath);
if (strcmp(paletteFileExtension, "gbapal") == 0)
{ {
ReadGbaPalette(options->paletteFilePath, &image.palette); ReadGbaPalette(options->paletteFilePath, &image.palette);
}
else
{
ReadJascPalette(options->paletteFilePath, &image.palette);
}
image.hasPalette = true; image.hasPalette = true;
} }
else else
@ -59,7 +69,7 @@ void ConvertPngToGba(char *inputPath, char *outputPath, struct PngToGbaOptions *
void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **argv) void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **argv)
{ {
char *inputFileExtension = GetFileExtension(inputPath); char *inputFileExtension = GetFileExtensionAfterDot(inputPath);
struct GbaToPngOptions options; struct GbaToPngOptions options;
options.paletteFilePath = NULL; options.paletteFilePath = NULL;
options.bitDepth = inputFileExtension[0] - '0'; options.bitDepth = inputFileExtension[0] - '0';
@ -138,7 +148,7 @@ void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **a
void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **argv) void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **argv)
{ {
char *outputFileExtension = GetFileExtension(outputPath); char *outputFileExtension = GetFileExtensionAfterDot(outputPath);
int bitDepth = outputFileExtension[0] - '0'; int bitDepth = outputFileExtension[0] - '0';
struct PngToGbaOptions options; struct PngToGbaOptions options;
options.numTiles = 0; options.numTiles = 0;
@ -198,9 +208,17 @@ void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **a
ConvertPngToGba(inputPath, outputPath, &options); ConvertPngToGba(inputPath, outputPath, &options);
} }
void HandlePngToJascPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
{
struct Palette palette = {0};
ReadPngPalette(inputPath, &palette);
WriteJascPalette(outputPath, &palette);
}
void HandlePngToGbaPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) void HandlePngToGbaPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
{ {
struct Palette palette; struct Palette palette = {0};
ReadPngPalette(inputPath, &palette); ReadPngPalette(inputPath, &palette);
WriteGbaPalette(outputPath, &palette); WriteGbaPalette(outputPath, &palette);
@ -208,7 +226,7 @@ void HandlePngToGbaPaletteCommand(char *inputPath, char *outputPath, int argc UN
void HandleGbaToJascPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) void HandleGbaToJascPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
{ {
struct Palette palette; struct Palette palette = {0};
ReadGbaPalette(inputPath, &palette); ReadGbaPalette(inputPath, &palette);
WriteJascPalette(outputPath, &palette); WriteJascPalette(outputPath, &palette);
@ -241,7 +259,7 @@ void HandleJascToGbaPaletteCommand(char *inputPath, char *outputPath, int argc,
} }
} }
struct Palette palette; struct Palette palette = {0};
ReadJascPalette(inputPath, &palette); ReadJascPalette(inputPath, &palette);
@ -483,6 +501,8 @@ void HandleHuffDecompressCommand(char *inputPath, char *outputPath, int argc UNU
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char converted = 0;
if (argc < 3) if (argc < 3)
FATAL_ERROR("Usage: gbagfx INPUT_PATH OUTPUT_PATH [options...]\n"); FATAL_ERROR("Usage: gbagfx INPUT_PATH OUTPUT_PATH [options...]\n");
@ -495,6 +515,7 @@ int main(int argc, char **argv)
{ "png", "4bpp", HandlePngToGbaCommand }, { "png", "4bpp", HandlePngToGbaCommand },
{ "png", "8bpp", HandlePngToGbaCommand }, { "png", "8bpp", HandlePngToGbaCommand },
{ "png", "gbapal", HandlePngToGbaPaletteCommand }, { "png", "gbapal", HandlePngToGbaPaletteCommand },
{ "png", "pal", HandlePngToJascPaletteCommand },
{ "gbapal", "pal", HandleGbaToJascPaletteCommand }, { "gbapal", "pal", HandleGbaToJascPaletteCommand },
{ "pal", "gbapal", HandleJascToGbaPaletteCommand }, { "pal", "gbapal", HandleJascToGbaPaletteCommand },
{ "latfont", "png", HandleLatinFontToPngCommand }, { "latfont", "png", HandleLatinFontToPngCommand },
@ -514,24 +535,53 @@ int main(int argc, char **argv)
char *inputPath = argv[1]; char *inputPath = argv[1];
char *outputPath = argv[2]; char *outputPath = argv[2];
char *inputFileExtension = GetFileExtension(inputPath); char *inputFileExtension = GetFileExtensionAfterDot(inputPath);
char *outputFileExtension = GetFileExtension(outputPath); char *outputFileExtension = GetFileExtensionAfterDot(outputPath);
if (inputFileExtension == NULL) if (inputFileExtension == NULL)
FATAL_ERROR("Input file \"%s\" has no extension.\n", inputPath); FATAL_ERROR("Input file \"%s\" has no extension.\n", inputPath);
if (outputFileExtension == NULL) if (outputFileExtension == NULL)
{
outputFileExtension = GetFileExtension(outputPath);
if (*outputFileExtension == '.')
outputFileExtension++;
if (*outputFileExtension == 0)
FATAL_ERROR("Output file \"%s\" has no extension.\n", outputPath); FATAL_ERROR("Output file \"%s\" has no extension.\n", outputPath);
size_t newOutputPathSize = strlen(inputPath) - strlen(inputFileExtension) + strlen(outputFileExtension);
outputPath = (char *)malloc(newOutputPathSize);
for (int i = 0; i < newOutputPathSize; i++)
{
outputPath[i] = inputPath[i];
if (outputPath[i] == '.')
{
strcpy(&outputPath[i + 1], outputFileExtension);
break;
}
}
}
for (int i = 0; handlers[i].function != NULL; i++) for (int i = 0; handlers[i].function != NULL; i++)
{ {
if ((handlers[i].inputFileExtension == NULL || strcmp(handlers[i].inputFileExtension, inputFileExtension) == 0) if ((handlers[i].inputFileExtension == NULL || strcmp(handlers[i].inputFileExtension, inputFileExtension) == 0)
&& (handlers[i].outputFileExtension == NULL || strcmp(handlers[i].outputFileExtension, outputFileExtension) == 0)) && (handlers[i].outputFileExtension == NULL || strcmp(handlers[i].outputFileExtension, outputFileExtension) == 0))
{ {
handlers[i].function(inputPath, outputPath, argc, argv); handlers[i].function(inputPath, outputPath, argc, argv);
return 0; converted = 1;
break;
} }
} }
FATAL_ERROR("Don't know how to convert \"%s\" to \"%s\".\n", inputPath, outputPath); if (outputPath != argv[2])
free(outputPath);
if (!converted)
FATAL_ERROR("Don't know how to convert \"%s\" to \"%s\".\n", argv[1], argv[2]);
return 0;
} }

View File

@ -47,6 +47,13 @@ char *GetFileExtension(char *path)
while (extension > path && *extension != '.') while (extension > path && *extension != '.')
extension--; extension--;
return extension;
}
char *GetFileExtensionAfterDot(char *path)
{
char *extension = GetFileExtension(path);
if (extension == path) if (extension == path)
return NULL; return NULL;

View File

@ -7,6 +7,7 @@
bool ParseNumber(char *s, char **end, int radix, int *intValue); bool ParseNumber(char *s, char **end, int radix, int *intValue);
char *GetFileExtension(char *path); char *GetFileExtension(char *path);
char *GetFileExtensionAfterDot(char *path);
unsigned char *ReadWholeFile(char *path, int *size); unsigned char *ReadWholeFile(char *path, int *size);
unsigned char *ReadWholeFileZeroPadded(char *path, int *size, int padAmount); unsigned char *ReadWholeFileZeroPadded(char *path, int *size, int padAmount);
void WriteWholeFile(char *path, void *buffer, int bufferSize); void WriteWholeFile(char *path, void *buffer, int bufferSize);