emote2ss

Animated webp to spritesheets converting tool
git clone git://bsandro.tech/emote2ss
Log | Files | Refs | README | LICENSE

commit 8c463a1188867b47d07df18cf0b25ac87c0bff7e
parent 013c05d3fd44635daa9acf74e9ad64cb7ca48bb2
Author: bsandro <[email protected]>
Date:   Wed, 16 Aug 2023 18:05:24 +0300

Working basic save dialog

Diffstat:
Mgui/main.c | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 64 insertions(+), 25 deletions(-)

diff --git a/gui/main.c b/gui/main.c @@ -26,6 +26,12 @@ #include <linux/limits.h> #endif +#ifdef _WIN32 +#define DIR_SEPARATOR '\\' +#else +#define DIR_SEPARATOR '/' +#endif + #define NUM_CHANNELS 4 #define UI_COLOR_FROM_RGBA(r, g, b, a) (((uint32_t) (r) << 16) | ((uint32_t) (g) << 8) | ((uint32_t) (b) << 0) | ((uint32_t) (a) << 24)) @@ -56,6 +62,8 @@ typedef struct { uint32_t frame_count; void *raw_mem; char *path; + char *dirname; + char *filename; } Animation; // let it be global variable for now @@ -91,17 +99,17 @@ void alloc_image(Animation *img, uint32_t frame_count) { img->raw_mem = mem; } -int read_file(const char *fname, const uint8_t **data, size_t *size) { +int read_file(const char *filename, const uint8_t **data, size_t *size) { assert(data != NULL); assert(size != NULL); *data = NULL; *size = 0; - FILE *infile = fopen(fname, "rb"); + FILE *infile = fopen(filename, "rb"); assert(infile != NULL); fseek(infile, 0, SEEK_END); size_t fsize = ftell(infile); - printf("%s: %zu bytes\n", fname, fsize); + printf("%s: %zu bytes\n", filename, fsize); fseek(infile, 0, SEEK_SET); uint8_t *fdata = malloc(fsize+1); @@ -111,7 +119,7 @@ int read_file(const char *fname, const uint8_t **data, size_t *size) { fclose(infile); if (!ok) { - fprintf(stderr, "cannot read file %s (%d)\n", fname, ok); + fprintf(stderr, "cannot read file %s (%d)\n", filename, ok); free(fdata); return -1; } @@ -120,13 +128,13 @@ int read_file(const char *fname, const uint8_t **data, size_t *size) { return 0; } -int read_webp(const char *fname, Animation *anim) { - printf("read_webp(%s)\n", fname); +int read_webp(const char *filename, Animation *anim) { + printf("read_webp(%s)\n", filename); WebPData webp_data; WebPDataInit(&webp_data); - if (read_file(fname, &webp_data.bytes, &webp_data.size) == -1) { + if (read_file(filename, &webp_data.bytes, &webp_data.size) == -1) { fprintf(stderr, "read_file error\n"); return -1; } @@ -178,8 +186,8 @@ int read_webp(const char *fname, Animation *anim) { return 0; } -void write_file(const char *fname, uint8_t *data, size_t len) { - FILE *fp = fopen(fname, "wb"); +void write_file(const char *filename, uint8_t *data, size_t len) { + FILE *fp = fopen(filename, "wb"); assert(fp!=NULL); size_t written = fwrite(data, sizeof(uint8_t), len, fp); assert(written==len); @@ -192,7 +200,6 @@ Spritesheet gen_spritesheet(Animation *img, int cols) { if ((int)img->frame_count % cols > 0) { ++rows; } - uint8_t *out; size_t frame_size = img->width * img->height * sizeof(uint32_t); size_t line_size = img->width * sizeof(uint32_t); size_t full_line = line_size * cols; @@ -211,11 +218,6 @@ Spritesheet gen_spritesheet(Animation *img, int cols) { } } int stride = full_line; - //printf("stride: %d\n", stride); - //size_t encoded = WebPEncodeLosslessRGBA(merged_orig, img->width * cols, img->height * rows, stride, &out); - //printf("size: %zu, encoded: %zu\n", img->width*img->height*sizeof(uint32_t), encoded); - //assert(encoded!=0); - //WebPFree(out); Spritesheet ss = {0}; ss.data = merged_orig; ss.stride = stride; @@ -228,6 +230,20 @@ Spritesheet gen_spritesheet(Animation *img, int cols) { return ss; } +void write_webp(const char *path, Animation *img) { + Spritesheet ss = gen_spritesheet(img, cols); + uint8_t *out; + FILE *fp = fopen(path, "wb"); + assert(fp!=NULL); + size_t encoded = WebPEncodeLosslessRGBA(ss.data, ss.width, ss.height, ss.stride, &out); + printf("size: %zu, encoded: %zu\n", img->width*img->height*sizeof(uint32_t), encoded); + assert(encoded!=0); + size_t written = fwrite(out, sizeof(uint8_t), encoded, fp); + assert(written==encoded); + WebPFree(out); + free(ss.data); +} + int WinModalEvent(UIElement *element, UIMessage msg, int di, void *dp) { if (msg == UI_MSG_DESTROY) { printf("modal bye\n"); @@ -239,10 +255,22 @@ int WinModalEvent(UIElement *element, UIMessage msg, int di, void *dp) { int ButtonDialogSaveEvent(UIElement *element, UIMessage msg, int di, void *dp) { if (msg == UI_MSG_CLICKED) { + // get values of path and filename inputs + UITextbox *path_input = (UITextbox *)element->parent->children; + UITextbox *filename_input = (UITextbox *)path_input->e.next; + printf("path_input: %s\nfilename_input: %s\n", path_input->string, filename_input->string); + int path_len = strlen(path_input->string) + strlen(filename_input->string) + 2; // DIR_SEPARATOR and '\0' + printf("path_len: %d\n", path_len); + char out_name[path_len]; + int n = snprintf(out_name, PATH_MAX, "%s%c%s", path_input->string, DIR_SEPARATOR, filename_input->string); + printf("strlen(out_name): %d\n", strlen(out_name)); + printf("out_name: %s\n", out_name); + write_webp(out_name, img); + + printf("save dialog window close\n"); assert(element->window==modal_win); UIElementDestroy(element->window); - //modal_win = NULL; } return 0; } @@ -279,9 +307,12 @@ void ShowSaveWindow(UIWindow *parent) { UIPanel *panel_top = UIPanelCreate(&panel_out->e, UI_PANEL_GRAY|UI_PANEL_MEDIUM_SPACING|UI_PANEL_HORIZONTAL); UITextbox *path_input = UITextboxCreate(&panel_top->e, UI_ELEMENT_TAB_STOP|UI_ELEMENT_H_FILL); - UITextboxReplace(path_input, img->path, -1, false); - UITextbox *name_input = UITextboxCreate(&panel_top->e, UI_ELEMENT_TAB_STOP|UI_ELEMENT_H_FILL); - UITextboxReplace(name_input, "ehlo.webp", -1, false); + UITextboxReplace(path_input, img->dirname, -1, false); + UITextbox *filename_input = UITextboxCreate(&panel_top->e, UI_ELEMENT_TAB_STOP|UI_ELEMENT_H_FILL); + char out_name[strlen(img->filename)+7]; + int n = snprintf(out_name, NAME_MAX, "atlas_%s", img->filename); + assert(n>0); + UITextboxReplace(filename_input, out_name, -1, false); UIButton *btn_save = UIButtonCreate(&panel_top->e, UI_ELEMENT_TAB_STOP, "Save", -1); btn_save->e.messageUser = ButtonDialogSaveEvent; @@ -402,30 +433,38 @@ int WinMain(HINSTANCE instance, HINSTANCE previousInstance, LPSTR commandLine, i img = malloc(sizeof(Animation)); assert(img!=NULL); bzero(img, sizeof(Animation)); - char out_name[NAME_MAX-1]; img->path = realpath(argv[1], NULL); assert(img->path!=NULL); + printf("img->path: %s\n", img->path); int r = read_webp(img->path, img); assert(r==0); UILabelSetContent(lbl_title, img->path, -1); - char *in_name = basename(img->path); - char *in_dir = dirname(img->path); - int n = snprintf(out_name, NAME_MAX-1, "atlas_%s", in_name); + char *name_copy = strndup(img->path, PATH_MAX); + char *path_copy = strndup(img->path, PATH_MAX); + img->filename = strndup(basename(name_copy), NAME_MAX); + img->dirname = strndup(dirname(path_copy), PATH_MAX); + free(name_copy); + free(path_copy); + + char out_name[strlen(img->filename)+7]; + int n = snprintf(out_name, NAME_MAX, "atlas_%s", img->filename); assert(n>0); - printf("[%s/%s -> %s]\ncols: %d\ndimensions: %dx%dpx\nframes: %d\n", in_dir, in_name, out_name, cols, img->width, img->height, img->frame_count); + printf("[%s/%s -> %s]\ncols: %d\ndimensions: %dx%dpx\nframes: %d\n", img->dirname, img->filename, out_name, cols, img->width, img->height, img->frame_count); update_preview(img_disp); //@todo cleanup on new image load! //free(img->path); + //free(img->dirname); + //free(img->filename); //free(img); // temporary return UIMessageLoop(); - //write_webp(out_name, img, cols); + //write_webp(out_name, img); return 0; }