236 lines
5.7 KiB
C
236 lines
5.7 KiB
C
#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;
|
|
}
|