commit 0b1662e3fee888fddaa09c8fb362f05de9b5108e
Author: bsandro <[email protected]>
Date: Wed, 3 May 2023 01:01:42 +0300
Basic reading webp info
Diffstat:
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;
+}