|
8 | 8 |
|
9 | 9 | enum class smcube_data_type
|
10 | 10 | {
|
11 |
| - Float32 = 0, |
12 |
| - Float16, |
| 11 | + Float32 = 0, // Data is 32 bit floating point |
| 12 | + Float16, // Data is 16 bit (half-precision) float |
13 | 13 | DataTypeCount
|
14 | 14 | };
|
15 | 15 |
|
| 16 | +// Flags used in `smcube_save_to_file_smcube`. |
| 17 | +// They can be combined together. |
16 | 18 | enum smcube_save_flags
|
17 | 19 | {
|
18 | 20 | smcube_save_flag_None = 0,
|
| 21 | + |
| 22 | + // Apply lossless data filter to make the file more compressible. |
| 23 | + // Usually you want this if you plan to compress the file with |
| 24 | + // zlib/zstd/lz4 or similar general purpose compressors. This costs |
| 25 | + // a tiny bit of performance when loading, but makes the data 2-3x more |
| 26 | + // compressible. |
19 | 27 | smcube_save_flag_FilterData = (1 << 0),
|
| 28 | + |
| 29 | + // Convert LUT data to half-precision (16 bit) floating point format. |
20 | 30 | smcube_save_flag_ConvertToFloat16 = (1 << 1),
|
| 31 | + |
| 32 | + // Make the data be 4 channels (RGBA) instead of usual 3 (RGB). |
| 33 | + // The fourth channel is not really used, but LUT in this format |
| 34 | + // can be faster and more convenient to load onto GPU. Since many |
| 35 | + // 3D APIs do not support 3-channel textures directly. |
21 | 36 | smcube_save_flag_ExpandTo4Channels = (1 << 2),
|
22 | 37 | };
|
23 | 38 |
|
24 | 39 | struct smcube_luts;
|
25 | 40 |
|
| 41 | +// Load LUT(s) from a file at given path. |
| 42 | +// |
| 43 | +// If file path ends with ".smcube" assumes it is a binary smol-cube file, |
| 44 | +// and effectively calls `smcube_load_from_file_smcube`. |
| 45 | +// If file path ends with ".cube" assumes it is a Resolve/Adobe LUT file, |
| 46 | +// and effectively calls `smcube_load_from_file_resolve_cube`. |
| 47 | +// |
| 48 | +// Use the resulting opaque handle in other functions to query/inspect/save |
| 49 | +// the LUT(s). Use `smcube_free` to delete the LUT(s). |
| 50 | +// |
| 51 | +// Returns nullptr in case of failure. |
26 | 52 | smcube_luts* smcube_load_from_file(const char* path);
|
| 53 | + |
| 54 | +// Load LUT(s) from smol-cube binaty file at path. |
27 | 55 | smcube_luts* smcube_load_from_file_smcube(const char* path);
|
| 56 | + |
| 57 | +// Load LUT(s) from Resolve/Adobe LUT file at path. |
28 | 58 | smcube_luts* smcube_load_from_file_resolve_cube(const char* path);
|
| 59 | + |
| 60 | +// Delete the LUT(s). |
29 | 61 | void smcube_free(smcube_luts* handle);
|
30 | 62 |
|
| 63 | +// Save LUT(s) to smol-cube format file. |
| 64 | +// Flags control filtering, format and channel conversion. |
| 65 | +// Returns true if all is ok. |
31 | 66 | bool smcube_save_to_file_smcube(const char* path, const smcube_luts* luts, smcube_save_flags flags = smcube_save_flag_None);
|
| 67 | + |
| 68 | +// Save LUT(s) to Resolve/Adobe LUT format file. |
| 69 | +// |
| 70 | +// Note that this only supports LUTs that the Resolve format can handle: |
| 71 | +// - 3 channels, |
| 72 | +// - 32 bit floating point, |
| 73 | +// - one 1D LUT, or one 3D LUT, or one 1D LUT followed by one 3D LUT, |
| 74 | +// - 3D LUT, if present, must have the same x/y/z sizes. |
| 75 | +// |
| 76 | +// Returns true if all is ok. |
32 | 77 | bool smcube_save_to_file_resolve_cube(const char* path, const smcube_luts* luts);
|
33 | 78 |
|
| 79 | +// Get "title" metadata of the LUT. |
| 80 | +// Title is optional and nullptr would be returned in that case. |
34 | 81 | const char* smcube_get_title(const smcube_luts* handle);
|
| 82 | + |
| 83 | +// Get "comment" metadata of the LUT. |
| 84 | +// Comment is optional and nullptr would be returned in that case. |
35 | 85 | const char* smcube_get_comment(const smcube_luts* handle);
|
| 86 | + |
| 87 | +// Get number of LUTs. |
| 88 | +// Most files contain just one LUT, but some could contain more |
| 89 | +// (typical combination is 1D "shaper" LUT followed by a 3D LUT). |
36 | 90 | size_t smcube_get_count(const smcube_luts* handle);
|
37 | 91 |
|
| 92 | +// Get number of channels in a LUT (3 = RGB, 4 = RGBA). |
38 | 93 | int smcube_lut_get_channels(const smcube_luts* handle, size_t index);
|
| 94 | + |
| 95 | +// Get dimension of a LUT (1 = 1D, 2 = 2D, 3 = 3D). |
39 | 96 | int smcube_lut_get_dimension(const smcube_luts* handle, size_t index);
|
| 97 | + |
| 98 | +// Get data type of the LUT data. |
40 | 99 | smcube_data_type smcube_lut_get_data_type(const smcube_luts* handle, size_t index);
|
| 100 | + |
| 101 | +// Get LUT size in X dimension. |
41 | 102 | int smcube_lut_get_size_x(const smcube_luts* handle, size_t index);
|
| 103 | +// Get LUT size in Y dimension (only relevant for 2D/3D LUTs). |
42 | 104 | int smcube_lut_get_size_y(const smcube_luts* handle, size_t index);
|
| 105 | +// Get LUT size in Z dimension (only relevant for 3D LUTs). |
43 | 106 | int smcube_lut_get_size_z(const smcube_luts* handle, size_t index);
|
| 107 | + |
| 108 | +// Get the actual data of the LUT. |
| 109 | +// |
| 110 | +// Data is laid out in row-major order, i.e. X dimension (which usually |
| 111 | +// means "red") changes the fastest, and Z dimension (which usually |
| 112 | +// means "blue") changes the slowest. |
| 113 | +// |
| 114 | +// The data is `size_x * size_y * size_z * channels` numbers in either |
| 115 | +// float (4 bytes/number) or half-float (2 bytes/number) depending on |
| 116 | +// LUT data type. |
| 117 | +// |
| 118 | +// If data is 4 channels, then the data can be directly loaded into a |
| 119 | +// 3D texture on most/all graphics APIs. |
44 | 120 | const void* smcube_lut_get_data(const smcube_luts* handle, size_t index);
|
45 | 121 |
|
| 122 | +// Calculate LUT data size in bytes. |
46 | 123 | size_t smcube_lut_get_data_size(const smcube_luts* handle, size_t index);
|
| 124 | + |
| 125 | +// Calculate byte size of the data type (4 or 2 currently). |
47 | 126 | size_t smcube_data_type_get_size(smcube_data_type type);
|
48 | 127 |
|
| 128 | +// Convert LUT data into a different format or channel count. |
| 129 | +// |
| 130 | +// Note that this leaves LUT data unchanged; new data is written into |
| 131 | +// a buffer that you provided. Destination buffer must contain |
| 132 | +// space for `size_x * size_y * size_z * dst_channels` numbers of |
| 133 | +// `dst_type` format. |
49 | 134 | void smcube_lut_convert_data(const smcube_luts* handle, size_t index, smcube_data_type dst_type, int dst_channels, void* dst_data);
|
0 commit comments