PageRenderTime 38ms CodeModel.GetById 13ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/apps/ociocheck/main.cpp

http://github.com/imageworks/OpenColorIO
C++ | 318 lines | 278 code | 38 blank | 2 comment | 33 complexity | 140ba4ef08535bde600751f73ff0edca MD5 | raw file
  1// SPDX-License-Identifier: BSD-3-Clause
  2// Copyright Contributors to the OpenColorIO Project.
  3
  4#include <cstdlib>
  5#include <iostream>
  6#include <fstream>
  7#include <set>
  8#include <vector>
  9
 10#include <OpenColorIO/OpenColorIO.h>
 11namespace OCIO = OCIO_NAMESPACE;
 12
 13#include "apputils/argparse.h"
 14
 15
 16const char * DESC_STRING = "\n\n"
 17"ociocheck is useful to validate that the specified OCIO configuration\n"
 18"is valid, and that all the color transforms are defined.\n"
 19"For example, it is possible that the configuration may reference\n"
 20"lookup tables that do not exist. ociocheck will find these cases.\n\n"
 21"ociocheck can also be used to clean up formatting on an existing profile\n"
 22"that has been manually edited, using the '-o' option.\n";
 23
 24int main(int argc, const char **argv)
 25{
 26    bool help = false;
 27    int errorcount = 0;
 28    std::string inputconfig;
 29    std::string outputconfig;
 30
 31    ArgParse ap;
 32    ap.options("ociocheck -- validate an OpenColorIO configuration\n\n"
 33               "usage:  ociocheck [options]\n",
 34               "--help", &help, "Print help message",
 35               "--iconfig %s", &inputconfig, "Input .ocio configuration file (default: $OCIO)",
 36               "--oconfig %s", &outputconfig, "Output .ocio file",
 37               NULL);
 38
 39    if (ap.parse(argc, argv) < 0)
 40    {
 41        std::cout << ap.geterror() << std::endl;
 42        ap.usage();
 43        std::cout << DESC_STRING;
 44        return 1;
 45    }
 46
 47    if (help)
 48    {
 49        ap.usage();
 50        std::cout << DESC_STRING;
 51        return 1;
 52    }
 53
 54    try
 55    {
 56        OCIO::ConstConfigRcPtr config;
 57
 58        std::cout << std::endl;
 59        std::cout << "OpenColorIO Library Version: " << OCIO::GetVersion() << std::endl;
 60        std::cout << "OpenColorIO Library VersionHex: " << OCIO::GetVersionHex() << std::endl;
 61
 62        if(!inputconfig.empty())
 63        {
 64            std::cout << "Loading " << inputconfig << std::endl;
 65            config = OCIO::Config::CreateFromFile(inputconfig.c_str());
 66        }
 67        else if(OCIO::GetEnvVariable("OCIO"))
 68        {
 69            std::cout << "Loading $OCIO " << OCIO::GetEnvVariable("OCIO") << std::endl;
 70            config = OCIO::Config::CreateFromEnv();
 71        }
 72        else
 73        {
 74            std::cout << "ERROR: You must specify an input OCIO configuration ";
 75            std::cout << "(either with --iconfig or $OCIO).\n";
 76            ap.usage ();
 77            std::cout << DESC_STRING;
 78            return 1;
 79        }
 80
 81        std::cout << std::endl;
 82        std::cout << "** General **" << std::endl;
 83        std::cout << "Search Path: " << config->getSearchPath() << std::endl;
 84        std::cout << "Working Dir: " << config->getWorkingDir() << std::endl;
 85        std::cout << std::endl;
 86
 87        if (config->getNumDisplays() == 0)
 88        {
 89            std::cout << "Error: At least one (display, view) pair must be defined." << std::endl;
 90            errorcount += 1;
 91        }
 92        else
 93        {
 94            std::cout << "Default Display: " << config->getDefaultDisplay() << std::endl;
 95            std::cout << "Default View: " << config->getDefaultView(config->getDefaultDisplay()) << std::endl;
 96        }
 97
 98        {
 99            std::cout << std::endl;
100            std::cout << "** Roles **" << std::endl;
101
102            std::set<std::string> usedroles;
103            const char * allroles[] = { OCIO::ROLE_DEFAULT, OCIO::ROLE_SCENE_LINEAR,
104                                        OCIO::ROLE_DATA, OCIO::ROLE_REFERENCE,
105                                        OCIO::ROLE_COMPOSITING_LOG, OCIO::ROLE_COLOR_TIMING,
106                                        OCIO::ROLE_COLOR_PICKING,
107                                        OCIO::ROLE_TEXTURE_PAINT, OCIO::ROLE_MATTE_PAINT,
108                                        NULL };
109            int MAXROLES=256;
110            for(int i=0;i<MAXROLES; ++i)
111            {
112                const char * role = allroles[i];
113                if(!role) break;
114                usedroles.insert(role);
115
116                OCIO::ConstColorSpaceRcPtr cs = config->getColorSpace(role);
117                if(cs)
118                {
119                    std::cout << cs->getName() << " (" << role << ")" << std::endl;
120                }
121                else
122                {
123                    std::cout << "ERROR: NOT DEFINED" << " (" << role << ")" << std::endl;
124                    errorcount += 1;
125                }
126            }
127
128            for(int i=0; i<config->getNumRoles(); ++i)
129            {
130                const char * role = config->getRoleName(i);
131                if(usedroles.find(role) != usedroles.end()) continue;
132
133                OCIO::ConstColorSpaceRcPtr cs = config->getColorSpace(role);
134                if(cs)
135                {
136                    std::cout << cs->getName() << " (" << role << ": user)" << std::endl;
137                }
138                else
139                {
140                    std::cout << "ERROR: NOT DEFINED" << " (" << role << ")" << std::endl;
141                    errorcount += 1;
142                }
143
144            }
145        }
146
147        std::cout << std::endl;
148        std::cout << "** ColorSpaces **" << std::endl;
149        OCIO::ConstColorSpaceRcPtr lin = config->getColorSpace(OCIO::ROLE_SCENE_LINEAR);
150        if(!lin)
151        {
152            std::cout << "Error: scene_linear role must be defined." << std::endl;
153            errorcount += 1;
154        }
155        else
156        {
157            for(int i=0; i<config->getNumColorSpaces(); ++i)
158            {
159                OCIO::ConstColorSpaceRcPtr cs = config->getColorSpace(config->getColorSpaceNameByIndex(i));
160
161                bool convertsToLinear = true;
162                std::string convertsToLinearErrorText;
163
164                bool convertsFromLinear = true;
165                std::string convertsFromLinearErrorText;
166
167                try
168                {
169                    OCIO::ConstProcessorRcPtr p = config->getProcessor(cs, lin);
170                }
171                catch(OCIO::Exception & exception)
172                {
173                    convertsToLinear = false;
174                    convertsToLinearErrorText = exception.what();
175                }
176
177                try
178                {
179                    OCIO::ConstProcessorRcPtr p = config->getProcessor(lin, cs);
180                }
181                catch(OCIO::Exception & exception)
182                {
183                    convertsFromLinear = false;
184                    convertsFromLinearErrorText = exception.what();
185                }
186
187                if(convertsToLinear && convertsFromLinear)
188                {
189                    std::cout << cs->getName() << std::endl;
190                }
191                else if(!convertsToLinear && !convertsFromLinear)
192                {
193                    std::cout << cs->getName();
194                    std::cout << " -- error" << std::endl;
195                    std::cout << "\t" << convertsToLinearErrorText << std::endl;
196                    std::cout << "\t" << convertsFromLinearErrorText << std::endl;
197
198                    errorcount += 1;
199                }
200                else if(convertsToLinear)
201                {
202                    std::cout << cs->getName();
203                    std::cout << " -- input only" << std::endl;
204                }
205                else if(convertsFromLinear)
206                {
207                    std::cout << cs->getName();
208                    std::cout << " -- output only" << std::endl;
209                }
210            }
211        }
212
213        std::cout << std::endl;
214        std::cout << "** Looks **" << std::endl;
215        if(config->getNumLooks()>0)
216        {
217            for(int i=0; i<config->getNumLooks(); ++i)
218            {
219                std::cout << config->getLookNameByIndex(i) << std::endl;
220
221                OCIO::ConstLookRcPtr look = config->getLook(config->getLookNameByIndex(i)); 
222
223                OCIO::ConstTransformRcPtr transform = look->getTransform();         
224
225                if(transform)
226                {
227                    try
228                    {
229                        OCIO::ConstProcessorRcPtr process = config->getProcessor(transform);
230                        std::cout << "src file found" << std::endl;
231                    }
232                    catch(OCIO::Exception & exception)
233                    {
234                        std::cerr << "ERROR: " << exception.what() << std::endl;
235                        errorcount += 1;
236                    }
237                }
238
239                OCIO::ConstTransformRcPtr invTransform = look->getInverseTransform();         
240
241                if(invTransform)
242                {
243                    try
244                    {
245                        OCIO::ConstProcessorRcPtr process = config->getProcessor(invTransform);
246                        std::cout << "src file found" << std::endl;
247                    }
248                    catch(OCIO::Exception & exception)
249                    {
250                        std::cerr << "ERROR: " << exception.what() << std::endl;
251                        errorcount += 1;
252                    }
253                }
254
255            }
256        }
257        else
258        {
259            std::cout << "no looks defined" << std::endl;
260        }
261        std::cout << std::endl;
262        std::cout << "** Sanity Check **" << std::endl;
263
264        try
265        {
266            config->sanityCheck();
267            std::cout << "passed" << std::endl;
268        }
269        catch(OCIO::Exception & exception)
270        {
271            std::cout << "ERROR" << std::endl;
272            errorcount += 1;
273            std::cout << exception.what() << std::endl;
274        }
275
276        if(!outputconfig.empty())
277        {
278            std::ofstream output;
279            output.open(outputconfig.c_str());
280
281            if(!output.is_open())
282            {
283                std::cout << "Error opening " << outputconfig << " for writing." << std::endl;
284            }
285            else
286            {
287                config->serialize(output);
288                output.close();
289                std::cout << "Wrote " << outputconfig << std::endl;
290            }
291        }
292    }
293    catch(OCIO::Exception & exception)
294    {
295        std::cout << "ERROR: " << exception.what() << std::endl;
296        return 1;
297    } catch (std::exception& exception) {
298        std::cout << "ERROR: " << exception.what() << "\n";
299        return 1;
300    }
301    catch(...)
302    {
303        std::cout << "Unknown error encountered." << std::endl;
304        return 1;
305    }
306
307    std::cout << std::endl;
308    if(errorcount == 0)
309    {
310        std::cout << "Tests complete." << std::endl << std::endl;
311        return 0;
312    }
313    else
314    {
315        std::cout << errorcount << " tests failed." << std::endl << std::endl;
316        return 1;
317    }
318}