MCPcopy Create free account
hub / github.com/ARM-software/astc-encoder / kmeans_assign

Function kmeans_assign

Source/astcenc_find_best_partitioning.cpp:146–199  ·  view source on GitHub ↗

* @brief Assign texels to clusters, based on a set of chosen center points. * * @param blk The image block color data to compress. * @param texel_count The number of texels in the block. * @param partition_count The number of partitions in the block. * @param cluster_centers The partition cluster center colors. * @param[out] partition_o

Source from the content-addressed store, hash-verified

144 * @param[out] partition_of_texel The partition assigned for each texel.
145 */
146static void kmeans_assign(
147 const image_block& blk,
148 unsigned int texel_count,
149 unsigned int partition_count,
150 const vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS],
151 uint8_t partition_of_texel[BLOCK_MAX_TEXELS]
152) {
153 promise(texel_count > 0);
154 promise(partition_count > 0);
155
156 uint8_t partition_texel_count[BLOCK_MAX_PARTITIONS] { 0 };
157
158 // Find the best partition for every texel
159 for (unsigned int i = 0; i < texel_count; i++)
160 {
161 float best_distance = std::numeric_limits<float>::max();
162 unsigned int best_partition = 0;
163
164 vfloat4 color = blk.texel(i);
165 for (unsigned int j = 0; j < partition_count; j++)
166 {
167 vfloat4 diff = color - cluster_centers[j];
168 float distance = dot_s(diff * diff, blk.channel_weight);
169 if (distance < best_distance)
170 {
171 best_distance = distance;
172 best_partition = j;
173 }
174 }
175
176 partition_of_texel[i] = static_cast<uint8_t>(best_partition);
177 partition_texel_count[best_partition]++;
178 }
179
180 // It is possible to get a situation where a partition ends up without any texels. In this case,
181 // assign texel N to partition N. This is silly, but ensures that every partition retains at
182 // least one texel. Reassigning a texel in this manner may cause another partition to go empty,
183 // so if we actually did a reassignment, run the whole loop over again.
184 bool problem_case;
185 do
186 {
187 problem_case = false;
188 for (unsigned int i = 0; i < partition_count; i++)
189 {
190 if (partition_texel_count[i] == 0)
191 {
192 partition_texel_count[partition_of_texel[i]]--;
193 partition_texel_count[i]++;
194 partition_of_texel[i] = static_cast<uint8_t>(i);
195 problem_case = true;
196 }
197 }
198 } while (problem_case);
199}
200
201/**
202 * @brief Compute new cluster centers based on their center of gravity.

Callers 1

Calls 3

texelMethod · 0.80
maxFunction · 0.70
dot_sFunction · 0.70

Tested by

no test coverage detected