mirror of
https://github.com/hyprwm/hyprgraphics.git
synced 2026-05-04 22:17:59 +02:00
pngs can now be embedded
This commit is contained in:
parent
b3d628d016
commit
bba4596882
4 changed files with 79 additions and 1 deletions
|
|
@ -6,10 +6,15 @@
|
|||
#include <hyprutils/memory/SharedPtr.hpp>
|
||||
|
||||
namespace Hyprgraphics {
|
||||
enum ImageFormat {
|
||||
PNG
|
||||
};
|
||||
|
||||
class CImage {
|
||||
public:
|
||||
// create an image from a provided path.
|
||||
CImage(const std::string& path);
|
||||
CImage(const unsigned char*, size_t, ImageFormat);
|
||||
~CImage();
|
||||
|
||||
CImage(const CImage&) = delete;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,30 @@
|
|||
using namespace Hyprgraphics;
|
||||
using namespace Hyprutils::Memory;
|
||||
|
||||
Hyprgraphics::CImage::CImage(const unsigned char* data, size_t size, ImageFormat format) {
|
||||
std::expected<cairo_surface_t*, std::string> CAIROSURFACE;
|
||||
if (format == ImageFormat::PNG) {
|
||||
CAIROSURFACE = PNG::createSurfaceFromPNG(data, size);
|
||||
mime = "image/png";
|
||||
} else {
|
||||
lastError = "Currently only PNG images are supported for embedding";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CAIROSURFACE) {
|
||||
lastError = CAIROSURFACE.error();
|
||||
return;
|
||||
}
|
||||
|
||||
if (const auto STATUS = cairo_surface_status(*CAIROSURFACE); STATUS != CAIRO_STATUS_SUCCESS) {
|
||||
lastError = std::format("Could not create surface: {}", cairo_status_to_string(STATUS));
|
||||
return;
|
||||
}
|
||||
|
||||
loadSuccess = true;
|
||||
pCairoSurface = makeShared<CCairoSurface>(CAIROSURFACE.value());
|
||||
}
|
||||
|
||||
Hyprgraphics::CImage::CImage(const std::string& path) : filepath(path) {
|
||||
std::expected<cairo_surface_t*, std::string> CAIROSURFACE;
|
||||
const auto len = path.length();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "Png.hpp"
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <cstdint>
|
||||
|
|
@ -32,6 +33,50 @@ std::expected<cairo_surface_t*, std::string> PNG::createSurfaceFromPNG(const std
|
|||
return std::unexpected("loading png: couldn't setjmp");
|
||||
|
||||
png_init_io(png, fp);
|
||||
|
||||
return loadPNG(png, info);
|
||||
}
|
||||
|
||||
struct MemoryReadState {
|
||||
const unsigned char* data;
|
||||
size_t size;
|
||||
size_t offset;
|
||||
};
|
||||
|
||||
void custom_read_function(png_structp png, png_bytep data, png_size_t length) {
|
||||
MemoryReadState* state = static_cast<MemoryReadState*>(png_get_io_ptr(png));
|
||||
if (state->offset + length > state->size) {
|
||||
png_error(png, "read error");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(data, state->data + state->offset, length);
|
||||
state->offset += length;
|
||||
}
|
||||
|
||||
std::expected<cairo_surface_t*, std::string> PNG::createSurfaceFromPNG(const unsigned char* data, size_t size) {
|
||||
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
png_infop info = png_create_info_struct(png);
|
||||
if (!png || !info)
|
||||
return std::unexpected("loading png: couldn't init libpng");
|
||||
|
||||
CScopeGuard x([&png, &info] { png_destroy_read_struct(&png, &info, nullptr); });
|
||||
|
||||
if (setjmp(png_jmpbuf(png)))
|
||||
return std::unexpected("loading png: couldn't setjmp");
|
||||
|
||||
MemoryReadState readState;
|
||||
readState.data = reinterpret_cast<const unsigned char*>(data);
|
||||
readState.size = size;
|
||||
readState.offset = 0;
|
||||
|
||||
png_set_read_fn(png, &readState, custom_read_function);
|
||||
png_set_sig_bytes(png, 0);
|
||||
|
||||
return loadPNG(png, info);
|
||||
}
|
||||
|
||||
static std::expected<cairo_surface_t*, std::string> loadPNG(png_structp png, png_infop info) {
|
||||
png_read_info(png, info);
|
||||
|
||||
const size_t W = png_get_image_width(png, info);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@
|
|||
#include <cairo/cairo.h>
|
||||
#include <string>
|
||||
#include <expected>
|
||||
#include <png.h>
|
||||
|
||||
namespace PNG {
|
||||
std::expected<cairo_surface_t*, std::string> createSurfaceFromPNG(const std::string&);
|
||||
};
|
||||
std::expected<cairo_surface_t*, std::string> createSurfaceFromPNG(const unsigned char*, size_t);
|
||||
};
|
||||
|
||||
static std::expected<cairo_surface_t*, std::string> loadPNG(png_structp, png_infop);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue