1 /*----------------------------------------------------------------------------*/
2 /**
3  *	This confidential and proprietary software may be used only as
4  *	authorised by a licensing agreement from ARM Limited
5  *	(C) COPYRIGHT 2011-2012, 2018 ARM Limited
6  *	ALL RIGHTS RESERVED
7  *
8  *	The entire notice above must be reproduced on all authorised
9  *	copies and copies may only be made to the extent permitted
10  *	by a licensing agreement from ARM Limited.
11  *
12  *	@brief	Internal function and data declarations for ASTC codec.
13  */
14 /*----------------------------------------------------------------------------*/
15 
16 #ifndef ASTC_CODEC_INTERNALS_INCLUDED
17 
18 #define ASTC_CODEC_INTERNALS_INCLUDED
19 
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include <math.h>
23 #include "mathlib.h"
24 
25 #ifndef MIN
26 	#define MIN(x,y) ((x)<(y)?(x):(y))
27 #endif
28 
29 #ifndef MAX
30 	#define MAX(x,y) ((x)>(y)?(x):(y))
31 #endif
32 
33 // Macro to silence warnings on ignored parameters.
34 // The presence of this macro should be a signal to look at refactoring.
35 #define IGNORE(param) ((void)&param)
36 
37 #define astc_isnan(p) ((p)!=(p))
38 
39 // ASTC parameters
40 #define MAX_TEXELS_PER_BLOCK 216
41 #define MAX_WEIGHTS_PER_BLOCK 64
42 #define MIN_WEIGHT_BITS_PER_BLOCK 24
43 #define MAX_WEIGHT_BITS_PER_BLOCK 96
44 #define PARTITION_BITS 10
45 #define PARTITION_COUNT (1 << PARTITION_BITS)
46 
47 // the sum of weights for one texel.
48 #define TEXEL_WEIGHT_SUM 16
49 #define MAX_DECIMATION_MODES 87
50 #define MAX_WEIGHT_MODES 2048
51 
52 // error reporting for codec internal errors.
53 #define ASTC_CODEC_INTERNAL_ERROR astc_codec_internal_error(__FILE__, __LINE__)
54 
55 void astc_codec_internal_error(const char *filename, int linenumber);
56 
57 // uncomment this macro to enable checking for inappropriate NaNs;
58 // works on Linux only, and slows down encoding significantly.
59 // #define DEBUG_CAPTURE_NAN
60 
61 // the PRINT_DIAGNOSTICS macro enables the -diag command line switch,
62 // which can be used to look for codec bugs
63 #define DEBUG_PRINT_DIAGNOSTICS
64 
65 #ifdef DEBUG_PRINT_DIAGNOSTICS
66 	extern int print_diagnostics;
67 #endif
68 
69 extern int print_tile_errors;
70 extern int print_statistics;
71 
72 extern int perform_srgb_transform;
73 extern int rgb_force_use_of_hdr;
74 extern int alpha_force_use_of_hdr;
75 
76 struct processed_line2
77 {
78 	float2 amod;
79 	float2 bs;
80 	float2 bis;
81 };
82 struct processed_line3
83 {
84 	float3 amod;
85 	float3 bs;
86 	float3 bis;
87 };
88 struct processed_line4
89 {
90 	float4 amod;
91 	float4 bs;
92 	float4 bis;
93 };
94 
95 enum astc_decode_mode
96 {
97 	DECODE_LDR_SRGB,
98 	DECODE_LDR,
99 	DECODE_HDR
100 };
101 
102 
103 /*
104 	Partition table representation:
105 	For each block size, we have 3 tables, each with 1024 partitionings;
106 	these three tables correspond to 2, 3 and 4 partitions respectively.
107 	For each partitioning, we have:
108 	* a 4-entry table indicating how many texels there are in each of the 4 partitions.
109 	  This may be from 0 to a very large value.
110 	* a table indicating the partition index of each of the texels in the block.
111 	  Each index may be 0, 1, 2 or 3.
112 	* Each element in the table is an uint8_t indicating partition index (0, 1, 2 or 3)
113 */
114 
115 struct partition_info
116 {
117 	int partition_count;
118 	uint8_t texels_per_partition[4];
119 	uint8_t partition_of_texel[MAX_TEXELS_PER_BLOCK];
120 	uint8_t texels_of_partition[4][MAX_TEXELS_PER_BLOCK];
121 
122 	uint64_t coverage_bitmaps[4];	// used for the purposes of k-means partition search.
123 };
124 
125 
126 
127 
128 /*
129    In ASTC, we don't necessarily provide a weight for every texel.
130    As such, for each block size, there are a number of patterns where some texels
131    have their weights computed as a weighted average of more than 1 weight.
132    As such, the codec uses a data structure that tells us: for each texel, which
133    weights it is a combination of for each weight, which texels it contributes to.
134    The decimation_table is this data structure.
135 */
136 struct decimation_table
137 {
138 	int num_texels;
139 	int num_weights;
140 	uint8_t texel_num_weights[MAX_TEXELS_PER_BLOCK];	// number of indices that go into the calculation for a texel
141 	uint8_t texel_weights_int[MAX_TEXELS_PER_BLOCK][4];	// the weight to assign to each weight
142 	float texel_weights_float[MAX_TEXELS_PER_BLOCK][4];	// the weight to assign to each weight
143 	uint8_t texel_weights[MAX_TEXELS_PER_BLOCK][4];	// the weights that go into a texel calculation
144 	uint8_t weight_num_texels[MAX_WEIGHTS_PER_BLOCK];	// the number of texels that a given weight contributes to
145 	uint8_t weight_texel[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK];	// the texels that the weight contributes to
146 	uint8_t weights_int[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK];	// the weights that the weight contributes to a texel.
147 	float weights_flt[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK];	// the weights that the weight contributes to a texel.
148 };
149 
150 
151 
152 
153 /*
154    data structure describing information that pertains to a block size and its associated block modes.
155 */
156 struct block_mode
157 {
158 	int8_t decimation_mode;
159 	int8_t quantization_mode;
160 	int8_t is_dual_plane;
161 	int8_t permit_encode;
162 	int8_t permit_decode;
163 	float percentile;
164 };
165 
166 
167 struct block_size_descriptor
168 {
169 	int decimation_mode_count;
170 	int decimation_mode_samples[MAX_DECIMATION_MODES];
171 	int decimation_mode_maxprec_1plane[MAX_DECIMATION_MODES];
172 	int decimation_mode_maxprec_2planes[MAX_DECIMATION_MODES];
173 	float decimation_mode_percentile[MAX_DECIMATION_MODES];
174 	int permit_encode[MAX_DECIMATION_MODES];
175 	const decimation_table *decimation_tables[MAX_DECIMATION_MODES + 1];
176 	block_mode block_modes[MAX_WEIGHT_MODES];
177 
178 	// for the k-means bed bitmap partitioning algorithm, we don't
179 	// want to consider more than 64 texels; this array specifies
180 	// which 64 texels (if that many) to consider.
181 	int texelcount_for_bitmap_partitioning;
182 	int texels_for_bitmap_partitioning[64];
183 };
184 
185 // data structure representing one block of an image.
186 // it is expanded to float prior to processing to save some computation time
187 // on conversions to/from uint8_t (this also allows us to handle HDR textures easily)
188 struct imageblock
189 {
190 	float orig_data[MAX_TEXELS_PER_BLOCK * 4];  // original input data
191 	float work_data[MAX_TEXELS_PER_BLOCK * 4];  // the data that we will compress, either linear or LNS (0..65535 in both cases)
192 	float deriv_data[MAX_TEXELS_PER_BLOCK * 4]; // derivative of the conversion function used, used to modify error weighting
193 
194 	uint8_t rgb_lns[MAX_TEXELS_PER_BLOCK];      // 1 if RGB data are being treated as LNS
195 	uint8_t alpha_lns[MAX_TEXELS_PER_BLOCK];    // 1 if Alpha data are being treated as LNS
196 	uint8_t nan_texel[MAX_TEXELS_PER_BLOCK];    // 1 if the texel is a NaN-texel.
197 
198 	float red_min, red_max;
199 	float green_min, green_max;
200 	float blue_min, blue_max;
201 	float alpha_min, alpha_max;
202 	int grayscale;				// 1 if R=G=B for every pixel, 0 otherwise
203 
204 	int xpos, ypos, zpos;
205 };
206 
207 
208 struct error_weighting_params
209 {
210 	float rgb_power;
211 	float rgb_base_weight;
212 	float rgb_mean_weight;
213 	float rgb_stdev_weight;
214 	float alpha_power;
215 	float alpha_base_weight;
216 	float alpha_mean_weight;
217 	float alpha_stdev_weight;
218 	float rgb_mean_and_stdev_mixing;
219 	int mean_stdev_radius;
220 	int enable_rgb_scale_with_alpha;
221 	int alpha_radius;
222 	int ra_normal_angular_scale;
223 	float block_artifact_suppression;
224 	float rgba_weights[4];
225 
226 	float block_artifact_suppression_expanded[MAX_TEXELS_PER_BLOCK];
227 
228 	// parameters that deal with heuristic codec speedups
229 	int partition_search_limit;
230 	float block_mode_cutoff;
231 	float texel_avg_error_limit;
232 	float partition_1_to_2_limit;
233 	float lowest_correlation_cutoff;
234 	int max_refinement_iters;
235 };
236 
237 
238 
239 
240 void update_imageblock_flags(imageblock * pb, int xdim, int ydim, int zdim);
241 
242 
243 void imageblock_initialize_orig_from_work(imageblock * pb, int pixelcount);
244 
245 
246 void imageblock_initialize_work_from_orig(imageblock * pb, int pixelcount);
247 
248 
249 
250 /*
251 	Data structure representing error weighting for one block of an image. this is used as
252 	a multiplier for the error weight to apply to each color component when computing PSNR.
253 
254 	This weighting has several uses: it's usable for RA, GA, BA, A weighting, which is useful
255 	for alpha-textures it's usable for HDR textures, where weighting should be approximately inverse to
256 	luminance it's usable for perceptual weighting, where we assign higher weight to low-variability
257 	regions than to high-variability regions. it's usable for suppressing off-edge block content in
258 	case the texture doesn't actually extend to the edge of the block.
259 
260 	For the default case (everything is evenly weighted), every weight is 1. For the RA,GA,BA,A case,
261 	we multiply the R,G,B weights with that of the alpha.
262 
263 	Putting the same weight in every component should result in the default case.
264 	The following relations should hold:
265 
266 	texel_weight_rg[i] = (texel_weight_r[i] + texel_weight_g[i]) / 2
267 	texel_weight_lum[i] = (texel_weight_r[i] + texel_weight_g[i] + texel_weight_b[i]) / 3
268 	texel_weight[i] = (texel_weight_r[i] + texel_weight_g[i] + texel_weight_b[i] + texel_weight_a[i] / 4
269  */
270 
271 struct error_weight_block
272 {
273 	float4 error_weights[MAX_TEXELS_PER_BLOCK];
274 	float texel_weight[MAX_TEXELS_PER_BLOCK];
275 	float texel_weight_gba[MAX_TEXELS_PER_BLOCK];
276 	float texel_weight_rba[MAX_TEXELS_PER_BLOCK];
277 	float texel_weight_rga[MAX_TEXELS_PER_BLOCK];
278 	float texel_weight_rgb[MAX_TEXELS_PER_BLOCK];
279 
280 	float texel_weight_rg[MAX_TEXELS_PER_BLOCK];
281 	float texel_weight_rb[MAX_TEXELS_PER_BLOCK];
282 	float texel_weight_gb[MAX_TEXELS_PER_BLOCK];
283 	float texel_weight_ra[MAX_TEXELS_PER_BLOCK];
284 
285 	float texel_weight_r[MAX_TEXELS_PER_BLOCK];
286 	float texel_weight_g[MAX_TEXELS_PER_BLOCK];
287 	float texel_weight_b[MAX_TEXELS_PER_BLOCK];
288 	float texel_weight_a[MAX_TEXELS_PER_BLOCK];
289 
290 	int contains_zeroweight_texels;
291 };
292 
293 
294 
295 struct error_weight_block_orig
296 {
297 	float4 error_weights[MAX_TEXELS_PER_BLOCK];
298 };
299 
300 
301 // enumeration of all the quantization methods we support under this format.
302 enum quantization_method
303 {
304 	QUANT_2 = 0,
305 	QUANT_3 = 1,
306 	QUANT_4 = 2,
307 	QUANT_5 = 3,
308 	QUANT_6 = 4,
309 	QUANT_8 = 5,
310 	QUANT_10 = 6,
311 	QUANT_12 = 7,
312 	QUANT_16 = 8,
313 	QUANT_20 = 9,
314 	QUANT_24 = 10,
315 	QUANT_32 = 11,
316 	QUANT_40 = 12,
317 	QUANT_48 = 13,
318 	QUANT_64 = 14,
319 	QUANT_80 = 15,
320 	QUANT_96 = 16,
321 	QUANT_128 = 17,
322 	QUANT_160 = 18,
323 	QUANT_192 = 19,
324 	QUANT_256 = 20
325 };
326 
327 
328 /*
329 	In ASTC, we support relatively many combinations of weight precisions and weight transfer functions.
330 	As such, for each combination we support, we have a hardwired data structure.
331 
332 	This structure provides the following information: A table, used to estimate the closest quantized
333 	weight for a given floating-point weight. For each quantized weight, the corresponding unquantized
334 	and floating-point values. For each quantized weight, a previous-value and a next-value.
335 */
336 
337 struct quantization_and_transfer_table
338 {
339 	quantization_method method;
340 	uint8_t unquantized_value[32];	// 0..64
341 	float unquantized_value_flt[32];	// 0..1
342 	uint8_t prev_quantized_value[32];
343 	uint8_t next_quantized_value[32];
344 	uint8_t closest_quantized_weight[1025];
345 };
346 
347 extern const quantization_and_transfer_table quant_and_xfer_tables[12];
348 
349 
350 
351 enum endpoint_formats
352 {
353 	FMT_LUMINANCE = 0,
354 	FMT_LUMINANCE_DELTA = 1,
355 	FMT_HDR_LUMINANCE_LARGE_RANGE = 2,
356 	FMT_HDR_LUMINANCE_SMALL_RANGE = 3,
357 	FMT_LUMINANCE_ALPHA = 4,
358 	FMT_LUMINANCE_ALPHA_DELTA = 5,
359 	FMT_RGB_SCALE = 6,
360 	FMT_HDR_RGB_SCALE = 7,
361 	FMT_RGB = 8,
362 	FMT_RGB_DELTA = 9,
363 	FMT_RGB_SCALE_ALPHA = 10,
364 	FMT_HDR_RGB = 11,
365 	FMT_RGBA = 12,
366 	FMT_RGBA_DELTA = 13,
367 	FMT_HDR_RGB_LDR_ALPHA = 14,
368 	FMT_HDR_RGBA = 15,
369 };
370 
371 
372 
373 struct symbolic_compressed_block
374 {
375 	int error_block;			// 1 marks error block, 0 marks non-error-block.
376 	int block_mode;				// 0 to 2047. Negative value marks constant-color block (-1: FP16, -2:UINT16)
377 	int partition_count;		// 1 to 4; Zero marks a constant-color block.
378 	int partition_index;		// 0 to 1023
379 	int color_formats[4];		// color format for each endpoint color pair.
380 	int color_formats_matched;	// color format for all endpoint pairs are matched.
381 	int color_values[4][12];	// quantized endpoint color pairs.
382 	int color_quantization_level;
383 	uint8_t plane1_weights[MAX_WEIGHTS_PER_BLOCK];	// quantized and decimated weights
384 	uint8_t plane2_weights[MAX_WEIGHTS_PER_BLOCK];
385 	int plane2_color_component;	// color component for the secondary plane of weights
386 	int constant_color[4];		// constant-color, as FP16 or UINT16. Used for constant-color blocks only.
387 };
388 
389 
390 struct physical_compressed_block
391 {
392 	uint8_t data[16];
393 };
394 
395 
396 
397 
398 const block_size_descriptor *get_block_size_descriptor(int xdim, int ydim, int zdim);
399 
400 
401 // ***********************************************************
402 // functions and data pertaining to quantization and encoding
403 // **********************************************************
404 extern const uint8_t color_quantization_tables[21][256];
405 extern const uint8_t color_unquantization_tables[21][256];
406 
407 void encode_ise(int quantization_level, int elements, const uint8_t * input_data, uint8_t * output_data, int bit_offset);
408 
409 void decode_ise(int quantization_level, int elements, const uint8_t * input_data, uint8_t * output_data, int bit_offset);
410 
411 int compute_ise_bitcount(int items, quantization_method quant);
412 
413 void build_quantization_mode_table(void);
414 extern int quantization_mode_table[17][128];
415 
416 
417 // **********************************************
418 // functions and data pertaining to partitioning
419 // **********************************************
420 
421 // function to get a pointer to a partition table or an array thereof.
422 const partition_info *get_partition_table(int xdim, int ydim, int zdim, int partition_count);
423 
424 
425 
426 
427 // functions to compute color averages and dominant directions
428 // for each partition in a block
429 
430 
431 void compute_averages_and_directions_rgb(const partition_info * pt,
432 										 const imageblock * blk,
433 										 const error_weight_block * ewb,
434 										 const float4 * color_scalefactors, float3 * averages, float3 * directions_rgb, float2 * directions_rg, float2 * directions_rb, float2 * directions_gb);
435 
436 
437 
438 void compute_averages_and_directions_rgba(const partition_info * pt,
439 										  const imageblock * blk,
440 										  const error_weight_block * ewb,
441 										  const float4 * color_scalefactors,
442 										  float4 * averages, float4 * directions_rgba, float3 * directions_gba, float3 * directions_rba, float3 * directions_rga, float3 * directions_rgb);
443 
444 
445 void compute_averages_and_directions_3_components(const partition_info * pt,
446 												  const imageblock * blk,
447 												  const error_weight_block * ewb,
448 												  const float3 * color_scalefactors, int component1, int component2, int component3, float3 * averages, float3 * directions);
449 
450 void compute_averages_and_directions_2_components(const partition_info * pt,
451 												  const imageblock * blk,
452 												  const error_weight_block * ewb, const float2 * color_scalefactors, int component1, int component2, float2 * averages, float2 * directions);
453 
454 // functions to compute error value across a tile given a partitioning
455 // (with the assumption that each partitioning has colors lying on a line where
456 // they are represented with infinite precision. Also return the length of the line
457 // segments that the partition's colors are actually projected onto.
458 float compute_error_squared_gba(const partition_info * pt,	// the partition that we use when computing the squared-error.
459 								const imageblock * blk, const error_weight_block * ewb, const processed_line3 * plines,
460 								// output: computed length of the partitioning's line. This is not part of the
461 								// error introduced by partitioning itself, but us used to estimate the error introduced by quantization
462 								float *length_of_lines);
463 
464 float compute_error_squared_rba(const partition_info * pt,	// the partition that we use when computing the squared-error.
465 								const imageblock * blk, const error_weight_block * ewb, const processed_line3 * plines,
466 								// output: computed length of the partitioning's line. This is not part of the
467 								// error introduced by partitioning itself, but us used to estimate the error introduced by quantization
468 								float *length_of_lines);
469 
470 float compute_error_squared_rga(const partition_info * pt,	// the partition that we use when computing the squared-error.
471 								const imageblock * blk, const error_weight_block * ewb, const processed_line3 * plines,
472 								// output: computed length of the partitioning's line. This is not part of the
473 								// error introduced by partitioning itself, but us used to estimate the error introduced by quantization
474 								float *length_of_lines);
475 
476 float compute_error_squared_rgb(const partition_info * pt,	// the partition that we use when computing the squared-error.
477 								const imageblock * blk, const error_weight_block * ewb, const processed_line3 * plines,
478 								// output: computed length of the partitioning's line. This is not part of the
479 								// error introduced by partitioning itself, but us used to estimate the error introduced by quantization
480 								float *length_of_lines);
481 
482 
483 float compute_error_squared_rgba(const partition_info * pt,	// the partition that we use when computing the squared-error.
484 								 const imageblock * blk, const error_weight_block * ewb, const processed_line4 * lines,	// one line for each of the partitions. The lines are assumed to be normalized.
485 								 float *length_of_lines);
486 
487 float compute_error_squared_rg(const partition_info * pt,	// the partition that we use when computing the squared-error.
488 							   const imageblock * blk, const error_weight_block * ewb, const processed_line2 * plines, float *length_of_lines);
489 
490 float compute_error_squared_rb(const partition_info * pt,	// the partition that we use when computing the squared-error.
491 							   const imageblock * blk, const error_weight_block * ewb, const processed_line2 * plines, float *length_of_lines);
492 
493 float compute_error_squared_gb(const partition_info * pt,	// the partition that we use when computing the squared-error.
494 							   const imageblock * blk, const error_weight_block * ewb, const processed_line2 * plines, float *length_of_lines);
495 
496 float compute_error_squared_ra(const partition_info * pt,	// the partition that we use when computing the squared-error.
497 							   const imageblock * blk, const error_weight_block * ewb, const processed_line2 * plines, float *length_of_lines);
498 
499 
500 // functions to compute error value across a tile for a particular line function
501 // for a single partition.
502 float compute_error_squared_rgb_single_partition(int partition_to_test, int xdim, int ydim, int zdim, const partition_info * pt,	// the partition that we use when computing the squared-error.
503 												 const imageblock * blk, const error_weight_block * ewb, const processed_line3 * lin	// the line for the partition.
504 	);
505 
506 
507 
508 // for each partition, compute its color weightings.
509 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]);
510 
511 
512 
513 // function to find the best partitioning for a given block.
514 
515 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,
516 							 // best partitionings to use if the endpoint colors are assumed to be uncorrelated
517 							 int *best_partitions_uncorrellated,
518 							 // best partitionings to use if the endpoint colors have the same chroma
519 							 int *best_partitions_samechroma,
520 							 // best partitionings to use if dual plane of weights are present
521 							 int *best_partitions_dual_weight_planes);
522 
523 
524 // use k-means clustering to compute a partition ordering for a block.
525 void kmeans_compute_partition_ordering(int xdim, int ydim, int zdim, int partition_count, const imageblock * blk, int *ordering);
526 
527 
528 
529 
530 // *********************************************************
531 // functions and data pertaining to images and imageblocks
532 // *********************************************************
533 
534 struct astc_codec_image
535 {
536 	uint8_t ***imagedata8;
537 	uint16_t ***imagedata16;
538 	int xsize;
539 	int ysize;
540 	int zsize;
541 	int padding;
542 };
543 
544 void destroy_image(astc_codec_image * img);
545 astc_codec_image *allocate_image(int bitness, int xsize, int ysize, int zsize, int padding);
546 void initialize_image(astc_codec_image * img);
547 void fill_image_padding_area(astc_codec_image * img);
548 
549 
550 extern float4 ***input_averages;
551 extern float4 ***input_variances;
552 extern float ***input_alpha_averages;
553 
554 
555 // the entries here : 0=red, 1=green, 2=blue, 3=alpha, 4=0.0, 5=1.0
556 struct swizzlepattern
557 {
558 	uint8_t r;
559 	uint8_t g;
560 	uint8_t b;
561 	uint8_t a;
562 };
563 
564 
565 
566 int determine_image_channels(const astc_codec_image * img);
567 
568 // function to compute regional averages and variances for an image
569 void compute_averages_and_variances(const astc_codec_image * img, float rgb_power_to_use, float alpha_power_to_use, int avg_kernel_radius, int var_kernel_radius, swizzlepattern swz);
570 
571 
572 /*
573 	Functions to load image from file.
574 	If successful, return an astc_codec_image object.
575 	If unsuccessful, returns NULL.
576 
577 	*result is used to return a result. In case of a successfully loaded image, bits[2:0]
578 	of *result indicate how many components are present, and bit[7] indicate whether
579 	the input image was LDR or HDR (0=LDR, 1=HDR).
580 
581 	In case of failure, *result is given a negative value.
582 */
583 
584 
585 astc_codec_image *load_ktx_uncompressed_image(const char *filename, int padding, int *result);
586 astc_codec_image *load_dds_uncompressed_image(const char *filename, int padding, int *result);
587 astc_codec_image *load_tga_image(const char *tga_filename, int padding, int *result);
588 astc_codec_image *load_image_with_stb(const char *filename, int padding, int *result);
589 
590 astc_codec_image *astc_codec_load_image(const char *filename, int padding, int *result);
591 int astc_codec_unlink(const char *filename);
592 
593 // function to store image to file
594 // If successful, returns the number of channels in input image
595 // If unsuccessful, returns a negative number.
596 int store_ktx_uncompressed_image(const astc_codec_image * img, const char *filename, int bitness);
597 int store_dds_uncompressed_image(const astc_codec_image * img, const char *filename, int bitness);
598 int store_tga_image(const astc_codec_image * img, const char *tga_filename, int bitness);
599 
600 int astc_codec_store_image(const astc_codec_image * img, const char *filename, int bitness, const char **format_string);
601 
602 int get_output_filename_enforced_bitness(const char *filename);
603 
604 
605 // compute a bunch of error metrics
606 void compute_error_metrics(int input_image_is_hdr, int input_components, const astc_codec_image * img1, const astc_codec_image * img2, int low_fstop, int high_fstop, int psnrmode);
607 
608 // fetch an image-block from the input file
609 void fetch_imageblock(const astc_codec_image * img, imageblock * pb,	// picture-block to initialize with image data
610 					  // block dimensions
611 					  int xdim, int ydim, int zdim,
612 					  // position in picture to fetch block from
613 					  int xpos, int ypos, int zpos, swizzlepattern swz);
614 
615 
616 // write an image block to the output file buffer.
617 // the data written are taken from orig_data.
618 void write_imageblock(astc_codec_image * img, const imageblock * pb,	// picture-block to initialize with image data
619 					  // block dimensions
620 					  int xdim, int ydim, int zdim,
621 					  // position in picture to write block to.
622 					  int xpos, int ypos, int zpos, swizzlepattern swz);
623 
624 
625 // helper function to check whether a given picture-block has alpha that is not
626 // just uniformly 1.
627 int imageblock_uses_alpha(int xdim, int ydim, int zdim, const imageblock * pb);
628 
629 
630 float compute_imageblock_difference(int xdim, int ydim, int zdim, const imageblock * p1, const imageblock * p2, const error_weight_block * ewb);
631 
632 
633 
634 
635 
636 // ***********************************************************
637 // functions pertaining to computing texel weights for a block
638 // ***********************************************************
639 
640 
641 struct endpoints
642 {
643 	int partition_count;
644 	float4 endpt0[4];
645 	float4 endpt1[4];
646 };
647 
648 
649 struct endpoints_and_weights
650 {
651 	endpoints ep;
652 	float weights[MAX_TEXELS_PER_BLOCK];
653 	float weight_error_scale[MAX_TEXELS_PER_BLOCK];
654 };
655 
656 
657 void compute_endpoints_and_ideal_weights_1_plane(int xdim, int ydim, int zdim, const partition_info * pt, const imageblock * blk, const error_weight_block * ewb, endpoints_and_weights * ei);
658 
659 void compute_endpoints_and_ideal_weights_2_planes(int xdim, int ydim, int zdim, const partition_info * pt, const imageblock * blk, const error_weight_block * ewb, int separate_component,
660 												  endpoints_and_weights * ei1,	// for the three components of the primary plane of weights
661 												  endpoints_and_weights * ei2	// for the remaining component.
662 	);
663 
664 void compute_ideal_weights_for_decimation_table(const endpoints_and_weights * eai, const decimation_table * it, float *weight_set, float *weights);
665 
666 void compute_ideal_quantized_weights_for_decimation_table(const endpoints_and_weights * eai,
667 														  const decimation_table * it,
668 														  float low_bound, float high_bound, const float *weight_set_in, float *weight_set_out, uint8_t * quantized_weight_set, int quantization_level);
669 
670 
671 float compute_error_of_weight_set(const endpoints_and_weights * eai, const decimation_table * it, const float *weights);
672 
673 
674 float compute_value_of_texel_flt(int texel_to_get, const decimation_table * it, const float *weights);
675 
676 
677 int compute_value_of_texel_int(int texel_to_get, const decimation_table * it, const int *weights);
678 
679 
680 void merge_endpoints(const endpoints * ep1,	// contains three of the color components
681 					 const endpoints * ep2,	// contains the remaining color component
682 					 int separate_component, endpoints * res);
683 
684 // functions dealing with color endpoints
685 
686 // function to pack a pair of color endpoints into a series of integers.
687 // the format used may or may not match the format specified;
688 // the return value is the format actually used.
689 int pack_color_endpoints(astc_decode_mode decode_mode, float4 color0, float4 color1, float4 rgbs_color, float4 rgbo_color, float2 luminances, int format, int *output, int quantization_level);
690 
691 
692 // unpack a pair of color endpoints from a series of integers.
693 void unpack_color_endpoints(astc_decode_mode decode_mode, int format, int quantization_level, const int *input, int *rgb_hdr, int *alpha_hdr, int *nan_endpoint, ushort4 * output0, ushort4 * output1);
694 
695 
696 struct encoding_choice_errors
697 {
698 	float rgb_scale_error;		// error of using LDR RGB-scale instead of complete endpoints.
699 	float rgb_luma_error;		// error of using HDR RGB-scale instead of complete endpoints.
700 	float luminance_error;		// error of using luminance instead of RGB
701 	float alpha_drop_error;		// error of discarding alpha
702 	float rgb_drop_error;		// error of discarding RGB
703 	int can_offset_encode;
704 	int can_blue_contract;
705 };
706 
707 // buffers used to store intermediate data in compress_symbolic_block_fixed_partition_*()
708 struct compress_fixed_partition_buffers
709 {
710 	endpoints_and_weights* ei1;
711 	endpoints_and_weights* ei2;
712 	endpoints_and_weights* eix1;
713 	endpoints_and_weights* eix2;
714 	float *decimated_quantized_weights;
715 	float *decimated_weights;
716 	float *flt_quantized_decimated_quantized_weights;
717 	uint8_t *u8_quantized_decimated_quantized_weights;
718 };
719 
720 struct compress_symbolic_block_buffers
721 {
722 	error_weight_block *ewb;
723 	error_weight_block_orig *ewbo;
724 	symbolic_compressed_block *tempblocks;
725 	imageblock *temp;
726 	compress_fixed_partition_buffers *plane1;
727 	compress_fixed_partition_buffers *planes2;
728 };
729 
730 void compute_encoding_choice_errors(int xdim, int ydim, int zdim, const imageblock * pb, const partition_info * pi, const error_weight_block * ewb,
731 									int separate_component,	// component that is separated out in 2-plane mode, -1 in 1-plane mode
732 									encoding_choice_errors * eci);
733 
734 
735 
736 void determine_optimal_set_of_endpoint_formats_to_use(int xdim, int ydim, int zdim, const partition_info * pt, const imageblock * blk, const error_weight_block * ewb, const endpoints * ep,
737 													  int separate_component,	// separate color component for 2-plane mode; -1 for single-plane mode
738 													  // bitcounts and errors computed for the various quantization methods
739 													  const int *qwt_bitcounts, const float *qwt_errors,
740 													  // output data
741 													  int partition_format_specifiers[4][4], int quantized_weight[4], int quantization_level[4], int quantization_level_mod[4]);
742 
743 
744 void recompute_ideal_colors(int xdim, int ydim, int zdim, int weight_quantization_mode, endpoints * ep,	// contains the endpoints we wish to update
745 							float4 * rgbs_vectors,	// used to return RGBS-vectors for endpoint mode #6
746 							float4 * rgbo_vectors,	// used to return RGBS-vectors for endpoint mode #7
747 							float2 * lum_vectors,	// used to return luminance-vectors.
748 							const uint8_t * weight_set,	// the current set of weight values
749 							const uint8_t * plane2_weight_set,	// NULL if plane 2 is not actually used.
750 							int plane2_color_component,	// color component for 2nd plane of weights; -1 if the 2nd plane of weights is not present
751 							const partition_info * pi, const decimation_table * it, const imageblock * pb,	// picture-block containing the actual data.
752 							const error_weight_block * ewb);
753 
754 
755 
756 void expand_block_artifact_suppression(int xdim, int ydim, int zdim, error_weighting_params * ewp);
757 
758 // Function to set error weights for each color component for each texel in a block.
759 // Returns the sum of all the error values set.
760 float prepare_error_weight_block(const astc_codec_image * input_image,
761 								 // dimensions of error weight block.
762 								 int xdim, int ydim, int zdim, const error_weighting_params * ewp, const imageblock * blk, error_weight_block * ewb, error_weight_block_orig * ewbo);
763 
764 
765 // functions pertaining to weight alignment
766 void prepare_angular_tables(void);
767 
768 void compute_angular_endpoints_1plane(float mode_cutoff,
769 									  const block_size_descriptor * bsd,
770 									  const float *decimated_quantized_weights, const float *decimated_weights, float low_value[MAX_WEIGHT_MODES], float high_value[MAX_WEIGHT_MODES]);
771 
772 void compute_angular_endpoints_2planes(float mode_cutoff,
773 									   const block_size_descriptor * bsd,
774 									   const float *decimated_quantized_weights,
775 									   const float *decimated_weights,
776 									   float low_value1[MAX_WEIGHT_MODES], float high_value1[MAX_WEIGHT_MODES], float low_value2[MAX_WEIGHT_MODES], float high_value2[MAX_WEIGHT_MODES]);
777 
778 
779 
780 
781 /* *********************************** high-level encode and decode functions ************************************ */
782 
783 float compress_symbolic_block(const astc_codec_image * input_image,
784 							  astc_decode_mode decode_mode, int xdim, int ydim, int zdim, const error_weighting_params * ewp, const imageblock * blk, symbolic_compressed_block * scb,
785 							  compress_symbolic_block_buffers * tmpbuf);
786 
787 
788 float4 lerp_color_flt(const float4 color0, const float4 color1, float weight,	// 0..1
789 					  float plane2_weight,	// 0..1
790 					  int plane2_color_component	// 0..3; -1 if only one plane of weights is present.
791 	);
792 
793 
794 ushort4 lerp_color_int(astc_decode_mode decode_mode, ushort4 color0, ushort4 color1, int weight,	// 0..64
795 					   int plane2_weight,	// 0..64
796 					   int plane2_color_component	// 0..3; -1 if only one plane of weights is present.
797 	);
798 
799 
800 void decompress_symbolic_block(astc_decode_mode decode_mode,
801 							   // dimensions of block
802 							   int xdim, int ydim, int zdim,
803 							   // position of block
804 							   int xpos, int ypos, int zpos, const symbolic_compressed_block * scb, imageblock * blk);
805 
806 
807 physical_compressed_block symbolic_to_physical(int xdim, int ydim, int zdim, const symbolic_compressed_block * sc);
808 
809 void physical_to_symbolic(int xdim, int ydim, int zdim, physical_compressed_block pb, symbolic_compressed_block * res);
810 
811 
812 uint16_t unorm16_to_sf16(uint16_t p);
813 uint16_t lns_to_sf16(uint16_t p);
814 
815 
816 #endif
817