#include #include #define STB_IMAGE_IMPLEMENTATION #include "../dep/stb_image.hh" #include #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 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の作成に失敗。"); } }