@@ -15,7 +15,7 @@ static inline void QuantCluster_Train(struct QuantCluster_t *Dst, const struct B
15
15
struct BGRAf_t Dist = BGRAf_Sub (Data , & Dst -> Centroid );
16
16
17
17
float DistW = BGRAf_Len2 (& Dist );
18
- float TrainW = 0.001f + DistW ; //! <- This will help outliers pop out more often (must not be 0.0!)
18
+ float TrainW = 0.01f + DistW ; //! <- This will help outliers pop out more often (must not be 0.0!)
19
19
DistW *= 1.0f + fabsf (Dist .b ); //! <- Further penalize distortion by luma distortion
20
20
struct BGRAf_t TrainData = BGRAf_Muli ( Data , TrainW );
21
21
struct BGRAf_t DistData = BGRAf_Muli (& Dist , DistW );
@@ -31,28 +31,30 @@ static inline int QuantCluster_Resolve(struct QuantCluster_t *x) {
31
31
}
32
32
33
33
//! Split a quantization cluster
34
- static inline void QuantCluster_Split (struct QuantCluster_t * Clusters , int SrcCluster , int DstCluster , const struct BGRAf_t * Data , int nData , int32_t * DataClusters ) {
34
+ static inline void QuantCluster_Split (struct QuantCluster_t * Clusters , int SrcCluster , int DstCluster , const struct BGRAf_t * Data , int nData , int32_t * DataClusters , int Recluster ) {
35
35
//! Shift the cluster in either direction of the distortion vector
36
36
struct BGRAf_t Dist = BGRAf_Divi (& Clusters [SrcCluster ].Dist , Clusters [SrcCluster ].DistWeight );
37
37
Clusters [DstCluster ].Centroid = BGRAf_Add (& Clusters [SrcCluster ].Centroid , & Dist );
38
38
Clusters [SrcCluster ].Centroid = BGRAf_Sub (& Clusters [SrcCluster ].Centroid , & Dist );
39
39
40
40
//! Re-assign clusters
41
- int n ;
42
- QuantCluster_ClearTraining (& Clusters [SrcCluster ]);
43
- QuantCluster_ClearTraining (& Clusters [DstCluster ]);
44
- for (n = 0 ;n < nData ;n ++ ) if (DataClusters [n ] == SrcCluster ) {
45
- float DistSrc = BGRAf_ColDistance (& Data [n ], & Clusters [SrcCluster ].Centroid );
46
- float DistDst = BGRAf_ColDistance (& Data [n ], & Clusters [DstCluster ].Centroid );
47
- if (DistSrc < DistDst ) {
48
- QuantCluster_Train (& Clusters [SrcCluster ], & Data [n ]);
49
- } else {
50
- QuantCluster_Train (& Clusters [DstCluster ], & Data [n ]);
51
- DataClusters [n ] = DstCluster ;
41
+ if (Recluster ) {
42
+ int n ;
43
+ QuantCluster_ClearTraining (& Clusters [SrcCluster ]);
44
+ QuantCluster_ClearTraining (& Clusters [DstCluster ]);
45
+ for (n = 0 ;n < nData ;n ++ ) if (DataClusters [n ] == SrcCluster ) {
46
+ float DistSrc = BGRAf_ColDistance (& Data [n ], & Clusters [SrcCluster ].Centroid );
47
+ float DistDst = BGRAf_ColDistance (& Data [n ], & Clusters [DstCluster ].Centroid );
48
+ if (DistSrc < DistDst ) {
49
+ QuantCluster_Train (& Clusters [SrcCluster ], & Data [n ]);
50
+ } else {
51
+ QuantCluster_Train (& Clusters [DstCluster ], & Data [n ]);
52
+ DataClusters [n ] = DstCluster ;
53
+ }
52
54
}
55
+ QuantCluster_Resolve (& Clusters [SrcCluster ]);
56
+ QuantCluster_Resolve (& Clusters [DstCluster ]);
53
57
}
54
- QuantCluster_Resolve (& Clusters [SrcCluster ]);
55
- QuantCluster_Resolve (& Clusters [DstCluster ]);
56
58
}
57
59
58
60
/**************************************/
@@ -117,8 +119,10 @@ void QuantCluster_Quantize(struct QuantCluster_t *Clusters, int nCluster, const
117
119
if (EmptyCluster != -1 ) DstCluster = EmptyCluster , EmptyCluster = Clusters [EmptyCluster ].Next ;
118
120
else DstCluster = nClusterCur ++ ;
119
121
120
- //! Split and recluster
121
- QuantCluster_Split (Clusters , MaxDistCluster , DstCluster , Data , nData , DataClusters );
122
+ //! Split cluster, but do NOT recluster the data.
123
+ //! By not re-clustering, we give outliers a better chance
124
+ //! of making it through to a better-fitting cluster.
125
+ QuantCluster_Split (Clusters , MaxDistCluster , DstCluster , Data , nData , DataClusters , 0 );
122
126
123
127
//! Check if we have more clusters that need splitting
124
128
MaxDistCluster = Clusters [MaxDistCluster ].Next ;
@@ -159,7 +163,7 @@ void QuantCluster_Quantize(struct QuantCluster_t *Clusters, int nCluster, const
159
163
160
164
//! Split the most distorted clusters into any empty ones
161
165
while (EmptyCluster != -1 && MaxDistCluster != -1 ) {
162
- QuantCluster_Split (Clusters , MaxDistCluster , EmptyCluster , Data , nData , DataClusters );
166
+ QuantCluster_Split (Clusters , MaxDistCluster , EmptyCluster , Data , nData , DataClusters , 1 );
163
167
MaxDistCluster = Clusters [MaxDistCluster ].Next ;
164
168
EmptyCluster = Clusters [EmptyCluster ].Next ;
165
169
}
0 commit comments