diff options
Diffstat (limited to 'tools/gbagfx/main.c')
-rw-r--r-- | tools/gbagfx/main.c | 146 |
1 files changed, 134 insertions, 12 deletions
diff --git a/tools/gbagfx/main.c b/tools/gbagfx/main.c index 86b0afa53..b02f4d9f5 100644 --- a/tools/gbagfx/main.c +++ b/tools/gbagfx/main.c @@ -12,6 +12,7 @@ #include "lz.h" #include "rl.h" #include "font.h" +#include "huff.h" struct CommandHandler { @@ -26,7 +27,17 @@ void ConvertGbaToPng(char *inputPath, char *outputPath, struct GbaToPngOptions * if (options->paletteFilePath != NULL) { - ReadGbaPalette(options->paletteFilePath, &image.palette); + char *paletteFileExtension = GetFileExtensionAfterDot(options->paletteFilePath); + + if (strcmp(paletteFileExtension, "gbapal") == 0) + { + ReadGbaPalette(options->paletteFilePath, &image.palette); + } + else + { + ReadJascPalette(options->paletteFilePath, &image.palette); + } + image.hasPalette = true; } else @@ -58,7 +69,7 @@ void ConvertPngToGba(char *inputPath, char *outputPath, struct PngToGbaOptions * void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **argv) { - char *inputFileExtension = GetFileExtension(inputPath); + char *inputFileExtension = GetFileExtensionAfterDot(inputPath); struct GbaToPngOptions options; options.paletteFilePath = NULL; options.bitDepth = inputFileExtension[0] - '0'; @@ -137,7 +148,7 @@ void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **a void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **argv) { - char *outputFileExtension = GetFileExtension(outputPath); + char *outputFileExtension = GetFileExtensionAfterDot(outputPath); int bitDepth = outputFileExtension[0] - '0'; struct PngToGbaOptions options; options.numTiles = 0; @@ -197,9 +208,17 @@ void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **a 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) { - struct Palette palette; + struct Palette palette = {0}; ReadPngPalette(inputPath, &palette); WriteGbaPalette(outputPath, &palette); @@ -207,7 +226,7 @@ void HandlePngToGbaPaletteCommand(char *inputPath, char *outputPath, int argc UN void HandleGbaToJascPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) { - struct Palette palette; + struct Palette palette = {0}; ReadGbaPalette(inputPath, &palette); WriteJascPalette(outputPath, &palette); @@ -240,7 +259,7 @@ void HandleJascToGbaPaletteCommand(char *inputPath, char *outputPath, int argc, } } - struct Palette palette; + struct Palette palette = {0}; ReadJascPalette(inputPath, &palette); @@ -319,6 +338,7 @@ void HandlePngToFullwidthJapaneseFontCommand(char *inputPath, char *outputPath, void HandleLZCompressCommand(char *inputPath, char *outputPath, int argc, char **argv) { int overflowSize = 0; + int minDistance = 2; // default, for compatibility with LZ77UnCompVram() for (int i = 3; i < argc; i++) { @@ -337,6 +357,19 @@ void HandleLZCompressCommand(char *inputPath, char *outputPath, int argc, char * if (overflowSize < 1) FATAL_ERROR("Overflow size must be positive.\n"); } + else if (strcmp(option, "-search") == 0) + { + if (i + 1 >= argc) + FATAL_ERROR("No size following \"-overflow\".\n"); + + i++; + + if (!ParseNumber(argv[i], NULL, 10, &minDistance)) + FATAL_ERROR("Failed to parse LZ min search distance.\n"); + + if (minDistance < 1) + FATAL_ERROR("LZ min search distance must be positive.\n"); + } else { FATAL_ERROR("Unrecognized option \"%s\".\n", option); @@ -353,7 +386,7 @@ void HandleLZCompressCommand(char *inputPath, char *outputPath, int argc, char * unsigned char *buffer = ReadWholeFileZeroPadded(inputPath, &fileSize, overflowSize); int compressedSize; - unsigned char *compressedData = LZCompress(buffer, fileSize + overflowSize, &compressedSize); + unsigned char *compressedData = LZCompress(buffer, fileSize + overflowSize, &compressedSize, minDistance); compressedData[1] = (unsigned char)fileSize; compressedData[2] = (unsigned char)(fileSize >> 8); @@ -411,8 +444,65 @@ void HandleRLDecompressCommand(char *inputPath, char *outputPath, int argc UNUSE free(uncompressedData); } +void HandleHuffCompressCommand(char *inputPath, char *outputPath, int argc, char **argv) +{ + int fileSize; + int bitDepth = 4; + + for (int i = 3; i < argc; i++) + { + char *option = argv[i]; + + if (strcmp(option, "-depth") == 0) + { + if (i + 1 >= argc) + FATAL_ERROR("No size following \"-depth\".\n"); + + i++; + + if (!ParseNumber(argv[i], NULL, 10, &bitDepth)) + FATAL_ERROR("Failed to parse bit depth.\n"); + + if (bitDepth != 4 && bitDepth != 8) + FATAL_ERROR("GBA only supports bit depth of 4 or 8.\n"); + } + else + { + FATAL_ERROR("Unrecognized option \"%s\".\n", option); + } + } + + unsigned char *buffer = ReadWholeFile(inputPath, &fileSize); + + int compressedSize; + unsigned char *compressedData = HuffCompress(buffer, fileSize, &compressedSize, bitDepth); + + free(buffer); + + WriteWholeFile(outputPath, compressedData, compressedSize); + + free(compressedData); +} + +void HandleHuffDecompressCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) +{ + int fileSize; + unsigned char *buffer = ReadWholeFile(inputPath, &fileSize); + + int uncompressedSize; + unsigned char *uncompressedData = HuffDecompress(buffer, fileSize, &uncompressedSize); + + free(buffer); + + WriteWholeFile(outputPath, uncompressedData, uncompressedSize); + + free(uncompressedData); +} + int main(int argc, char **argv) { + char converted = 0; + if (argc < 3) FATAL_ERROR("Usage: gbagfx INPUT_PATH OUTPUT_PATH [options...]\n"); @@ -425,6 +515,7 @@ int main(int argc, char **argv) { "png", "4bpp", HandlePngToGbaCommand }, { "png", "8bpp", HandlePngToGbaCommand }, { "png", "gbapal", HandlePngToGbaPaletteCommand }, + { "png", "pal", HandlePngToJascPaletteCommand }, { "gbapal", "pal", HandleGbaToJascPaletteCommand }, { "pal", "gbapal", HandleJascToGbaPaletteCommand }, { "latfont", "png", HandleLatinFontToPngCommand }, @@ -433,7 +524,9 @@ int main(int argc, char **argv) { "png", "hwjpnfont", HandlePngToHalfwidthJapaneseFontCommand }, { "fwjpnfont", "png", HandleFullwidthJapaneseFontToPngCommand }, { "png", "fwjpnfont", HandlePngToFullwidthJapaneseFontCommand }, + { NULL, "huff", HandleHuffCompressCommand }, { NULL, "lz", HandleLZCompressCommand }, + { "huff", NULL, HandleHuffDecompressCommand }, { "lz", NULL, HandleLZDecompressCommand }, { NULL, "rl", HandleRLCompressCommand }, { "rl", NULL, HandleRLDecompressCommand }, @@ -442,14 +535,36 @@ int main(int argc, char **argv) char *inputPath = argv[1]; char *outputPath = argv[2]; - char *inputFileExtension = GetFileExtension(inputPath); - char *outputFileExtension = GetFileExtension(outputPath); + char *inputFileExtension = GetFileExtensionAfterDot(inputPath); + char *outputFileExtension = GetFileExtensionAfterDot(outputPath); if (inputFileExtension == NULL) FATAL_ERROR("Input file \"%s\" has no extension.\n", inputPath); if (outputFileExtension == NULL) - FATAL_ERROR("Output file \"%s\" has no extension.\n", outputPath); + { + outputFileExtension = GetFileExtension(outputPath); + + if (*outputFileExtension == '.') + outputFileExtension++; + + if (*outputFileExtension == 0) + 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++) { @@ -457,9 +572,16 @@ int main(int argc, char **argv) && (handlers[i].outputFileExtension == NULL || strcmp(handlers[i].outputFileExtension, outputFileExtension) == 0)) { 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; } |