SVNからのミラー
This commit is contained in:
78
src/uw/image.cc
Normal file
78
src/uw/image.cc
Normal file
@@ -0,0 +1,78 @@
|
||||
#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の作成に失敗。");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user