• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0
2 // ----------------------------------------------------------------------------
3 // Copyright 2011-2020 Arm Limited
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
6 // use this file except in compliance with the License. You may obtain a copy
7 // of the License at:
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 // License for the specific language governing permissions and limitations
15 // under the License.
16 // ----------------------------------------------------------------------------
17 
18 /**
19  * @brief Functions and data declarations.
20  */
21 
22 #ifndef ASTC_CODEC_INTERNALS_INCLUDED
23 #define ASTC_CODEC_INTERNALS_INCLUDED
24 
25 #include <cstddef>
26 #include <cstdint>
27 #include <cstdio>
28 #include <cstdlib>
29 
30 #include "astc_mathlib.h"
31 
32 // ASTC parameters
33 #define MAX_TEXELS_PER_BLOCK 216
34 #define MAX_WEIGHTS_PER_BLOCK 64
35 #define MIN_WEIGHT_BITS_PER_BLOCK 24
36 #define MAX_WEIGHT_BITS_PER_BLOCK 96
37 #define PARTITION_BITS 10
38 #define PARTITION_COUNT (1 << PARTITION_BITS)
39 
40 // the sum of weights for one texel.
41 #define TEXEL_WEIGHT_SUM 16
42 #define MAX_DECIMATION_MODES 87
43 #define MAX_WEIGHT_MODES 2048
44 
45 enum astc_decode_mode
46 {
47 	DECODE_LDR_SRGB,
48 	DECODE_LDR,
49 	DECODE_HDR
50 };
51 
52 /*
53 	Partition table representation:
54 	For each block size, we have 3 tables, each with 1024 partitionings;
55 	these three tables correspond to 2, 3 and 4 partitions respectively.
56 	For each partitioning, we have:
57 	* a 4-entry table indicating how many texels there are in each of the 4 partitions.
58 	  This may be from 0 to a very large value.
59 	* a table indicating the partition index of each of the texels in the block.
60 	  Each index may be 0, 1, 2 or 3.
61 	* Each element in the table is an uint8_t indicating partition index (0, 1, 2 or 3)
62 */
63 
64 struct partition_info
65 {
66 	int partition_count;
67 	uint8_t texels_per_partition[4];
68 	uint8_t partition_of_texel[MAX_TEXELS_PER_BLOCK];
69 	uint8_t texels_of_partition[4][MAX_TEXELS_PER_BLOCK];
70 	uint64_t coverage_bitmaps[4];
71 };
72 
73 /*
74    In ASTC, we don't necessarily provide a weight for every texel.
75    As such, for each block size, there are a number of patterns where some texels
76    have their weights computed as a weighted average of more than 1 weight.
77    As such, the codec uses a data structure that tells us: for each texel, which
78    weights it is a combination of for each weight, which texels it contributes to.
79    The decimation_table is this data structure.
80 */
81 struct decimation_table
82 {
83 	int num_texels;
84 	int num_weights;
85 	uint8_t texel_num_weights[MAX_TEXELS_PER_BLOCK];	// number of indices that go into the calculation for a texel
86 	uint8_t texel_weights_int[MAX_TEXELS_PER_BLOCK][4];	// the weight to assign to each weight
87 	float texel_weights_float[MAX_TEXELS_PER_BLOCK][4];	// the weight to assign to each weight
88 	uint8_t texel_weights[MAX_TEXELS_PER_BLOCK][4];	// the weights that go into a texel calculation
89 	uint8_t weight_num_texels[MAX_WEIGHTS_PER_BLOCK];	// the number of texels that a given weight contributes to
90 	uint8_t weight_texel[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK];	// the texels that the weight contributes to
91 	uint8_t weights_int[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK];	// the weights that the weight contributes to a texel.
92 	float weights_flt[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK];	// the weights that the weight contributes to a texel.
93 
94 	// folded data structures:
95 	//  * texel_weights_texel[i][j] = texel_weights[weight_texel[i][j]];
96 	//  * texel_weights_float_texel[i][j] = texel_weights_float[weight_texel[i][j]
97 	uint8_t texel_weights_texel[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK][4];
98 	float texel_weights_float_texel[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK][4];
99 };
100 
101 /*
102    data structure describing information that pertains to a block size and its associated block modes.
103 */
104 struct block_mode
105 {
106 	int8_t decimation_mode;
107 	int8_t quantization_mode;
108 	int8_t is_dual_plane;
109 	int8_t permit_encode;
110 	int8_t permit_decode;
111 	float percentile;
112 };
113 
114 struct block_size_descriptor
115 {
116 	int xdim;
117 	int ydim;
118 	int zdim;
119 	int texel_count;
120 
121 	int decimation_mode_count;
122 	int decimation_mode_samples[MAX_DECIMATION_MODES];
123 	int decimation_mode_maxprec_1plane[MAX_DECIMATION_MODES];
124 	int decimation_mode_maxprec_2planes[MAX_DECIMATION_MODES];
125 	float decimation_mode_percentile[MAX_DECIMATION_MODES];
126 	int permit_encode[MAX_DECIMATION_MODES];
127 	const decimation_table *decimation_tables[MAX_DECIMATION_MODES];
128 	block_mode block_modes[MAX_WEIGHT_MODES];
129 
130 	// for the k-means bed bitmap partitioning algorithm, we don't
131 	// want to consider more than 64 texels; this array specifies
132 	// which 64 texels (if that many) to consider.
133 	int texelcount_for_bitmap_partitioning;
134 	int texels_for_bitmap_partitioning[64];
135 
136 	// All the partitioning information for this block size
137 	partition_info partitions[(3*PARTITION_COUNT)+1];
138 };
139 
140 // data structure representing one block of an image.
141 // it is expanded to float prior to processing to save some computation time
142 // on conversions to/from uint8_t (this also allows us to handle HDR textures easily)
143 struct imageblock
144 {
145 	float orig_data[MAX_TEXELS_PER_BLOCK * 4];  // original input data
146 	float data_r[MAX_TEXELS_PER_BLOCK];  // the data that we will compress, either linear or LNS (0..65535 in both cases)
147 	float data_g[MAX_TEXELS_PER_BLOCK];
148 	float data_b[MAX_TEXELS_PER_BLOCK];
149 	float data_a[MAX_TEXELS_PER_BLOCK];
150 
151 	uint8_t rgb_lns[MAX_TEXELS_PER_BLOCK];      // 1 if RGB data are being treated as LNS
152 	uint8_t alpha_lns[MAX_TEXELS_PER_BLOCK];    // 1 if Alpha data are being treated as LNS
153 	uint8_t nan_texel[MAX_TEXELS_PER_BLOCK];    // 1 if the texel is a NaN-texel.
154 
155 	float red_min, red_max;
156 	float green_min, green_max;
157 	float blue_min, blue_max;
158 	float alpha_min, alpha_max;
159 	int grayscale;				// 1 if R=G=B for every pixel, 0 otherwise
160 
161 	int xpos, ypos, zpos;
162 };
163 
164 void update_imageblock_flags(
165 	imageblock* pb,
166 	int xdim,
167 	int ydim,
168 	int zdim);
169 
170 void imageblock_initialize_orig_from_work(
171 	imageblock * pb,
172 	int pixelcount);
173 
174 void imageblock_initialize_work_from_orig(
175 	imageblock * pb,
176 	int pixelcount);
177 
178 // enumeration of all the quantization methods we support under this format.
179 enum quantization_method
180 {
181 	QUANT_2 = 0,
182 	QUANT_3 = 1,
183 	QUANT_4 = 2,
184 	QUANT_5 = 3,
185 	QUANT_6 = 4,
186 	QUANT_8 = 5,
187 	QUANT_10 = 6,
188 	QUANT_12 = 7,
189 	QUANT_16 = 8,
190 	QUANT_20 = 9,
191 	QUANT_24 = 10,
192 	QUANT_32 = 11,
193 	QUANT_40 = 12,
194 	QUANT_48 = 13,
195 	QUANT_64 = 14,
196 	QUANT_80 = 15,
197 	QUANT_96 = 16,
198 	QUANT_128 = 17,
199 	QUANT_160 = 18,
200 	QUANT_192 = 19,
201 	QUANT_256 = 20
202 };
203 
204 /**
205  * @brief Weight quantization transfer table.
206  *
207  * ASTC can store texel weights at many quantization levels, so for performance
208  * we store essential information about each level as a precomputed data
209  * structure.
210  *
211  * Unquantized weights are integers in the range [0, 64], or floats [0, 1].
212  *
213  * This structure provides the following information:
214  * A table, used to estimate the closest quantized
215 	weight for a given floating-point weight. For each quantized weight, the corresponding unquantized
216 	and floating-point values. For each quantized weight, a previous-value and a next-value.
217 */
218 struct quantization_and_transfer_table
219 {
220 	/** The quantization level used */
221 	quantization_method method;
222 	/** The unscrambled unquantized value. */
223 	// TODO: Converted to floats to support AVX gathers
224 	float unquantized_value_unsc[33];
225 	/** The scrambling order: value[map[i]] == value_unsc[i] */
226 	// TODO: Converted to u32 to support AVX gathers
227 	int32_t scramble_map[32];
228 	/** The scrambled unquantized values. */
229 	uint8_t unquantized_value[32];
230 	/**
231 	 * An encoded table of previous-and-next weight values, indexed by the
232 	 * current unquantized value.
233 	 *  * bits 7:0 = previous-index, unquantized
234 	 *  * bits 15:8 = next-index, unquantized
235 	 *  * bits 23:16 = previous-index, quantized
236 	 *  * bits 31:24 = next-index, quantized
237 	 */
238 	uint32_t prev_next_values[65];
239 };
240 
241 extern const quantization_and_transfer_table quant_and_xfer_tables[12];
242 
243 enum endpoint_formats
244 {
245 	FMT_LUMINANCE = 0,
246 	FMT_LUMINANCE_DELTA = 1,
247 	FMT_HDR_LUMINANCE_LARGE_RANGE = 2,
248 	FMT_HDR_LUMINANCE_SMALL_RANGE = 3,
249 	FMT_LUMINANCE_ALPHA = 4,
250 	FMT_LUMINANCE_ALPHA_DELTA = 5,
251 	FMT_RGB_SCALE = 6,
252 	FMT_HDR_RGB_SCALE = 7,
253 	FMT_RGB = 8,
254 	FMT_RGB_DELTA = 9,
255 	FMT_RGB_SCALE_ALPHA = 10,
256 	FMT_HDR_RGB = 11,
257 	FMT_RGBA = 12,
258 	FMT_RGBA_DELTA = 13,
259 	FMT_HDR_RGB_LDR_ALPHA = 14,
260 	FMT_HDR_RGBA = 15,
261 };
262 
263 struct symbolic_compressed_block
264 {
265 	int error_block;			// 1 marks error block, 0 marks non-error-block.
266 	int block_mode;				// 0 to 2047. Negative value marks constant-color block (-1: FP16, -2:UINT16)
267 	int partition_count;		// 1 to 4; Zero marks a constant-color block.
268 	int partition_index;		// 0 to 1023
269 	int color_formats[4];		// color format for each endpoint color pair.
270 	int color_formats_matched;	// color format for all endpoint pairs are matched.
271 	int color_values[4][12];	// quantized endpoint color pairs.
272 	int color_quantization_level;
273 	uint8_t plane1_weights[MAX_WEIGHTS_PER_BLOCK];	// quantized and decimated weights
274 	uint8_t plane2_weights[MAX_WEIGHTS_PER_BLOCK];
275 	int plane2_color_component;	// color component for the secondary plane of weights
276 	int constant_color[4];		// constant-color, as FP16 or UINT16. Used for constant-color blocks only.
277 };
278 
279 struct physical_compressed_block
280 {
281 	uint8_t data[16];
282 };
283 
284 /* ============================================================================
285   Functions and data pertaining to quantization and encoding
286 ============================================================================ */
287 
288 /**
289  * @brief Populate the blocksize descriptor for the target block size.
290  *
291  * This will also initialize the partition table metadata, which is stored
292  * as part of the BSD structure.
293  *
294  * @param xdim The x axis size of the block.
295  * @param ydim The y axis size of the block.
296  * @param zdim The z axis size of the block.
297  * @param bsd  The structure to populate.
298  */
299 void init_block_size_descriptor(
300 	int xdim,
301 	int ydim,
302 	int zdim,
303 	block_size_descriptor* bsd);
304 
305 void term_block_size_descriptor(
306 	block_size_descriptor* bsd);
307 
308 /**
309  * @brief Populate the partition tables for the target block size.
310  *
311  * Note the block_size_size descriptor must be initialized before calling this
312  * function.
313  *
314  * @param bsd  The structure to populate.
315  */
316 void init_partition_tables(
317 	block_size_descriptor* bsd);
318 
get_partition_table(const block_size_descriptor * bsd,int partition_count)319 static inline const partition_info *get_partition_table(
320 	const block_size_descriptor* bsd,
321 	int partition_count
322 ) {
323 	if (partition_count == 1) {
324 		partition_count = 5;
325 	}
326 	int index = (partition_count - 2) * PARTITION_COUNT;
327 	return bsd->partitions + index;
328 }
329 
330 /**
331  * @brief Get the percentile table for 2D block modes.
332  *
333  * This is an empirically determined prioritization of which block modes to
334  * use in the search in terms of their centile (lower centiles = more useful).
335  *
336  * Returns a dynamically allocated array; caller must free with delete[].
337  *
338  * @param xdim The block x size.
339  * @param ydim The block y size.
340  *
341  * @return The unpacked table.
342  */
343 const float *get_2d_percentile_table(
344 	int xdim,
345 	int ydim);
346 
347 // ***********************************************************
348 // functions and data pertaining to quantization and encoding
349 // **********************************************************
350 
351 extern const uint8_t color_unquantization_tables[21][256];
352 extern int quantization_mode_table[17][128];
353 
354 void decode_ise(
355 	int quantization_level,
356 	int elements,
357 	const uint8_t* input_data,
358 	uint8_t* output_data,
359 	int bit_offset);
360 
361 int compute_ise_bitcount(
362 	int items,
363 	quantization_method quant);
364 
365 void build_quantization_mode_table(void);
366 
367 // unpack a pair of color endpoints from a series of integers.
368 void unpack_color_endpoints(
369 	astc_decode_mode decode_mode,
370 	int format,
371 	int quantization_level,
372 	const int* input,
373 	int* rgb_hdr,
374 	int* alpha_hdr,
375 	int* nan_endpoint,
376 	uint4* output0,
377 	uint4* output1);
378 
379 /* *********************************** high-level encode and decode functions ************************************ */
380 
381 void decompress_symbolic_block(
382 	astc_decode_mode decode_mode,
383 	const block_size_descriptor* bsd,
384 	int xpos,
385 	int ypos,
386 	int zpos,
387 	const symbolic_compressed_block* scb,
388 	imageblock* blk);
389 
390 void physical_to_symbolic(
391 	const block_size_descriptor* bsd,
392 	physical_compressed_block pb,
393 	symbolic_compressed_block* res);
394 
395 uint16_t unorm16_to_sf16(
396 	uint16_t p);
397 
398 uint16_t lns_to_sf16(
399 	uint16_t p);
400 
401 #endif
402