フォーク元 suwako/mivfx
最初コミット
このコミットが含まれているのは:
コミット
d040da7c87
|
@ -0,0 +1 @@
|
|||
mivfx
|
|
@ -0,0 +1,24 @@
|
|||
NAME=mivfx
|
||||
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
|
||||
CFLAGS=-Wall -Wextra -g
|
||||
LDFLAGS=-lX11 -lpng
|
||||
|
||||
all:
|
||||
${CC} ${CFLAGS} -o ${NAME} ${FILES} ${LDFLAGS}
|
||||
|
||||
clean:
|
||||
rm -f ${NAME}
|
||||
|
||||
install: all
|
||||
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||
cp -f ${NAME} ${DESTDIR}${PREFIX}/bin
|
||||
chmod 755 ${DESTDIR}${PREFIX}/bin/${NAME}
|
||||
|
||||
uninstall:
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/${NAME}
|
||||
|
||||
.PHONY: all clean install uninstall
|
|
@ -0,0 +1,78 @@
|
|||
#include "png.h"
|
||||
|
||||
XImage* read_png(Display *d, const char *filename) {
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
if (!fp) {
|
||||
perror("ファイルを開けられません。");
|
||||
return NULL;
|
||||
}
|
||||
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
png_infop info = png_create_info_struct(png);
|
||||
|
||||
png_init_io(png, fp);
|
||||
png_read_info(png, info);
|
||||
|
||||
int width = png_get_image_width(png, info);
|
||||
int height = png_get_image_height(png, info);
|
||||
int bit_depth = png_get_bit_depth(png, info);
|
||||
int color_type = png_get_color_type(png, info);
|
||||
|
||||
if (bit_depth == 16) {
|
||||
png_set_strip_16(png);
|
||||
}
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
png_set_palette_to_rgb(png);
|
||||
}
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
|
||||
png_set_expand_gray_1_2_4_to_8(png);
|
||||
}
|
||||
if (png_get_valid(png, info, PNG_INFO_tRNS)) {
|
||||
png_set_tRNS_to_alpha(png);
|
||||
}
|
||||
if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
|
||||
}
|
||||
|
||||
png_read_update_info(png, info);
|
||||
|
||||
png_bytep *row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
|
||||
for (int y = 0; y < height; y++) {
|
||||
row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png, info));
|
||||
}
|
||||
|
||||
png_read_image(png, row_pointers);
|
||||
|
||||
char *imgdata = malloc(4 * width * height);
|
||||
char *dst = imgdata;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
png_bytep row = row_pointers[y];
|
||||
for (int x = 0; x < width; x++) {
|
||||
png_bytep px = &(row[x * 4]);
|
||||
*dst++ = px[2]; // 青
|
||||
*dst++ = px[1]; // 緑
|
||||
*dst++ = px[0]; // 赤
|
||||
*dst++ = px[3]; // 透明
|
||||
}
|
||||
}
|
||||
|
||||
// 掃除
|
||||
for (int y = 0; y < height; y++) {
|
||||
free(row_pointers[y]);
|
||||
}
|
||||
free(row_pointers);
|
||||
|
||||
png_destroy_read_struct(&png, &info, NULL);
|
||||
fclose(fp);
|
||||
|
||||
// XImageを創作
|
||||
XImage* img = XCreateImage(d, CopyFromParent, 24, ZPixmap, 0, imgdata, width, height, 32, 0);
|
||||
if (img == NULL) {
|
||||
free(imgdata);
|
||||
fprintf(stderr, "PNGのXImageを創作に失敗しました。\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef _PNG_H
|
||||
#define _PNG_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <png.h>
|
||||
|
||||
XImage* read_png(Display *d, const char *filename);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,103 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#include "format/png.h"
|
||||
|
||||
int XErrorHandlerd(Display *d, XErrorEvent *event) {
|
||||
char error_text[120];
|
||||
XGetErrorText(d, event->error_code, error_text, sizeof(error_text));
|
||||
fprintf(stderr, "Xエラー: %s\n", error_text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XImage* openimg(Display *d, const char *filename) {
|
||||
FILE *fp;
|
||||
fp = fopen(filename, "rb");
|
||||
if (!fp) {
|
||||
perror("ファイルを開けられません。");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned char buf[16];
|
||||
fread(buf, 1, 16, fp);
|
||||
fclose(fp);
|
||||
|
||||
if (memcmp(buf, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8) == 0) { // PNG
|
||||
return read_png(d, filename);
|
||||
}
|
||||
|
||||
fprintf(stderr, "不明なファイル種類。\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
XSetErrorHandler(XErrorHandlerd);
|
||||
if (argc < 2) {
|
||||
printf("使用方法: %s <画像ファイル>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Display *d = XOpenDisplay(NULL);
|
||||
if (d == NULL) {
|
||||
fprintf(stderr, "画面を開けられません。\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int scr = DefaultScreen(d);
|
||||
Window w = XCreateSimpleWindow(d, RootWindow(d, scr), 0, 0, 500, 500, 1, BlackPixel(d, scr), WhitePixel(d, scr));
|
||||
XSelectInput(d, w, ExposureMask | KeyPressMask);
|
||||
XMapWindow(d, w);
|
||||
XFlush(d);
|
||||
|
||||
GC gc = XCreateGC(d, w, 0, NULL);
|
||||
if (gc == NULL) {
|
||||
fprintf(stderr, "グラフィックス内容を創作に失敗しました。\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
XImage *ximg = openimg(d, argv[1]);
|
||||
if (ximg == NULL) {
|
||||
fprintf(stderr, "画像を開けられません: %s\n", argv[1]);
|
||||
XFreeGC(d, gc);
|
||||
XCloseDisplay(d);
|
||||
return 1;
|
||||
}
|
||||
|
||||
double scale = 1.0;
|
||||
|
||||
while (1) {
|
||||
XEvent e;
|
||||
XNextEvent(d, &e);
|
||||
|
||||
if (e.type == Expose) {
|
||||
int nw = (int)(ximg->width * scale);
|
||||
int nh = (int)(ximg->height * scale);
|
||||
XPutImage(d, w, gc, ximg, 0, 0, 0, 0, nw, nh);
|
||||
}
|
||||
|
||||
if (e.type == KeyPress) {
|
||||
XWindowAttributes attrs;
|
||||
XGetWindowAttributes(d, w, &attrs);
|
||||
|
||||
KeySym keysym = XLookupKeysym(&e.xkey, 0);
|
||||
|
||||
if (keysym == XK_q) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 掃除
|
||||
XFreeGC(d, gc);
|
||||
XDestroyImage(ximg);
|
||||
XDestroyWindow(d, w);
|
||||
XCloseDisplay(d);
|
||||
|
||||
return 0;
|
||||
}
|
読み込み中…
新しいイシューから参照