summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bimg/3rdparty/astc/astc_find_best_partitioning.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bimg/3rdparty/astc/astc_find_best_partitioning.cpp')
-rw-r--r--3rdparty/bimg/3rdparty/astc/astc_find_best_partitioning.cpp865
1 files changed, 0 insertions, 865 deletions
diff --git a/3rdparty/bimg/3rdparty/astc/astc_find_best_partitioning.cpp b/3rdparty/bimg/3rdparty/astc/astc_find_best_partitioning.cpp
deleted file mode 100644
index f53ab1c9b3e..00000000000
--- a/3rdparty/bimg/3rdparty/astc/astc_find_best_partitioning.cpp
+++ /dev/null
@@ -1,865 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/**
- * This confidential and proprietary software may be used only as
- * authorised by a licensing agreement from ARM Limited
- * (C) COPYRIGHT 2011-2012 ARM Limited
- * ALL RIGHTS RESERVED
- *
- * The entire notice above must be reproduced on all authorised
- * copies and copies may only be made to the extent permitted
- * by a licensing agreement from ARM Limited.
- *
- * @brief ASTC encoding of texture
- *
- * major step 1:
- * * find best partitioning assuming uncorrelated colors
- * * find best partitioning assuming RGBS color representation
- *
- * finding best partitioning for a block:
- * * for each available partitioning:
- * * compute mean-color-value and dominant direction.
- * * this defines two lines, both of which go through the
- * mean-color-value:
- * * one line has a direction defined by the dominant direction;
- * this line 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 an RGBS color representation.
- * * we then compute, as a sum across the block, the squared-errors
- * that result from using the dominant-direction-lines and the
- * squared-errors that result from using the 0001-lines.
- */
-/*----------------------------------------------------------------------------*/
-
-/*
- * Partition table representation:
- * We have 3 tables, each with 1024 partitionings
- * (these correspond to the 3x128 hardware partitionings crossed with all the
- * partition-transform modes in the hardware.)
- *
- * For each partitioning, we have:
- * * a 4-entry table indicating how many texels there are in each of the 4
- * partitions. this may be from 2 to about 60 or so.
- * * a 64-entry table indicating the partition index of each of the 64 texels
- * in the block. each index may be 0, 1, 2 or 3.
- *
- * each element in the table is an uint8_t indicating partition index (0, 1, 2 or 3)
- */
-
-#include <math.h>
-
-#include "astc_codec_internals.h"
-
-#ifdef DEBUG_PRINT_DIAGNOSTICS
- #include <stdio.h>
-#endif
-
-#include "mathlib.h"
-
-int imageblock_uses_alpha(int xdim, int ydim, int zdim, const imageblock * pb)
-{
- IGNORE(xdim);
- IGNORE(ydim);
- IGNORE(zdim);
-
- return pb->alpha_max != pb->alpha_min;
-}
-
-static void compute_alpha_minmax(int xdim, int ydim, int zdim, const partition_info * pt, const imageblock * blk, const error_weight_block * ewb, float *alpha_min, float *alpha_max)
-{
- int i;
- int partition_count = pt->partition_count;
-
- int texels_per_block = xdim * ydim * zdim;
-
- for (i = 0; i < partition_count; i++)
- {
- alpha_min[i] = 1e38f;
- alpha_max[i] = -1e38f;
- }
-
- for (i = 0; i < texels_per_block; i++)
- {
- if (ewb->texel_weight[i] > 1e-10)
- {
- int partition = pt->partition_of_texel[i];
- float alphaval = blk->work_data[4 * i + 3];
- if (alphaval > alpha_max[partition])
- alpha_max[partition] = alphaval;
- if (alphaval < alpha_min[partition])
- alpha_min[partition] = alphaval;
- }
- }
-
- for (i = 0; i < partition_count; i++)
- {
- if (alpha_min[i] >= alpha_max[i])
- {
- alpha_min[i] = 0;
- alpha_max[i] = 1e-10f;
- }
- }
-}
-
-
-static void compute_rgb_minmax(int xdim,
- int ydim,
- int zdim,
- const partition_info * pt,
- const imageblock * blk, const error_weight_block * ewb, float *red_min, float *red_max, float *green_min, float *green_max, float *blue_min, float *blue_max)
-{
- int i;
- int partition_count = pt->partition_count;
- int texels_per_block = xdim * ydim * zdim;
-
- for (i = 0; i < partition_count; i++)
- {
- red_min[i] = 1e38f;
- red_max[i] = -1e38f;
- green_min[i] = 1e38f;
- green_max[i] = -1e38f;
- blue_min[i] = 1e38f;
- blue_max[i] = -1e38f;
- }
-
- for (i = 0; i < texels_per_block; i++)
- {
- if (ewb->texel_weight[i] > 1e-10f)
- {
- int partition = pt->partition_of_texel[i];
- float redval = blk->work_data[4 * i];
- float greenval = blk->work_data[4 * i + 1];
- float blueval = blk->work_data[4 * i + 2];
- if (redval > red_max[partition])
- red_max[partition] = redval;
- if (redval < red_min[partition])
- red_min[partition] = redval;
- if (greenval > green_max[partition])
- green_max[partition] = greenval;
- if (greenval < green_min[partition])
- green_min[partition] = greenval;
- if (blueval > blue_max[partition])
- blue_max[partition] = blueval;
- if (blueval < blue_min[partition])
- blue_min[partition] = blueval;
- }
- }
- for (i = 0; i < partition_count; i++)
- {
- if (red_min[i] >= red_max[i])
- {
- red_min[i] = 0.0f;
- red_max[i] = 1e-10f;
- }
- if (green_min[i] >= green_max[i])
- {
- green_min[i] = 0.0f;
- green_max[i] = 1e-10f;
- }
- if (blue_min[i] >= blue_max[i])
- {
- blue_min[i] = 0.0f;
- blue_max[i] = 1e-10f;
- }
- }
-}
-
-
-
-void compute_partition_error_color_weightings(int xdim, int ydim, int zdim, const error_weight_block * ewb, const partition_info * pi, float4 error_weightings[4], float4 color_scalefactors[4])
-{
- int i;
- int texels_per_block = xdim * ydim * zdim;
- int pcnt = pi->partition_count;
- for (i = 0; i < pcnt; i++)
- error_weightings[i] = float4(1e-12f, 1e-12f, 1e-12f, 1e-12f);
- for (i = 0; i < texels_per_block; i++)
- {
- int part = pi->partition_of_texel[i];
- error_weightings[part] = error_weightings[part] + ewb->error_weights[i];
- }
- for (i = 0; i < pcnt; i++)
- {
- error_weightings[i] = error_weightings[i] * (1.0f / pi->texels_per_partition[i]);
- }
- for (i = 0; i < pcnt; i++)
- {
- color_scalefactors[i].x = sqrt(error_weightings[i].x);
- color_scalefactors[i].y = sqrt(error_weightings[i].y);
- color_scalefactors[i].z = sqrt(error_weightings[i].z);
- color_scalefactors[i].w = sqrt(error_weightings[i].w);
- }
-
-}
-
-
-/*
- main function to identify the best partitioning for a given number of texels */
-
-
-void find_best_partitionings(int partition_search_limit, int xdim, int ydim, int zdim, int partition_count,
- const imageblock * pb, const error_weight_block * ewb, int candidates_to_return,
- // best partitionings to use if the endpoint colors are assumed to be uncorrelated
- int *best_partitions_uncorrellated,
- // best partitionings to use if the endpoint colors have the same chroma
- int *best_partitions_samechroma,
- // best partitionings to use if using dual plane of weights
- int *best_partitions_dual_weight_planes)
-{
-
-
- int i, j;
-
- int texels_per_block = xdim * ydim * zdim;
-
- // constant used to estimate quantization error for a given partitioning;
- // the optimal value for this constant depends on bitrate.
- // These constants have been determined empirically.
-
- float weight_imprecision_estim = 100;
-
- if (texels_per_block <= 20)
- weight_imprecision_estim = 0.03f;
- else if (texels_per_block <= 31)
- weight_imprecision_estim = 0.04f;
- else if (texels_per_block <= 41)
- weight_imprecision_estim = 0.05f;
- else
- weight_imprecision_estim = 0.055f;
-
-
- int partition_sequence[PARTITION_COUNT];
-
- kmeans_compute_partition_ordering(xdim, ydim, zdim, partition_count, pb, partition_sequence);
-
-
- float weight_imprecision_estim_squared = weight_imprecision_estim * weight_imprecision_estim;
-
-#ifdef DEBUG_PRINT_DIAGNOSTICS
- if (print_diagnostics)
- printf("weight_imprecision_estim = %g\n", weight_imprecision_estim);
-#endif
-
- int uses_alpha = imageblock_uses_alpha(xdim, ydim, zdim, pb);
-
- const partition_info *ptab = get_partition_table(xdim, ydim, zdim, partition_count);
-
- // partitioning errors assuming uncorrelated-chrominance endpoints
- float uncorr_errors[PARTITION_COUNT];
- // partitioning errors assuming same-chrominance endpoints
- float samechroma_errors[PARTITION_COUNT];
-
- // partitioning errors assuming that one of the color channels
- // is uncorrelated from all the other ones
- float separate_errors[4 * PARTITION_COUNT];
-
-
- float *separate_red_errors = separate_errors;
- float *separate_green_errors = separate_errors + PARTITION_COUNT;
- float *separate_blue_errors = separate_errors + 2 * PARTITION_COUNT;
- float *separate_alpha_errors = separate_errors + 3 * PARTITION_COUNT;
-
- int defacto_search_limit = PARTITION_COUNT - 1;
-
- if (uses_alpha)
- {
-
- #ifdef DEBUG_PRINT_DIAGNOSTICS
- if (print_diagnostics)
- printf("Partition testing with alpha, %d partitions\n\n", partition_count);
- #endif
-
- for (i = 0; i < PARTITION_COUNT; i++)
- {
- int partition = partition_sequence[i];
- int bk_partition_count = ptab[partition].partition_count;
-
- if (bk_partition_count < partition_count)
- {
- #ifdef DEBUG_PRINT_DIAGNOSTICS
- if (print_diagnostics)
- printf("Partitioning %d-%d: invalid\n", partition_count, partition);
- #endif
-
- uncorr_errors[i] = 1e35f;
- samechroma_errors[i] = 1e35f;
- separate_red_errors[i] = 1e35f;
- separate_green_errors[i] = 1e35f;
- separate_blue_errors[i] = 1e35f;
- separate_alpha_errors[i] = 1e35f;
- continue;
- }
- // the sentinel value for partitions above the search limit must be smaller
- // than the sentinel value for invalid partitions
- if (i >= partition_search_limit)
- {
- #ifdef DEBUG_PRINT_DIAGNOSTICS
- if (print_diagnostics)
- printf("Partitioning %d-%d: excluded from testing\n", partition_count, partition);
- #endif
-
- defacto_search_limit = i;
-
- uncorr_errors[i] = 1e34f;
- samechroma_errors[i] = 1e34f;
- separate_red_errors[i] = 1e34f;
- separate_green_errors[i] = 1e34f;
- separate_blue_errors[i] = 1e34f;
- separate_alpha_errors[i] = 1e34f;
- break;
- }
-
- // compute the weighting to give to each color channel
- // in each partition.
- float4 error_weightings[4];
- float4 color_scalefactors[4];
- float4 inverse_color_scalefactors[4];
- compute_partition_error_color_weightings(xdim, ydim, zdim, ewb, ptab + partition, error_weightings, color_scalefactors);
-
- for (j = 0; j < partition_count; j++)
- {
- inverse_color_scalefactors[j].x = 1.0f / MAX(color_scalefactors[j].x, 1e-7f);
- inverse_color_scalefactors[j].y = 1.0f / MAX(color_scalefactors[j].y, 1e-7f);
- inverse_color_scalefactors[j].z = 1.0f / MAX(color_scalefactors[j].z, 1e-7f);
- inverse_color_scalefactors[j].w = 1.0f / MAX(color_scalefactors[j].w, 1e-7f);
- }
-
- float4 averages[4];
- float4 directions_rgba[4];
- float3 directions_gba[4];
- float3 directions_rba[4];
- float3 directions_rga[4];
- float3 directions_rgb[4];
-
- compute_averages_and_directions_rgba(ptab + partition, pb, ewb, color_scalefactors, averages, directions_rgba, directions_gba, directions_rba, directions_rga, directions_rgb);
-
- line4 uncorr_lines[4];
- line4 samechroma_lines[4];
- line3 separate_red_lines[4];
- line3 separate_green_lines[4];
- line3 separate_blue_lines[4];
- line3 separate_alpha_lines[4];
-
- processed_line4 proc_uncorr_lines[4];
- processed_line4 proc_samechroma_lines[4];
- processed_line3 proc_separate_red_lines[4];
- processed_line3 proc_separate_green_lines[4];
- processed_line3 proc_separate_blue_lines[4];
- processed_line3 proc_separate_alpha_lines[4];
-
- float uncorr_linelengths[4];
- float samechroma_linelengths[4];
- float separate_red_linelengths[4];
- float separate_green_linelengths[4];
- float separate_blue_linelengths[4];
- float separate_alpha_linelengths[4];
-
-
-
- for (j = 0; j < partition_count; j++)
- {
- uncorr_lines[j].a = averages[j];
- if (dot(directions_rgba[j], directions_rgba[j]) == 0.0f)
- uncorr_lines[j].b = normalize(float4(1, 1, 1, 1));
- else
- uncorr_lines[j].b = normalize(directions_rgba[j]);
-
- proc_uncorr_lines[j].amod = (uncorr_lines[j].a - uncorr_lines[j].b * dot(uncorr_lines[j].a, uncorr_lines[j].b)) * inverse_color_scalefactors[j];
- proc_uncorr_lines[j].bs = (uncorr_lines[j].b * color_scalefactors[j]);
- proc_uncorr_lines[j].bis = (uncorr_lines[j].b * inverse_color_scalefactors[j]);
-
-
- samechroma_lines[j].a = float4(0, 0, 0, 0);
- if (dot(averages[j], averages[j]) == 0)
- samechroma_lines[j].b = normalize(float4(1, 1, 1, 1));
- else
- samechroma_lines[j].b = normalize(averages[j]);
-
- proc_samechroma_lines[j].amod = (samechroma_lines[j].a - samechroma_lines[j].b * dot(samechroma_lines[j].a, samechroma_lines[j].b)) * inverse_color_scalefactors[j];
- proc_samechroma_lines[j].bs = (samechroma_lines[j].b * color_scalefactors[j]);
- proc_samechroma_lines[j].bis = (samechroma_lines[j].b * inverse_color_scalefactors[j]);
-
- separate_red_lines[j].a = averages[j].yzw;
- if (dot(directions_gba[j], directions_gba[j]) == 0.0f)
- separate_red_lines[j].b = normalize(float3(1, 1, 1));
- else
- separate_red_lines[j].b = normalize(directions_gba[j]);
-
- separate_green_lines[j].a = averages[j].xzw;
- if (dot(directions_rba[j], directions_rba[j]) == 0.0f)
- separate_green_lines[j].b = normalize(float3(1, 1, 1));
- else
- separate_green_lines[j].b = normalize(directions_rba[j]);
-
- separate_blue_lines[j].a = averages[j].xyw;
- if (dot(directions_rga[j], directions_rga[j]) == 0.0f)
- separate_blue_lines[j].b = normalize(float3(1, 1, 1));
- else
- separate_blue_lines[j].b = normalize(directions_rga[j]);
-
- separate_alpha_lines[j].a = averages[j].xyz;
- if (dot(directions_rgb[j], directions_rgb[j]) == 0.0f)
- separate_alpha_lines[j].b = normalize(float3(1, 1, 1));
- else
- separate_alpha_lines[j].b = normalize(directions_rgb[j]);
-
- proc_separate_red_lines[j].amod = (separate_red_lines[j].a - separate_red_lines[j].b * dot(separate_red_lines[j].a, separate_red_lines[j].b)) * inverse_color_scalefactors[j].yzw;
- proc_separate_red_lines[j].bs = (separate_red_lines[j].b * color_scalefactors[j].yzw);
- proc_separate_red_lines[j].bis = (separate_red_lines[j].b * inverse_color_scalefactors[j].yzw);
-
- proc_separate_green_lines[j].amod =
- (separate_green_lines[j].a - separate_green_lines[j].b * dot(separate_green_lines[j].a, separate_green_lines[j].b)) * inverse_color_scalefactors[j].xzw;
- proc_separate_green_lines[j].bs = (separate_green_lines[j].b * color_scalefactors[j].xzw);
- proc_separate_green_lines[j].bis = (separate_green_lines[j].b * inverse_color_scalefactors[j].xzw);
-
- proc_separate_blue_lines[j].amod = (separate_blue_lines[j].a - separate_blue_lines[j].b * dot(separate_blue_lines[j].a, separate_blue_lines[j].b)) * inverse_color_scalefactors[j].xyw;
- proc_separate_blue_lines[j].bs = (separate_blue_lines[j].b * color_scalefactors[j].xyw);
- proc_separate_blue_lines[j].bis = (separate_blue_lines[j].b * inverse_color_scalefactors[j].xyw);
-
- proc_separate_alpha_lines[j].amod =
- (separate_alpha_lines[j].a - separate_alpha_lines[j].b * dot(separate_alpha_lines[j].a, separate_alpha_lines[j].b)) * inverse_color_scalefactors[j].xyz;
- proc_separate_alpha_lines[j].bs = (separate_alpha_lines[j].b * color_scalefactors[j].xyz);
- proc_separate_alpha_lines[j].bis = (separate_alpha_lines[j].b * inverse_color_scalefactors[j].xyz);
-
- }
-
- float uncorr_error = compute_error_squared_rgba(ptab + partition,
- pb,
- ewb,
- proc_uncorr_lines,
- uncorr_linelengths);
- float samechroma_error = compute_error_squared_rgba(ptab + partition,
- pb,
- ewb,
- proc_samechroma_lines,
- samechroma_linelengths);
-
-
- float separate_red_error = compute_error_squared_gba(ptab + partition,
- pb,
- ewb,
- proc_separate_red_lines,
- separate_red_linelengths);
-
- float separate_green_error = compute_error_squared_rba(ptab + partition,
- pb,
- ewb,
- proc_separate_green_lines,
- separate_green_linelengths);
-
- float separate_blue_error = compute_error_squared_rga(ptab + partition,
- pb,
- ewb,
- proc_separate_blue_lines,
- separate_blue_linelengths);
-
- float separate_alpha_error = compute_error_squared_rgb(ptab + partition,
- pb,
- ewb,
- proc_separate_alpha_lines,
- separate_alpha_linelengths);
-
- // compute minimum & maximum alpha values in each partition
- float red_min[4], red_max[4];
- float green_min[4], green_max[4];
- float blue_min[4], blue_max[4];
- float alpha_min[4], alpha_max[4];
- compute_alpha_minmax(xdim, ydim, zdim, ptab + partition, pb, ewb, alpha_min, alpha_max);
-
- compute_rgb_minmax(xdim, ydim, zdim, ptab + partition, pb, ewb, red_min, red_max, green_min, green_max, blue_min, blue_max);
-
- /*
- Compute an estimate of error introduced by weight quantization imprecision.
- This error is computed as follows, for each partition
- 1: compute the principal-axis vector (full length) in error-space
- 2: convert the principal-axis vector to regular RGB-space
- 3: scale the vector by a constant that estimates average quantization error
- 4: for each texel, square the vector, then do a dot-product with the texel's error weight;
- sum up the results across all texels.
- 4(optimized): square the vector once, then do a dot-product with the average texel error,
- then multiply by the number of texels.
- */
-
- for (j = 0; j < partition_count; j++)
- {
- float tpp = (float)(ptab[partition].texels_per_partition[j]);
-
- float4 ics = inverse_color_scalefactors[j];
- float4 error_weights = error_weightings[j] * (tpp * weight_imprecision_estim_squared);
-
- float4 uncorr_vector = (uncorr_lines[j].b * uncorr_linelengths[j]) * ics;
- float4 samechroma_vector = (samechroma_lines[j].b * samechroma_linelengths[j]) * ics;
- float3 separate_red_vector = (separate_red_lines[j].b * separate_red_linelengths[j]) * ics.yzw;
- float3 separate_green_vector = (separate_green_lines[j].b * separate_green_linelengths[j]) * ics.xzw;
- float3 separate_blue_vector = (separate_blue_lines[j].b * separate_blue_linelengths[j]) * ics.xyw;
- float3 separate_alpha_vector = (separate_alpha_lines[j].b * separate_alpha_linelengths[j]) * ics.xyz;
-
- uncorr_vector = uncorr_vector * uncorr_vector;
- samechroma_vector = samechroma_vector * samechroma_vector;
- separate_red_vector = separate_red_vector * separate_red_vector;
- separate_green_vector = separate_green_vector * separate_green_vector;
- separate_blue_vector = separate_blue_vector * separate_blue_vector;
- separate_alpha_vector = separate_alpha_vector * separate_alpha_vector;
-
- uncorr_error += dot(uncorr_vector, error_weights);
- samechroma_error += dot(samechroma_vector, error_weights);
- separate_red_error += dot(separate_red_vector, error_weights.yzw);
- separate_green_error += dot(separate_green_vector, error_weights.xzw);
- separate_blue_error += dot(separate_blue_vector, error_weights.xyw);
- separate_alpha_error += dot(separate_alpha_vector, error_weights.xyz);
-
- float red_scalar = (red_max[j] - red_min[j]);
- float green_scalar = (green_max[j] - green_min[j]);
- float blue_scalar = (blue_max[j] - blue_min[j]);
- float alpha_scalar = (alpha_max[j] - alpha_min[j]);
- red_scalar *= red_scalar;
- green_scalar *= green_scalar;
- blue_scalar *= blue_scalar;
- alpha_scalar *= alpha_scalar;
- separate_red_error += red_scalar * error_weights.x;
- separate_green_error += green_scalar * error_weights.y;
- separate_blue_error += blue_scalar * error_weights.z;
- separate_alpha_error += alpha_scalar * error_weights.w;
- }
-
- uncorr_errors[i] = uncorr_error;
- samechroma_errors[i] = samechroma_error;
- separate_red_errors[i] = separate_red_error;
- separate_green_errors[i] = separate_green_error;
- separate_blue_errors[i] = separate_blue_error;
- separate_alpha_errors[i] = separate_alpha_error;
-
- #ifdef DEBUG_PRINT_DIAGNOSTICS
- if (print_diagnostics)
- printf("Partitioning %d-%d errors: uncorr=%g, samechroma=%g, sep-alpha=%g\n", partition_count, i, uncorr_error, samechroma_error, separate_alpha_error);
- #endif
- }
- }
- else
- {
-
- #ifdef DEBUG_PRINT_DIAGNOSTICS
- if (print_diagnostics)
- printf("Partition testing without alpha, %d partitions\n", partition_count);
- #endif
-
-
-
- for (i = 0; i < PARTITION_COUNT; i++)
- {
-
- int partition = partition_sequence[i];
-
- int bk_partition_count = ptab[partition].partition_count;
- if (bk_partition_count < partition_count)
- {
- #ifdef DEBUG_PRINT_DIAGNOSTICS
- if (print_diagnostics)
- printf("Partitioning %d-%d: invalid\n", partition_count, i);
- #endif
-
- uncorr_errors[i] = 1e35f;
- samechroma_errors[i] = 1e35f;
- separate_red_errors[i] = 1e35f;
- separate_green_errors[i] = 1e35f;
- separate_blue_errors[i] = 1e35f;
- continue;
- }
- // the sentinel value for valid partitions above the search limit must be smaller
- // than the sentinel value for invalid partitions
- if (i >= partition_search_limit)
- {
- #ifdef DEBUG_PRINT_DIAGNOSTICS
- if (print_diagnostics)
- printf(" Partitioning %d-%d: excluded from testing\n", partition_count, partition);
- #endif
-
- defacto_search_limit = i;
- uncorr_errors[i] = 1e34f;
- samechroma_errors[i] = 1e34f;
- separate_red_errors[i] = 1e34f;
- separate_green_errors[i] = 1e34f;
- separate_blue_errors[i] = 1e34f;
- break;
-
- }
-
- // compute the weighting to give to each color channel
- // in each partition.
- float4 error_weightings[4];
- float4 color_scalefactors[4];
- float4 inverse_color_scalefactors[4];
-
- compute_partition_error_color_weightings(xdim, ydim, zdim, ewb, ptab + partition, error_weightings, color_scalefactors);
-
- for (j = 0; j < partition_count; j++)
- {
- inverse_color_scalefactors[j].x = 1.0f / MAX(color_scalefactors[j].x, 1e-7f);
- inverse_color_scalefactors[j].y = 1.0f / MAX(color_scalefactors[j].y, 1e-7f);
- inverse_color_scalefactors[j].z = 1.0f / MAX(color_scalefactors[j].z, 1e-7f);
- inverse_color_scalefactors[j].w = 1.0f / MAX(color_scalefactors[j].w, 1e-7f);
- }
-
- float3 averages[4];
- float3 directions_rgb[4];
- float2 directions_rg[4];
- float2 directions_rb[4];
- float2 directions_gb[4];
-
- compute_averages_and_directions_rgb(ptab + partition, pb, ewb, color_scalefactors, averages, directions_rgb, directions_rg, directions_rb, directions_gb);
-
- line3 uncorr_lines[4];
- line3 samechroma_lines[4];
- line2 separate_red_lines[4];
- line2 separate_green_lines[4];
- line2 separate_blue_lines[4];
-
- processed_line3 proc_uncorr_lines[4];
- processed_line3 proc_samechroma_lines[4];
-
- processed_line2 proc_separate_red_lines[4];
- processed_line2 proc_separate_green_lines[4];
- processed_line2 proc_separate_blue_lines[4];
-
- float uncorr_linelengths[4];
- float samechroma_linelengths[4];
- float separate_red_linelengths[4];
- float separate_green_linelengths[4];
- float separate_blue_linelengths[4];
-
- for (j = 0; j < partition_count; j++)
- {
- uncorr_lines[j].a = averages[j];
- if (dot(directions_rgb[j], directions_rgb[j]) == 0.0f)
- uncorr_lines[j].b = normalize(float3(1, 1, 1));
- else
- uncorr_lines[j].b = normalize(directions_rgb[j]);
-
-
- samechroma_lines[j].a = float3(0, 0, 0);
-
- if (dot(averages[j], averages[j]) == 0.0f)
- samechroma_lines[j].b = normalize(float3(1, 1, 1));
- else
- samechroma_lines[j].b = normalize(averages[j]);
-
- proc_uncorr_lines[j].amod = (uncorr_lines[j].a - uncorr_lines[j].b * dot(uncorr_lines[j].a, uncorr_lines[j].b)) * inverse_color_scalefactors[j].xyz;
- proc_uncorr_lines[j].bs = (uncorr_lines[j].b * color_scalefactors[j].xyz);
- proc_uncorr_lines[j].bis = (uncorr_lines[j].b * inverse_color_scalefactors[j].xyz);
-
- proc_samechroma_lines[j].amod = (samechroma_lines[j].a - samechroma_lines[j].b * dot(samechroma_lines[j].a, samechroma_lines[j].b)) * inverse_color_scalefactors[j].xyz;
- proc_samechroma_lines[j].bs = (samechroma_lines[j].b * color_scalefactors[j].xyz);
- proc_samechroma_lines[j].bis = (samechroma_lines[j].b * inverse_color_scalefactors[j].xyz);
-
- separate_red_lines[j].a = averages[j].yz;
- if (dot(directions_gb[j], directions_gb[j]) == 0.0f)
- separate_red_lines[j].b = normalize(float2(1, 1));
- else
- separate_red_lines[j].b = normalize(directions_gb[j]);
-
- separate_green_lines[j].a = averages[j].xz;
- if (dot(directions_rb[j], directions_rb[j]) == 0.0f)
- separate_green_lines[j].b = normalize(float2(1, 1));
- else
- separate_green_lines[j].b = normalize(directions_rb[j]);
-
- separate_blue_lines[j].a = averages[j].xy;
- if (dot(directions_rg[j], directions_rg[j]) == 0.0f)
- separate_blue_lines[j].b = normalize(float2(1, 1));
- else
- separate_blue_lines[j].b = normalize(directions_rg[j]);
-
- proc_separate_red_lines[j].amod = (separate_red_lines[j].a - separate_red_lines[j].b * dot(separate_red_lines[j].a, separate_red_lines[j].b)) * inverse_color_scalefactors[j].yz;
- proc_separate_red_lines[j].bs = (separate_red_lines[j].b * color_scalefactors[j].yz);
- proc_separate_red_lines[j].bis = (separate_red_lines[j].b * inverse_color_scalefactors[j].yz);
-
- proc_separate_green_lines[j].amod =
- (separate_green_lines[j].a - separate_green_lines[j].b * dot(separate_green_lines[j].a, separate_green_lines[j].b)) * inverse_color_scalefactors[j].xz;
- proc_separate_green_lines[j].bs = (separate_green_lines[j].b * color_scalefactors[j].xz);
- proc_separate_green_lines[j].bis = (separate_green_lines[j].b * inverse_color_scalefactors[j].xz);
-
- proc_separate_blue_lines[j].amod = (separate_blue_lines[j].a - separate_blue_lines[j].b * dot(separate_blue_lines[j].a, separate_blue_lines[j].b)) * inverse_color_scalefactors[j].xy;
- proc_separate_blue_lines[j].bs = (separate_blue_lines[j].b * color_scalefactors[j].xy);
- proc_separate_blue_lines[j].bis = (separate_blue_lines[j].b * inverse_color_scalefactors[j].xy);
-
- }
-
- float uncorr_error = compute_error_squared_rgb(ptab + partition,
- pb,
- ewb,
- proc_uncorr_lines,
- uncorr_linelengths);
- float samechroma_error = compute_error_squared_rgb(ptab + partition,
- pb,
- ewb,
- proc_samechroma_lines,
- samechroma_linelengths);
-
- float separate_red_error = compute_error_squared_gb(ptab + partition,
- pb,
- ewb,
- proc_separate_red_lines,
- separate_red_linelengths);
-
- float separate_green_error = compute_error_squared_rb(ptab + partition,
- pb,
- ewb,
- proc_separate_green_lines,
- separate_green_linelengths);
-
- float separate_blue_error = compute_error_squared_rg(ptab + partition,
- pb,
- ewb,
- proc_separate_blue_lines,
- separate_blue_linelengths);
-
- float red_min[4], red_max[4];
- float green_min[4], green_max[4];
- float blue_min[4], blue_max[4];
-
-
- compute_rgb_minmax(xdim, ydim, zdim, ptab + partition, pb, ewb, red_min, red_max, green_min, green_max, blue_min, blue_max);
-
-
-
- /*
- compute an estimate of error introduced by weight imprecision.
- This error is computed as follows, for each partition
- 1: compute the principal-axis vector (full length) in error-space
- 2: convert the principal-axis vector to regular RGB-space
- 3: scale the vector by a constant that estimates average quantization error.
- 4: for each texel, square the vector, then do a dot-product with the texel's error weight;
- sum up the results across all texels.
- 4(optimized): square the vector once, then do a dot-product with the average texel error,
- then multiply by the number of texels.
- */
-
-
- for (j = 0; j < partition_count; j++)
- {
- float tpp = (float)(ptab[partition].texels_per_partition[j]);
-
- float3 ics = inverse_color_scalefactors[j].xyz;
- float3 error_weights = error_weightings[j].xyz * (tpp * weight_imprecision_estim_squared);
-
- float3 uncorr_vector = (uncorr_lines[j].b * uncorr_linelengths[j]) * ics;
- float3 samechroma_vector = (samechroma_lines[j].b * samechroma_linelengths[j]) * ics;
-
- float2 separate_red_vector = (separate_red_lines[j].b * separate_red_linelengths[j]) * ics.yz;
- float2 separate_green_vector = (separate_green_lines[j].b * separate_green_linelengths[j]) * ics.xz;
- float2 separate_blue_vector = (separate_blue_lines[j].b * separate_blue_linelengths[j]) * ics.xy;
-
- uncorr_vector = uncorr_vector * uncorr_vector;
- samechroma_vector = samechroma_vector * samechroma_vector;
- separate_red_vector = separate_red_vector * separate_red_vector;
- separate_green_vector = separate_green_vector * separate_green_vector;
- separate_blue_vector = separate_blue_vector * separate_blue_vector;
-
- uncorr_error += dot(uncorr_vector, error_weights);
- samechroma_error += dot(samechroma_vector, error_weights);
- separate_red_error += dot(separate_red_vector, error_weights.yz);
- separate_green_error += dot(separate_green_vector, error_weights.xz);
- separate_blue_error += dot(separate_blue_vector, error_weights.xy);
-
- float red_scalar = (red_max[j] - red_min[j]);
- float green_scalar = (green_max[j] - green_min[j]);
- float blue_scalar = (blue_max[j] - blue_min[j]);
-
- red_scalar *= red_scalar;
- green_scalar *= green_scalar;
- blue_scalar *= blue_scalar;
-
- separate_red_error += red_scalar * error_weights.x;
- separate_green_error += green_scalar * error_weights.y;
- separate_blue_error += blue_scalar * error_weights.z;
- }
-
-
- uncorr_errors[i] = uncorr_error;
- samechroma_errors[i] = samechroma_error;
-
- separate_red_errors[i] = separate_red_error;
- separate_green_errors[i] = separate_green_error;
- separate_blue_errors[i] = separate_blue_error;
-
- #ifdef DEBUG_PRINT_DIAGNOSTICS
- if (print_diagnostics)
- printf("Partitioning %d-%d errors: uncorr=%f, samechroma=%f, sep-red=%f, sep-green=%f, sep-blue=%f\n",
- partition_count, partition, uncorr_error, samechroma_error, separate_red_error, separate_green_error, separate_blue_error);
- #endif
- }
- }
-
-
- for (i = 0; i < candidates_to_return; i++)
- {
- int best_uncorr_partition = 0;
- int best_samechroma_partition = 0;
- float best_uncorr_error = 1e30f;
- float best_samechroma_error = 1e30f;
- for (j = 0; j <= defacto_search_limit; j++)
- {
- if (uncorr_errors[j] < best_uncorr_error)
- {
- best_uncorr_partition = j;
- best_uncorr_error = uncorr_errors[j];
- }
- }
- best_partitions_uncorrellated[i] = partition_sequence[best_uncorr_partition];
- uncorr_errors[best_uncorr_partition] = 1e30f;
- samechroma_errors[best_uncorr_partition] = 1e30f;
-
- for (j = 0; j <= defacto_search_limit; j++)
- {
- if (samechroma_errors[j] < best_samechroma_error)
- {
- best_samechroma_partition = j;
- best_samechroma_error = samechroma_errors[j];
- }
- }
- best_partitions_samechroma[i] = partition_sequence[best_samechroma_partition];
- samechroma_errors[best_samechroma_partition] = 1e30f;
- uncorr_errors[best_samechroma_partition] = 1e30f;
- }
-
- for (i = 0; i < 2 * candidates_to_return; i++)
- {
- int best_partition = 0;
- float best_partition_error = 1e30f;
-
- for (j = 0; j <= defacto_search_limit; j++)
- {
- if (1 || !uses_alpha)
- {
- if (separate_errors[j] < best_partition_error)
- {
- best_partition = j;
- best_partition_error = separate_errors[j];
- }
- if (separate_errors[j + PARTITION_COUNT] < best_partition_error)
- {
- best_partition = j + PARTITION_COUNT;
- best_partition_error = separate_errors[j + PARTITION_COUNT];
- }
- if (separate_errors[j + 2 * PARTITION_COUNT] < best_partition_error)
- {
- best_partition = j + 2 * PARTITION_COUNT;
- best_partition_error = separate_errors[j + 2 * PARTITION_COUNT];
- }
- }
- if (uses_alpha)
- {
- if (separate_errors[j + 3 * PARTITION_COUNT] < best_partition_error)
- {
- best_partition = j + 3 * PARTITION_COUNT;
- best_partition_error = separate_errors[j + 3 * PARTITION_COUNT];
- }
- }
- }
-
- separate_errors[best_partition] = 1e30f;
- best_partition = ((best_partition >> PARTITION_BITS) << PARTITION_BITS) | partition_sequence[best_partition & (PARTITION_COUNT - 1)];
- best_partitions_dual_weight_planes[i] = best_partition;
- }
-
-}