1 /* 2 Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. 3 All Rights Reserved. 4 5 Redistribution and use in source and binary forms, with or without 6 modification, are permitted provided that the following conditions are 7 met: 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. 16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 OF 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 35 OCIO_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 << "src=" << t.getSrc() << ", "; 134 os << "dst=" << t.getDst(); 135 os << ">"; 136 return os; 137 } 138 139 140 /////////////////////////////////////////////////////////////////////////////////////////////////////// 141 142 void BuildColorSpaceOps(OpRcPtrVec & ops, 143 const Config& config, 144 const ConstContextRcPtr & context, 145 const ColorSpaceTransform & colorSpaceTransform, 146 TransformDirection dir) 147 { 148 TransformDirection combinedDir = CombineTransformDirections(dir, 149 colorSpaceTransform.getDirection()); 150 151 ConstColorSpaceRcPtr src, dst; 152 153 if(combinedDir == TRANSFORM_DIR_FORWARD) 154 { 155 src = config.getColorSpace( context->resolveStringVar( colorSpaceTransform.getSrc() ) ); 156 dst = config.getColorSpace( context->resolveStringVar( colorSpaceTransform.getDst() ) ); 157 } 158 else if(combinedDir == TRANSFORM_DIR_INVERSE) 159 { 160 dst = config.getColorSpace( context->resolveStringVar( colorSpaceTransform.getSrc() ) ); 161 src = config.getColorSpace( context->resolveStringVar( colorSpaceTransform.getDst() ) ); 162 } 163 164 BuildColorSpaceOps(ops, config, context, src, dst); 165 } 166 167 namespace 168 { 169 bool AreColorSpacesInSameEqualityGroup(const ConstColorSpaceRcPtr & csa, 170 const ConstColorSpaceRcPtr & csb) 171 { 172 std::string a = csa->getEqualityGroup(); 173 std::string b = csb->getEqualityGroup(); 174 175 if(!a.empty()) return (a==b); 176 return false; 177 } 178 } 179 180 void BuildColorSpaceOps(OpRcPtrVec & ops, 181 const Config & config, 182 const ConstContextRcPtr & context, 183 const ConstColorSpaceRcPtr & srcColorSpace, 184 const ConstColorSpaceRcPtr & dstColorSpace) 185 { 186 if(!srcColorSpace) 187 throw Exception("BuildColorSpaceOps failed, null srcColorSpace."); 188 if(!dstColorSpace) 189 throw Exception("BuildColorSpaceOps failed, null dstColorSpace."); 190 191 if(AreColorSpacesInSameEqualityGroup(srcColorSpace, dstColorSpace)) 192 return; 193 if(dstColorSpace->isData() || srcColorSpace->isData()) 194 return; 195 196 // Consider dt8 -> vd8? 197 // One would have to explode the srcColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE); 198 // result, and walk through it step by step. If the dstColorspace family were 199 // ever encountered in transit, we'd want to short circuit the result. 200 201 AllocationData srcAllocation; 202 srcAllocation.allocation = srcColorSpace->getAllocation(); 203 srcAllocation.vars.resize( srcColorSpace->getAllocationNumVars()); 204 if(srcAllocation.vars.size() > 0) 205 { 206 srcColorSpace->getAllocationVars(&srcAllocation.vars[0]); 207 } 208 209 CreateGpuAllocationNoOp(ops, srcAllocation); 210 211 // Go to the reference space, either by using 212 // * cs->ref in the forward direction 213 // * ref->cs in the inverse direction 214 if(srcColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE)) 215 { 216 BuildOps(ops, config, context, srcColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE), TRANSFORM_DIR_FORWARD); 217 } 218 else if(srcColorSpace->getTransform(COLORSPACE_DIR_FROM_REFERENCE)) 219 { 220 BuildOps(ops, config, context, srcColorSpace->getTransform(COLORSPACE_DIR_FROM_REFERENCE), TRANSFORM_DIR_INVERSE); 221 } 222 // Otherwise, both are not defined so its a no-op. This is not an error condition. 223 224 // Go from the reference space, either by using 225 // * ref->cs in the forward direction 226 // * cs->ref in the inverse direction 227 if(dstColorSpace->getTransform(COLORSPACE_DIR_FROM_REFERENCE)) 228 { 229 BuildOps(ops, config, context, dstColorSpace->getTransform(COLORSPACE_DIR_FROM_REFERENCE), TRANSFORM_DIR_FORWARD); 230 } 231 else if(dstColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE)) 232 { 233 BuildOps(ops, config, context, dstColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE), TRANSFORM_DIR_INVERSE); 234 } 235 // Otherwise, both are not defined so its a no-op. This is not an error condition. 236 237 AllocationData dstAllocation; 238 dstAllocation.allocation = dstColorSpace->getAllocation(); 239 dstAllocation.vars.resize( dstColorSpace->getAllocationNumVars()); 240 if(dstAllocation.vars.size() > 0) 241 { 242 dstColorSpace->getAllocationVars(&dstAllocation.vars[0]); 243 } 244 245 CreateGpuAllocationNoOp(ops, dstAllocation); 246 } 247 } 248 OCIO_NAMESPACE_EXIT 249