1 // SPDX-License-Identifier: Apache-2.0
2 // ----------------------------------------------------------------------------
3 // Copyright 2011-2023 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 ASTCENCCLI_INTERNAL_INCLUDED
23 #define ASTCENCCLI_INTERNAL_INCLUDED
24
25 #include <cstddef>
26 #include <cstdint>
27 #include <cstdio>
28 #include <cstdlib>
29
30 #include "astcenc.h"
31 #include "astcenc_mathlib.h"
32
33 /**
34 * @brief The payload stored in a compressed ASTC image.
35 */
36 struct astc_compressed_image
37 {
38 /** @brief The block width in texels. */
39 unsigned int block_x;
40
41 /** @brief The block height in texels. */
42 unsigned int block_y;
43
44 /** @brief The block depth in texels. */
45 unsigned int block_z;
46
47 /** @brief The image width in texels. */
48 unsigned int dim_x;
49
50 /** @brief The image height in texels. */
51 unsigned int dim_y;
52
53 /** @brief The image depth in texels. */
54 unsigned int dim_z;
55
56 /** @brief The binary data payload. */
57 uint8_t* data;
58
59 /** @brief The binary data length in bytes. */
60 size_t data_len;
61 };
62
63 /**
64 * @brief Config options that have been read from command line.
65 */
66 struct cli_config_options
67 {
68 /** @brief The number of threads to use for processing. */
69 unsigned int thread_count;
70
71 /** @brief The number of repeats to execute for benchmarking. */
72 unsigned int repeat_count;
73
74 /** @brief The number of image slices to load for a 3D image. */
75 unsigned int array_size;
76
77 /** @brief @c true if running in silent mode with minimal output. */
78 bool silentmode;
79
80 /** @brief @c true if the images should be y-flipped. */
81 bool y_flip;
82
83 /** @brief @c true if diagnostic images should be stored. */
84 bool diagnostic_images;
85
86 /** @brief The low exposure fstop for error computation. */
87 int low_fstop;
88
89 /** @brief The high exposure fstop for error computation. */
90 int high_fstop;
91
92 /** @brief The pre-encode swizzle. */
93 astcenc_swizzle swz_encode;
94
95 /** @brief The post-decode swizzle. */
96 astcenc_swizzle swz_decode;
97 };
98
99 /**
100 * @brief Print a string to stderr.
101 */
print_error(const char * format)102 static inline void print_error(
103 const char* format
104 ) {
105 fprintf(stderr, "%s", format);
106 }
107
108 /**
109 * @brief Print a formatted string to stderr.
110 */
111 template<typename ... _Args>
print_error(const char * format,_Args...args)112 static inline void print_error(
113 const char* format,
114 _Args...args
115 ) {
116 fprintf(stderr, format, args...);
117 }
118
119 /**
120 * @brief Load uncompressed image.
121 *
122 * @param filename The file path on disk.
123 * @param y_flip Should this image be Y flipped?
124 * @param[out] is_hdr Is the loaded image HDR?
125 * @param[out] component_count The number of components in the loaded image.
126 *
127 * @return The astc image file, or nullptr on error.
128 */
129 astcenc_image* load_ncimage(
130 const char* filename,
131 bool y_flip,
132 bool& is_hdr,
133 unsigned int& component_count);
134
135 /**
136 * @brief Load uncompressed PNG image.
137 *
138 * @param filename The file path on disk.
139 * @param y_flip Should this image be Y flipped?
140 * @param[out] is_hdr Is the loaded image HDR?
141 * @param[out] component_count The number of components in the loaded image.
142 *
143 * @return The astc image file, or nullptr on error.
144 */
145 astcenc_image* load_png_with_wuffs(
146 const char* filename,
147 bool y_flip,
148 bool& is_hdr,
149 unsigned int& component_count);
150
151 /**
152 * @brief Save an uncompressed image.
153 *
154 * @param img The source data for the image.
155 * @param filename The name of the file to save.
156 * @param y_flip Should the image be vertically flipped?
157 *
158 * @return @c true if the image saved OK, @c false on error.
159 */
160 bool store_ncimage(
161 const astcenc_image* img,
162 const char* filename,
163 int y_flip);
164
165 /**
166 * @brief Check if the output file type requires a specific bitness.
167 *
168 * @param filename The file name, containing hte extension to check.
169 *
170 * @return Valid values are:
171 * * -1 - error - unknown file type.
172 * * 0 - no enforced bitness.
173 * * 8 - enforced 8-bit UNORM.
174 * * 16 - enforced 16-bit FP16.
175 */
176 int get_output_filename_enforced_bitness(
177 const char* filename);
178
179 /**
180 * @brief Allocate a new image in a canonical format.
181 *
182 * Allocated images must be freed with a @c free_image() call.
183 *
184 * @param bitness The number of bits per component (8, 16, or 32).
185 * @param dim_x The width of the image, in texels.
186 * @param dim_y The height of the image, in texels.
187 * @param dim_z The depth of the image, in texels.
188 *
189 * @return The allocated image, or @c nullptr on error.
190 */
191 astcenc_image* alloc_image(
192 unsigned int bitness,
193 unsigned int dim_x,
194 unsigned int dim_y,
195 unsigned int dim_z);
196
197 /**
198 * @brief Free an image.
199 *
200 * @param img The image to free.
201 */
202 void free_image(
203 astcenc_image* img);
204
205 /**
206 * @brief Determine the number of active components in an image.
207 *
208 * @param img The image to analyze.
209 *
210 * @return The number of active components in the image.
211 */
212 int determine_image_components(
213 const astcenc_image* img);
214
215 /**
216 * @brief Load a compressed .astc image.
217 *
218 * @param filename The file to load.
219 * @param img The image to populate with loaded data.
220 *
221 * @return Non-zero on error, zero on success.
222 */
223 int load_cimage(
224 const char* filename,
225 astc_compressed_image& img);
226
227 /**
228 * @brief Store a compressed .astc image.
229 *
230 * @param img The image to store.
231 * @param filename The file to save.
232 *
233 * @return Non-zero on error, zero on success.
234 */
235 int store_cimage(
236 const astc_compressed_image& img,
237 const char* filename);
238
239 /**
240 * @brief Load a compressed .ktx image.
241 *
242 * @param filename The file to load.
243 * @param is_srgb Is this an sRGB encoded file?
244 * @param img The image to populate with loaded data.
245 *
246 * @return Non-zero on error, zero on success.
247 */
248 bool load_ktx_compressed_image(
249 const char* filename,
250 bool& is_srgb,
251 astc_compressed_image& img) ;
252
253 /**
254 * @brief Store a compressed .ktx image.
255 *
256 * @param img The image to store.
257 * @param filename The file to store.
258 * @param is_srgb Is this an sRGB encoded file?
259 *
260 * @return Non-zero on error, zero on success.
261 */
262 bool store_ktx_compressed_image(
263 const astc_compressed_image& img,
264 const char* filename,
265 bool is_srgb);
266
267 /**
268 * @brief Create an image from a 2D float data array.
269 *
270 * @param data The raw input data.
271 * @param dim_x The width of the image, in texels.
272 * @param dim_y The height of the image, in texels.
273 * @param y_flip Should this image be vertically flipped?
274 *
275 * @return The populated image.
276 */
277 astcenc_image* astc_img_from_floatx4_array(
278 const float* data,
279 unsigned int dim_x,
280 unsigned int dim_y,
281 bool y_flip);
282
283 /**
284 * @brief Create an image from a 2D byte data array.
285 *
286 * @param data The raw input data.
287 * @param dim_x The width of the image, in texels.
288 * @param dim_y The height of the image, in texels.
289 * @param y_flip Should this image be vertically flipped?
290 *
291 * @return The populated image.
292 */
293 astcenc_image* astc_img_from_unorm8x4_array(
294 const uint8_t* data,
295 unsigned int dim_x,
296 unsigned int dim_y,
297 bool y_flip);
298
299 /**
300 * @brief Create a flattened RGBA FLOAT32 data array for a single slice from an image structure.
301 *
302 * The returned data array is allocated with @c new[] and must be freed with a @c delete[] call.
303 *
304 * @param img The input image.
305 * @param y_flip Should the data in the array be Y flipped?
306 * @param z_index The slice index to convert.
307 *
308 * @return The data array.
309 */
310 float* floatx4_array_from_astc_img(
311 const astcenc_image* img,
312 bool y_flip,
313 unsigned int z_index);
314
315 /**
316 * @brief Create a flattened RGBA UNORM8 data array from an image structure.
317 *
318 * The returned data array is allocated with @c new[] and must be freed with a @c delete[] call.
319 *
320 * @param img The input image.
321 * @param y_flip Should the data in the array be Y flipped?
322 *
323 * @return The data array.
324 */
325 uint8_t* unorm8x4_array_from_astc_img(
326 const astcenc_image* img,
327 bool y_flip);
328
329 /* ============================================================================
330 Functions for printing build info and help messages
331 ============================================================================ */
332
333 /**
334 * @brief Print the tool copyright and version header to stdout.
335 */
336 void astcenc_print_header();
337
338 /**
339 * @brief Print the tool copyright, version, and short-form help to stdout.
340 */
341 void astcenc_print_shorthelp();
342
343 /**
344 * @brief Print the tool copyright, version, and long-form help to stdout.
345 */
346 void astcenc_print_longhelp();
347
348 /**
349 * @brief Compute error metrics comparing two images.
350 *
351 * @param compute_hdr_metrics True if HDR metrics should be computed.
352 * @param compute_normal_metrics True if normal map metrics should be computed.
353 * @param input_components The number of input color components.
354 * @param img1 The original image.
355 * @param img2 The compressed image.
356 * @param fstop_lo The low exposure fstop (HDR only).
357 * @param fstop_hi The high exposure fstop (HDR only).
358 */
359 void compute_error_metrics(
360 bool compute_hdr_metrics,
361 bool compute_normal_metrics,
362 int input_components,
363 const astcenc_image* img1,
364 const astcenc_image* img2,
365 int fstop_lo,
366 int fstop_hi);
367
368 /**
369 * @brief Get the current time.
370 *
371 * @return The current time in seconds since arbitrary epoch.
372 */
373 double get_time();
374
375 /**
376 * @brief Get the number of CPU cores.
377 *
378 * @return The number of online or onlineable CPU cores in the system.
379 */
380 int get_cpu_count();
381
382 /**
383 * @brief Launch N worker threads and wait for them to complete.
384 *
385 * All threads run the same thread function, and have the same thread payload, but are given a
386 * unique thread ID (0 .. N-1) as a parameter to the run function to allow thread-specific behavior.
387 *
388 * @param operation The name of the operation for this async task.
389 * @param thread_count The number of threads to spawn.
390 * @param func The function to execute. Must have the signature:
391 * void (int thread_count, int thread_id, void* payload)
392 * @param payload Pointer to an opaque thread payload object.
393 */
394 void launch_threads(
395 const char* operation,
396 int thread_count,
397 void (*func)(int, int, void*),
398 void *payload);
399
400 /**
401 * @brief The main entry point.
402 *
403 * @param argc The number of arguments.
404 * @param argv The vector of arguments.
405 *
406 * @return 0 on success, non-zero otherwise.
407 */
408 int astcenc_main(
409 int argc,
410 char **argv);
411
412 #endif
413