PageRenderTime 105ms CodeModel.GetById 32ms app.highlight 67ms RepoModel.GetById 1ms app.codeStats 0ms

/src/core/ParseUtils.cpp

http://github.com/imageworks/OpenColorIO
C++ | 510 lines | 382 code | 90 blank | 38 comment | 230 complexity | 375bac55a1b3a0a108d30e042d2766b3 MD5 | raw file
  1/*
  2Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al.
  3All Rights Reserved.
  4
  5Redistribution and use in source and binary forms, with or without
  6modification, are permitted provided that the following conditions are
  7met:
  8* Redistributions of source code must retain the above copyright
  9  notice, this list of conditions and the following disclaimer.
 10* Redistributions in binary form must reproduce the above copyright
 11  notice, this list of conditions and the following disclaimer in the
 12  documentation and/or other materials provided with the distribution.
 13* Neither the name of Sony Pictures Imageworks nor the names of its
 14  contributors may be used to endorse or promote products derived from
 15  this software without specific prior written permission.
 16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 17"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 18LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 19A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 20OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 21SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 22LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 23DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 24THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 25(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 26OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 27*/
 28
 29#include <iostream>
 30#include <set>
 31#include <sstream>
 32
 33#include <OpenColorIO/OpenColorIO.h>
 34
 35#include "ParseUtils.h"
 36#include "pystring/pystring.h"
 37
 38OCIO_NAMESPACE_ENTER
 39{
 40    const char * BoolToString(bool val)
 41    {
 42        if(val) return "true";
 43        return "false";
 44    }
 45    
 46    bool BoolFromString(const char * s)
 47    {
 48        std::string str = pystring::lower(s);
 49        if((str == "true") || (str=="yes")) return true;
 50        return false;
 51    }
 52    
 53    const char * LoggingLevelToString(LoggingLevel level)
 54    {
 55        if(level == LOGGING_LEVEL_NONE) return "none";
 56        else if(level == LOGGING_LEVEL_WARNING) return "warning";
 57        else if(level == LOGGING_LEVEL_INFO) return "info";
 58        else if(level == LOGGING_LEVEL_DEBUG) return "debug";
 59        return "unknown";
 60    }
 61    
 62    LoggingLevel LoggingLevelFromString(const char * s)
 63    {
 64        std::string str = pystring::lower(s);
 65        if(str == "0" || str == "none") return LOGGING_LEVEL_NONE;
 66        else if(str == "1" || str == "warning") return LOGGING_LEVEL_WARNING;
 67        else if(str == "2" || str == "info") return LOGGING_LEVEL_INFO;
 68        else if(str == "3" || str == "debug") return LOGGING_LEVEL_DEBUG;
 69        return LOGGING_LEVEL_UNKNOWN;
 70    }
 71    
 72    const char * TransformDirectionToString(TransformDirection dir)
 73    {
 74        if(dir == TRANSFORM_DIR_FORWARD) return "forward";
 75        else if(dir == TRANSFORM_DIR_INVERSE) return "inverse";
 76        return "unknown";
 77    }
 78    
 79    TransformDirection TransformDirectionFromString(const char * s)
 80    {
 81        std::string str = pystring::lower(s);
 82        if(str == "forward") return TRANSFORM_DIR_FORWARD;
 83        else if(str == "inverse") return TRANSFORM_DIR_INVERSE;
 84        return TRANSFORM_DIR_UNKNOWN;
 85    }
 86    
 87    TransformDirection CombineTransformDirections(TransformDirection d1,
 88                                                  TransformDirection d2)
 89    {
 90        // Any unknowns always combine to be unknown.
 91        if(d1 == TRANSFORM_DIR_UNKNOWN || d2 == TRANSFORM_DIR_UNKNOWN)
 92            return TRANSFORM_DIR_UNKNOWN;
 93        
 94        if(d1 == TRANSFORM_DIR_FORWARD && d2 == TRANSFORM_DIR_FORWARD)
 95            return TRANSFORM_DIR_FORWARD;
 96        
 97        if(d1 == TRANSFORM_DIR_INVERSE && d2 == TRANSFORM_DIR_INVERSE)
 98            return TRANSFORM_DIR_FORWARD;
 99        
100        return TRANSFORM_DIR_INVERSE;
101    }
102    
103    TransformDirection GetInverseTransformDirection(TransformDirection dir)
104    {
105        if(dir == TRANSFORM_DIR_FORWARD) return TRANSFORM_DIR_INVERSE;
106        else if(dir == TRANSFORM_DIR_INVERSE) return TRANSFORM_DIR_FORWARD;
107        return TRANSFORM_DIR_UNKNOWN;
108    }
109    
110    const char * ColorSpaceDirectionToString(ColorSpaceDirection dir)
111    {
112        if(dir == COLORSPACE_DIR_TO_REFERENCE) return "to_reference";
113        else if(dir == COLORSPACE_DIR_FROM_REFERENCE) return "from_reference";
114        return "unknown";
115    }
116    
117    ColorSpaceDirection ColorSpaceDirectionFromString(const char * s)
118    {
119        std::string str = pystring::lower(s);
120        if(str == "to_reference") return COLORSPACE_DIR_TO_REFERENCE;
121        else if(str == "from_reference") return COLORSPACE_DIR_FROM_REFERENCE;
122        return COLORSPACE_DIR_UNKNOWN;
123    }
124    
125    const char * BitDepthToString(BitDepth bitDepth)
126    {
127        if(bitDepth == BIT_DEPTH_UINT8) return "8ui";
128        else if(bitDepth == BIT_DEPTH_UINT10) return "10ui";
129        else if(bitDepth == BIT_DEPTH_UINT12) return "12ui";
130        else if(bitDepth == BIT_DEPTH_UINT14) return "14ui";
131        else if(bitDepth == BIT_DEPTH_UINT16) return "16ui";
132        else if(bitDepth == BIT_DEPTH_UINT32) return "32ui";
133        else if(bitDepth == BIT_DEPTH_F16) return "16f";
134        else if(bitDepth == BIT_DEPTH_F32) return "32f";
135        return "unknown";
136    }
137    
138    BitDepth BitDepthFromString(const char * s)
139    {
140        std::string str = pystring::lower(s);
141        if(str == "8ui") return BIT_DEPTH_UINT8;
142        else if(str == "10ui") return BIT_DEPTH_UINT10;
143        else if(str == "12ui") return BIT_DEPTH_UINT12;
144        else if(str == "14ui") return BIT_DEPTH_UINT14;
145        else if(str == "16ui") return BIT_DEPTH_UINT16;
146        else if(str == "32ui") return BIT_DEPTH_UINT32;
147        else if(str == "16f") return BIT_DEPTH_F16;
148        else if(str == "32f") return BIT_DEPTH_F32;
149        return BIT_DEPTH_UNKNOWN;
150    }
151    
152    bool BitDepthIsFloat(BitDepth bitDepth)
153    {
154        if(bitDepth == BIT_DEPTH_F16) return true;
155        else if(bitDepth == BIT_DEPTH_F32) return true;
156        return false;
157    }
158    
159    int BitDepthToInt(BitDepth bitDepth)
160    {
161        if(bitDepth == BIT_DEPTH_UINT8) return 8;
162        else if(bitDepth == BIT_DEPTH_UINT10) return 10;
163        else if(bitDepth == BIT_DEPTH_UINT12) return 12;
164        else if(bitDepth == BIT_DEPTH_UINT14) return 14;
165        else if(bitDepth == BIT_DEPTH_UINT16) return 16;
166        else if(bitDepth == BIT_DEPTH_UINT32) return 32;
167        
168        return 0;
169    }
170    
171    const char * AllocationToString(Allocation alloc)
172    {
173        if(alloc == ALLOCATION_UNIFORM) return "uniform";
174        else if(alloc == ALLOCATION_LG2) return "lg2";
175        return "unknown";
176    }
177    
178    Allocation AllocationFromString(const char * s)
179    {
180        std::string str = pystring::lower(s);
181        if(str == "uniform") return ALLOCATION_UNIFORM;
182        else if(str == "lg2") return ALLOCATION_LG2;
183        return ALLOCATION_UNKNOWN;
184    }
185    
186    const char * InterpolationToString(Interpolation interp)
187    {
188        if(interp == INTERP_NEAREST) return "nearest";
189        else if(interp == INTERP_LINEAR) return "linear";
190        else if(interp == INTERP_TETRAHEDRAL) return "tetrahedral";
191        else if(interp == INTERP_BEST) return "best";
192        return "unknown";
193    }
194    
195    Interpolation InterpolationFromString(const char * s)
196    {
197        std::string str = pystring::lower(s);
198        if(str == "nearest") return INTERP_NEAREST;
199        else if(str == "linear") return INTERP_LINEAR;
200        else if(str == "tetrahedral") return INTERP_TETRAHEDRAL;
201        else if(str == "best") return INTERP_BEST;
202        return INTERP_UNKNOWN;
203    }
204    
205    const char * GpuLanguageToString(GpuLanguage language)
206    {
207        if(language == GPU_LANGUAGE_CG) return "cg";
208        else if(language == GPU_LANGUAGE_GLSL_1_0) return "glsl_1.0";
209        else if(language == GPU_LANGUAGE_GLSL_1_3) return "glsl_1.3";
210        return "unknown";
211    }
212    
213    GpuLanguage GpuLanguageFromString(const char * s)
214    {
215        std::string str = pystring::lower(s);
216        if(str == "cg") return GPU_LANGUAGE_CG;
217        else if(str == "glsl_1.0") return GPU_LANGUAGE_GLSL_1_0;
218        else if(str == "glsl_1.3") return GPU_LANGUAGE_GLSL_1_3;
219        return GPU_LANGUAGE_UNKNOWN;
220    }
221    
222    
223    const char * EnvironmentModeToString(EnvironmentMode mode)
224    {
225        if(mode == ENV_ENVIRONMENT_LOAD_PREDEFINED) return "loadpredefined";
226        else if(mode == ENV_ENVIRONMENT_LOAD_ALL) return "loadall";
227        return "unknown";
228    }
229    
230    EnvironmentMode EnvironmentModeFromString(const char * s)
231    {
232        std::string str = pystring::lower(s);
233        if(str == "loadpredefined") return ENV_ENVIRONMENT_LOAD_PREDEFINED;
234        else if(str == "loadall") return ENV_ENVIRONMENT_LOAD_ALL;
235        return ENV_ENVIRONMENT_UNKNOWN;
236    }
237    
238    const char * ROLE_DEFAULT = "default";
239    const char * ROLE_REFERENCE = "reference";
240    const char * ROLE_DATA = "data";
241    const char * ROLE_COLOR_PICKING = "color_picking";
242    const char * ROLE_SCENE_LINEAR = "scene_linear";
243    const char * ROLE_COMPOSITING_LOG = "compositing_log";
244    const char * ROLE_COLOR_TIMING = "color_timing";
245    const char * ROLE_TEXTURE_PAINT = "texture_paint";
246    const char * ROLE_MATTE_PAINT = "matte_paint";
247    
248    namespace
249    {
250        const int FLOAT_DECIMALS = 7;
251        const int DOUBLE_DECIMALS = 16;
252    }
253    
254    std::string FloatToString(float value)
255    {
256        std::ostringstream pretty;
257        pretty.precision(FLOAT_DECIMALS);
258        pretty << value;
259        return pretty.str();
260    }
261    
262    std::string FloatVecToString(const float * fval, unsigned int size)
263    {
264        if(size<=0) return "";
265        
266        std::ostringstream pretty;
267        pretty.precision(FLOAT_DECIMALS);
268        for(unsigned int i=0; i<size; ++i)
269        {
270            if(i!=0) pretty << " ";
271            pretty << fval[i];
272        }
273        
274        return pretty.str();
275    }
276    
277    bool StringToFloat(float * fval, const char * str)
278    {
279        if(!str) return false;
280        
281        std::istringstream inputStringstream(str);
282        float x;
283        if(!(inputStringstream >> x))
284        {
285            return false;
286        }
287        
288        if(fval) *fval = x;
289        return true;
290    }
291    
292    bool StringToInt(int * ival, const char * str, bool failIfLeftoverChars)
293    {
294        if(!str) return false;
295        if(!ival) return false;
296        
297        std::istringstream i(str);
298        char c=0;
299        if (!(i >> *ival) || (failIfLeftoverChars && i.get(c))) return false;
300        return true;
301    }
302    
303    
304    std::string DoubleToString(double value)
305    {
306        std::ostringstream pretty;
307        pretty.precision(DOUBLE_DECIMALS);
308        pretty << value;
309        return pretty.str();
310    }
311    
312    
313    bool StringVecToFloatVec(std::vector<float> &floatArray,
314                             const std::vector<std::string> &lineParts)
315    {
316        floatArray.resize(lineParts.size());
317        
318        for(unsigned int i=0; i<lineParts.size(); i++)
319        {
320            std::istringstream inputStringstream(lineParts[i]);
321            float x;
322            if(!(inputStringstream >> x))
323            {
324                return false;
325            }
326            floatArray[i] = x;
327        }
328        
329        return true;
330    }
331    
332    
333    bool StringVecToIntVec(std::vector<int> &intArray,
334                           const std::vector<std::string> &lineParts)
335    {
336        intArray.resize(lineParts.size());
337        
338        for(unsigned int i=0; i<lineParts.size(); i++)
339        {
340            std::istringstream inputStringstream(lineParts[i]);
341            int x;
342            if(!(inputStringstream >> x))
343            {
344                return false;
345            }
346            intArray[i] = x;
347        }
348        
349        return true;
350    }
351    
352    ////////////////////////////////////////////////////////////////////////////
353    
354    // read the next non empty line, and store it in 'line'
355    // return 'true' on success
356    
357    bool nextline(std::istream &istream, std::string &line)
358    {
359        while ( istream.good() )
360        {
361            std::getline(istream, line);
362            if(line.size() > 0 && line[line.size() - 1] == '\r')
363            {
364                line.resize(line.size() - 1);
365            }
366            if(!pystring::strip(line).empty())
367            {
368                return true;
369            }
370        }
371        
372        line = "";
373        return false;
374    }
375    
376    
377    bool StrEqualsCaseIgnore(const std::string & a, const std::string & b)
378    {
379        return (pystring::lower(a) == pystring::lower(b));
380    }
381    
382    // If a ',' is in the string, split on it
383    // If a ':' is in the string, split on it
384    // Otherwise, assume a single string.
385    // Also, strip whitespace from all parts.
386    
387    void SplitStringEnvStyle(std::vector<std::string> & outputvec, const char * str)
388    {
389        if(!str) return;
390        
391        std::string s = pystring::strip(str);
392        if(pystring::find(s, ",") > -1)
393        {
394            pystring::split(s, outputvec, ",");
395        }
396        else if(pystring::find(s, ":") > -1)
397        {
398            pystring::split(s, outputvec, ":");
399        }
400        else
401        {
402            outputvec.push_back(s);
403        }
404        
405        for(unsigned int i=0; i<outputvec.size(); ++i)
406        {
407            outputvec[i] = pystring::strip(outputvec[i]);
408        }
409    }
410    
411    std::string JoinStringEnvStyle(const std::vector<std::string> & outputvec)
412    {
413        return pystring::join(", ", outputvec);
414    }
415    
416    // Ordering and capitalization from vec1 is preserved
417    std::vector<std::string> IntersectStringVecsCaseIgnore(const std::vector<std::string> & vec1,
418                                                           const std::vector<std::string> & vec2)
419    {
420        std::vector<std::string> newvec;
421        std::set<std::string> allvalues;
422        
423        // Seed the set with all values from vec2
424        for(unsigned int i=0; i<vec2.size(); ++i)
425        {
426            allvalues.insert(pystring::lower(vec2[i]));
427        }
428        
429        for(unsigned int i=0; i<vec1.size(); ++i)
430        {
431            std::string key = pystring::lower(vec1[i]);
432            if(allvalues.find(key) != allvalues.end())
433            {
434                newvec.push_back(vec1[i]);
435            }
436        }
437        
438        return newvec;
439    }
440    
441    
442    int FindInStringVecCaseIgnore(const std::vector<std::string> & vec, const std::string & str)
443    {
444        std::string teststr = pystring::lower(str);
445        for(unsigned int i=0; i<vec.size(); ++i)
446        {
447            if(pystring::lower(vec[i]) == teststr) return static_cast<int>(i);
448        }
449        
450        return -1;
451    }
452}
453OCIO_NAMESPACE_EXIT
454
455
456
457///////////////////////////////////////////////////////////////////////////////
458
459#ifdef OCIO_UNIT_TEST
460
461OCIO_NAMESPACE_USING
462
463#include "UnitTest.h"
464
465OIIO_ADD_TEST(ParseUtils, StringToInt)
466{
467    int ival = 0;
468    bool success = false;
469    
470    success = StringToInt(&ival, "", false);
471    OIIO_CHECK_EQUAL(success, false);
472    
473    success = StringToInt(&ival, "9", false);
474    OIIO_CHECK_EQUAL(success, true);
475    OIIO_CHECK_EQUAL(ival, 9);
476    
477    success = StringToInt(&ival, " 10 ", false);
478    OIIO_CHECK_EQUAL(success, true);
479    OIIO_CHECK_EQUAL(ival, 10);
480    
481    success = StringToInt(&ival, " 101", true);
482    OIIO_CHECK_EQUAL(success, true);
483    OIIO_CHECK_EQUAL(ival, 101);
484    
485    success = StringToInt(&ival, " 11x ", false);
486    OIIO_CHECK_EQUAL(success, true);
487    OIIO_CHECK_EQUAL(ival, 11);
488    
489    success = StringToInt(&ival, " 12x ", true);
490    OIIO_CHECK_EQUAL(success, false);
491    
492    success = StringToInt(&ival, "13", true);
493    OIIO_CHECK_EQUAL(success, true);
494    OIIO_CHECK_EQUAL(ival, 13);
495    
496    success = StringToInt(&ival, "-14", true);
497    OIIO_CHECK_EQUAL(success, true);
498    OIIO_CHECK_EQUAL(ival, -14);
499    
500    success = StringToInt(&ival, "x-15", false);
501    OIIO_CHECK_EQUAL(success, false);
502    
503    success = StringToInt(&ival, "x-16", false);
504    OIIO_CHECK_EQUAL(success, false);
505    
506    
507}
508
509
510#endif // OCIO_UNIT_TEST