Commit 6e53fb89 for libheif
commit 6e53fb8910fe1bd581d20f151a118f4d871d69bf
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Sun Apr 12 15:08:19 2026 +0200
replace bubble sort with std::stable_partition in ipma property sorting (#1763)
diff --git a/libheif/box.cc b/libheif/box.cc
index 9d486e4d..510ca72f 100644
--- a/libheif/box.cc
+++ b/libheif/box.cc
@@ -3364,19 +3364,17 @@ void Box_ipma::sort_properties(const std::shared_ptr<Box_ipco>& ipco)
{
auto properties = ipco->get_all_child_boxes();
- for (auto& item : m_entries) {
- size_t nAssoc = item.associations.size();
-
- // simple Bubble sort as a stable sorting algorithm
+ // Stable-partition: all descriptive properties before all transformative properties.
+ // The order within each group is preserved (spec requires it for transformative properties).
- for (size_t n = 0; n < nAssoc - 1; n++)
- for (size_t i = 0; i < nAssoc - 1 - n; i++) {
- // If transformative property precedes descriptive property, swap them.
- if (properties[item.associations[i].property_index - 1]->is_transformative_property() &&
- !properties[item.associations[i + 1].property_index - 1]->is_transformative_property()) {
- std::swap(item.associations[i], item.associations[i+1]);
- }
- }
+ for (auto& item : m_entries) {
+ std::stable_partition(item.associations.begin(), item.associations.end(),
+ [&properties](const PropertyAssociation& assoc) {
+ if (assoc.property_index == 0 || assoc.property_index > properties.size()) {
+ return true; // keep invalid/unset entries in the descriptive group
+ }
+ return !properties[assoc.property_index - 1]->is_transformative_property();
+ });
}
}