Kickass
This commit is contained in:
parent
22ce22fa4c
commit
05fd969619
12 changed files with 164 additions and 828 deletions
|
@ -8,10 +8,9 @@ CFLAGS += -I$(INCLUDE_PATH)
|
|||
LDFLAGS =
|
||||
|
||||
CAMMY = cammy
|
||||
CAMMY_OBJS = pnglite.o png.o main.o dither.o export.o import.o rgb.o \
|
||||
slice.o tile.o
|
||||
CAMMY_OBJS = main.o export.o import.o dither.o
|
||||
|
||||
CAMMY_HEADERS = pnglite.h png.h commands.h
|
||||
CAMMY_HEADERS = commands.h
|
||||
|
||||
CAMMY_LDFLAGS = ../src/libcammy.a -lz
|
||||
|
||||
|
|
94
bin/dither.c
94
bin/dither.c
|
@ -1,94 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <cammy/image.h>
|
||||
#include <cammy/photo.h>
|
||||
|
||||
#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 }
|
||||
}
|
||||
};
|
||||
|
||||
static void usage(int argc, char **argv, const char *message, ...) {
|
||||
if (message) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, message);
|
||||
vfprintf(stderr, message, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
fprintf(stderr, "usage: %1$s dither input.png output.png\n", argv[0]);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int cammy_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 = 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;
|
||||
}
|
42
bin/export.c
42
bin/export.c
|
@ -15,13 +15,11 @@
|
|||
#include "png.h"
|
||||
#include "commands.h"
|
||||
|
||||
static cammy_tile_palette palette = {
|
||||
.colors = {
|
||||
{ 0, 0, 0 },
|
||||
{ 85, 85, 85 },
|
||||
{ 171, 171, 171 },
|
||||
{ 255, 255, 255 }
|
||||
}
|
||||
static cammy_image_color palette[4] = {
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 85, 85, 85, 0 },
|
||||
{ 171, 171, 171, 0 },
|
||||
{ 255, 255, 255, 0 }
|
||||
};
|
||||
|
||||
static void usage(int argc, char **argv, const char *message, ...) {
|
||||
|
@ -42,7 +40,7 @@ static void usage(int argc, char **argv, const char *message, ...) {
|
|||
int cammy_export(int argc, char **argv) {
|
||||
cammy_sram *sram;
|
||||
int photo = 0;
|
||||
uint8_t *buf;
|
||||
cammy_image *image;
|
||||
|
||||
if (argc < 3) {
|
||||
usage(argc, argv, "No save file provided");
|
||||
|
@ -65,34 +63,26 @@ int cammy_export(int argc, char **argv) {
|
|||
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;
|
||||
if ((image = cammy_photo_export(&sram->data->photos[photo],
|
||||
CAMMY_IMAGE_24BPP_RGB,
|
||||
palette)) == NULL) {
|
||||
goto error_photo_export;
|
||||
}
|
||||
|
||||
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;
|
||||
if (cammy_image_save(image, argv[4]) < 0) {
|
||||
goto error_image_save;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
cammy_image_destroy(image);
|
||||
|
||||
cammy_sram_close(sram);
|
||||
|
||||
return 0;
|
||||
|
||||
error_png_save:
|
||||
free(buf);
|
||||
error_image_save:
|
||||
cammy_image_destroy(image);
|
||||
|
||||
error_malloc_buf:
|
||||
error_photo_export:
|
||||
cammy_sram_close(sram);
|
||||
|
||||
error_sram_open:
|
||||
|
|
57
bin/import.c
57
bin/import.c
|
@ -7,7 +7,6 @@
|
|||
#include <cammy/photo.h>
|
||||
#include <cammy/sram.h>
|
||||
|
||||
#include "pnglite.h"
|
||||
#include "commands.h"
|
||||
|
||||
static void usage(int argc, char **argv, const char *message, ...) {
|
||||
|
@ -27,11 +26,8 @@ static void usage(int argc, char **argv, const char *message, ...) {
|
|||
|
||||
int cammy_import(int argc, char **argv) {
|
||||
cammy_sram *sram;
|
||||
png_t *png;
|
||||
cammy_image *image;
|
||||
int photo = 0;
|
||||
uint8_t *buf;
|
||||
|
||||
int error;
|
||||
|
||||
if (argc < 3) {
|
||||
usage(argc, argv, "No save file provided");
|
||||
|
@ -54,64 +50,33 @@ int cammy_import(int argc, char **argv) {
|
|||
goto error_sram_open;
|
||||
}
|
||||
|
||||
png_init(malloc, free);
|
||||
|
||||
if ((png = malloc(sizeof(*png))) == NULL) {
|
||||
goto error_malloc_png;
|
||||
if ((image = cammy_image_open(argv[4])) == NULL) {
|
||||
goto error_image_open;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (image->width != CAMMY_PHOTO_WIDTH
|
||||
|| image->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 (cammy_photo_import(&sram->data->photos[photo-1], image) < 0) {
|
||||
goto error_photo_import;
|
||||
}
|
||||
|
||||
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_image_destroy(image);
|
||||
|
||||
cammy_sram_close(sram);
|
||||
|
||||
return 0;
|
||||
|
||||
error_png_get_data:
|
||||
free(buf);
|
||||
|
||||
error_malloc_buf:
|
||||
error_photo_import:
|
||||
error_invalid_dimensions:
|
||||
png_close_file(png);
|
||||
cammy_image_destroy(image);
|
||||
|
||||
error_png_open_file_read:
|
||||
free(png);
|
||||
|
||||
error_malloc_png:
|
||||
error_image_open:
|
||||
cammy_sram_close(sram);
|
||||
|
||||
error_sram_open:
|
||||
|
|
|
@ -14,12 +14,6 @@ static struct {
|
|||
{ "import", cammy_import },
|
||||
{ "export", cammy_export },
|
||||
{ "dither", cammy_dither },
|
||||
{ "rgb-split", cammy_rgb_split },
|
||||
{ "rgb-merge", cammy_rgb_merge },
|
||||
{ "tile-import", cammy_tile_import },
|
||||
{ "tile-export", cammy_tile_export },
|
||||
{ "tile-convert", cammy_tile_convert },
|
||||
{ "slice", cammy_slice },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
236
bin/rgb.c
236
bin/rgb.c
|
@ -1,236 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <cammy/image.h>
|
||||
#include <cammy/photo.h>
|
||||
#include <cammy/sram.h>
|
||||
|
||||
#include "pnglite.h"
|
||||
#include "commands.h"
|
||||
|
||||
static void split_usage(int argc, char **argv, const char *message, ...) {
|
||||
if (message) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, message);
|
||||
vfprintf(stderr, message, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int cammy_rgb_split(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) {
|
||||
split_usage(argc, argv, "No save file provided");
|
||||
} else if (argc < 4) {
|
||||
split_usage(argc, argv, "No red photo number provided");
|
||||
} else if (argc < 5) {
|
||||
split_usage(argc, argv, "No green photo number provided");
|
||||
} else if (argc < 6) {
|
||||
split_usage(argc, argv, "No blue photo number provided");
|
||||
} else if (argc < 7) {
|
||||
split_usage(argc, argv, "No photo provided");
|
||||
}
|
||||
|
||||
cammy_validate_photo_number(argc, argv, photo_r = atoi(argv[3]));
|
||||
cammy_validate_photo_number(argc, argv, photo_g = atoi(argv[4]));
|
||||
cammy_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 void merge_usage(int argc, char **argv, const char *message, ...) {
|
||||
if (message) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, message);
|
||||
vfprintf(stderr, message, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
fprintf(stderr, "usage: %1$s rgb-merge file.sav rn gn bn output.png\n",
|
||||
argv[0]);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int cammy_rgb_merge(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) {
|
||||
merge_usage(argc, argv, "No save file provided");
|
||||
} else if (argc < 4) {
|
||||
merge_usage(argc, argv, "No red photo number provided");
|
||||
} else if (argc < 5) {
|
||||
merge_usage(argc, argv, "No green photo number provided");
|
||||
} else if (argc < 6) {
|
||||
merge_usage(argc, argv, "No blue photo number provided");
|
||||
} else if (argc < 7) {
|
||||
merge_usage(argc, argv, "No photo provided");
|
||||
}
|
||||
|
||||
cammy_validate_photo_number(argc, argv, photo_r = atoi(argv[3]));
|
||||
cammy_validate_photo_number(argc, argv, photo_g = atoi(argv[4]));
|
||||
cammy_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;
|
||||
}
|
287
bin/tile.c
287
bin/tile.c
|
@ -1,287 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <cammy/image.h>
|
||||
#include <cammy/screen.h>
|
||||
#include <cammy/photo.h>
|
||||
#include <cammy/sram.h>
|
||||
|
||||
#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 }
|
||||
}
|
||||
};
|
||||
|
||||
static void import_usage(int argc, char **argv, const char *message, ...) {
|
||||
if (message) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, message);
|
||||
vfprintf(stderr, message, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
fprintf(stderr, "usage: %1$s tile-import file.sav 1..30 printer.tile\n"
|
||||
" %1$s tile-export file.sav 1..30 output.tile\n"
|
||||
" %1$s tile-convert printer.tile output.png\n",
|
||||
argv[0]);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int cammy_tile_import(int argc, char **argv) {
|
||||
cammy_sram *sram;
|
||||
cammy_image dest, *src;
|
||||
int photo;
|
||||
|
||||
cammy_image_point to = {
|
||||
0, 0
|
||||
};
|
||||
|
||||
cammy_image_region from = {
|
||||
16, 16, CAMMY_PHOTO_WIDTH, CAMMY_PHOTO_HEIGHT
|
||||
};
|
||||
|
||||
if (argc < 2) {
|
||||
import_usage(argc, argv, "No camera SRAM file provided");
|
||||
} else if (argc < 3) {
|
||||
import_usage(argc, argv, "No picture number provided");
|
||||
} else if (argc < 4) {
|
||||
import_usage(argc, argv,
|
||||
"No Game Boy screen tile data file provided");
|
||||
}
|
||||
|
||||
photo = atoi(argv[3]);
|
||||
|
||||
if (photo < 1 || photo > CAMMY_SRAM_PHOTO_COUNT) {
|
||||
import_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;
|
||||
}
|
||||
|
||||
dest.format = CAMMY_IMAGE_2BPP_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, &to, &from);
|
||||
|
||||
cammy_image_close(src);
|
||||
|
||||
cammy_sram_close(sram);
|
||||
|
||||
return 0;
|
||||
|
||||
error_image_open_tile:
|
||||
cammy_sram_close(sram);
|
||||
|
||||
error_sram_open:
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void export_usage(int argc, char **argv, const char *message, ...) {
|
||||
if (message) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, message);
|
||||
vfprintf(stderr, message, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
fprintf(stderr, "usage: %1$s tile-import file.sav 1..30 printer.tile\n"
|
||||
" %1$s tile-export file.sav 1..30 output.tile\n"
|
||||
" %1$s tile-convert printer.tile output.png\n",
|
||||
argv[0]);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int cammy_tile_export(int argc, char **argv) {
|
||||
cammy_sram *sram;
|
||||
cammy_image *dest, src;
|
||||
int photo;
|
||||
|
||||
cammy_image_point to = {
|
||||
16, 16
|
||||
};
|
||||
|
||||
cammy_image_region from = {
|
||||
0, 0, CAMMY_PHOTO_WIDTH, CAMMY_PHOTO_HEIGHT
|
||||
};
|
||||
|
||||
if (argc < 2) {
|
||||
export_usage(argc, argv, "No camera SRAM file provided");
|
||||
} else if (argc < 3) {
|
||||
export_usage(argc, argv, "No picture number provided");
|
||||
} else if (argc < 4) {
|
||||
export_usage(argc, argv,
|
||||
"No Game Boy screen tile data file provided");
|
||||
}
|
||||
|
||||
photo = atoi(argv[3]);
|
||||
|
||||
if (photo < 1 || photo > CAMMY_SRAM_PHOTO_COUNT) {
|
||||
export_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;
|
||||
}
|
||||
|
||||
src.format = CAMMY_IMAGE_2BPP_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_2BPP_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, &to, &from);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
cammy_image_close(dest);
|
||||
|
||||
cammy_sram_close(sram);
|
||||
|
||||
return 0;
|
||||
|
||||
error_image_save_tile_dest:
|
||||
cammy_image_destroy(dest);
|
||||
|
||||
error_image_new_dest:
|
||||
cammy_sram_close(sram);
|
||||
|
||||
error_sram_open:
|
||||
return errno || 1;
|
||||
}
|
||||
|
||||
static void convert_usage(int argc, char **argv, const char *message, ...) {
|
||||
if (message) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, message);
|
||||
vfprintf(stderr, message, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
fprintf(stderr, "usage: %1$s tile-convert printer.tile output.png\n",
|
||||
argv[0]);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int cammy_tile_convert(int argc, char **argv) {
|
||||
int fd;
|
||||
void *in, *out;
|
||||
|
||||
if (argc < 3) {
|
||||
convert_usage(argc, argv,
|
||||
"No input Game Boy screen tile data file provided");
|
||||
} else if (argc < 4) {
|
||||
convert_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;
|
||||
}
|
|
@ -52,6 +52,13 @@ typedef struct _cammy_image_region {
|
|||
size_t x, y, width, height;
|
||||
} cammy_image_region;
|
||||
|
||||
int cammy_image_init(cammy_image *image,
|
||||
cammy_image_format format,
|
||||
cammy_image_color *palette,
|
||||
size_t width,
|
||||
size_t height,
|
||||
uint8_t *buf);
|
||||
|
||||
cammy_image *cammy_image_new(cammy_image_format format,
|
||||
cammy_image_color *palette,
|
||||
size_t width,
|
||||
|
|
|
@ -38,22 +38,11 @@ typedef struct _cammy_photo {
|
|||
|
||||
#pragma pack(pop)
|
||||
|
||||
int cammy_photo_import(cammy_photo *dest,
|
||||
cammy_image *src);
|
||||
|
||||
cammy_image *cammy_photo_export(cammy_photo *src,
|
||||
cammy_image_format format,
|
||||
cammy_tile_palette *palette);
|
||||
|
||||
void cammy_photo_merge(cammy_photo *srcr,
|
||||
cammy_photo *srcg,
|
||||
cammy_photo *srcb,
|
||||
uint8_t *dest,
|
||||
int depth);
|
||||
|
||||
void cammy_photo_import(cammy_photo *dest, uint8_t *src, int depth);
|
||||
|
||||
void cammy_photo_import_rgb(cammy_photo *destr,
|
||||
cammy_photo *destg,
|
||||
cammy_photo *destb,
|
||||
uint8_t *src,
|
||||
int depth);
|
||||
cammy_image_color *palette);
|
||||
|
||||
#endif /* _CAMMY_PHOTO_H */
|
||||
|
|
|
@ -22,10 +22,6 @@ typedef struct _cammy_tile {
|
|||
uint8_t data[CAMMY_TILE_SIZE];
|
||||
} cammy_tile;
|
||||
|
||||
typedef struct _cammy_tile_palette {
|
||||
uint8_t colors[4][3];
|
||||
} cammy_tile_palette;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif /* _CAMMY_TILE_H */
|
||||
|
|
105
src/image.c
105
src/image.c
|
@ -128,52 +128,50 @@ static inline size_t size_2bpp_tile(size_t width, size_t height) {
|
|||
return CAMMY_TILE_SIZE * tiles_width * tiles_height;
|
||||
}
|
||||
|
||||
cammy_image *cammy_image_new(cammy_image_format format,
|
||||
cammy_image_color *palette,
|
||||
static inline size_t size_format(cammy_image_format format,
|
||||
size_t width,
|
||||
size_t height) {
|
||||
cammy_image *image;
|
||||
size_t size;
|
||||
|
||||
switch (format) {
|
||||
case CAMMY_IMAGE_2BPP_TILE: {
|
||||
if (palette == NULL) {
|
||||
palette = default_palette;
|
||||
case CAMMY_IMAGE_2BPP_TILE:
|
||||
return size_2bpp_tile(width, height);
|
||||
|
||||
case CAMMY_IMAGE_24BPP_RGB:
|
||||
return 3 * width * height;
|
||||
|
||||
case CAMMY_IMAGE_32BPP_RGBA:
|
||||
return 4 * width * height;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size = size_2bpp_tile(width, height);
|
||||
int cammy_image_init(cammy_image *image,
|
||||
cammy_image_format format,
|
||||
cammy_image_color *palette,
|
||||
size_t width,
|
||||
size_t height,
|
||||
uint8_t *buf) {
|
||||
size_t size = size_format(format, width, height);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAMMY_IMAGE_24BPP_RGB: {
|
||||
size = 3 * width * height;
|
||||
break;
|
||||
}
|
||||
|
||||
case CAMMY_IMAGE_32BPP_RGBA: {
|
||||
size = 4 * width * height;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
if (size == 0) {
|
||||
errno = EINVAL;
|
||||
goto error_invalid_format;
|
||||
}
|
||||
}
|
||||
|
||||
if ((image = malloc(sizeof(*image))) == NULL) {
|
||||
goto error_malloc_image;
|
||||
|
||||
goto error_invalid_size;
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
image->buf = buf;
|
||||
} else {
|
||||
if ((image->buf = malloc(size)) == NULL) {
|
||||
goto error_malloc_buf;
|
||||
}
|
||||
}
|
||||
|
||||
if (palette) {
|
||||
memcpy(&image->palette, palette, sizeof(image->palette));
|
||||
} else {
|
||||
memset(&image->palette, '\0', sizeof(image->palette));
|
||||
memset(image->buf, '\0', size);
|
||||
|
||||
if (palette == NULL) {
|
||||
palette = default_palette;
|
||||
}
|
||||
|
||||
image->format = format;
|
||||
|
@ -181,13 +179,33 @@ cammy_image *cammy_image_new(cammy_image_format format,
|
|||
image->width = width;
|
||||
image->height = height;
|
||||
|
||||
return image;
|
||||
return 0;
|
||||
|
||||
error_malloc_buf:
|
||||
error_invalid_size:
|
||||
return -1;
|
||||
}
|
||||
|
||||
cammy_image *cammy_image_new(cammy_image_format format,
|
||||
cammy_image_color *palette,
|
||||
size_t width,
|
||||
size_t height) {
|
||||
cammy_image *image;
|
||||
|
||||
if ((image = malloc(sizeof(*image))) == NULL) {
|
||||
goto error_malloc_image;
|
||||
}
|
||||
|
||||
if (cammy_image_init(image, format, palette, width, height, NULL) < 0) {
|
||||
goto error_image_init;
|
||||
}
|
||||
|
||||
return image;
|
||||
|
||||
error_image_init:
|
||||
free(image);
|
||||
|
||||
error_malloc_image:
|
||||
error_invalid_format:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -283,12 +301,18 @@ static cammy_image *load_png(const char *file) {
|
|||
goto error_image_new;
|
||||
}
|
||||
|
||||
printf("Got buf %p size %zu\n", image->buf, image->size);
|
||||
|
||||
if (png_get_data(&png, image->buf) < 0) {
|
||||
goto error_png_get_data;
|
||||
}
|
||||
|
||||
printf("Still here\n");
|
||||
|
||||
png_close_file(&png);
|
||||
|
||||
printf("Hmmst\n");
|
||||
|
||||
return image;
|
||||
|
||||
error_png_get_data:
|
||||
|
@ -303,8 +327,6 @@ error_png_open_file_read:
|
|||
}
|
||||
|
||||
cammy_image *cammy_image_open(const char *file) {
|
||||
cammy_image *image;
|
||||
|
||||
int fd;
|
||||
uint8_t buf[4];
|
||||
|
||||
|
@ -332,13 +354,8 @@ cammy_image *cammy_image_open(const char *file) {
|
|||
goto error_invalid_format;
|
||||
}
|
||||
|
||||
if ((image = loader(file)) == NULL) {
|
||||
goto error_load_image;
|
||||
}
|
||||
return loader(file);
|
||||
|
||||
return image;
|
||||
|
||||
error_load_image:
|
||||
error_invalid_format:
|
||||
error_read:
|
||||
error_lseek:
|
||||
|
@ -633,7 +650,7 @@ static void copy_2bpp_tile_to_rgb(cammy_image *dest,
|
|||
from->y + y,
|
||||
from->width);
|
||||
|
||||
buf_write(src->buf,
|
||||
buf_write(dest->buf,
|
||||
from->x + x,
|
||||
from->y + y,
|
||||
from->width,
|
||||
|
|
110
src/photo.c
110
src/photo.c
|
@ -5,73 +5,69 @@
|
|||
#include <cammy/image.h>
|
||||
#include <cammy/photo.h>
|
||||
|
||||
int cammy_photo_import(cammy_photo *dest,
|
||||
cammy_image *src) {
|
||||
cammy_image image;
|
||||
|
||||
cammy_image_region from = {
|
||||
0, 0, CAMMY_PHOTO_WIDTH, CAMMY_PHOTO_HEIGHT
|
||||
};
|
||||
|
||||
cammy_image_point to = {
|
||||
0, 0
|
||||
};
|
||||
|
||||
if (cammy_image_init(&image,
|
||||
CAMMY_IMAGE_2BPP_TILE,
|
||||
NULL,
|
||||
CAMMY_PHOTO_WIDTH,
|
||||
CAMMY_PHOTO_HEIGHT,
|
||||
(uint8_t *)dest->tiles) < 0) {
|
||||
goto error_image_init;
|
||||
}
|
||||
|
||||
cammy_image_copy(&image, src, &to, &from);
|
||||
|
||||
return 0;
|
||||
|
||||
error_image_init:
|
||||
return -1;
|
||||
}
|
||||
|
||||
cammy_image *cammy_photo_export(cammy_photo *src,
|
||||
cammy_image_format format,
|
||||
cammy_tile_palette *palette) {
|
||||
cammy_image *image;
|
||||
cammy_image_color *palette) {
|
||||
cammy_image image, *dest;
|
||||
|
||||
if ((image = cammy_image_new(format,
|
||||
cammy_image_region from = {
|
||||
0, 0, CAMMY_PHOTO_WIDTH, CAMMY_PHOTO_HEIGHT
|
||||
};
|
||||
|
||||
cammy_image_point to = {
|
||||
0, 0
|
||||
};
|
||||
|
||||
if (cammy_image_init(&image,
|
||||
CAMMY_IMAGE_2BPP_TILE,
|
||||
palette,
|
||||
CAMMY_PHOTO_WIDTH,
|
||||
CAMMY_PHOTO_HEIGHT,
|
||||
(uint8_t *)src->tiles) < 0) {
|
||||
goto error_image_init;
|
||||
}
|
||||
|
||||
if ((dest = cammy_image_new(format,
|
||||
palette,
|
||||
CAMMY_PHOTO_WIDTH,
|
||||
CAMMY_PHOTO_HEIGHT)) == NULL) {
|
||||
goto error_image_new;
|
||||
}
|
||||
|
||||
cammy_image_copy_from_tile(dest,
|
||||
(cammy_tile *)&src->tiles,
|
||||
CAMMY_PHOTO_WIDTH,
|
||||
CAMMY_PHOTO_HEIGHT,
|
||||
depth,
|
||||
palette);
|
||||
cammy_image_copy(dest, &image, &to, &from);
|
||||
|
||||
return image;
|
||||
return dest;
|
||||
|
||||
error_image_new:
|
||||
error_image_init:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void cammy_photo_merge(cammy_photo *srcr,
|
||||
cammy_photo *srcg,
|
||||
cammy_photo *srcb,
|
||||
uint8_t *dest,
|
||||
int depth) {
|
||||
cammy_image_merge_tiles(dest,
|
||||
(cammy_tile *)&srcr->tiles,
|
||||
(cammy_tile *)&srcg->tiles,
|
||||
(cammy_tile *)&srcb->tiles,
|
||||
CAMMY_PHOTO_WIDTH,
|
||||
CAMMY_PHOTO_HEIGHT,
|
||||
depth);
|
||||
}
|
||||
|
||||
void cammy_photo_import(cammy_photo *dest, uint8_t *src, int depth) {
|
||||
memset(&dest->thumb, '\xff', sizeof(dest->thumb));
|
||||
|
||||
cammy_image_dither_to_tile((cammy_tile *)&dest->tiles,
|
||||
src,
|
||||
0, 0, 0, 0,
|
||||
CAMMY_PHOTO_WIDTH,
|
||||
CAMMY_PHOTO_HEIGHT,
|
||||
CAMMY_PHOTO_WIDTH,
|
||||
CAMMY_PHOTO_HEIGHT,
|
||||
CAMMY_PHOTO_WIDTH,
|
||||
CAMMY_PHOTO_HEIGHT,
|
||||
depth);
|
||||
}
|
||||
|
||||
void cammy_photo_import_rgb(cammy_photo *destr,
|
||||
cammy_photo *destg,
|
||||
cammy_photo *destb,
|
||||
uint8_t *src,
|
||||
int depth) {
|
||||
memset(&destr->thumb, '\xff', sizeof(destr->thumb));
|
||||
memset(&destg->thumb, '\xff', sizeof(destg->thumb));
|
||||
memset(&destb->thumb, '\xff', sizeof(destb->thumb));
|
||||
|
||||
cammy_image_split_to_tiles((cammy_tile *)&destr->tiles,
|
||||
(cammy_tile *)&destg->tiles,
|
||||
(cammy_tile *)&destb->tiles,
|
||||
src,
|
||||
CAMMY_PHOTO_WIDTH,
|
||||
CAMMY_PHOTO_HEIGHT,
|
||||
depth);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue