Fix rgbgfx -Z palette overgeneration on merged color sets (#1912)

- Fix logic for color set comparison (which affects sorting them)
- Prune color sets which are proper subsets of newly-encountered ones
  (a comment implied we were already doing this, but we weren't)
- Add more verbose logging to debug this behavior
This commit is contained in:
vulcandth
2026-06-07 09:55:05 -04:00
committed by GitHub
parent 075f132d77
commit 998f636495
6 changed files with 100 additions and 29 deletions
+31 -16
View File
@@ -42,29 +42,44 @@ void ColorSet::add(uint16_t color) {
}
ColorSet::ComparisonResult ColorSet::compare(ColorSet const &other) const {
// This works because the sets are sorted numerically
// This algorithm works because the sets are sorted numerically
assume(std::is_sorted(RANGE(_colorIndices)));
assume(std::is_sorted(RANGE(other._colorIndices)));
auto ours = _colorIndices.begin(), theirs = other._colorIndices.begin();
bool weBigger = true, theyBigger = true;
auto self_item = begin(), other_item = other.begin();
auto const self_end = end(), other_end = other.end();
bool self_has_unique = false, other_has_unique = false;
while (ours != end() && theirs != other.end()) {
if (*ours == *theirs) {
++ours;
++theirs;
} else if (*ours < *theirs) {
++ours;
theyBigger = false;
} else { // *ours > *theirs
++theirs;
weBigger = false;
while (self_item != self_end && other_item != other_end) {
if (*self_item < *other_item) {
// *self_item is not in other, so self cannot be a strict subset of other
self_has_unique = true;
++self_item;
} else if (*self_item > *other_item) {
// *other_item is not in self, so self cannot be a strict superset of other
other_has_unique = true;
++other_item;
} else {
// *self_item == *other_item, so continue comparing
++self_item;
++other_item;
}
// Early return optimization: we already know self and other are incomparable
if (self_has_unique && other_has_unique) {
return INCOMPARABLE;
}
}
weBigger &= theirs == other.end();
theyBigger &= ours == end();
return theyBigger ? THEY_BIGGER : (weBigger ? WE_BIGGER : NEITHER);
// Check if either color set has unique items remaining after one set has been fully iterated
if (self_item != self_end) {
self_has_unique = true;
}
if (other_item != other_end) {
other_has_unique = true;
}
return self_has_unique ? other_has_unique ? INCOMPARABLE : STRICT_SUPERSET : SUBSET_OR_EQUAL;
}
size_t ColorSet::size() const {