fix bug with image decoding

This commit is contained in:
GenevensiS
2026-05-03 05:03:08 +02:00
parent 05d205cafa
commit 9a5be16e4e
4 changed files with 61 additions and 55 deletions
+31 -31
View File
@@ -36,44 +36,44 @@ inline static String encodeRectInWxString(RealRect rect, int degrees) {
_("</mse-crop-data>"); _("</mse-crop-data>");
} }
/// Retreive a rect encoded in a string, return true if successful /// Retreive a rect encoded in a string, return true if "<mse-crop-data>" was found
inline static bool decodeRectFromString(const String& rectString, RealRect& rect_out, int& degrees_out) { inline static bool decodeRectFromString(const String& rectString, RealRect& rect_out, int& degrees_out) {
size_t start = rectString.find(_("<mse-crop-data>")); size_t start = rectString.find(_("<mse-crop-data>"));
if (start == String::npos) return false; if (start == String::npos) return false;
size_t end = rectString.find(_("</mse-crop-data>"), start + 15); size_t end = rectString.find(_("</mse-crop-data>"), start + 15);
if (end == String::npos) return false; if (end == String::npos) return true;
String string = rectString.substr(start + 15, end - (start + 15)); String string = rectString.substr(start + 15, end - (start + 15));
if (string.empty()) return false; if (string.empty()) return true;
size_t divider = string.find(_(";")); size_t divider = string.find(_(";"));
if (divider == String::npos) return false; if (divider == String::npos) return true;
if (divider == 0) return false; if (divider == 0) return true;
int x; 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); string = string.substr(divider + 1);
divider = string.find(_(";")); divider = string.find(_(";"));
if (divider == String::npos) return false; if (divider == String::npos) return true;
if (divider == 0) return false; if (divider == 0) return true;
int y; 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); string = string.substr(divider + 1);
divider = string.find(_(";")); divider = string.find(_(";"));
if (divider == String::npos) return false; if (divider == String::npos) return true;
if (divider == 0) return false; if (divider == 0) return true;
int width; 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); string = string.substr(divider + 1);
divider = string.find(_(";")); divider = string.find(_(";"));
if (divider == String::npos) return false; if (divider == String::npos) return true;
if (divider == 0) return false; if (divider == 0) return true;
int height; 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); string = string.substr(divider + 1);
if(!string.ToInt(&degrees_out)) return false; if(!string.ToInt(&degrees_out)) return true;
rect_out = RealRect(x, y, width, height); rect_out = RealRect(x, y, width, height);
return true; 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 /// 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) { inline static String transformEncodedRect(const String& rectString, RectTransform transform, double param_x, double param_y, int mode) {
RealRect rect(0,0,0,0); RealRect rect(0.0, 0.0, 0.0, 0.0);
int degrees; int degrees = 0;
if (!decodeRectFromString(rectString, rect, degrees)) return _(""); decodeRectFromString(rectString, rect, degrees);
transform(rect, degrees, param_x, param_y, mode); if (rect.width > 0.0 && rect.height > 0.0) {
return encodeRectInWxString(rect, degrees); 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 /// 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) { 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(_("<mse-crop-data>")); size_t start = rectString.find(_("<mse-crop-data>"));
if (start == String::npos) return rectString; if (start == String::npos) return rectString;
size_t end = 0; size_t end = 0;
@@ -184,22 +185,21 @@ inline static std::string encodeImageInString(const Image& img) {
return s; return s;
} }
/// Retreive an image encoded in a string /// Retreive an image encoded in a string, return true if "<mse-image-data>" was found
inline static Image decodeImageFromString(const String& string) { inline static bool decodeImageFromString(const String& string, Image& img_out) {
Image img;
size_t first = string.find(_("<mse-image-data>")); size_t first = string.find(_("<mse-image-data>"));
if (first == String::npos) return img; if (first == String::npos) return false;
size_t last = string.find(_("</mse-image-data>"), first + 16); size_t last = string.find(_("</mse-image-data>"), 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(); 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(); const std::string& temppath = (wxFileName::CreateTempFileName(_("mse")) + _(".png")).ToStdString();
UTF8ToFile(temppath, s); UTF8ToFile(temppath, s);
img.LoadFile(temppath, wxBITMAP_TYPE_PNG); img_out.LoadFile(temppath, wxBITMAP_TYPE_PNG);
wxRemoveFile(temppath); wxRemoveFile(temppath);
wxRemoveFile(temppath.substr(0, temppath.size() - 4)); wxRemoveFile(temppath.substr(0, temppath.size() - 4));
return img; return true;
} }
// ----------------------------------------------------------------------------- : Metadata manipulation // ----------------------------------------------------------------------------- : Metadata manipulation
+27 -21
View File
@@ -242,39 +242,45 @@ bool CardListBase::doBulkModification() {
return false; return false;
} }
void CardListBase::parseImageMetadata(CardP& card, const Image& image) void CardListBase::parseImageMetadata(CardP& card, const Image& image) {
{
for (IndexMap<FieldP, ValueP>::iterator it = card->data.begin(); it != card->data.end(); it++) { for (IndexMap<FieldP, ValueP>::iterator it = card->data.begin(); it != card->data.end(); it++) {
ImageValue* value = dynamic_cast<ImageValue*>(it->get()); ImageValue* value = dynamic_cast<ImageValue*>(it->get());
if (value && !value->filename.empty()) { if (value && !value->filename.empty()) {
RealRect rect(0.0, 0.0, 0.0, 0.0); RealRect rect(0.0, 0.0, 0.0, 0.0);
int degrees = 0; int degrees = 0;
decodeRectFromString(value->filename.toStringForKey(), rect, degrees); if (decodeRectFromString(value->filename.toStringForKey(), rect, degrees)) {
rect = rect.intersect(RealRect(0.0, 0.0, image.GetWidth(), image.GetHeight())); rect = rect.intersect(RealRect(0.0, 0.0, image.GetWidth(), image.GetHeight()));
if (rect.width > 0.0 && rect.height > 0.0) { if (rect.width > 0.0 && rect.height > 0.0) {
Image img = image.GetSubImage(rect); Image img = image.GetSubImage(rect);
img = rotate_image(img, deg_to_rad(360 - degrees)); img = rotate_image(img, deg_to_rad(360 - degrees));
LocalFileName filename = set->newFileName("cropped_image", _(".png")); // a new unique name in the package LocalFileName filename = set->newFileName(_("cropped_image"), _(".png")); // a new unique name in the package
img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG); img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG);
value->filename = filename; value->filename = filename;
} }
else { else {
value->filename = LocalFileName(); 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<FieldP, ValueP>::iterator it = card->data.begin(); it != card->data.end(); it++) { for (IndexMap<FieldP, ValueP>::iterator it = card->data.begin(); it != card->data.end(); it++) {
ImageValue* value = dynamic_cast<ImageValue*>(it->get()); ImageValue* value = dynamic_cast<ImageValue*>(it->get());
if (value) { if (value && !value->filename.empty()) {
Image img = decodeImageFromString(value->filename.toStringForKey()); Image img;
if (img.IsOk()) { if (decodeImageFromString(value->filename.toStringForKey(), img)) {
LocalFileName filename = set->newFileName(_("decoded_image"), _(".png")); // a new unique name in the package if (img.IsOk()) {
img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG); LocalFileName filename = set->newFileName(_("decoded_image"), _(".png")); // a new unique name in the package
value->filename = filename; 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() + _("'"));
}
} }
} }
} }
+1 -1
View File
@@ -95,7 +95,7 @@ void PackageInfoPanel::draw(DC& dc) {
dc.DrawText(d.short_name, x, y); 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.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; y += dc.GetCharHeight() + 7;
dc.SetFont(*wxNORMAL_FONT); dc.SetFont(*wxNORMAL_FONT);
+1 -1
View File
@@ -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_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_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_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")); menuBar->Append(menuTool, _MENU_("tool"));
SetMenuBar(menuBar); SetMenuBar(menuBar);