79 lines
2.2 KiB
C++
79 lines
2.2 KiB
C++
#include <X11/Xlib.h>
|
|
#include <string>
|
|
#define STB_IMAGE_IMPLEMENTATION
|
|
#include "../dep/stb_image.hh"
|
|
|
|
#include <stdexcept>
|
|
|
|
#include "image.hh"
|
|
|
|
namespace uw {
|
|
Image::Image(Screen &screen, const std::string imgPath) : uwScreen{ screen } {
|
|
if (imgPath.empty()) throw std::runtime_error("画像パスが空です。");
|
|
|
|
data = stbi_load(imgPath.c_str(), &width, &height, &chan, 4);
|
|
if (!data) throw std::runtime_error("画像の読み込みに失敗: " + imgPath);
|
|
|
|
imageExtent.width = width;
|
|
imageExtent.height = height;
|
|
imagePath = imgPath;
|
|
|
|
v = DefaultVisual(screen.getDisplay(), screen.getScreen());
|
|
|
|
createDepth();
|
|
createPixmap();
|
|
createImage();
|
|
createGC();
|
|
}
|
|
|
|
Image::~Image() {
|
|
if (gc) XFreeGC(uwScreen.getDisplay(), gc);
|
|
if (pm) XFreePixmap(uwScreen.getDisplay(), pm);
|
|
if (image) XFree(image);
|
|
if (data) stbi_image_free(data);
|
|
}
|
|
|
|
void Image::createDepth() {
|
|
depth = DefaultDepth(uwScreen.getDisplay(), uwScreen.getScreen());
|
|
|
|
if (depth != 24 && depth != 32) {
|
|
throw std::runtime_error(
|
|
"「" + std::to_string(depth) + "」の様な視覚の深さは未対応です。");
|
|
}
|
|
|
|
imageExtent.depth = depth;
|
|
}
|
|
|
|
void Image::createPixmap() {
|
|
pm = XCreatePixmap(uwScreen.getDisplay(), uwScreen.getWindow(), width, height,
|
|
depth);
|
|
}
|
|
|
|
void Image::createImage() {
|
|
if (depth == 24) {
|
|
std::vector<uchar> cd(data, data + (width * height * 4));
|
|
cdata = cd;
|
|
|
|
for (int i = 0; i < width * height; i++) {
|
|
cdata[i * 4 + 0] = data[i * 4 + 2];
|
|
cdata[i * 4 + 1] = data[i * 4 + 1];
|
|
cdata[i * 4 + 2] = data[i * 4 + 0];
|
|
cdata[i * 4 + 3] = data[i * 4 + 3];
|
|
}
|
|
|
|
image = XCreateImage(uwScreen.getDisplay(), v, depth, ZPixmap, 0,
|
|
(char *)cdata.data(), width, height, 32, 0);
|
|
} else {
|
|
image = XCreateImage(uwScreen.getDisplay(), v, depth, ZPixmap, 0,
|
|
(char *)data, width, height, 32, 0);
|
|
}
|
|
|
|
if (!image) throw std::runtime_error("XImageの作成に失敗。");
|
|
}
|
|
|
|
void Image::createGC() {
|
|
gc = XCreateGC(uwScreen.getDisplay(), pm, 0, nullptr);
|
|
if (!gc) throw std::runtime_error("GCの作成に失敗。");
|
|
}
|
|
}
|