commit ca53d7d32806bb43437c9c401bb1ae32215ab960
parent 0960303193e14f0e7492df1819da4680b6044f0b
Author: bsandro <email@bsandro.tech>
Date: Mon, 28 Aug 2023 23:48:45 +0300
began splitting source code into different files
Diffstat:
A | gui/animation.c | | | 135 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | gui/animation.h | | | 24 | ++++++++++++++++++++++++ |
M | gui/main.c | | | 146 | ++++--------------------------------------------------------------------------- |
3 files changed, 166 insertions(+), 139 deletions(-)
diff --git a/gui/animation.c b/gui/animation.c
@@ -0,0 +1,135 @@
+#define _GNU_SOURCE
+
+#include "animation.h"
+#include <libgen.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <strings.h>
+#include "webp/decode.h"
+#include "webp/demux.h"
+
+#ifdef __OpenBSD__
+#include <sys/syslimits.h>
+#endif
+
+#ifdef __linux__
+#include <linux/limits.h>
+#endif
+
+Animation * ImageLoad(const char *path) {
+ Animation *img = malloc(sizeof(Animation));
+ assert(img!=NULL);
+ bzero(img, sizeof(Animation));
+ img->path = realpath(path, NULL);
+ assert(img->path!=NULL);
+ printf("img->path: %s\n", img->path);
+ int r = WebpRead(img->path, img);
+ assert(r==0);
+
+ 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);
+
+ //printf("[%s/%s]\ncols: %d\ndimensions: %dx%dpx\nframes: %d\n", img->dirname, img->filename, cols, img->width, img->height, img->frame_count);
+
+ return img;
+}
+
+void ImageUnload(Animation **img) {
+ free((*img)->path);
+ free((*img)->dirname);
+ free((*img)->filename);
+ free(*img);
+ *img = NULL;
+}
+
+int WebpRead(const char *filename, Animation *anim) {
+ printf("WebpRead(%s)\n", filename);
+
+ WebPData webp_data;
+ WebPDataInit(&webp_data);
+
+ if (ReadFile(filename, &webp_data.bytes, &webp_data.size) == -1) {
+ fprintf(stderr, "ReadFile error\n");
+ return -1;
+ }
+
+ if (!WebPGetInfo(webp_data.bytes, webp_data.size, NULL, NULL)) {
+ fprintf(stderr, "invalid webp\n");
+ WebPDataClear(&webp_data);
+ return -1;
+ }
+
+ WebPAnimDecoder *dec = WebPAnimDecoderNew(&webp_data, NULL);
+ assert(dec != NULL);
+
+ WebPAnimInfo anim_info;
+ if (!WebPAnimDecoderGetInfo(dec, &anim_info)) {
+ fprintf(stderr, "error decoding animation info\n");
+ // @todo cleanup
+ return -1;
+ }
+
+ anim->width = anim_info.canvas_width;
+ anim->height = anim_info.canvas_height;
+ anim->loop_count = anim_info.loop_count;
+ anim->bgcolor = anim_info.bgcolor;
+ AnimationCreate(anim, anim_info.frame_count);
+
+ uint32_t frame_index = 0;
+ int prev_ts = 0;
+ while (WebPAnimDecoderHasMoreFrames(dec)) {
+ Frame *frame;
+ uint8_t *curr_rgba, *frame_rgba;
+ int ts;
+ if (!WebPAnimDecoderGetNext(dec, &frame_rgba, &ts)) {
+ fprintf(stderr, "error decoding frame %d\n", frame_index);
+ return -1;
+ }
+ assert(frame_index < anim_info.frame_count);
+ frame = &anim->frames[frame_index];
+ curr_rgba = frame->rgba;
+ frame->duration = ts - prev_ts;
+ memcpy(curr_rgba, frame_rgba, anim->width * anim->height * NUM_CHANNELS);
+ // ... <- nani kore?
+ ++frame_index;
+ prev_ts = ts;
+ }
+
+ WebPDataClear(&webp_data);
+ WebPAnimDecoderDelete(dec);
+ return 0;
+}
+
+void AnimationCreate(Animation *img, uint32_t frame_count) {
+ assert(frame_count > 0);
+ uint8_t *mem = NULL;
+ Frame *frames = NULL;
+ const uint64_t rgba_size = img->width * img->height * NUM_CHANNELS;
+ const uint64_t img_size = frame_count * rgba_size * sizeof(uint8_t);
+ const uint64_t frames_size = frame_count * sizeof(Frame);
+
+ assert(img_size == (size_t)img_size);
+ assert(frames_size == (size_t)frames_size);
+
+ printf("img mem: %" PRIu64 "\nframes mem: %" PRIu64 "\n", img_size, frames_size);
+
+ mem = malloc(img_size);
+ frames = malloc(frames_size);
+ assert(mem != NULL);
+ assert(frames != NULL);
+
+ for (uint32_t i=0; i<frame_count; ++i) {
+ frames[i].rgba = mem+i*rgba_size;
+ frames[i].duration = 0;
+ frames[i].is_key = false;
+ }
+ img->frame_count = frame_count;
+ img->frames = frames;
+ img->raw_mem = mem;
+}
diff --git a/gui/animation.h b/gui/animation.h
@@ -0,0 +1,24 @@
+#include <stdbool.h>
+#include <stdint.h>
+
+#define NUM_CHANNELS 4
+
+typedef struct {
+ uint8_t *rgba;
+ int duration;
+ bool is_key;
+} Frame;
+
+typedef struct {
+ int width, height, bgcolor, loop_count;
+ Frame *frames;
+ uint32_t frame_count;
+ void *raw_mem;
+ char *path;
+ char *dirname;
+ char *filename;
+} Animation;
+
+Animation * ImageLoad(const char *path);
+void ImageUnload(Animation **img);
+int WebpRead(const char *filename, Animation *anim);
diff --git a/gui/main.c b/gui/main.c
@@ -2,7 +2,7 @@
* Loosely based on the libwebp example program "anim_dump"
*/
-#define _GNU_SOURCE
+// #define _GNU_SOURCE
// moved into the compiler command line arguments
// #define UI_LINUX
@@ -20,6 +20,8 @@
#include <assert.h>
#include "luigi.h"
+#include "animation.h"
+
#ifdef __OpenBSD__
#include <sys/syslimits.h>
#endif
@@ -34,7 +36,6 @@
#define DIR_SEPARATOR '/'
#endif
-#define NUM_CHANNELS 4
#define WIN_WIDTH 750
#define WIN_HEIGHT 400
@@ -54,22 +55,6 @@ typedef struct {
int width, height, stride;
} Spritesheet;
-typedef struct {
- uint8_t *rgba;
- int duration;
- bool is_key;
-} Frame;
-
-typedef struct {
- int width, height, bgcolor, loop_count;
- Frame *frames;
- uint32_t frame_count;
- void *raw_mem;
- char *path;
- char *dirname;
- char *filename;
-} Animation;
-
// let it be global variable for now
static Animation *img = NULL;
static int cols = 1;
@@ -78,38 +63,11 @@ static UIImageDisplay *img_disp = NULL;
static UILabel *lbl_header = NULL;
//@todo headers!
-Animation * ImageLoad(const char *);
-void ImageUnload(Animation **);
+//Animation * ImageLoad(const char *);
+//void ImageUnload(Animation **);
void PreviewUpdate(Animation *, UIImageDisplay *);
-void AnimationCreate(Animation *img, uint32_t frame_count) {
- assert(frame_count > 0);
- uint8_t *mem = NULL;
- Frame *frames = NULL;
- const uint64_t rgba_size = img->width * img->height * NUM_CHANNELS;
- const uint64_t img_size = frame_count * rgba_size * sizeof(uint8_t);
- const uint64_t frames_size = frame_count * sizeof(Frame);
-
- assert(img_size == (size_t)img_size);
- assert(frames_size == (size_t)frames_size);
-
- printf("img mem: %" PRIu64 "\nframes mem: %" PRIu64 "\n", img_size, frames_size);
-
- mem = malloc(img_size);
- frames = malloc(frames_size);
- assert(mem != NULL);
- assert(frames != NULL);
-
- for (uint32_t i=0; i<frame_count; ++i) {
- frames[i].rgba = mem+i*rgba_size;
- frames[i].duration = 0;
- frames[i].is_key = false;
- }
- img->frame_count = frame_count;
- img->frames = frames;
- img->raw_mem = mem;
-}
-
+// @todo collision with ms windows function
int ReadFile(const char *filename, const uint8_t **data, size_t *size) {
assert(data != NULL);
assert(size != NULL);
@@ -139,64 +97,6 @@ int ReadFile(const char *filename, const uint8_t **data, size_t *size) {
return 0;
}
-int WebpRead(const char *filename, Animation *anim) {
- printf("WebpRead(%s)\n", filename);
-
- WebPData webp_data;
- WebPDataInit(&webp_data);
-
- if (ReadFile(filename, &webp_data.bytes, &webp_data.size) == -1) {
- fprintf(stderr, "ReadFile error\n");
- return -1;
- }
-
- if (!WebPGetInfo(webp_data.bytes, webp_data.size, NULL, NULL)) {
- fprintf(stderr, "invalid webp\n");
- WebPDataClear(&webp_data);
- return -1;
- }
-
- WebPAnimDecoder *dec = WebPAnimDecoderNew(&webp_data, NULL);
- assert(dec != NULL);
-
- WebPAnimInfo anim_info;
- if (!WebPAnimDecoderGetInfo(dec, &anim_info)) {
- fprintf(stderr, "error decoding animation info\n");
- // @todo cleanup
- return -1;
- }
-
- anim->width = anim_info.canvas_width;
- anim->height = anim_info.canvas_height;
- anim->loop_count = anim_info.loop_count;
- anim->bgcolor = anim_info.bgcolor;
- AnimationCreate(anim, anim_info.frame_count);
-
- uint32_t frame_index = 0;
- int prev_ts = 0;
- while (WebPAnimDecoderHasMoreFrames(dec)) {
- Frame *frame;
- uint8_t *curr_rgba, *frame_rgba;
- int ts;
- if (!WebPAnimDecoderGetNext(dec, &frame_rgba, &ts)) {
- fprintf(stderr, "error decoding frame %d\n", frame_index);
- return -1;
- }
- assert(frame_index < anim_info.frame_count);
- frame = &anim->frames[frame_index];
- curr_rgba = frame->rgba;
- frame->duration = ts - prev_ts;
- memcpy(curr_rgba, frame_rgba, anim->width * anim->height * NUM_CHANNELS);
- // ... <- nani kore?
- ++frame_index;
- prev_ts = ts;
- }
-
- WebPDataClear(&webp_data);
- WebPAnimDecoderDelete(dec);
- return 0;
-}
-
Spritesheet GenSpritesheet(Animation *img, int cols) {
int rows = (int)img->frame_count / cols;
if ((int)img->frame_count % cols > 0) {
@@ -303,7 +203,7 @@ int ButtonDialogOpenEvent(UIElement *element, UIMessage msg, int di, void *dp) {
img = ImageLoad(filepath);
assert(img!=NULL);
PreviewUpdate(img, img_disp);
-
+ UILabelSetContent(lbl_header, img->path, -1);
}
return 0;
}
@@ -445,38 +345,6 @@ int WinMainEvent(UIElement *element, UIMessage msg, int di, void *dp) {
return 0;
}
-void ImageUnload(Animation **img) {
- free((*img)->path);
- free((*img)->dirname);
- free((*img)->filename);
- free(*img);
- *img = NULL;
-}
-
-Animation * ImageLoad(const char *path) {
- Animation *img = malloc(sizeof(Animation));
- assert(img!=NULL);
- bzero(img, sizeof(Animation));
- img->path = realpath(path, NULL);
- assert(img->path!=NULL);
- printf("img->path: %s\n", img->path);
- int r = WebpRead(img->path, img);
- assert(r==0);
-
- 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);
-
- printf("[%s/%s]\ncols: %d\ndimensions: %dx%dpx\nframes: %d\n", img->dirname, img->filename, cols, img->width, img->height, img->frame_count);
-
- UILabelSetContent(lbl_header, img->path, -1);
-
- return img;
-}
-
#ifdef UI_LINUX
int main(int argc, const char **argv) {
#else