PageRenderTime 54ms CodeModel.GetById 37ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

/src/core/ColorSpaceTransform.cpp

http://github.com/imageworks/OpenColorIO
C++ | 246 lines | 164 code | 41 blank | 41 comment | 19 complexity | b3aa443380294695e3a446f929dd73fb 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 <OpenColorIO/OpenColorIO.h>
 30
 31#include "NoOps.h"
 32#include "OpBuilders.h"
 33
 34
 35OCIO_NAMESPACE_ENTER
 36{
 37    ColorSpaceTransformRcPtr ColorSpaceTransform::Create()
 38    {
 39        return ColorSpaceTransformRcPtr(new ColorSpaceTransform(), &deleter);
 40    }
 41    
 42    void ColorSpaceTransform::deleter(ColorSpaceTransform* t)
 43    {
 44        delete t;
 45    }
 46    
 47    
 48    class ColorSpaceTransform::Impl
 49    {
 50    public:
 51        TransformDirection dir_;
 52        std::string src_;
 53        std::string dst_;
 54        
 55        Impl() :
 56            dir_(TRANSFORM_DIR_FORWARD)
 57        { }
 58        
 59        ~Impl()
 60        { }
 61        
 62        Impl& operator= (const Impl & rhs)
 63        {
 64            dir_ = rhs.dir_;
 65            src_ = rhs.src_;
 66            dst_ = rhs.dst_;
 67            return *this;
 68        }
 69    };
 70    
 71    ///////////////////////////////////////////////////////////////////////////
 72    
 73    
 74    
 75    ColorSpaceTransform::ColorSpaceTransform()
 76        : m_impl(new ColorSpaceTransform::Impl)
 77    {
 78    }
 79    
 80    TransformRcPtr ColorSpaceTransform::createEditableCopy() const
 81    {
 82        ColorSpaceTransformRcPtr transform = ColorSpaceTransform::Create();
 83        *(transform->m_impl) = *m_impl;
 84        return transform;
 85    }
 86    
 87    ColorSpaceTransform::~ColorSpaceTransform()
 88    {
 89        delete m_impl;
 90        m_impl = NULL;
 91    }
 92    
 93    ColorSpaceTransform& ColorSpaceTransform::operator= (const ColorSpaceTransform & rhs)
 94    {
 95        *m_impl = *rhs.m_impl;
 96        return *this;
 97    }
 98    
 99    TransformDirection ColorSpaceTransform::getDirection() const
100    {
101        return getImpl()->dir_;
102    }
103    
104    void ColorSpaceTransform::setDirection(TransformDirection dir)
105    {
106        getImpl()->dir_ = dir;
107    }
108    
109    const char * ColorSpaceTransform::getSrc() const
110    {
111        return getImpl()->src_.c_str();
112    }
113    
114    void ColorSpaceTransform::setSrc(const char * src)
115    {
116        getImpl()->src_ = src;
117    }
118    
119    const char * ColorSpaceTransform::getDst() const
120    {
121        return getImpl()->dst_.c_str();
122    }
123    
124    void ColorSpaceTransform::setDst(const char * dst)
125    {
126        getImpl()->dst_ = dst;
127    }
128    
129    std::ostream& operator<< (std::ostream& os, const ColorSpaceTransform& t)
130    {
131        os << "<ColorSpaceTransform ";
132        os << "direction=" << TransformDirectionToString(t.getDirection()) << ", ";
133        os << ">\n";
134        return os;
135    }
136    
137    
138    ///////////////////////////////////////////////////////////////////////////////////////////////////////
139    
140    void BuildColorSpaceOps(OpRcPtrVec & ops,
141                            const Config& config,
142                            const ConstContextRcPtr & context,
143                            const ColorSpaceTransform & colorSpaceTransform,
144                            TransformDirection dir)
145    {
146        TransformDirection combinedDir = CombineTransformDirections(dir,
147                                                  colorSpaceTransform.getDirection());
148        
149        ConstColorSpaceRcPtr src, dst;
150        
151        if(combinedDir == TRANSFORM_DIR_FORWARD)
152        {
153            src = config.getColorSpace( colorSpaceTransform.getSrc() );
154            dst = config.getColorSpace( colorSpaceTransform.getDst() );
155        }
156        else if(combinedDir == TRANSFORM_DIR_INVERSE)
157        {
158            dst = config.getColorSpace( colorSpaceTransform.getSrc() );
159            src = config.getColorSpace( colorSpaceTransform.getDst() );
160        }
161        
162        BuildColorSpaceOps(ops, config, context, src, dst);
163    }
164    
165    namespace
166    {
167        bool AreColorSpacesInSameEqualityGroup(const ConstColorSpaceRcPtr & csa,
168                                               const ConstColorSpaceRcPtr & csb)
169        {
170            std::string a = csa->getEqualityGroup();
171            std::string b = csb->getEqualityGroup();
172            
173            if(!a.empty()) return (a==b);
174            return false;
175        }
176    }
177    
178    void BuildColorSpaceOps(OpRcPtrVec & ops,
179                            const Config & config,
180                            const ConstContextRcPtr & context,
181                            const ConstColorSpaceRcPtr & srcColorSpace,
182                            const ConstColorSpaceRcPtr & dstColorSpace)
183    {
184        if(!srcColorSpace)
185            throw Exception("BuildColorSpaceOps failed, null srcColorSpace.");
186        if(!dstColorSpace)
187            throw Exception("BuildColorSpaceOps failed, null dstColorSpace.");
188        
189        if(AreColorSpacesInSameEqualityGroup(srcColorSpace, dstColorSpace))
190            return;
191        if(dstColorSpace->isData() || srcColorSpace->isData())
192            return;
193        
194        // Consider dt8 -> vd8?
195        // One would have to explode the srcColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE);
196        // result, and walk through it step by step.  If the dstColorspace family were
197        // ever encountered in transit, we'd want to short circuit the result.
198        
199        AllocationData srcAllocation;
200        srcAllocation.allocation = srcColorSpace->getAllocation();
201        srcAllocation.vars.resize( srcColorSpace->getAllocationNumVars());
202        if(srcAllocation.vars.size() > 0)
203        {
204            srcColorSpace->getAllocationVars(&srcAllocation.vars[0]);
205        }
206        
207        CreateGpuAllocationNoOp(ops, srcAllocation);
208        
209        // Go to the reference space, either by using
210        // * cs->ref in the forward direction
211        // * ref->cs in the inverse direction
212        if(srcColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE))
213        {
214            BuildOps(ops, config, context, srcColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE), TRANSFORM_DIR_FORWARD);
215        }
216        else if(srcColorSpace->getTransform(COLORSPACE_DIR_FROM_REFERENCE))
217        {
218            BuildOps(ops, config, context, srcColorSpace->getTransform(COLORSPACE_DIR_FROM_REFERENCE), TRANSFORM_DIR_INVERSE);
219        }
220        // Otherwise, both are not defined so its a no-op. This is not an error condition.
221        
222        // Go from the reference space, either by using
223        // * ref->cs in the forward direction
224        // * cs->ref in the inverse direction
225        if(dstColorSpace->getTransform(COLORSPACE_DIR_FROM_REFERENCE))
226        {
227            BuildOps(ops, config, context, dstColorSpace->getTransform(COLORSPACE_DIR_FROM_REFERENCE), TRANSFORM_DIR_FORWARD);
228        }
229        else if(dstColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE))
230        {
231            BuildOps(ops, config, context, dstColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE), TRANSFORM_DIR_INVERSE);
232        }
233        // Otherwise, both are not defined so its a no-op. This is not an error condition.
234        
235        AllocationData dstAllocation;
236        dstAllocation.allocation = dstColorSpace->getAllocation();
237        dstAllocation.vars.resize( dstColorSpace->getAllocationNumVars());
238        if(dstAllocation.vars.size() > 0)
239        {
240            dstColorSpace->getAllocationVars(&dstAllocation.vars[0]);
241        }
242        
243        CreateGpuAllocationNoOp(ops, dstAllocation);
244    }
245}
246OCIO_NAMESPACE_EXIT