summaryrefslogtreecommitdiff
path: root/quantize.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantize.c')
-rw-r--r--quantize.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/quantize.c b/quantize.c
index fc31f36..e5d4a59 100644
--- a/quantize.c
+++ b/quantize.c
@@ -234,6 +234,17 @@ SubdivColorMap(NewColorMapType * NewColorSubdiv,
j++, QuantizedColor = QuantizedColor->Pnext)
SortArray[j] = QuantizedColor;
+ /*
+ * Because qsort isn't stable, this can produce differing
+ * results for the order of tuples depending on platform
+ * details of how qsort() is implemented.
+ *
+ * We mitigate this problem by sorting on all three axes rather
+ * than only the one specied by SortRGBAxis; that way the instability
+ * can only become an issue if there are multiple color indices
+ * referring to identical RGB tuples. Older versions of this
+ * sorted on only the one axis.
+ */
qsort(SortArray, NewColorSubdiv[Index].NumEntries,
sizeof(QuantizedColorType *), SortCmpRtn);
@@ -298,12 +309,22 @@ SubdivColorMap(NewColorMapType * NewColorSubdiv,
/****************************************************************************
Routine called by qsort to compare two entries.
*****************************************************************************/
+
static int
SortCmpRtn(const void *Entry1,
const void *Entry2) {
-
- return (*((QuantizedColorType **) Entry1))->RGB[SortRGBAxis] -
- (*((QuantizedColorType **) Entry2))->RGB[SortRGBAxis];
+ QuantizedColorType *entry1 = (*((QuantizedColorType **) Entry1));
+ QuantizedColorType *entry2 = (*((QuantizedColorType **) Entry2));
+
+ /* sort on all axes of the color space! */
+ int hash1 = entry1->RGB[SortRGBAxis] * 256 * 256
+ + entry1->RGB[(SortRGBAxis+1) % 3] * 256
+ + entry1->RGB[(SortRGBAxis+2) % 3];
+ int hash2 = entry2->RGB[SortRGBAxis] * 256 * 256
+ + entry2->RGB[(SortRGBAxis+1) % 3] * 256
+ + entry2->RGB[(SortRGBAxis+2) % 3];
+
+ return hash1 - hash2;
}
/* end */