303 lines
7.7 KiB
C
Raw Normal View History

2015-11-13 22:44:23 -08:00
// Copyright (c) 2015 YamaArashi
2015-11-13 21:57:22 -08:00
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "global.h"
#include "util.h"
#include "gfx.h"
#include "convert_png.h"
#include "jasc_pal.h"
#include "lz.h"
2015-11-23 17:44:06 -08:00
#include "font.h"
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
struct CommandHandler
2015-11-13 21:57:22 -08:00
{
2015-11-23 17:44:06 -08:00
const char *inputFileExtension;
const char *outputFileExtension;
void(*function)(char *inputPath, char *outputPath, int argc, char **argv);
};
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
void ConvertGbaToPng(char *inputPath, char *outputPath, int width, int bitDepth, char *paletteFilePath, bool hasTransparency)
{
struct Image image;
2015-11-13 21:57:22 -08:00
if (paletteFilePath != NULL) {
ReadGbaPalette(paletteFilePath, &image.palette);
image.hasPalette = true;
} else {
image.hasPalette = false;
}
2015-11-23 17:44:06 -08:00
ReadImage(inputPath, width, bitDepth, &image, !image.hasPalette);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
image.hasTransparency = hasTransparency;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
WritePng(outputPath, &image);
2015-11-13 21:57:22 -08:00
FreeImage(&image);
}
2015-11-23 17:44:06 -08:00
void ConvertPngToGba(char *inputPath, char *outputPath, int numTiles, int bitDepth)
2015-11-13 21:57:22 -08:00
{
struct Image image;
image.bitDepth = bitDepth;
2015-11-23 17:44:06 -08:00
ReadPng(inputPath, &image);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
WriteImage(outputPath, numTiles, bitDepth, &image, !image.hasPalette);
2015-11-13 21:57:22 -08:00
FreeImage(&image);
}
2015-11-23 17:44:06 -08:00
void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **argv)
2015-11-13 21:57:22 -08:00
{
2015-11-23 17:44:06 -08:00
char *inputFileExtension = GetFileExtension(inputPath);
int bitDepth = inputFileExtension[0] - '0';
char *paletteFilePath;
bool hasPalette = false;
bool hasTransparency = false;
int width = 1;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
for (int i = 3; i < argc; i++) {
char *option = argv[i];
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
if (strcmp(option, "-palette") == 0) {
if (i + 1 >= argc)
FATAL_ERROR("No palette file path following \"-palette\".\n");
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
i++;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
paletteFilePath = argv[i];
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
hasPalette = true;
} else if (strcmp(option, "-object") == 0) {
hasTransparency = true;
} else if (strcmp(option, "-width") == 0) {
if (i + 1 >= argc)
FATAL_ERROR("No width following \"-width\".\n");
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
i++;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
if (!ParseNumber(argv[i], NULL, 10, &width))
FATAL_ERROR("Failed to parse width.\n");
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
if (width < 1)
FATAL_ERROR("Width must be positive.\n");
} else {
FATAL_ERROR("Unrecognized option \"%s\".\n", option);
}
}
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
ConvertGbaToPng(inputPath, outputPath, width, bitDepth, hasPalette ? paletteFilePath : NULL, hasTransparency);
2015-11-13 21:57:22 -08:00
}
2015-11-23 17:44:06 -08:00
void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **argv)
2015-11-13 21:57:22 -08:00
{
2015-11-23 17:44:06 -08:00
char *outputFileExtension = GetFileExtension(outputPath);
int bitDepth = outputFileExtension[0] - '0';
int numTiles = 0;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
for (int i = 3; i < argc; i++) {
char *option = argv[i];
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
if (strcmp(option, "-num_tiles") == 0) {
if (i + 1 >= argc)
FATAL_ERROR("No number of tiles following \"-num_tiles\".\n");
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
i++;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
if (!ParseNumber(argv[i], NULL, 10, &numTiles))
FATAL_ERROR("Failed to parse number of tiles.\n");
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
if (numTiles < 1)
FATAL_ERROR("Number of tiles must be positive.\n");
} else {
FATAL_ERROR("Unrecognized option \"%s\".\n", option);
}
}
ConvertPngToGba(inputPath, outputPath, numTiles, bitDepth);
2015-11-13 21:57:22 -08:00
}
2015-11-23 17:44:06 -08:00
void HandleGbaToJascPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
2015-11-13 21:57:22 -08:00
{
2015-11-23 17:44:06 -08:00
struct Palette palette;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
ReadGbaPalette(inputPath, &palette);
WriteJascPalette(outputPath, &palette);
2015-11-13 21:57:22 -08:00
}
void HandleJascToGbaPaletteCommand(char *inputPath, char *outputPath, int argc, char **argv)
2015-11-13 21:57:22 -08:00
{
int numColors = 0;
for (int i = 3; i < argc; i++) {
char *option = argv[i];
if (strcmp(option, "-num_colors") == 0) {
if (i + 1 >= argc)
FATAL_ERROR("No number of colors following \"-num_colors\".\n");
i++;
if (!ParseNumber(argv[i], NULL, 10, &numColors))
FATAL_ERROR("Failed to parse number of colors.\n");
if (numColors < 1)
FATAL_ERROR("Number of colors must be positive.\n");
} else {
FATAL_ERROR("Unrecognized option \"%s\".\n", option);
}
}
2015-11-23 17:44:06 -08:00
struct Palette palette;
2015-11-22 15:29:11 -08:00
2015-11-23 17:44:06 -08:00
ReadJascPalette(inputPath, &palette);
if (numColors != 0)
palette.numColors = numColors;
2015-11-23 17:44:06 -08:00
WriteGbaPalette(outputPath, &palette);
}
2015-11-22 15:29:11 -08:00
2015-11-23 17:44:06 -08:00
void HandleLatinFontToPngCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
{
struct Image image;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
ReadLatinFont(inputPath, &image);
WritePng(outputPath, &image);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
FreeImage(&image);
}
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
void HandlePngToLatinFontCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
{
struct Image image;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
image.bitDepth = 2;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
ReadPng(inputPath, &image);
WriteLatinFont(outputPath, &image);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
FreeImage(&image);
}
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
void HandleHalfwidthJapaneseFontToPngCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
{
struct Image image;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
ReadHalfwidthJapaneseFont(inputPath, &image);
WritePng(outputPath, &image);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
FreeImage(&image);
}
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
void HandlePngToHalfwidthJapaneseFontCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
{
struct Image image;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
image.bitDepth = 2;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
ReadPng(inputPath, &image);
WriteHalfwidthJapaneseFont(outputPath, &image);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
FreeImage(&image);
}
2015-11-22 15:29:11 -08:00
2015-11-23 17:44:06 -08:00
void HandleFullwidthJapaneseFontToPngCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
{
struct Image image;
2015-11-22 15:29:11 -08:00
2015-11-23 17:44:06 -08:00
ReadFullwidthJapaneseFont(inputPath, &image);
WritePng(outputPath, &image);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
FreeImage(&image);
}
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
void HandlePngToFullwidthJapaneseFontCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
{
struct Image image;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
image.bitDepth = 2;
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
ReadPng(inputPath, &image);
WriteFullwidthJapaneseFont(outputPath, &image);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
FreeImage(&image);
}
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
void HandleLZCompressCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
{
int fileSize;
unsigned char *buffer = ReadWholeFile(inputPath, &fileSize);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
int compressedSize;
unsigned char *compressedData = LZCompress(buffer, fileSize, &compressedSize);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
free(buffer);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
WriteWholeFile(outputPath, compressedData, compressedSize);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
free(compressedData);
}
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
void HandleLZDecompressCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
{
int fileSize;
unsigned char *buffer = ReadWholeFile(inputPath, &fileSize);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
int uncompressedSize;
unsigned char *uncompressedData = LZDecompress(buffer, fileSize, &uncompressedSize);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
free(buffer);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
WriteWholeFile(outputPath, uncompressedData, uncompressedSize);
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
free(uncompressedData);
}
2015-11-13 21:57:22 -08:00
2015-11-23 17:44:06 -08:00
int main(int argc, char **argv)
{
if (argc < 3)
FATAL_ERROR("Usage: gbagfx INPUT_PATH OUTPUT_PATH [options...]\n");
struct CommandHandler handlers[] =
{
{ "1bpp", "png", HandleGbaToPngCommand },
{ "4bpp", "png", HandleGbaToPngCommand },
{ "8bpp", "png", HandleGbaToPngCommand },
{ "png", "1bpp", HandlePngToGbaCommand },
{ "png", "4bpp", HandlePngToGbaCommand },
{ "png", "8bpp", HandlePngToGbaCommand },
{ "gbapal", "pal", HandleGbaToJascPaletteCommand },
{ "pal", "gbapal", HandleJascToGbaPaletteCommand },
{ "latfont", "png", HandleLatinFontToPngCommand },
{ "png", "latfont", HandlePngToLatinFontCommand },
{ "hwjpnfont", "png", HandleHalfwidthJapaneseFontToPngCommand },
{ "png", "hwjpnfont", HandlePngToHalfwidthJapaneseFontCommand },
{ "fwjpnfont", "png", HandleFullwidthJapaneseFontToPngCommand },
{ "png", "fwjpnfont", HandlePngToFullwidthJapaneseFontCommand },
{ NULL, "lz", HandleLZCompressCommand },
{ "lz", NULL, HandleLZDecompressCommand },
{ NULL, NULL, NULL }
};
char *inputPath = argv[1];
char *outputPath = argv[2];
for (int i = 0; handlers[i].function != NULL; i++) {
char *inputFileExtension = GetFileExtension(inputPath);
char *outputFileExtension = GetFileExtension(outputPath);
if ((handlers[i].inputFileExtension == NULL || strcmp(handlers[i].inputFileExtension, inputFileExtension) == 0)
&& (handlers[i].outputFileExtension == NULL || strcmp(handlers[i].outputFileExtension, outputFileExtension) == 0)) {
handlers[i].function(inputPath, outputPath, argc, argv);
return 0;
}
2015-11-13 21:57:22 -08:00
}
2015-11-23 17:44:06 -08:00
FATAL_ERROR("Don't know how to convert \"%s\" to \"%s\".\n", inputPath, outputPath);
2015-11-13 21:57:22 -08:00
}