emote2ss

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

commit 0b1662e3fee888fddaa09c8fb362f05de9b5108e
Author: bsandro <[email protected]>
Date:   Wed,  3 May 2023 01:01:42 +0300

Basic reading webp info

Diffstat:
A.gitignore | 2++
AFlanClap.webp | 0
AMakefile | 26++++++++++++++++++++++++++
Asrc/main.c | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 144 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,2 @@ +emote2ss +*.o diff --git a/FlanClap.webp b/FlanClap.webp Binary files differ. diff --git a/Makefile b/Makefile @@ -0,0 +1,26 @@ +NAME=$(shell basename ${PWD}) +SRC=$(wildcard *.c src/*.c) +DEPS:=$(wildcard *.h src/*.h) +OBJ:=$(SRC:.c=.o) +LIBS:=libwebp libwebpdecoder libwebpdemux +CFLAGS=-Og -g -std=c99 -Werror -Wall -Wextra -I. -I./src/ ${shell pkg-config --cflags $(LIBS)} +LDFLAGS=-lc ${shell pkg-config --libs $(LIBS)} + +all: $(NAME) + +.PHONY: clean run test + +clean: + @rm -f $(OBJ) $(NAME) + +%.o : %.c $(DEPS) + @$(CC) $(CFLAGS) -c $< -o $@ + +$(NAME): $(OBJ) + @$(CC) $(OBJ) -o $@ $(LDFLAGS) + +run: $(NAME) + @./$(NAME) + +test: $(NAME) + @./$(NAME) FlanClap.webp diff --git a/src/main.c b/src/main.c @@ -0,0 +1,116 @@ +#include <stdio.h> +#include "webp/decode.h" +#include "webp/demux.h" +#include <stdbool.h> +#include <stdlib.h> + +static void print_webp_version() { + int dec_ver = WebPGetDecoderVersion(); + int demux_ver = WebPGetDemuxVersion(); + printf("---------------------------\n"); + printf("webp decoder version: %d.%d.%d\n", (dec_ver>>16)&0xff, (dec_ver>>8)&0xff, dec_ver&0xff); + printf("webp demuxer version: %d.%d.%d\n", (demux_ver>>16)&0xff, (demux_ver>>8)&0xff, demux_ver&0xff); +} + +typedef struct { + uint8_t *rgba; + int duration; + bool is_key; +} DecodedFrame; + +typedef struct { + int width, height, bgcolor, loop_count; + DecodedFrame *frames; + uint32_t frames_count; + void *raw_mem; +} AnimatedImage; + +int read_file(const char *fname, const uint8_t **data, size_t *size) { + if (data == NULL || size == NULL) return -1; + *data = NULL; + *size = 0; + FILE *infile = fopen(fname, "rb"); + if (infile == NULL) { + fprintf(stderr, "cannot open file %s\n", fname); + return -1; + } + fseek(infile, 0, SEEK_END); + size_t fsize = ftell(infile); + printf("%s: %zu bytes\n", fname, fsize); + fseek(infile, 0, SEEK_SET); + + uint8_t *fdata = malloc(fsize+1); + if (fdata == NULL) { + fclose(infile); + fprintf(stderr, "malloc failed\n"); + return -1; + } + fdata[fsize] = '\0'; + int ok = (fread(fdata, fsize, 1, infile)==1); + fclose(infile); + + if (!ok) { + fprintf(stderr, "cannot read file %s (%d)\n", fname, ok); + free(fdata); + return -1; + } + + *data = fdata; + *size = fsize; + + return 0; +} + +int read_webp(const char *fname, AnimatedImage *anim) { + printf("read_webp(%s)\n", fname); + + WebPData webp_data; + WebPDataInit(&webp_data); + + if (read_file(fname, &webp_data.bytes, &webp_data.size) == -1) { + fprintf(stderr, "read_file 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); + if (dec == NULL) { + fprintf(stderr, "decoder error\n"); + // @todo cleanup + return -1; + } + + WebPAnimInfo anim_info; + if (!WebPAnimDecoderGetInfo(dec, &anim_info)) { + fprintf(stderr, "error decoding animation info\n"); + // @todo cleanup + return -1; + } + anim->frames_count = anim_info.frame_count; + anim->width = anim_info.canvas_width; + anim->height = anim_info.canvas_height; + anim->loop_count = anim_info.loop_count; + anim->bgcolor = anim_info.bgcolor; + + WebPDataClear(&webp_data); + return 0; +} + +int main(int argc, const char **argv) { + atexit(print_webp_version); + + if (argc >= 1) { + for (int i=1; i<argc; ++i) { + AnimatedImage anim = {0}; + read_webp(argv[i], &anim); + printf("dimensions: %dx%d\nframes: %d\n", anim.width, anim.height, anim.frames_count); + } + } + + return 0; +}