From c4f9d8e593b55cbfcc0a770403d39c04311fb8bb Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Mon, 4 Jul 2016 19:48:48 -0500 Subject: [PATCH] Refactor subcommands from main.c into their own frickin' files --- bin/Makefile | 7 +- bin/commands.h | 18 ++ bin/dither.c | 79 +++++ bin/export.c | 85 ++++++ bin/import.c | 103 +++++++ bin/main.c | 789 ++----------------------------------------------- bin/png.c | 104 +++++++ bin/png.h | 16 + bin/rgb.c | 206 +++++++++++++ bin/slice.c | 52 ++++ bin/tile.c | 241 +++++++++++++++ 11 files changed, 926 insertions(+), 774 deletions(-) create mode 100644 bin/commands.h create mode 100644 bin/dither.c create mode 100644 bin/export.c create mode 100644 bin/import.c create mode 100644 bin/png.c create mode 100644 bin/png.h create mode 100644 bin/rgb.c create mode 100644 bin/slice.c create mode 100644 bin/tile.c diff --git a/bin/Makefile b/bin/Makefile index 2f49749..dee8db2 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -8,8 +8,11 @@ CFLAGS += -I$(INCLUDE_PATH) LDFLAGS = CAMMY = cammy -CAMMY_OBJS = pnglite.o main.o -CAMMY_HEADERS = pnglite.h +CAMMY_OBJS = pnglite.o png.o main.o dither.o export.o import.o rgb.o \ + slice.o tile.o + +CAMMY_HEADERS = pnglite.h png.h commands.h + CAMMY_LDFLAGS = ../src/libcammy.a -lz PROGRAMS = cammy diff --git a/bin/commands.h b/bin/commands.h new file mode 100644 index 0000000..f6aba58 --- /dev/null +++ b/bin/commands.h @@ -0,0 +1,18 @@ +#ifndef _COMMANDS_H +#define _COMMANDS_H + +void cammy_command_usage(int argc, char **argv, const char *message, ...); + +void cammy_command_validate_photo_number(int argc, char **argv, int num); + +int cammy_command_import(int argc, char **argv); +int cammy_command_export(int argc, char **argv); +int cammy_command_dither(int argc, char **argv); +int cammy_command_split_rgb(int argc, char **argv); +int cammy_command_merge_rgb(int argc, char **argv); +int cammy_command_import_tile(int argc, char **argv); +int cammy_command_export_tile(int argc, char **argv); +int cammy_command_convert_tile(int argc, char **argv); +int cammy_command_slice(int argc, char **argv); + +#endif /* _COMMANDS_H */ diff --git a/bin/dither.c b/bin/dither.c new file mode 100644 index 0000000..1cb2f56 --- /dev/null +++ b/bin/dither.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "pnglite.h" +#include "png.h" +#include "commands.h" + +static cammy_tile_palette palette = { + .colors = { + { 0, 0, 0 }, + { 85, 85, 85 }, + { 171, 171, 171 }, + { 255, 255, 255 } + } +}; + +int cammy_command_dither(int argc, char **argv) { + uint8_t *bufin, *bufout; + size_t width, height; + int depth; + + if (argc < 3) { + cammy_command_usage(argc, argv, "No PNG input file provided"); + } else if (argc < 4) { + cammy_command_usage(argc, argv, "No PNG output filename provided"); + } + + if ((bufin = cammy_png_load(argv[2], &width, + &height, + &depth)) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "cammy_png_load()", strerror(errno)); + + goto error_png_load; + } + + if ((bufout = malloc(width * height * 3)) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "malloc()", strerror(errno)); + + goto error_malloc_bufout; + } + + cammy_image_dither(bufout, bufin, width, height, depth, &palette); + + if (cammy_png_save(argv[3], bufout, + width, + height, 8, PNG_TRUECOLOR) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "cammy_png_save()", argv[3], strerror(errno)); + + goto error_png_save; + } + + free(bufout); + + free(bufin); + + return 0; + +error_png_save: + free(bufout); + +error_malloc_bufout: + free(bufin); + +error_png_load: + return 1; +} diff --git a/bin/export.c b/bin/export.c new file mode 100644 index 0000000..b4a7bfb --- /dev/null +++ b/bin/export.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "pnglite.h" +#include "png.h" +#include "commands.h" + +static cammy_tile_palette palette = { + .colors = { + { 0, 0, 0 }, + { 85, 85, 85 }, + { 171, 171, 171 }, + { 255, 255, 255 } + } +}; + +int cammy_command_export(int argc, char **argv) { + cammy_sram *sram; + int photo = 0; + uint8_t *buf; + + if (argc < 3) { + cammy_command_usage(argc, argv, "No save file provided"); + } else if (argc < 4) { + cammy_command_usage(argc, argv, "No photo number provided"); + } else if (argc < 5) { + cammy_command_usage(argc, argv, "No output filename provided"); + } + + photo = atoi(argv[3]); + + if (photo < 1 || photo > CAMMY_SRAM_PHOTO_COUNT) { + cammy_command_usage(argc, argv, "Invalid photo number"); + } + + if ((sram = cammy_sram_open(argv[2])) == NULL) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "cammy_sram_open()", argv[2], strerror(errno)); + + goto error_sram_open; + } + + if ((buf = malloc(CAMMY_PHOTO_WIDTH * CAMMY_PHOTO_HEIGHT * 3)) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "malloc()", strerror(errno)); + + goto error_malloc_buf; + } + + cammy_photo_export(&sram->data->photos[photo-1], buf, 3, &palette); + + if (cammy_png_save(argv[4], buf, + CAMMY_PHOTO_WIDTH, + CAMMY_PHOTO_HEIGHT, 8, PNG_TRUECOLOR) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "cammy_png_save()", argv[4], strerror(errno)); + + goto error_png_save; + } + + free(buf); + + cammy_sram_close(sram); + + return 0; + +error_png_save: + free(buf); + +error_malloc_buf: + cammy_sram_close(sram); + +error_sram_open: + return 1; +} diff --git a/bin/import.c b/bin/import.c new file mode 100644 index 0000000..24899ad --- /dev/null +++ b/bin/import.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include + +#include +#include + +#include "pnglite.h" +#include "commands.h" + +int cammy_command_import(int argc, char **argv) { + cammy_sram *sram; + png_t *png; + int photo = 0; + uint8_t *buf; + + int error; + + if (argc < 3) { + cammy_command_usage(argc, argv, "No save file provided"); + } else if (argc < 4) { + cammy_command_usage(argc, argv, "No photo number provided"); + } else if (argc < 5) { + cammy_command_usage(argc, argv, "No photo provided"); + } + + photo = atoi(argv[3]); + + if (photo < 1 || photo > CAMMY_SRAM_PHOTO_COUNT) { + cammy_command_usage(argc, argv, "Invalid photo number"); + } + + if ((sram = cammy_sram_open(argv[2])) == NULL) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "cammy_sram_open()", argv[2], strerror(errno)); + + goto error_sram_open; + } + + png_init(malloc, free); + + if ((png = malloc(sizeof(*png))) == NULL) { + goto error_malloc_png; + } + + if ((error = png_open_file_read(png, argv[4])) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "png_open_file_read()", argv[4], png_error_string(error)); + + goto error_png_open_file_read; + } + + if (png->width != CAMMY_PHOTO_WIDTH + || png->height != CAMMY_PHOTO_HEIGHT) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], argv[4], "Invalid image dimensions"); + + goto error_invalid_dimensions; + } + + if ((buf = malloc(png->width * png->height * png->bpp)) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "malloc()", strerror(errno)); + + goto error_malloc_buf; + } + + if ((error = png_get_data(png, buf)) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "png_get_data()", argv[4], png_error_string(error)); + + goto error_png_get_data; + } + + cammy_photo_import(&sram->data->photos[photo-1], buf, (int)png->bpp); + + free(buf); + + png_close_file(png); + + free(png); + + cammy_sram_close(sram); + + return 0; + +error_png_get_data: + free(buf); + +error_malloc_buf: +error_invalid_dimensions: + png_close_file(png); + +error_png_open_file_read: + free(png); + +error_malloc_png: + cammy_sram_close(sram); + +error_sram_open: + return 1; +} diff --git a/bin/main.c b/bin/main.c index 2e7e0cf..c169ccd 100644 --- a/bin/main.c +++ b/bin/main.c @@ -1,30 +1,13 @@ #include #include -#include #include -#include -#include -#include -#include -#include -#include "pnglite.h" +#include -#include -#include -#include -#include #include -static cammy_tile_palette palette = { - .colors = { - { 0, 0, 0 }, - { 85, 85, 85 }, - { 171, 171, 171 }, - { 255, 255, 255 } - } -}; +#include "commands.h" -static void usage(int argc, char **argv, const char *message, ...) { +void cammy_command_usage(int argc, char **argv, const char *message, ...) { if (message) { va_list args; @@ -48,771 +31,33 @@ static void usage(int argc, char **argv, const char *message, ...) { exit(1); } -static int save_buf_to_png_file(const char *file, - void *buf, - size_t width, - size_t height, - int depth, - int format) { - png_t *png; - - png_init(malloc, free); - - if ((png = malloc(sizeof(*png))) == NULL) { - goto error_malloc_png; - } - - if (png_open_file_write(png, file) < 0) { - goto error_png_open_file_write; - } - - if (png_set_data(png, width, height, depth, format, buf) < 0) { - goto error_png_set_data; - } - - png_close_file(png); - - free(png); - - return 0; - -error_png_set_data: - png_close_file(png); - -error_png_open_file_write: - free(png); - -error_malloc_png: - return -1; -} - -static uint8_t *read_png_file(const char *file, - size_t *width, - size_t *height, - int *depth) { - png_t *png; - uint8_t *buf; - - png_init(malloc, free); - - if ((png = malloc(sizeof(*png))) == NULL) { - goto error_malloc_png; - } - - if (png_open_file_read(png, file) < 0) { - goto error_png_open_file_read; - } - - *width = png->width; - *height = png->height; - *depth = png->bpp; - - if ((buf = malloc(*width * *height * *depth)) == NULL) { - goto error_malloc_buf; - } - - if (png_get_data(png, buf) < 0) { - goto error_png_get_data; - } - - png_close_file(png); - - free(png); - - return buf; - -error_png_get_data: - free(buf); - -error_malloc_buf: - png_close_file(png); - -error_png_open_file_read: - free(png); - -error_malloc_png: - return NULL; -} - -static int import(int argc, char **argv) { - cammy_sram *sram; - png_t *png; - int photo = 0; - uint8_t *buf; - - int error; - - if (argc < 3) { - usage(argc, argv, "No save file provided"); - } else if (argc < 4) { - usage(argc, argv, "No photo number provided"); - } else if (argc < 5) { - usage(argc, argv, "No photo provided"); - } - - photo = atoi(argv[3]); - - if (photo < 1 || photo > CAMMY_SRAM_PHOTO_COUNT) { - usage(argc, argv, "Invalid photo number"); - } - - if ((sram = cammy_sram_open(argv[2])) == NULL) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "cammy_sram_open()", argv[2], strerror(errno)); - - goto error_sram_open; - } - - png_init(malloc, free); - - if ((png = malloc(sizeof(*png))) == NULL) { - goto error_malloc_png; - } - - if ((error = png_open_file_read(png, argv[4])) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "png_open_file_read()", argv[4], png_error_string(error)); - - goto error_png_open_file_read; - } - - if (png->width != CAMMY_PHOTO_WIDTH - || png->height != CAMMY_PHOTO_HEIGHT) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], argv[4], "Invalid image dimensions"); - - goto error_invalid_dimensions; - } - - if ((buf = malloc(png->width * png->height * png->bpp)) == NULL) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], "malloc()", strerror(errno)); - - goto error_malloc_buf; - } - - if ((error = png_get_data(png, buf)) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "png_get_data()", argv[4], png_error_string(error)); - - goto error_png_get_data; - } - - cammy_photo_import(&sram->data->photos[photo-1], buf, (int)png->bpp); - - free(buf); - - png_close_file(png); - - free(png); - - cammy_sram_close(sram); - - return 0; - -error_png_get_data: - free(buf); - -error_malloc_buf: -error_invalid_dimensions: - png_close_file(png); - -error_png_open_file_read: - free(png); - -error_malloc_png: - cammy_sram_close(sram); - -error_sram_open: - return 1; -} - -static int export(int argc, char **argv) { - cammy_sram *sram; - int photo = 0; - uint8_t *buf; - - if (argc < 3) { - usage(argc, argv, "No save file provided"); - } else if (argc < 4) { - usage(argc, argv, "No photo number provided"); - } else if (argc < 5) { - usage(argc, argv, "No output filename provided"); - } - - photo = atoi(argv[3]); - - if (photo < 1 || photo > CAMMY_SRAM_PHOTO_COUNT) { - usage(argc, argv, "Invalid photo number"); - } - - if ((sram = cammy_sram_open(argv[2])) == NULL) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "cammy_sram_open()", argv[2], strerror(errno)); - - goto error_sram_open; - } - - if ((buf = malloc(CAMMY_PHOTO_WIDTH * CAMMY_PHOTO_HEIGHT * 3)) == NULL) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], "malloc()", strerror(errno)); - - goto error_malloc_buf; - } - - cammy_photo_export(&sram->data->photos[photo-1], buf, 3, &palette); - - if (save_buf_to_png_file(argv[4], buf, - CAMMY_PHOTO_WIDTH, - CAMMY_PHOTO_HEIGHT, 8, PNG_TRUECOLOR) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "save_buf_to_png_file()", argv[4], strerror(errno)); - - goto error_save_buf_to_png_file; - } - - free(buf); - - cammy_sram_close(sram); - - return 0; - -error_save_buf_to_png_file: - free(buf); - -error_malloc_buf: - cammy_sram_close(sram); - -error_sram_open: - return 1; -} - -static int dither(int argc, char **argv) { - uint8_t *bufin, *bufout; - size_t width, height; - int depth; - - if (argc < 3) { - usage(argc, argv, "No PNG input file provided"); - } else if (argc < 4) { - usage(argc, argv, "No PNG output filename provided"); - } - - if ((bufin = read_png_file(argv[2], &width, - &height, - &depth)) == NULL) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], "read_png_file()", strerror(errno)); - - goto error_read_png_file; - } - - if ((bufout = malloc(width * height * 3)) == NULL) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], "malloc()", strerror(errno)); - - goto error_malloc_bufout; - } - - cammy_image_dither(bufout, bufin, width, height, depth, &palette); - - if (save_buf_to_png_file(argv[3], bufout, - width, - height, 8, PNG_TRUECOLOR) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "save_buf_to_png_file()", argv[3], strerror(errno)); - - goto error_save_buf_to_png_file; - } - - free(bufout); - - free(bufin); - - return 0; - -error_save_buf_to_png_file: - free(bufout); - -error_malloc_bufout: - free(bufin); - -error_read_png_file: - return 1; -} - -static void validate_photo_number(int argc, char **argv, int num) { +void cammy_command_validate_photo_number(int argc, char **argv, int num) { if (num < 1 || num > CAMMY_SRAM_PHOTO_COUNT) { - usage(argc, argv, "Invalid photo number"); + cammy_command_usage(argc, argv, "Invalid photo number"); } } -static int split_rgb(int argc, char **argv) { - cammy_sram *sram; - png_t *png; - - int photo_r = 0, - photo_g = 0, - photo_b = 0; - - uint8_t *buf; - - int error; - - if (argc < 3) { - usage(argc, argv, "No save file provided"); - } else if (argc < 4) { - usage(argc, argv, "No red photo number provided"); - } else if (argc < 5) { - usage(argc, argv, "No green photo number provided"); - } else if (argc < 6) { - usage(argc, argv, "No blue photo number provided"); - } else if (argc < 7) { - usage(argc, argv, "No photo provided"); - } - - validate_photo_number(argc, argv, photo_r = atoi(argv[3])); - validate_photo_number(argc, argv, photo_g = atoi(argv[4])); - validate_photo_number(argc, argv, photo_b = atoi(argv[5])); - - if ((sram = cammy_sram_open(argv[2])) == NULL) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "cammy_sram_open()", argv[2], strerror(errno)); - - goto error_sram_open; - } - - png_init(malloc, free); - - if ((png = malloc(sizeof(*png))) == NULL) { - goto error_malloc_png; - } - - if ((error = png_open_file_read(png, argv[6])) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "png_open_file_read()", argv[6], png_error_string(error)); - - goto error_png_open_file_read; - } - - if (png->width != CAMMY_PHOTO_WIDTH - || png->height != CAMMY_PHOTO_HEIGHT) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], argv[6], "Invalid image dimensions"); - - goto error_invalid_dimensions; - } - - if ((buf = malloc(png->width * png->height * png->bpp)) == NULL) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], "malloc()", strerror(errno)); - - goto error_malloc; - } - - if ((error = png_get_data(png, buf)) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "png_get_data()", argv[4], png_error_string(error)); - - goto error_png_get_data; - } - - cammy_photo_import_rgb(&sram->data->photos[photo_r-1], - &sram->data->photos[photo_g-1], - &sram->data->photos[photo_b-1], buf, (int)png->bpp); - - free(buf); - - png_close_file(png); - - free(png); - - cammy_sram_close(sram); - - return 0; - -error_png_get_data: - free(buf); - -error_malloc: -error_invalid_dimensions: - png_close_file(png); - -error_png_open_file_read: - free(png); - -error_malloc_png: - cammy_sram_close(sram); - -error_sram_open: - return 1; -} - -static int merge_rgb(int argc, char **argv) { - cammy_sram *sram; - png_t *png; - - int photo_r = 0, - photo_g = 0, - photo_b = 0; - - uint8_t *buf; - - int error; - - if (argc < 3) { - usage(argc, argv, "No save file provided"); - } else if (argc < 4) { - usage(argc, argv, "No red photo number provided"); - } else if (argc < 5) { - usage(argc, argv, "No green photo number provided"); - } else if (argc < 6) { - usage(argc, argv, "No blue photo number provided"); - } else if (argc < 7) { - usage(argc, argv, "No photo provided"); - } - - validate_photo_number(argc, argv, photo_r = atoi(argv[3])); - validate_photo_number(argc, argv, photo_g = atoi(argv[4])); - validate_photo_number(argc, argv, photo_b = atoi(argv[5])); - - if ((sram = cammy_sram_open(argv[2])) == NULL) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "cammy_sram_open()", argv[2], strerror(errno)); - - goto error_sram_open; - } - - png_init(malloc, free); - - if ((png = malloc(sizeof(*png))) == NULL) { - goto error_malloc_png; - } - - if ((error = png_open_file_write(png, argv[6])) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "png_open_file_write()", argv[6], png_error_string(error)); - - goto error_png_open_file_write; - } - - if ((buf = malloc(CAMMY_PHOTO_WIDTH * CAMMY_PHOTO_HEIGHT * 3)) == NULL) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], "malloc()", strerror(errno)); - - goto error_malloc_buf; - } - - cammy_photo_merge(&sram->data->photos[photo_r-1], - &sram->data->photos[photo_g-1], - &sram->data->photos[photo_b-1], buf, 3); - - if ((error = png_set_data(png, - CAMMY_PHOTO_WIDTH, - CAMMY_PHOTO_HEIGHT, 8, PNG_TRUECOLOR, buf)) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "png_set_data()", argv[6], png_error_string(error)); - - goto error_png_set_data; - } - - png_close_file(png); - - free(buf); - - free(png); - - cammy_sram_close(sram); - - return 0; - -error_png_set_data: - free(buf); - -error_malloc_buf: - png_close_file(png); - -error_png_open_file_write: - free(png); - -error_malloc_png: - cammy_sram_close(sram); - -error_sram_open: - return 1; -} - -static int import_tile(int argc, char **argv) { - cammy_sram *sram; - cammy_image *dest, *src; - int photo; - - if (argc < 2) { - usage(argc, argv, "No camera SRAM file provided"); - } else if (argc < 3) { - usage(argc, argv, "No picture number provided"); - } else if (argc < 4) { - usage(argc, argv, "No Game Boy screen tile data file provided"); - } - - photo = atoi(argv[3]); - - if (photo < 1 || photo > CAMMY_SRAM_PHOTO_COUNT) { - usage(argc, argv, "Invalid photo number"); - } - - if ((sram = cammy_sram_open(argv[2])) == NULL) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "cammy_sram_open()", argv[2], strerror(errno)); - - goto error_sram_open; - } - - if ((src = cammy_image_open_tile(argv[4], CAMMY_SCREEN_WIDTH, - CAMMY_SCREEN_HEIGHT)) == NULL) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "cammy_image_open_tile()", argv[4], strerror(errno)); - - goto error_image_open_tile; - } - - if ((dest = malloc(sizeof(*dest))) == NULL) { - goto error_malloc_dest; - } - - dest->format = CAMMY_IMAGE_TILE; - dest->tiles = (cammy_tile *)&sram->data->photos[photo-1].tiles; - dest->width = CAMMY_PHOTO_WIDTH; - dest->height = CAMMY_PHOTO_HEIGHT; - - cammy_image_copy(dest, src, - 0, 0, 16, 16, CAMMY_PHOTO_WIDTH, CAMMY_PHOTO_HEIGHT); - - free(dest); - - cammy_image_close(src); - - cammy_sram_close(sram); - - return 0; - -error_malloc_dest: - cammy_image_close(src); - -error_image_open_tile: - cammy_sram_close(sram); - -error_sram_open: - return 1; -} - -static int export_tile(int argc, char **argv) { - cammy_sram *sram; - cammy_image *dest, *src; - int photo; - - if (argc < 2) { - usage(argc, argv, "No camera SRAM file provided"); - } else if (argc < 3) { - usage(argc, argv, "No picture number provided"); - } else if (argc < 4) { - usage(argc, argv, "No Game Boy screen tile data file provided"); - } - - photo = atoi(argv[3]); - - if (photo < 1 || photo > CAMMY_SRAM_PHOTO_COUNT) { - usage(argc, argv, "Invalid photo number"); - } - - if ((sram = cammy_sram_open(argv[2])) == NULL) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "cammy_sram_open()", argv[2], strerror(errno)); - - goto error_sram_open; - } - - if ((src = malloc(sizeof(*src))) == NULL) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], "malloc()", strerror(errno)); - - goto error_malloc_src; - } - - src->format = CAMMY_IMAGE_TILE; - src->size = CAMMY_PHOTO_SIZE; - src->width = CAMMY_PHOTO_WIDTH; - src->height = CAMMY_PHOTO_HEIGHT; - src->tiles = (cammy_tile *)&sram->data->photos[photo-1].tiles; - - if ((dest = cammy_image_new(CAMMY_IMAGE_TILE, - CAMMY_SCREEN_WIDTH, - CAMMY_SCREEN_HEIGHT)) == NULL) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], "cammy_image_new()", strerror(errno)); - - goto error_image_new_dest; - } - - memset(dest->buf, '\0', dest->size); - - cammy_image_copy(dest, src, - 16, 16, 0, 0, CAMMY_PHOTO_WIDTH, CAMMY_PHOTO_HEIGHT); - - if (cammy_image_save_tile(dest, argv[4]) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "cammy_image_save_tile()", argv[4], strerror(errno)); - - goto error_image_save_tile_dest; - } - - free(dest); - - cammy_image_close(src); - - cammy_sram_close(sram); - - return 0; - -error_image_save_tile_dest: - cammy_image_destroy(dest); - -error_image_new_dest: - free(src); - -error_malloc_src: - cammy_sram_close(sram); - -error_sram_open: - return errno || 1; -} - -static int convert_tile(int argc, char **argv) { - int fd; - void *in, *out; - - if (argc < 3) { - usage(argc, argv, "No input Game Boy screen tile data file provided"); - } else if (argc < 4) { - usage(argc, argv, "No output PNG filename provided"); - } - - if ((fd = open(argv[2], O_RDONLY)) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "open()", argv[2], strerror(errno)); - - goto error_open; - } - - if ((in = malloc(CAMMY_SCREEN_SIZE)) == NULL) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], "malloc()", strerror(errno)); - - goto error_malloc_in; - } - - if (read(fd, in, CAMMY_SCREEN_SIZE) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "read()", argv[2], strerror(errno)); - - goto error_read; - } - - if ((out = malloc(CAMMY_SCREEN_WIDTH * CAMMY_SCREEN_HEIGHT * 3)) == NULL) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], "malloc()", strerror(errno)); - - goto error_malloc_out; - } - - cammy_image_copy_from_tile(out, in, - CAMMY_SCREEN_WIDTH, - CAMMY_SCREEN_HEIGHT, 3, &palette); - - if (save_buf_to_png_file(argv[3], out, - CAMMY_SCREEN_WIDTH, - CAMMY_SCREEN_HEIGHT, 8, PNG_TRUECOLOR) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "save_buf_to_png_file()", argv[3], strerror(errno)); - - goto error_save_buf_to_png_file; - } - - return 0; - -error_save_buf_to_png_file: - free(out); - -error_malloc_out: -error_read: - free(in); - -error_malloc_in: - close(fd); - -error_open: - return errno; -} - -static int slice(int argc, char **argv) { - uint8_t *buf; - - size_t width, height, - x_pad, y_pad; - - int depth; - - if (argc < 3) { - usage(argc, argv, "No X padding provided"); - } else if (argc < 4) { - usage(argc, argv, "No Y padding provided"); - } else if (argc < 5) { - usage(argc, argv, "No input PNG image provided"); - } - - x_pad = atoi(argv[2]); - y_pad = atoi(argv[3]); - - if ((buf = read_png_file(argv[4], &width, &height, &depth)) == NULL) { - goto error_read_png_file; - } - - if (cammy_image_slice(buf, width, height, x_pad, y_pad, depth) < 0) { - goto error_image_slice; - } - - free(buf); - - return 0; - -error_image_slice: - free(buf); - -error_read_png_file: - return 1; -} - static struct { char *name; int (*fun)(int, char **); } commands[] = { - { "import", import }, - { "export", export }, - { "dither", dither }, - { "split-rgb", split_rgb }, - { "merge-rgb", merge_rgb }, - { "import-tile", import_tile }, - { "export-tile", export_tile }, - { "convert-tile", convert_tile }, - { "slice", slice }, - { NULL, NULL } + { "import", cammy_command_import }, + { "export", cammy_command_export }, + { "dither", cammy_command_dither }, + { "split-rgb", cammy_command_split_rgb }, + { "merge-rgb", cammy_command_merge_rgb }, + { "import-tile", cammy_command_import_tile }, + { "export-tile", cammy_command_export_tile }, + { "convert-tile", cammy_command_convert_tile }, + { "slice", cammy_command_slice }, + { NULL, NULL } }; int main(int argc, char **argv) { int i; if (argc < 2) { - usage(argc, argv, "No command specified"); + cammy_command_usage(argc, argv, "No command specified"); } for (i=0; commands[i].name; i++) { @@ -821,7 +66,7 @@ int main(int argc, char **argv) { } } - usage(argc, argv, "Unknown command '%s'", argv[1]); + cammy_command_usage(argc, argv, "Unknown command '%s'", argv[1]); return 0; } diff --git a/bin/png.c b/bin/png.c new file mode 100644 index 0000000..667196c --- /dev/null +++ b/bin/png.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "pnglite.h" +#include "png.h" + +int cammy_png_save(const char *file, + void *buf, + size_t width, + size_t height, + int depth, + int format) { + png_t *png; + + png_init(malloc, free); + + if ((png = malloc(sizeof(*png))) == NULL) { + goto error_malloc_png; + } + + if (png_open_file_write(png, file) < 0) { + goto error_png_open_file_write; + } + + if (png_set_data(png, width, height, depth, format, buf) < 0) { + goto error_png_set_data; + } + + png_close_file(png); + + free(png); + + return 0; + +error_png_set_data: + png_close_file(png); + +error_png_open_file_write: + free(png); + +error_malloc_png: + return -1; +} + +uint8_t *cammy_png_load(const char *file, + size_t *width, + size_t *height, + int *depth) { + png_t *png; + uint8_t *buf; + + png_init(malloc, free); + + if ((png = malloc(sizeof(*png))) == NULL) { + goto error_malloc_png; + } + + if (png_open_file_read(png, file) < 0) { + goto error_png_open_file_read; + } + + *width = png->width; + *height = png->height; + *depth = png->bpp; + + if ((buf = malloc(*width * *height * *depth)) == NULL) { + goto error_malloc_buf; + } + + if (png_get_data(png, buf) < 0) { + goto error_png_get_data; + } + + png_close_file(png); + + free(png); + + return buf; + +error_png_get_data: + free(buf); + +error_malloc_buf: + png_close_file(png); + +error_png_open_file_read: + free(png); + +error_malloc_png: + return NULL; +} diff --git a/bin/png.h b/bin/png.h new file mode 100644 index 0000000..207696a --- /dev/null +++ b/bin/png.h @@ -0,0 +1,16 @@ +#ifndef _PNG_H +#define _PNG_H + +int cammy_png_save(const char *file, + void *buf, + size_t width, + size_t height, + int depth, + int format); + +uint8_t *cammy_png_load(const char *file, + size_t *width, + size_t *height, + int *depth); + +#endif /* _PNG_H */ diff --git a/bin/rgb.c b/bin/rgb.c new file mode 100644 index 0000000..6515bfc --- /dev/null +++ b/bin/rgb.c @@ -0,0 +1,206 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include "pnglite.h" +#include "commands.h" + +int cammy_command_split_rgb(int argc, char **argv) { + cammy_sram *sram; + png_t *png; + + int photo_r = 0, + photo_g = 0, + photo_b = 0; + + uint8_t *buf; + + int error; + + if (argc < 3) { + cammy_command_usage(argc, argv, "No save file provided"); + } else if (argc < 4) { + cammy_command_usage(argc, argv, "No red photo number provided"); + } else if (argc < 5) { + cammy_command_usage(argc, argv, "No green photo number provided"); + } else if (argc < 6) { + cammy_command_usage(argc, argv, "No blue photo number provided"); + } else if (argc < 7) { + cammy_command_usage(argc, argv, "No photo provided"); + } + + cammy_command_validate_photo_number(argc, argv, photo_r = atoi(argv[3])); + cammy_command_validate_photo_number(argc, argv, photo_g = atoi(argv[4])); + cammy_command_validate_photo_number(argc, argv, photo_b = atoi(argv[5])); + + if ((sram = cammy_sram_open(argv[2])) == NULL) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "cammy_sram_open()", argv[2], strerror(errno)); + + goto error_sram_open; + } + + png_init(malloc, free); + + if ((png = malloc(sizeof(*png))) == NULL) { + goto error_malloc_png; + } + + if ((error = png_open_file_read(png, argv[6])) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "png_open_file_read()", argv[6], png_error_string(error)); + + goto error_png_open_file_read; + } + + if (png->width != CAMMY_PHOTO_WIDTH + || png->height != CAMMY_PHOTO_HEIGHT) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], argv[6], "Invalid image dimensions"); + + goto error_invalid_dimensions; + } + + if ((buf = malloc(png->width * png->height * png->bpp)) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "malloc()", strerror(errno)); + + goto error_malloc; + } + + if ((error = png_get_data(png, buf)) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "png_get_data()", argv[4], png_error_string(error)); + + goto error_png_get_data; + } + + cammy_photo_import_rgb(&sram->data->photos[photo_r-1], + &sram->data->photos[photo_g-1], + &sram->data->photos[photo_b-1], buf, (int)png->bpp); + + free(buf); + + png_close_file(png); + + free(png); + + cammy_sram_close(sram); + + return 0; + +error_png_get_data: + free(buf); + +error_malloc: +error_invalid_dimensions: + png_close_file(png); + +error_png_open_file_read: + free(png); + +error_malloc_png: + cammy_sram_close(sram); + +error_sram_open: + return 1; +} + +int cammy_command_merge_rgb(int argc, char **argv) { + cammy_sram *sram; + png_t *png; + + int photo_r = 0, + photo_g = 0, + photo_b = 0; + + uint8_t *buf; + + int error; + + if (argc < 3) { + cammy_command_usage(argc, argv, "No save file provided"); + } else if (argc < 4) { + cammy_command_usage(argc, argv, "No red photo number provided"); + } else if (argc < 5) { + cammy_command_usage(argc, argv, "No green photo number provided"); + } else if (argc < 6) { + cammy_command_usage(argc, argv, "No blue photo number provided"); + } else if (argc < 7) { + cammy_command_usage(argc, argv, "No photo provided"); + } + + cammy_command_validate_photo_number(argc, argv, photo_r = atoi(argv[3])); + cammy_command_validate_photo_number(argc, argv, photo_g = atoi(argv[4])); + cammy_command_validate_photo_number(argc, argv, photo_b = atoi(argv[5])); + + if ((sram = cammy_sram_open(argv[2])) == NULL) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "cammy_sram_open()", argv[2], strerror(errno)); + + goto error_sram_open; + } + + png_init(malloc, free); + + if ((png = malloc(sizeof(*png))) == NULL) { + goto error_malloc_png; + } + + if ((error = png_open_file_write(png, argv[6])) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "png_open_file_write()", argv[6], png_error_string(error)); + + goto error_png_open_file_write; + } + + if ((buf = malloc(CAMMY_PHOTO_WIDTH * CAMMY_PHOTO_HEIGHT * 3)) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "malloc()", strerror(errno)); + + goto error_malloc_buf; + } + + cammy_photo_merge(&sram->data->photos[photo_r-1], + &sram->data->photos[photo_g-1], + &sram->data->photos[photo_b-1], buf, 3); + + if ((error = png_set_data(png, + CAMMY_PHOTO_WIDTH, + CAMMY_PHOTO_HEIGHT, 8, PNG_TRUECOLOR, buf)) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "png_set_data()", argv[6], png_error_string(error)); + + goto error_png_set_data; + } + + png_close_file(png); + + free(buf); + + free(png); + + cammy_sram_close(sram); + + return 0; + +error_png_set_data: + free(buf); + +error_malloc_buf: + png_close_file(png); + +error_png_open_file_write: + free(png); + +error_malloc_png: + cammy_sram_close(sram); + +error_sram_open: + return 1; +} diff --git a/bin/slice.c b/bin/slice.c new file mode 100644 index 0000000..e3b6f84 --- /dev/null +++ b/bin/slice.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "png.h" +#include "commands.h" + +int cammy_command_slice(int argc, char **argv) { + uint8_t *buf; + + size_t width, height, + x_pad, y_pad; + + int depth; + + if (argc < 3) { + cammy_command_usage(argc, argv, "No X padding provided"); + } else if (argc < 4) { + cammy_command_usage(argc, argv, "No Y padding provided"); + } else if (argc < 5) { + cammy_command_usage(argc, argv, "No input PNG image provided"); + } + + x_pad = atoi(argv[2]); + y_pad = atoi(argv[3]); + + if ((buf = cammy_png_load(argv[4], &width, &height, &depth)) == NULL) { + goto error_read_png_file; + } + + if (cammy_image_slice(buf, width, height, x_pad, y_pad, depth) < 0) { + goto error_image_slice; + } + + free(buf); + + return 0; + +error_image_slice: + free(buf); + +error_read_png_file: + return 1; +} diff --git a/bin/tile.c b/bin/tile.c new file mode 100644 index 0000000..5512f39 --- /dev/null +++ b/bin/tile.c @@ -0,0 +1,241 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "pnglite.h" +#include "png.h" +#include "commands.h" + +static cammy_tile_palette palette = { + .colors = { + { 0, 0, 0 }, + { 85, 85, 85 }, + { 171, 171, 171 }, + { 255, 255, 255 } + } +}; + +int cammy_command_import_tile(int argc, char **argv) { + cammy_sram *sram; + cammy_image *dest, *src; + int photo; + + if (argc < 2) { + cammy_command_usage(argc, argv, "No camera SRAM file provided"); + } else if (argc < 3) { + cammy_command_usage(argc, argv, "No picture number provided"); + } else if (argc < 4) { + cammy_command_usage(argc, argv, + "No Game Boy screen tile data file provided"); + } + + photo = atoi(argv[3]); + + if (photo < 1 || photo > CAMMY_SRAM_PHOTO_COUNT) { + cammy_command_usage(argc, argv, "Invalid photo number"); + } + + if ((sram = cammy_sram_open(argv[2])) == NULL) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "cammy_sram_open()", argv[2], strerror(errno)); + + goto error_sram_open; + } + + if ((src = cammy_image_open_tile(argv[4], CAMMY_SCREEN_WIDTH, + CAMMY_SCREEN_HEIGHT)) == NULL) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "cammy_image_open_tile()", argv[4], strerror(errno)); + + goto error_image_open_tile; + } + + if ((dest = malloc(sizeof(*dest))) == NULL) { + goto error_malloc_dest; + } + + dest->format = CAMMY_IMAGE_TILE; + dest->tiles = (cammy_tile *)&sram->data->photos[photo-1].tiles; + dest->width = CAMMY_PHOTO_WIDTH; + dest->height = CAMMY_PHOTO_HEIGHT; + + cammy_image_copy(dest, src, + 0, 0, 16, 16, CAMMY_PHOTO_WIDTH, CAMMY_PHOTO_HEIGHT); + + free(dest); + + cammy_image_close(src); + + cammy_sram_close(sram); + + return 0; + +error_malloc_dest: + cammy_image_close(src); + +error_image_open_tile: + cammy_sram_close(sram); + +error_sram_open: + return 1; +} + +int cammy_command_export_tile(int argc, char **argv) { + cammy_sram *sram; + cammy_image *dest, *src; + int photo; + + if (argc < 2) { + cammy_command_usage(argc, argv, "No camera SRAM file provided"); + } else if (argc < 3) { + cammy_command_usage(argc, argv, "No picture number provided"); + } else if (argc < 4) { + cammy_command_usage(argc, argv, + "No Game Boy screen tile data file provided"); + } + + photo = atoi(argv[3]); + + if (photo < 1 || photo > CAMMY_SRAM_PHOTO_COUNT) { + cammy_command_usage(argc, argv, "Invalid photo number"); + } + + if ((sram = cammy_sram_open(argv[2])) == NULL) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "cammy_sram_open()", argv[2], strerror(errno)); + + goto error_sram_open; + } + + if ((src = malloc(sizeof(*src))) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "malloc()", strerror(errno)); + + goto error_malloc_src; + } + + src->format = CAMMY_IMAGE_TILE; + src->size = CAMMY_PHOTO_SIZE; + src->width = CAMMY_PHOTO_WIDTH; + src->height = CAMMY_PHOTO_HEIGHT; + src->tiles = (cammy_tile *)&sram->data->photos[photo-1].tiles; + + if ((dest = cammy_image_new(CAMMY_IMAGE_TILE, + CAMMY_SCREEN_WIDTH, + CAMMY_SCREEN_HEIGHT)) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "cammy_image_new()", strerror(errno)); + + goto error_image_new_dest; + } + + memset(dest->buf, '\0', dest->size); + + cammy_image_copy(dest, src, + 16, 16, 0, 0, CAMMY_PHOTO_WIDTH, CAMMY_PHOTO_HEIGHT); + + if (cammy_image_save_tile(dest, argv[4]) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "cammy_image_save_tile()", argv[4], strerror(errno)); + + goto error_image_save_tile_dest; + } + + free(dest); + + cammy_image_close(src); + + cammy_sram_close(sram); + + return 0; + +error_image_save_tile_dest: + cammy_image_destroy(dest); + +error_image_new_dest: + free(src); + +error_malloc_src: + cammy_sram_close(sram); + +error_sram_open: + return errno || 1; +} + +int cammy_command_convert_tile(int argc, char **argv) { + int fd; + void *in, *out; + + if (argc < 3) { + cammy_command_usage(argc, argv, + "No input Game Boy screen tile data file provided"); + } else if (argc < 4) { + cammy_command_usage(argc, argv, "No output PNG filename provided"); + } + + if ((fd = open(argv[2], O_RDONLY)) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "open()", argv[2], strerror(errno)); + + goto error_open; + } + + if ((in = malloc(CAMMY_SCREEN_SIZE)) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "malloc()", strerror(errno)); + + goto error_malloc_in; + } + + if (read(fd, in, CAMMY_SCREEN_SIZE) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "read()", argv[2], strerror(errno)); + + goto error_read; + } + + if ((out = malloc(CAMMY_SCREEN_WIDTH * CAMMY_SCREEN_HEIGHT * 3)) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "malloc()", strerror(errno)); + + goto error_malloc_out; + } + + cammy_image_copy_from_tile(out, in, + CAMMY_SCREEN_WIDTH, + CAMMY_SCREEN_HEIGHT, 3, &palette); + + if (cammy_png_save(argv[3], out, + CAMMY_SCREEN_WIDTH, + CAMMY_SCREEN_HEIGHT, 8, PNG_TRUECOLOR) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "cammy_png_save()", argv[3], strerror(errno)); + + goto error_png_save; + } + + return 0; + +error_png_save: + free(out); + +error_malloc_out: +error_read: + free(in); + +error_malloc_in: + close(fd); + +error_open: + return errno; +}