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 */ 36struct 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 */ 66struct 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 */ 102static 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 */ 111template<typename ... _Args> 112static 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 */ 129astcenc_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 */ 145astcenc_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 */ 160bool 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 */ 176int 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 */ 191astcenc_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 */ 202void 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 */ 212int 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 */ 223int 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 */ 235int 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 */ 248bool 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 */ 262bool 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 */ 277astcenc_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 */ 293astcenc_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 */ 310float* 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 */ 325uint8_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 */ 336void astcenc_print_header(); 337 338/** 339 * @brief Print the tool copyright, version, and short-form help to stdout. 340 */ 341void astcenc_print_shorthelp(); 342 343/** 344 * @brief Print the tool copyright, version, and long-form help to stdout. 345 */ 346void 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 */ 359void 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 */ 373double 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 */ 380int 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 */ 394void 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 */ 408int astcenc_main( 409 int argc, 410 char **argv); 411 412#endif 413