• 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 partition_of_texel[MAX_TEXELS_PER_BLOCK];
68 };
69 
70 /*
71    In ASTC, we don't necessarily provide a weight for every texel.
72    As such, for each block size, there are a number of patterns where some texels
73    have their weights computed as a weighted average of more than 1 weight.
74    As such, the codec uses a data structure that tells us: for each texel, which
75    weights it is a combination of for each weight, which texels it contributes to.
76    The decimation_table is this data structure.
77 */
78 struct decimation_table
79 {
80 	int num_weights;
81 	uint8_t texel_num_weights[MAX_TEXELS_PER_BLOCK];	// number of indices that go into the calculation for a texel
82 	uint8_t texel_weights_int[MAX_TEXELS_PER_BLOCK][4];	// the weight to assign to each weight
83 	uint8_t texel_weights[MAX_TEXELS_PER_BLOCK][4];	// the weights that go into a texel calculation
84 };
85 
86 /*
87    data structure describing information that pertains to a block size and its associated block modes.
88 */
89 struct block_mode
90 {
91 	int8_t decimation_mode;
92 	int8_t quantization_mode;
93 	int8_t is_dual_plane;
94 	int8_t permit_decode;
95 };
96 
97 struct block_size_descriptor
98 {
99 	int xdim;
100 	int ydim;
101 	int zdim;
102 	int texel_count;
103 
104 	int decimation_mode_count;
105 	const decimation_table *decimation_tables[MAX_DECIMATION_MODES];
106 	block_mode block_modes[MAX_WEIGHT_MODES];
107 
108 	// All the partitioning information for this block size
109 	partition_info partitions[(3*PARTITION_COUNT)+1];
110 };
111 
112 // data structure representing one block of an image.
113 // it is expanded to float prior to processing to save some computation time
114 // on conversions to/from uint8_t (this also allows us to handle HDR textures easily)
115 struct imageblock
116 {
117 	float orig_data[MAX_TEXELS_PER_BLOCK * 4];  // original input data
118 	float data_r[MAX_TEXELS_PER_BLOCK];  // the data that we will compress, either linear or LNS (0..65535 in both cases)
119 	float data_g[MAX_TEXELS_PER_BLOCK];
120 	float data_b[MAX_TEXELS_PER_BLOCK];
121 	float data_a[MAX_TEXELS_PER_BLOCK];
122 
123 	uint8_t rgb_lns[MAX_TEXELS_PER_BLOCK];      // 1 if RGB data are being treated as LNS
124 	uint8_t alpha_lns[MAX_TEXELS_PER_BLOCK];    // 1 if Alpha data are being treated as LNS
125 	uint8_t nan_texel[MAX_TEXELS_PER_BLOCK];    // 1 if the texel is a NaN-texel.
126 
127 	float red_min, red_max;
128 	float green_min, green_max;
129 	float blue_min, blue_max;
130 	float alpha_min, alpha_max;
131 	int grayscale;				// 1 if R=G=B for every pixel, 0 otherwise
132 
133 	int xpos, ypos, zpos;
134 };
135 
136 void update_imageblock_flags(
137 	imageblock* pb,
138 	int xdim,
139 	int ydim,
140 	int zdim);
141 
142 void imageblock_initialize_orig_from_work(
143 	imageblock * pb,
144 	int pixelcount);
145 
146 void imageblock_initialize_work_from_orig(
147 	imageblock * pb,
148 	int pixelcount);
149 
150 // enumeration of all the quantization methods we support under this format.
151 enum quantization_method
152 {
153 	QUANT_2 = 0,
154 	QUANT_3 = 1,
155 	QUANT_4 = 2,
156 	QUANT_5 = 3,
157 	QUANT_6 = 4,
158 	QUANT_8 = 5,
159 	QUANT_10 = 6,
160 	QUANT_12 = 7,
161 	QUANT_16 = 8,
162 	QUANT_20 = 9,
163 	QUANT_24 = 10,
164 	QUANT_32 = 11,
165 	QUANT_40 = 12,
166 	QUANT_48 = 13,
167 	QUANT_64 = 14,
168 	QUANT_80 = 15,
169 	QUANT_96 = 16,
170 	QUANT_128 = 17,
171 	QUANT_160 = 18,
172 	QUANT_192 = 19,
173 	QUANT_256 = 20
174 };
175 
176 /**
177  * @brief Weight quantization transfer table.
178  *
179  * ASTC can store texel weights at many quantization levels, so for performance
180  * we store essential information about each level as a precomputed data
181  * structure.
182  *
183  * Unquantized weights are integers in the range [0, 64], or floats [0, 1].
184  *
185  * This structure provides the following information:
186  * A table, used to estimate the closest quantized
187 	weight for a given floating-point weight. For each quantized weight, the corresponding unquantized
188 	and floating-point values. For each quantized weight, a previous-value and a next-value.
189 */
190 struct quantization_and_transfer_table
191 {
192 	/** The scrambled unquantized values. */
193 	uint8_t unquantized_value[32];
194 };
195 
196 extern const quantization_and_transfer_table quant_and_xfer_tables[12];
197 
198 enum endpoint_formats
199 {
200 	FMT_LUMINANCE = 0,
201 	FMT_LUMINANCE_DELTA = 1,
202 	FMT_HDR_LUMINANCE_LARGE_RANGE = 2,
203 	FMT_HDR_LUMINANCE_SMALL_RANGE = 3,
204 	FMT_LUMINANCE_ALPHA = 4,
205 	FMT_LUMINANCE_ALPHA_DELTA = 5,
206 	FMT_RGB_SCALE = 6,
207 	FMT_HDR_RGB_SCALE = 7,
208 	FMT_RGB = 8,
209 	FMT_RGB_DELTA = 9,
210 	FMT_RGB_SCALE_ALPHA = 10,
211 	FMT_HDR_RGB = 11,
212 	FMT_RGBA = 12,
213 	FMT_RGBA_DELTA = 13,
214 	FMT_HDR_RGB_LDR_ALPHA = 14,
215 	FMT_HDR_RGBA = 15,
216 };
217 
218 struct symbolic_compressed_block
219 {
220 	int error_block;			// 1 marks error block, 0 marks non-error-block.
221 	int block_mode;				// 0 to 2047. Negative value marks constant-color block (-1: FP16, -2:UINT16)
222 	int partition_count;		// 1 to 4; Zero marks a constant-color block.
223 	int partition_index;		// 0 to 1023
224 	int color_formats[4];		// color format for each endpoint color pair.
225 	int color_formats_matched;	// color format for all endpoint pairs are matched.
226 	int color_values[4][12];	// quantized endpoint color pairs.
227 	int color_quantization_level;
228 	uint8_t plane1_weights[MAX_WEIGHTS_PER_BLOCK];	// quantized and decimated weights
229 	uint8_t plane2_weights[MAX_WEIGHTS_PER_BLOCK];
230 	int plane2_color_component;	// color component for the secondary plane of weights
231 	int constant_color[4];		// constant-color, as FP16 or UINT16. Used for constant-color blocks only.
232 };
233 
234 struct physical_compressed_block
235 {
236 	uint8_t data[16];
237 };
238 
239 /* ============================================================================
240   Functions and data pertaining to quantization and encoding
241 ============================================================================ */
242 
243 /**
244  * @brief Populate the blocksize descriptor for the target block size.
245  *
246  * This will also initialize the partition table metadata, which is stored
247  * as part of the BSD structure.
248  *
249  * @param xdim The x axis size of the block.
250  * @param ydim The y axis size of the block.
251  * @param zdim The z axis size of the block.
252  * @param bsd  The structure to populate.
253  */
254 void init_block_size_descriptor(
255 	int xdim,
256 	int ydim,
257 	int zdim,
258 	block_size_descriptor* bsd);
259 
260 void term_block_size_descriptor(
261 	block_size_descriptor* bsd);
262 
263 /**
264  * @brief Populate the partition tables for the target block size.
265  *
266  * Note the block_size_size descriptor must be initialized before calling this
267  * function.
268  *
269  * @param bsd  The structure to populate.
270  */
271 void init_partition_tables(
272 	block_size_descriptor* bsd);
273 
get_partition_table(const block_size_descriptor * bsd,int partition_count)274 static inline const partition_info *get_partition_table(
275 	const block_size_descriptor* bsd,
276 	int partition_count
277 ) {
278 	if (partition_count == 1) {
279 		partition_count = 5;
280 	}
281 	int index = (partition_count - 2) * PARTITION_COUNT;
282 	return bsd->partitions + index;
283 }
284 
285 // ***********************************************************
286 // functions and data pertaining to quantization and encoding
287 // **********************************************************
288 
289 extern const uint8_t color_unquantization_tables[21][256];
290 extern int quantization_mode_table[17][128];
291 
292 void decode_ise(
293 	int quantization_level,
294 	int elements,
295 	const uint8_t* input_data,
296 	uint8_t* output_data,
297 	int bit_offset);
298 
299 int compute_ise_bitcount(
300 	int items,
301 	quantization_method quant);
302 
303 void build_quantization_mode_table(void);
304 
305 // unpack a pair of color endpoints from a series of integers.
306 void unpack_color_endpoints(
307 	astc_decode_mode decode_mode,
308 	int format,
309 	int quantization_level,
310 	const int* input,
311 	int* rgb_hdr,
312 	int* alpha_hdr,
313 	int* nan_endpoint,
314 	uint4* output0,
315 	uint4* output1);
316 
317 /* *********************************** high-level encode and decode functions ************************************ */
318 
319 void decompress_symbolic_block(
320 	astc_decode_mode decode_mode,
321 	const block_size_descriptor* bsd,
322 	int xpos,
323 	int ypos,
324 	int zpos,
325 	const symbolic_compressed_block* scb,
326 	imageblock* blk);
327 
328 void physical_to_symbolic(
329 	const block_size_descriptor* bsd,
330 	physical_compressed_block pb,
331 	symbolic_compressed_block* res);
332 
333 uint16_t unorm16_to_sf16(
334 	uint16_t p);
335 
336 uint16_t lns_to_sf16(
337 	uint16_t p);
338 
339 #endif
340