godot/thirdparty/astcenc/astcenc_find_best_partitioning.cpp

// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at:
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
// ----------------------------------------------------------------------------

#if !defined(ASTCENC_DECOMPRESS_ONLY)

/**
 * @brief Functions for finding best partition for a block.
 *
 * The partition search operates in two stages. The first pass uses kmeans clustering to group
 * texels into an ideal partitioning for the requested partition count, and then compares that
 * against the 1024 partitionings generated by the ASTC partition hash function. The generated
 * partitions are then ranked by the number of texels in the wrong partition, compared to the ideal
 * clustering. All 1024 partitions are tested for similarity and ranked, apart from duplicates and
 * partitionings that actually generate fewer than the requested partition count, but only the top
 * N candidates are actually put through a more detailed search. N is determined by the compressor
 * quality preset.
 *
 * For the detailed search, each candidate is checked against two possible encoding methods:
 *
 *   - The best partitioning assuming different chroma colors (RGB + RGB or RGB + delta endpoints).
 *   - The best partitioning assuming same chroma colors (RGB + scale endpoints).
 *
 * This is implemented by computing the compute mean color and dominant direction for each
 * partition. This defines two lines, both of which go through the mean color value.
 *
 * - One line has a direction defined by the dominant direction; this is used to assess the error
 *   from using an uncorrelated color representation.
 * - The other line goes through (0,0,0,1) and is used to assess the error from using a same chroma
 *   (RGB + scale) color representation.
 *
 * The best candidate is selected by computing the squared-errors that result from using these
 * lines for endpoint selection.
 */

#include <limits>
#include "astcenc_internal.h"

/**
 * @brief Pick some initial kmeans cluster centers.
 *
 * @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[out] cluster_centers   The initial partition cluster center colors.
 */
static void kmeans_init(
	const image_block& blk,
	unsigned int texel_count,
	unsigned int partition_count,
	vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS]
) {}

/**
 * @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_of_texel   The partition assigned for each texel.
 */
static void kmeans_assign(
	const image_block& blk,
	unsigned int texel_count,
	unsigned int partition_count,
	const vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS],
	uint8_t partition_of_texel[BLOCK_MAX_TEXELS]
) {}

/**
 * @brief Compute new cluster centers based on their center of gravity.
 *
 * @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[out]  cluster_centers      The new cluster center colors.
 * @param       partition_of_texel   The partition assigned for each texel.
 */
static void kmeans_update(
	const image_block& blk,
	unsigned int texel_count,
	unsigned int partition_count,
	vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS],
	const uint8_t partition_of_texel[BLOCK_MAX_TEXELS]
) {}

/**
 * @brief Compute bit-mismatch for partitioning in 2-partition mode.
 *
 * @param a   The texel assignment bitvector for the block.
 * @param b   The texel assignment bitvector for the partition table.
 *
 * @return    The number of bit mismatches.
 */
static inline uint8_t partition_mismatch2(
	const uint64_t a[2],
	const uint64_t b[2]
) {}

/**
 * @brief Compute bit-mismatch for partitioning in 3-partition mode.
 *
 * @param a   The texel assignment bitvector for the block.
 * @param b   The texel assignment bitvector for the partition table.
 *
 * @return    The number of bit mismatches.
 */
static inline uint8_t partition_mismatch3(
	const uint64_t a[3],
	const uint64_t b[3]
) {}

/**
 * @brief Compute bit-mismatch for partitioning in 4-partition mode.
 *
 * @param a   The texel assignment bitvector for the block.
 * @param b   The texel assignment bitvector for the partition table.
 *
 * @return    The number of bit mismatches.
 */
static inline uint8_t partition_mismatch4(
	const uint64_t a[4],
	const uint64_t b[4]
) {}

mismatch_dispatch;

/**
 * @brief Count the partition table mismatches vs the data clustering.
 *
 * @param      bsd               The block size information.
 * @param      partition_count   The number of partitions in the block.
 * @param      bitmaps           The block texel partition assignment patterns.
 * @param[out] mismatch_counts   The array storing per partitioning mismatch counts.
 */
static void count_partition_mismatch_bits(
	const block_size_descriptor& bsd,
	unsigned int partition_count,
	const uint64_t bitmaps[BLOCK_MAX_PARTITIONS],
	uint8_t mismatch_counts[BLOCK_MAX_PARTITIONINGS]
) {}

/**
 * @brief Use counting sort on the mismatch array to sort partition candidates.
 *
 * @param      partitioning_count   The number of packed partitionings.
 * @param      mismatch_count       Partitioning mismatch counts, in index order.
 * @param[out] partition_ordering   Partition index values, in mismatch order.
 *
 * @return The number of active partitions in this selection.
 */
static unsigned int get_partition_ordering_by_mismatch_bits(
	unsigned int texel_count,
	unsigned int partitioning_count,
	const uint8_t mismatch_count[BLOCK_MAX_PARTITIONINGS],
	uint16_t partition_ordering[BLOCK_MAX_PARTITIONINGS]
) {}

/**
 * @brief Use k-means clustering to compute a partition ordering for a block..
 *
 * @param      bsd                  The block size information.
 * @param      blk                  The image block color data to compress.
 * @param      partition_count      The desired number of partitions in the block.
 * @param[out] partition_ordering   The list of recommended partition indices, in priority order.
 *
 * @return The number of active partitionings in this selection.
 */
static unsigned int compute_kmeans_partition_ordering(
	const block_size_descriptor& bsd,
	const image_block& blk,
	unsigned int partition_count,
	uint16_t partition_ordering[BLOCK_MAX_PARTITIONINGS]
) {}

/**
 * @brief Insert a partitioning into an order list of results, sorted by error.
 *
 * @param      max_values      The max number of entries in the best result arrays.
 * @param      this_error      The error of the new entry.
 * @param      this_partition  The partition ID of the new entry.
 * @param[out] best_errors     The array of best error values.
 * @param[out] best_partitions The array of best partition values.
 */
static void insert_result(
	unsigned int max_values,
	float this_error,
	unsigned int this_partition,
	float* best_errors,
	unsigned int* best_partitions)
{}

/* See header for documentation. */
unsigned int find_best_partition_candidates(
	const block_size_descriptor& bsd,
	const image_block& blk,
	unsigned int partition_count,
	unsigned int partition_search_limit,
	unsigned int best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES],
	unsigned int requested_candidates
) {}

#endif