diff --git a/src/image/Image.cpp b/src/image/Image.cpp index f87d088..6844f90 100644 --- a/src/image/Image.cpp +++ b/src/image/Image.cpp @@ -17,23 +17,23 @@ Hyprgraphics::CImage::CImage(const std::string& path) : filepath(path) { const auto len = path.length(); if (path.find(".png") == len - 4 || path.find(".PNG") == len - 4) { CAIROSURFACE = PNG::createSurfaceFromPNG(path); - mime = "image/png"; + mime = "image/png"; } else if (path.find(".jpg") == len - 4 || path.find(".JPG") == len - 4 || path.find(".jpeg") == len - 5 || path.find(".JPEG") == len - 5) { CAIROSURFACE = JPEG::createSurfaceFromJPEG(path); imageHasAlpha = false; - mime = "image/jpeg"; + mime = "image/jpeg"; } else if (path.find(".bmp") == len - 4 || path.find(".BMP") == len - 4) { CAIROSURFACE = BMP::createSurfaceFromBMP(path); imageHasAlpha = false; - mime = "image/bmp"; + mime = "image/bmp"; } else if (path.find(".webp") == len - 5 || path.find(".WEBP") == len - 5) { CAIROSURFACE = WEBP::createSurfaceFromWEBP(path); - mime = "image/webp"; + mime = "image/webp"; } else if (path.find(".jxl") == len - 4 || path.find(".JXL") == len - 4) { #ifdef JXL_FOUND CAIROSURFACE = JXL::createSurfaceFromJXL(path); - mime = "image/jxl"; + mime = "image/jxl"; #else lastError = "hyprgraphics compiled without JXL support"; return; @@ -49,15 +49,15 @@ Hyprgraphics::CImage::CImage(const std::string& path) : filepath(path) { if (first_word == "PNG") { CAIROSURFACE = PNG::createSurfaceFromPNG(path); - mime = "image/png"; + mime = "image/png"; } else if (first_word == "JPEG") { CAIROSURFACE = JPEG::createSurfaceFromJPEG(path); imageHasAlpha = false; - mime = "image/jpeg"; + mime = "image/jpeg"; } else if (first_word == "BMP") { CAIROSURFACE = BMP::createSurfaceFromBMP(path); imageHasAlpha = false; - mime = "image/bmp"; + mime = "image/bmp"; } else { lastError = "unrecognized image"; return; diff --git a/src/image/formats/Bmp.cpp b/src/image/formats/Bmp.cpp index ccc6804..a2ee0a7 100644 --- a/src/image/formats/Bmp.cpp +++ b/src/image/formats/Bmp.cpp @@ -102,8 +102,8 @@ std::expected BMP::createSurfaceFromBMP(const std if (!std::filesystem::exists(path)) return std::unexpected("loading bmp: file doesn't exist"); - std::ifstream bitmapImageStream(path); - BmpHeader bitmapHeader; + std::ifstream bitmapImageStream(path); + BmpHeader bitmapHeader; if (const auto RET = bitmapHeader.load(bitmapImageStream); RET.has_value()) return std::unexpected("loading bmp: " + *RET); diff --git a/src/image/formats/Png.cpp b/src/image/formats/Png.cpp index 7a01379..9651da8 100644 --- a/src/image/formats/Png.cpp +++ b/src/image/formats/Png.cpp @@ -31,16 +31,16 @@ std::expected PNG::createSurfaceFromPNG(const std spng_set_png_buffer(ctx, PNGCONTENT.data(), PNGCONTENT.size()); spng_ihdr ihdr{0}; - if (spng_get_ihdr(ctx, &ihdr)) - return std::unexpected("loading png: file content was empty (bad file?)"); + if (int ret = spng_get_ihdr(ctx, &ihdr); ret) + return std::unexpected(std::string{"loading png: spng_get_ihdr failed: "} + spng_strerror(ret)); int fmt = SPNG_FMT_PNG; if (ihdr.color_type == SPNG_COLOR_TYPE_INDEXED) fmt = SPNG_FMT_RGB8; size_t imageLength = 0; - if (spng_decoded_image_size(ctx, fmt, &imageLength)) - return std::unexpected("loading png: spng_decoded_image_size failed"); + if (int ret = spng_decoded_image_size(ctx, fmt, &imageLength); ret) + return std::unexpected(std::string{"loading png: spng_decoded_image_size failed: "} + spng_strerror(ret)); uint8_t* imageData = (uint8_t*)malloc(imageLength); @@ -48,9 +48,25 @@ std::expected PNG::createSurfaceFromPNG(const std return std::unexpected("loading png: mallocing failed, out of memory?"); // TODO: allow proper decode of high bitrate images - if (spng_decode_image(ctx, imageData, imageLength, SPNG_FMT_RGBA8, 0)) { + bool succeededDecode = false; + int ret = spng_decode_image(ctx, imageData, imageLength, SPNG_FMT_RGBA8, 0); + if (!ret) + succeededDecode = true; + + if (!succeededDecode && ret == SPNG_EBUFSIZ) { + // hack, but I don't know why decoded_image_size is sometimes wrong + imageLength = ihdr.height * ihdr.width * 4 /* FIXME: this is wrong if we doing >32bpp!!!! */; + imageData = (uint8_t*)realloc(imageData, imageLength); + + ret = spng_decode_image(ctx, imageData, imageLength, SPNG_FMT_RGBA8, 0); + } + + if (!ret) + succeededDecode = true; + + if (!succeededDecode) { free(imageData); - return std::unexpected("loading png: spng_decode_image failed (invalid image?)"); + return std::unexpected(std::string{"loading png: spng_decode_image failed: "} + spng_strerror(ret) + " (bad image?)"); } // convert RGBA8888 -> ARGB8888 premult for cairo