From 9a5be16e4e6b444b787432c5c0a5d691fa3bff46 Mon Sep 17 00:00:00 2001 From: GenevensiS <66968533+G-e-n-e-v-e-n-s-i-S@users.noreply.github.com> Date: Sun, 3 May 2026 05:03:08 +0200 Subject: [PATCH] fix bug with image decoding --- src/data/format/image_encoding.hpp | 62 +++++++++++++++--------------- src/gui/control/card_list.cpp | 48 +++++++++++++---------- src/gui/packages_window.cpp | 4 +- src/gui/symbol/window.cpp | 2 +- 4 files changed, 61 insertions(+), 55 deletions(-) diff --git a/src/data/format/image_encoding.hpp b/src/data/format/image_encoding.hpp index b8c45fa9..14af23bb 100644 --- a/src/data/format/image_encoding.hpp +++ b/src/data/format/image_encoding.hpp @@ -36,44 +36,44 @@ inline static String encodeRectInWxString(RealRect rect, int degrees) { _(""); } -/// Retreive a rect encoded in a string, return true if successful +/// Retreive a rect encoded in a string, return true if "" was found inline static bool decodeRectFromString(const String& rectString, RealRect& rect_out, int& degrees_out) { size_t start = rectString.find(_("")); if (start == String::npos) return false; size_t end = rectString.find(_(""), start + 15); - if (end == String::npos) return false; + if (end == String::npos) return true; String string = rectString.substr(start + 15, end - (start + 15)); - if (string.empty()) return false; + if (string.empty()) return true; size_t divider = string.find(_(";")); - if (divider == String::npos) return false; - if (divider == 0) return false; + if (divider == String::npos) return true; + if (divider == 0) return true; int x; - if(!string.substr(0, divider).ToInt(&x)) return false; + if(!string.substr(0, divider).ToInt(&x)) return true; string = string.substr(divider + 1); divider = string.find(_(";")); - if (divider == String::npos) return false; - if (divider == 0) return false; + if (divider == String::npos) return true; + if (divider == 0) return true; int y; - if(!string.substr(0, divider).ToInt(&y)) return false; + if(!string.substr(0, divider).ToInt(&y)) return true; string = string.substr(divider + 1); divider = string.find(_(";")); - if (divider == String::npos) return false; - if (divider == 0) return false; + if (divider == String::npos) return true; + if (divider == 0) return true; int width; - if(!string.substr(0, divider).ToInt(&width)) return false; + if(!string.substr(0, divider).ToInt(&width)) return true; string = string.substr(divider + 1); divider = string.find(_(";")); - if (divider == String::npos) return false; - if (divider == 0) return false; + if (divider == String::npos) return true; + if (divider == 0) return true; int height; - if(!string.substr(0, divider).ToInt(&height)) return false; + if(!string.substr(0, divider).ToInt(&height)) return true; string = string.substr(divider + 1); - if(!string.ToInt(°rees_out)) return false; + if(!string.ToInt(°rees_out)) return true; rect_out = RealRect(x, y, width, height); return true; @@ -81,17 +81,18 @@ inline static bool decodeRectFromString(const String& rectString, RealRect& rect /// Retreive a rect encoded in a string, apply a transformation, then encode it back inline static String transformEncodedRect(const String& rectString, RectTransform transform, double param_x, double param_y, int mode) { - RealRect rect(0,0,0,0); - int degrees; - if (!decodeRectFromString(rectString, rect, degrees)) return _(""); - transform(rect, degrees, param_x, param_y, mode); - return encodeRectInWxString(rect, degrees); + RealRect rect(0.0, 0.0, 0.0, 0.0); + int degrees = 0; + decodeRectFromString(rectString, rect, degrees); + if (rect.width > 0.0 && rect.height > 0.0) { + transform(rect, degrees, param_x, param_y, mode); + return encodeRectInWxString(rect, degrees); + } + return _(""); } /// Retreive all rects encoded in a string, apply a transformation, then encode them back inline static String transformAllEncodedRects(const String& rectString, RectTransform transform, double param_x, double param_y, int mode = 0) { - RealRect rect(0,0,0,0); - int degrees; size_t start = rectString.find(_("")); if (start == String::npos) return rectString; size_t end = 0; @@ -184,22 +185,21 @@ inline static std::string encodeImageInString(const Image& img) { return s; } -/// Retreive an image encoded in a string -inline static Image decodeImageFromString(const String& string) { - Image img; +/// Retreive an image encoded in a string, return true if "" was found +inline static bool decodeImageFromString(const String& string, Image& img_out) { size_t first = string.find(_("")); - if (first == String::npos) return img; + if (first == String::npos) return false; size_t last = string.find(_(""), first + 16); - if (last == String::npos) return img; + if (last == String::npos) return true; std::string s = string.substr(first + 16, last - (first + 16)).ToStdString(); - if (s.empty()) return img; + if (s.empty()) return true; const std::string& temppath = (wxFileName::CreateTempFileName(_("mse")) + _(".png")).ToStdString(); UTF8ToFile(temppath, s); - img.LoadFile(temppath, wxBITMAP_TYPE_PNG); + img_out.LoadFile(temppath, wxBITMAP_TYPE_PNG); wxRemoveFile(temppath); wxRemoveFile(temppath.substr(0, temppath.size() - 4)); - return img; + return true; } // ----------------------------------------------------------------------------- : Metadata manipulation diff --git a/src/gui/control/card_list.cpp b/src/gui/control/card_list.cpp index 86597ca6..64ae8c53 100644 --- a/src/gui/control/card_list.cpp +++ b/src/gui/control/card_list.cpp @@ -242,39 +242,45 @@ bool CardListBase::doBulkModification() { return false; } -void CardListBase::parseImageMetadata(CardP& card, const Image& image) -{ +void CardListBase::parseImageMetadata(CardP& card, const Image& image) { for (IndexMap::iterator it = card->data.begin(); it != card->data.end(); it++) { ImageValue* value = dynamic_cast(it->get()); if (value && !value->filename.empty()) { RealRect rect(0.0, 0.0, 0.0, 0.0); int degrees = 0; - decodeRectFromString(value->filename.toStringForKey(), rect, degrees); - rect = rect.intersect(RealRect(0.0, 0.0, image.GetWidth(), image.GetHeight())); - if (rect.width > 0.0 && rect.height > 0.0) { - Image img = image.GetSubImage(rect); - img = rotate_image(img, deg_to_rad(360 - degrees)); - LocalFileName filename = set->newFileName("cropped_image", _(".png")); // a new unique name in the package - img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG); - value->filename = filename; - } - else { - value->filename = LocalFileName(); + if (decodeRectFromString(value->filename.toStringForKey(), rect, degrees)) { + rect = rect.intersect(RealRect(0.0, 0.0, image.GetWidth(), image.GetHeight())); + if (rect.width > 0.0 && rect.height > 0.0) { + Image img = image.GetSubImage(rect); + img = rotate_image(img, deg_to_rad(360 - degrees)); + LocalFileName filename = set->newFileName(_("cropped_image"), _(".png")); // a new unique name in the package + img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG); + value->filename = filename; + } + else { + value->filename = LocalFileName(); + //queue_message(MESSAGE_WARNING, _("failed to recover image crop for card '") + card->identification() + _("'")); + } } } } } -void CardListBase::parseImageMetadata(CardP& card) -{ +void CardListBase::parseImageMetadata(CardP& card) { for (IndexMap::iterator it = card->data.begin(); it != card->data.end(); it++) { ImageValue* value = dynamic_cast(it->get()); - if (value) { - Image img = decodeImageFromString(value->filename.toStringForKey()); - if (img.IsOk()) { - LocalFileName filename = set->newFileName(_("decoded_image"), _(".png")); // a new unique name in the package - img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG); - value->filename = filename; + if (value && !value->filename.empty()) { + Image img; + if (decodeImageFromString(value->filename.toStringForKey(), img)) { + if (img.IsOk()) { + LocalFileName filename = set->newFileName(_("decoded_image"), _(".png")); // a new unique name in the package + img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG); + value->filename = filename; + } + else { + value->filename = LocalFileName(); + //queue_message(MESSAGE_WARNING, _("failed to recover image encode for card '") + card->identification() + _("'")); + } } } } diff --git a/src/gui/packages_window.cpp b/src/gui/packages_window.cpp index 97567fd3..30358846 100644 --- a/src/gui/packages_window.cpp +++ b/src/gui/packages_window.cpp @@ -93,9 +93,9 @@ void PackageInfoPanel::draw(DC& dc) { x += 7; dc.SetFont(wxFont(16, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, _("Arial"))); dc.DrawText(d.short_name, x, y); - y += dc.GetCharHeight() + 7; + y += dc.GetCharHeight() + 7; dc.SetFont(wxFont(12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, _("Arial"))); - dc.DrawText(d.full_name, x, y); + if (d.full_name != d.short_name) dc.DrawText(d.full_name, x, y); y += dc.GetCharHeight() + 7; dc.SetFont(*wxNORMAL_FONT); diff --git a/src/gui/symbol/window.cpp b/src/gui/symbol/window.cpp index a362c196..743d3f03 100644 --- a/src/gui/symbol/window.cpp +++ b/src/gui/symbol/window.cpp @@ -98,7 +98,7 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) { add_menu_item_tr(menuTool, ID_MODE_POINTS, "mode_curve", "points", wxITEM_CHECK); add_menu_item_tr(menuTool, ID_MODE_SHAPES, settings.darkModePrefix() + "circle", "basic_shapes", wxITEM_CHECK); add_menu_item_tr(menuTool, ID_MODE_SYMMETRY, "mode_symmetry", "symmetry", wxITEM_CHECK); - add_menu_item_tr(menuTool, ID_MODE_PAINT, settings.darkModePrefix() + "mode_paint", "paint", wxITEM_CHECK); + //add_menu_item_tr(menuTool, ID_MODE_PAINT, settings.darkModePrefix() + "mode_paint", "paint", wxITEM_CHECK); menuBar->Append(menuTool, _MENU_("tool")); SetMenuBar(menuBar);