From ed50041589974d31296cb30dc1897f7fba6336c2 Mon Sep 17 00:00:00 2001 From: B Stack Date: Wed, 20 Nov 2019 08:36:44 -0500 Subject: add upstream 10.18 --- wx+/image_resources.cpp | 109 +++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 56 deletions(-) (limited to 'wx+/image_resources.cpp') diff --git a/wx+/image_resources.cpp b/wx+/image_resources.cpp index faabbb2a..91189ba6 100644 --- a/wx+/image_resources.cpp +++ b/wx+/image_resources.cpp @@ -11,10 +11,10 @@ #include #include #include -#include +#include #include -#include #include +#include #include #include #include "image_tools.h" @@ -143,24 +143,6 @@ private: //hardware_concurrency() == 0 if "not computable or well defined" }; - -void loadAnimFromZip(wxZipInputStream& zipInput, wxAnimation& anim) -{ - //work around wxWidgets bug: - //construct seekable input stream (zip-input stream is not seekable) for wxAnimation::Load() - //luckily this method call is very fast: below measurement precision! - std::vector data; - data.reserve(10000); - - int newValue = 0; - while ((newValue = zipInput.GetC()) != wxEOF) - data.push_back(static_cast(newValue)); - - wxMemoryInputStream seekAbleStream(&data.front(), data.size()); //stream does not take ownership of data - - anim.Load(seekAbleStream, wxANIMATION_TYPE_GIF); -} - //================================================================================================ //================================================================================================ @@ -204,44 +186,59 @@ void GlobalBitmaps::init(const Zstring& filePath) { assert(bitmaps_.empty() && anims_.empty()); - wxFFileInputStream input(utfTo(filePath)); - if (input.IsOk()) //if not... we don't want to react too harsh here + //wxFFileInputStream/wxZipInputStream loads in junks of 512 bytes => WTF!!! => implement sane file loading: + try { - //activate support for .png files - wxImage::AddHandler(new wxPNGHandler); //ownership passed - - wxZipInputStream streamIn(input, wxConvUTF8); - //do NOT rely on wxConvLocal! On failure shows unhelpful popup "Cannot convert from the charset 'Unknown encoding (-1)'!" - - //do we need xBRZ scaling for high quality DPI images? - const int hqScale = std::clamp(std::ceil(fastFromDIP(1000) / 1000.0), 1, xbrz::SCALE_FACTOR_MAX); - //even for 125% DPI scaling, "2xBRZ + bilinear downscale" gives a better result than mere "125% bilinear upscale"! - if (hqScale > 1) - dpiScaler_ = std::make_unique(hqScale); - - while (const auto& entry = std::unique_ptr(streamIn.GetNextEntry())) //take ownership!) - { - const wxString name = entry->GetName(); - - if (endsWith(name, L".png")) - { - wxImage img(streamIn, wxBITMAP_TYPE_PNG); - - //end this alpha/no-alpha/mask/wxDC::DrawBitmap/RTL/high-contrast-scheme interoperability nightmare here and now!!!! - //=> there's only one type of wxImage: with alpha channel, no mask!!! - convertToVanillaImage(img); - - if (dpiScaler_) - dpiScaler_->add(name, img); //scale in parallel! - else - bitmaps_.emplace(name, img); - } - else if (endsWith(name, L".gif")) - loadAnimFromZip(streamIn, anims_[name]); - else - assert(false); - } + const std::string rawStream = loadBinContainer(filePath, nullptr /*notifyUnbufferedIO*/); //throw FileError + wxMemoryInputStream memStream(rawStream.c_str(), rawStream.size()); //does not take ownership + wxZipInputStream zipStream(memStream, wxConvUTF8); + //do NOT rely on wxConvLocal! On failure shows unhelpful popup "Cannot convert from the charset 'Unknown encoding (-1)'!" + + //activate support for .png files + wxImage::AddHandler(new wxPNGHandler); //ownership passed + + //do we need xBRZ scaling for high quality DPI images? + const int hqScale = std::clamp(std::ceil(fastFromDIP(1000) / 1000.0), 1, xbrz::SCALE_FACTOR_MAX); + //even for 125% DPI scaling, "2xBRZ + bilinear downscale" gives a better result than mere "125% bilinear upscale"! + if (hqScale > 1) + dpiScaler_ = std::make_unique(hqScale); + + while (const auto& entry = std::unique_ptr(zipStream.GetNextEntry())) //take ownership!) + { + const wxString name = entry->GetName(); + + if (endsWith(name, L".png")) + { + wxImage img(zipStream, wxBITMAP_TYPE_PNG); + assert(img.IsOk()); + + //end this alpha/no-alpha/mask/wxDC::DrawBitmap/RTL/high-contrast-scheme interoperability nightmare here and now!!!! + //=> there's only one type of wxImage: with alpha channel, no mask!!! + convertToVanillaImage(img); + + if (dpiScaler_) + dpiScaler_->add(name, img); //scale in parallel! + else + bitmaps_.emplace(name, img); + } + else if (endsWith(name, L".gif")) + { + //work around wxWidgets bug: wxAnimation::Load() requires seekable input stream (zip-input stream is not seekable) + std::string stream(entry->GetSize(), '\0'); + if (!stream.empty() && zipStream.ReadAll(&stream[0], stream.size())) + { + wxMemoryInputStream seekAbleStream(stream.c_str(), stream.size()); //stream does not take ownership of data + [[maybe_unused]] const bool loadSuccess = anims_[name].Load(seekAbleStream, wxANIMATION_TYPE_GIF); + assert(loadSuccess); + } + else + assert(false); + } + else + assert(false); + } } + catch (FileError&) { assert(false); } } -- cgit