From 5ea4944aa25580bf73e6c70a5a1e038e77e01aea Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E8=AB=8F=E8=A8=AA=E5=AD=90?= Date: Tue, 24 Oct 2023 20:39:40 +0900 Subject: [PATCH] =?utf8?q?WEBP=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Makefile | 4 ++-- format/webp.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ format/webp.h | 11 +++++++++++ main.c | 3 +++ 4 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 format/webp.c create mode 100644 format/webp.h diff --git a/Makefile b/Makefile index 530f3ec..49b7d81 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,9 @@ VERSION=0.1.0 # Linux、Haiku、かIllumos = /usr、FreeBSDかOpenBSD = /usr/local、NetBSD = /usr/pkg PREFIX=/usr CC=cc -FILES=main.c format/png.c +FILES=main.c format/png.c format/webp.c CFLAGS=-Wall -Wextra -g -LDFLAGS=-lX11 -lpng +LDFLAGS=-lX11 -lpng -lwebp all: ${CC} ${CFLAGS} -o ${NAME} ${FILES} ${LDFLAGS} diff --git a/format/webp.c b/format/webp.c new file mode 100644 index 0000000..8f7c423 --- /dev/null +++ b/format/webp.c @@ -0,0 +1,50 @@ +#include "webp.h" + +XImage* read_webp(Display *d, const char *filename) { + FILE *fp = fopen(filename, "rb"); + if (!fp) { + perror("ファイルを開けられません。"); + return NULL; + } + + fseek(fp, 0, SEEK_END); + size_t filesize = ftell(fp); + fseek(fp, 0, SEEK_SET); + + uint8_t *data = malloc(filesize); + fread(data, filesize, 1, fp); + fclose(fp); + + int width, height; + uint8_t *imgdata = WebPDecodeRGBA(data, filesize, &width, &height); + free(data); + + if (imgdata == NULL) { + fprintf(stderr, "WEBP画像を逆符号化に失敗しました。\n"); + return NULL; + } + + // RGBAからARGBに交換(X11の為) + uint32_t *argbdata = malloc(4 * width * height); + uint32_t *dest = argbdata; + uint8_t *src = imgdata; + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + uint8_t r = *src++; + uint8_t g = *src++; + uint8_t b = *src++; + uint8_t a = *src++; + *dest++ = (a << 24) | (r << 16) | (g << 8) | b; + } + } + free(imgdata); + + XImage* img = XCreateImage(d, CopyFromParent, 24, ZPixmap, 0, (char*)argbdata, width, height, 32, 0); + if (img == NULL) { + free(argbdata); + fprintf(stderr, "WEBPのXImageを創作に失敗しました。\n"); + return NULL; + } + + return img; +} diff --git a/format/webp.h b/format/webp.h new file mode 100644 index 0000000..fa83d58 --- /dev/null +++ b/format/webp.h @@ -0,0 +1,11 @@ +#ifndef _WEBP_H +#define _WEBP_H + +#include +#include +#include +#include + +XImage* read_webp(Display *d, const char *filename); + +#endif diff --git a/main.c b/main.c index 7ce2d63..c9a528d 100644 --- a/main.c +++ b/main.c @@ -8,6 +8,7 @@ #include #include "format/png.h" +#include "format/webp.h" int XErrorHandlerd(Display *d, XErrorEvent *event) { char error_text[120]; @@ -30,6 +31,8 @@ XImage* openimg(Display *d, const char *filename) { if (memcmp(buf, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8) == 0) { // PNG return read_png(d, filename); + } else if (memcmp(buf + 8, "WEBP", 4) == 0) { // WEBP + return read_webp(d, filename); } fprintf(stderr, "不明なファイル種類。\n"); -- 2.43.0