# 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}
--- /dev/null
+#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;
+}
#include <X11/keysym.h>
#include "format/png.h"
+#include "format/webp.h"
int XErrorHandlerd(Display *d, XErrorEvent *event) {
char error_text[120];
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");