├── .github └── workflows │ └── main.yml ├── .gitignore ├── CMakeLists.txt ├── CMakePresets.json ├── doc ├── chart-pbrneutral-loadtime.png ├── chart-pbrneutral-size.png └── shot-viewer.jpg ├── launch.vs.json ├── libs ├── argh │ ├── LICENSE │ ├── README.md │ └── argh.h ├── sokol │ ├── LICENSE │ ├── README.md │ ├── sokol_app.h │ ├── sokol_gfx.h │ ├── sokol_glue.h │ ├── sokol_log.h │ └── sokol_time.h └── stb_image.h ├── license.txt ├── readme.md ├── src ├── smol_cube.cpp ├── smol_cube.h ├── smol_cube_conv_app.cpp └── smol_cube_viewer_app.cpp └── tests ├── luts ├── khronos-pbrNeutral.cube ├── resolve-DCI-P3 Kodak 2383 D65.cube ├── resolve-LMT ACES v0.1.1.cube ├── synthetic │ └── shaper_3d.cube ├── tinyglade-Bluecine_75.cube ├── tinyglade-Cold_Ice.cube ├── tinyglade-LUNA_COLOR.cube └── tinyglade-Sam_Kolder.cube ├── photo1.jpg ├── photo2.jpg ├── photo3.jpg └── photo4.jpg /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | windows: 11 | runs-on: windows-2022 12 | timeout-minutes: 5 13 | strategy: 14 | fail-fast: false 15 | steps: 16 | - uses: actions/checkout@v1 17 | - name: Windows 18 | run: | 19 | mkdir out && cd out 20 | cmake -DCMAKE_BUILD_TYPE=Release .. 21 | cd .. 22 | cmake --build out --config Release 23 | shell: cmd 24 | 25 | mac: 26 | runs-on: macOS-latest 27 | timeout-minutes: 5 28 | strategy: 29 | fail-fast: false 30 | steps: 31 | - uses: actions/checkout@v1 32 | - name: macOS 33 | run: | 34 | mkdir out && cd out 35 | cmake -DCMAKE_BUILD_TYPE=Release .. 36 | cd .. 37 | cmake --build out --config Release 38 | 39 | linux: 40 | runs-on: ubuntu-latest 41 | timeout-minutes: 5 42 | strategy: 43 | fail-fast: false 44 | steps: 45 | - uses: actions/checkout@v1 46 | - name: Ubuntu 47 | run: | 48 | sudo apt-get update && sudo apt-get install -y libxcursor-dev libxi-dev libgl-dev 49 | mkdir out && cd out 50 | cmake -DCMAKE_BUILD_TYPE=Release .. 51 | cd .. 52 | cmake --build out --config Release 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | out/* 3 | build/* 4 | .DS_Store 5 | *.cube.txt 6 | *.smcube 7 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.21) 2 | if(POLICY CMP0091) 3 | cmake_policy(SET CMP0091 NEW) # enable MSVC_RUNTIME_LIBRARY 4 | endif() 5 | 6 | project ("smol-cube") 7 | 8 | add_executable (smol-cube-conv 9 | src/smol_cube_conv_app.cpp 10 | src/smol_cube.cpp 11 | src/smol_cube.h 12 | ) 13 | add_executable (smol-cube-viewer 14 | src/smol_cube_viewer_app.cpp 15 | src/smol_cube.cpp 16 | src/smol_cube.h 17 | ) 18 | 19 | set_property(TARGET smol-cube-conv PROPERTY CXX_STANDARD 17) 20 | set_property(TARGET smol-cube-viewer PROPERTY CXX_STANDARD 17) 21 | 22 | set_property(TARGET smol-cube-conv PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") 23 | set_property(TARGET smol-cube-viewer PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") 24 | 25 | target_compile_definitions(smol-cube-conv PRIVATE _CRT_SECURE_NO_DEPRECATE _CRT_NONSTDC_NO_WARNINGS NOMINMAX) 26 | target_compile_definitions(smol-cube-viewer PRIVATE _CRT_SECURE_NO_DEPRECATE _CRT_NONSTDC_NO_WARNINGS NOMINMAX) 27 | 28 | if(((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "GNU")) AND 29 | ((CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64") OR (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64"))) 30 | target_compile_options(smol-cube-conv PRIVATE -msse4.1) 31 | target_compile_options(smol-cube-viewer PRIVATE -msse4.1) 32 | endif() 33 | 34 | if (APPLE) 35 | target_compile_options(smol-cube-viewer PRIVATE -x objective-c++) 36 | target_link_libraries(smol-cube-viewer PRIVATE 37 | "-framework Cocoa" 38 | "-framework Metal" 39 | "-framework MetalKit" 40 | "-framework QuartzCore" 41 | ) 42 | endif () 43 | if (CMAKE_SYSTEM_NAME STREQUAL "Linux") 44 | target_link_libraries(smol-cube-viewer PRIVATE X11 Xi Xcursor GL) 45 | endif () 46 | -------------------------------------------------------------------------------- /CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "configurePresets": [ 4 | { 5 | "name": "all-base", 6 | "hidden": true, 7 | "generator": "Ninja", 8 | "binaryDir": "${sourceDir}/out/build/${presetName}", 9 | "installDir": "${sourceDir}/out/install/${presetName}" 10 | }, 11 | { 12 | "name": "windows-base", 13 | "hidden": true, 14 | "inherits": "all-base", 15 | "cacheVariables": { 16 | "CMAKE_C_COMPILER": "cl.exe", 17 | "CMAKE_CXX_COMPILER": "cl.exe" 18 | }, 19 | "condition": { 20 | "type": "equals", 21 | "lhs": "${hostSystemName}", 22 | "rhs": "Windows" 23 | } 24 | }, 25 | { 26 | "name": "mac-base", 27 | "inherits": "all-base", 28 | "hidden": true, 29 | "generator": "Xcode", 30 | "binaryDir": "${sourceDir}/out/${presetName}", 31 | "condition": { 32 | "type": "equals", 33 | "lhs": "${hostSystemName}", 34 | "rhs": "Darwin" 35 | }, 36 | "cacheVariables": { 37 | "CMAKE_OSX_DEPLOYMENT_TARGET": "10.14" 38 | } 39 | }, 40 | { 41 | "name": "x64-debug", 42 | "displayName": "x64 Debug", 43 | "inherits": "windows-base", 44 | "architecture": { 45 | "value": "x64", 46 | "strategy": "external" 47 | }, 48 | "cacheVariables": { 49 | "CMAKE_BUILD_TYPE": "Debug" 50 | } 51 | }, 52 | { 53 | "name": "x64-release", 54 | "displayName": "x64 Release", 55 | "inherits": "x64-debug", 56 | "cacheVariables": { 57 | "CMAKE_BUILD_TYPE": "Release" 58 | } 59 | }, 60 | { 61 | "name": "x64-release-dbg", 62 | "displayName": "x64 RelWithDebInfo", 63 | "inherits": "x64-debug", 64 | "cacheVariables": { 65 | "CMAKE_BUILD_TYPE": "RelWithDebInfo" 66 | } 67 | }, 68 | { 69 | "name": "mac-debug", 70 | "displayName": "Mac Debug", 71 | "inherits": "mac-base", 72 | "cacheVariables": { 73 | "CMAKE_BUILD_TYPE": "Debug" 74 | } 75 | }, 76 | { 77 | "name": "mac-release", 78 | "displayName": "Mac Release", 79 | "inherits": "mac-base", 80 | "cacheVariables": { 81 | "CMAKE_BUILD_TYPE": "Release" 82 | } 83 | } 84 | ] 85 | } -------------------------------------------------------------------------------- /doc/chart-pbrneutral-loadtime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aras-p/smol-cube/85beaba023ffd60ed2b83edb25c476d429337472/doc/chart-pbrneutral-loadtime.png -------------------------------------------------------------------------------- /doc/chart-pbrneutral-size.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aras-p/smol-cube/85beaba023ffd60ed2b83edb25c476d429337472/doc/chart-pbrneutral-size.png -------------------------------------------------------------------------------- /doc/shot-viewer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aras-p/smol-cube/85beaba023ffd60ed2b83edb25c476d429337472/doc/shot-viewer.jpg -------------------------------------------------------------------------------- /launch.vs.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.1", 3 | "defaults": {}, 4 | "configurations": [ 5 | { 6 | "type": "default", 7 | "project": "CMakeLists.txt", 8 | "projectTarget": "smol-cube-conv.exe", 9 | "name": "smol-cube-conv.exe", 10 | "currentDir": "${workspaceRoot}", 11 | "args": [ 12 | "--float16", 13 | "--rgba", 14 | "--verbose", 15 | "--roundtrip", 16 | "tests/luts/synthetic/shaper_3d.cube", 17 | "tests/luts/tinyglade-LUNA_COLOR.cube", 18 | "tests/luts/khronos-pbrNeutral.cube", 19 | "\"tests/luts/resolve-LMT ACES v0.1.1.cube\"" 20 | ] 21 | }, 22 | { 23 | "type": "default", 24 | "project": "CMakeLists.txt", 25 | "projectTarget": "smol-cube-viewer.exe", 26 | "name": "smol-cube-viewer.exe", 27 | "currentDir": "${workspaceRoot}", 28 | "args": [ 29 | ] 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /libs/argh/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Adi Shavit 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of nor the names of its contributors may be used to 13 | endorse or promote products derived from this software without specific 14 | prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /libs/argh/README.md: -------------------------------------------------------------------------------- 1 | ![logo](assets/argh_logo_small.png) 2 | 3 | > *Frustration-free command line processing* 4 | 5 | [![Language](https://img.shields.io/badge/language-C++-blue.svg)](https://isocpp.org/) 6 | [![Standard](https://img.shields.io/badge/C%2B%2B-11-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) 7 | [![License](https://img.shields.io/badge/license-BSD-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) 8 | [![Try it online](https://img.shields.io/badge/try%20it-online-orange.svg)](http://melpon.org/wandbox/permlink/ralxPN49F7cUY2yw) 9 | [![Build Status](https://travis-ci.org/adishavit/argh.svg?branch=master)](https://travis-ci.org/adishavit/argh) 10 | 11 | So many different command line processing libraries out there and none of them just work! 12 | Some bring their whole extended family of related and unrelated external dependencies (*yes, I'm looking at you Boost*). 13 | Some require quirky syntax and/or very verbose setups that sacrifice simplicity for the generation of a cute usage message and validation. Many come to dominate your `main()` file and yet others do not build on multiple plaforms - for some even their own tests and trivial usage cause crashes on some systems. *Argh!* 14 | 15 | If you're writing a highly-sophisticated command line tool, then `Boost.Program_options` and its kind might give you many advanced options. However, if you need to get up and running quickly, effectively and with minimal fuss, give the single header-file `argh` a try. 16 | 17 | ## TL;DR 18 | It doesn't get much simpler than this: 19 | ```cpp 20 | #include 21 | #include "argh.h" 22 | 23 | int main(int, char* argv[]) 24 | { 25 | argh::parser cmdl(argv); 26 | 27 | if (cmdl[{ "-v", "--verbose" }]) 28 | std::cout << "Verbose, I am.\n"; 29 | 30 | return EXIT_SUCCESS; 31 | } 32 | ``` 33 | #### TL;DR Videos 34 | - [Arguments over Arguments - Adi Shavit - Core C++ 2019](https://youtu.be/hCbEHzDvLno) 35 | - [Arguments over Arguments, but you already know this... - Adi Shavit - CppCon 2019](https://youtu.be/KkjKkGuQUqU) 36 | 37 | ## Philosophy 38 | 39 | Contrary to many alternatives, `argh` takes a minimalist *laissez-faire* approach, very suitable for fuss-less prototyping with the following rules: 40 | 41 | The API is: 42 | - Minimalistic but expressive: 43 | - No getters nor binders 44 | - Just the `[]` and `()` operators 45 | - Easy iteration (range-`for` too) 46 | - You don't pay for what you don't use 47 | - Conversion to typed variables happens (via `std::istream >>`) on the user side *after* the parsing phase 48 | - No exceptions thrown for failures 49 | - Liberal BSD license 50 | - Single header file 51 | - No non-`std` dependencies 52 | 53 | `argh` does **not** care about: 54 | 55 | - How many '`-`' preceded your option 56 | - Which flags and options you support - that is your responsibility 57 | - Syntax validation: *any* command line is a valid (*not necessarily unique*) combination of positional *parameters*, *flags* and *options* 58 | - Automatically producing a usage message 59 | 60 | ## Tutorial 61 | 62 | Create parser: 63 | 64 | ```cpp 65 | auto cmdl = argh::parser(argc, argv); 66 | ``` 67 | In fact, you can even drop `argc`. This will also work: 68 | ```cpp 69 | argh::parser cmdl(argv); 70 | ``` 71 | 72 | Positional argument access by (integer) index with `[]`: 73 | ```cpp 74 | cout << "Exe name is: " << cmdl[0] << '\n'; 75 | ^^^ 76 | assert(cmdl[10000].empty()); // out-of-bound index returns empty string 77 | ^^^^^ 78 | ``` 79 | Boolean flag argument access by (string) name with `[]`: 80 | ```cpp 81 | cout << "Verbose mode is " << ( cmdl["verbose"] ? "ON" : "OFF" ) << '\n'; 82 | ^^^^^^^^^^^ 83 | ``` 84 | Any dashes are trimmed so are not required. 85 | 86 | Your flag can have several alternatives, just list them with `[{ "", "", ... }]`: 87 | ```cpp 88 | cout << "Verbose mode is " << ( cmdl[{ "-v", "--verbose" }] ? "ON" : "OFF" ) << '\n'; 89 | ^^^^^^^^^^^^^^^^^^^^^^^ 90 | ``` 91 | Beyond `bool` and `std::string` access with `[]`, as shown above, we can also access the argument values as an `std::istream`. This is very useful for type conversions. 92 | 93 | `std::istream` positional argument access by (integer) index with `()`: 94 | ```cpp 95 | std::string my_app_name; 96 | cmdl(0) >> my_app_name; // streaming into a string 97 | ^^^ 98 | cout << "Exe name is: " << my_app_name << '\n'; 99 | ``` 100 | We can also check if a particular positional arg was given or not (this is like using `[]` above): 101 | ```cpp 102 | if (!cmdl(10)) 103 | cerr << "Must provide at least 10 arguments!" << '\n'; 104 | else if (cmdl(11)) 105 | cout << "11th argument is: " << cmdl[11] << '\n'; 106 | ``` 107 | But we can also set default values for positional arguments. These are passed as the second argument: 108 | ```cpp 109 | float scale_factor; 110 | cmdl(2, 1.0f) >> scale_factor; 111 | ^^^^^^^ 112 | ``` 113 | If the position argument was not given or the streaming conversion failed, the default value will be used. 114 | 115 | Similarly, parameters can be accessed by name(s) (i.e. by string or list of string literals) with: 116 | `( [, ])` or `({ "", "", ... } [, ])`: 117 | ```cpp 118 | float scale_factor; 119 | cmdl("scale", 1.0f) >> scale_factor; // Use 1.0f as default value 120 | ^^^^^^^^^^^^^ 121 | 122 | float threshold; 123 | if (!(cmdl({ "-t", "--threshold"}) >> threshold)) // Check for missing param and/or bad (inconvertible) param value 124 | cerr << "Must provide a valid threshold value! Got '" << cmdl("threshold").str() << "'" << endl; 125 | else ^^^^^^ 126 | cout << "Threshold set to: " << threshold << '\n'; 127 | ``` 128 | As shown above, use `std::istream::str()` to get the param value as a `std:string` or just stream the value into a variable of a suitable type. Standard stream state indicates failure, including when the argument was not given. 129 | When using multiple names, the first value found will be returned. 130 | 131 | Positional arguments can be iterated upon directly using *range-for*: 132 | ```cpp 133 | cout << "Positional args:\n"; 134 | for (auto& pos_arg : cmdl) 135 | cout << '\t' << pos_arg << '\n'; 136 | ``` 137 | Similarly, `cmdl.size()` will return the count of *positional* arguments. 138 | 139 | Positional arguments, flags *and* parameters are accessible as "ranges": 140 | ```cpp 141 | cout << "Positional args:\n"; 142 | for (auto& pos_arg : cmdl.pos_args()) 143 | cout << '\t' << pos_arg << '\n'; 144 | 145 | cout << "\nFlags:\n"; 146 | for (auto& flag : cmdl.flags()) 147 | cout << '\t' << flag << '\n'; 148 | 149 | cout << "\nParameters:\n"; 150 | for (auto& param : cmdl.params()) 151 | cout << '\t' << param.first << " : " << param.second << '\n'; 152 | ``` 153 | 154 | If a parameter appears several times in the command line, all its duplicates may be accessed, in order, like so: 155 | 156 | ```cpp 157 | cout << "\nValues for all `--input` parameters:\n"; 158 | for (auto& param : cmdl.params("input")) // iterate on all params called "input" 159 | cout << '\t' << param.first << " : " << param.second << '\n'; 160 | ``` 161 | 162 | 163 | By default, options are assumed to be boolean flags. 164 | When this is not what you want, there are several ways to specify when an option is a parameter with an associated value. 165 | 166 | 1. Specify **`PREFER_PARAM_FOR_UNREG_OPTION`** mode to interpret *any* `