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 #include "OpBuilders.h" 31 32 #include <sstream> 33 34 OCIO_NAMESPACE_ENTER 35 { 36 GroupTransformRcPtr GroupTransform::Create() 37 { 38 return GroupTransformRcPtr(new GroupTransform(), &deleter); 39 } 40 41 void GroupTransform::deleter(GroupTransform* t) 42 { 43 delete t; 44 } 45 46 namespace 47 { 48 typedef std::vector<TransformRcPtr> TransformRcPtrVec; 49 } 50 51 class GroupTransform::Impl 52 { 53 public: 54 TransformDirection dir_; 55 TransformRcPtrVec vec_; 56 57 Impl() : 58 dir_(TRANSFORM_DIR_FORWARD) 59 { } 60 61 ~Impl() 62 { 63 vec_.clear(); 64 } 65 66 Impl& operator= (const Impl & rhs) 67 { 68 dir_ = rhs.dir_; 69 70 vec_.clear(); 71 72 for(unsigned int i=0; i<rhs.vec_.size(); ++i) 73 { 74 vec_.push_back(rhs.vec_[i]->createEditableCopy()); 75 } 76 77 return *this; 78 } 79 }; 80 81 82 83 /////////////////////////////////////////////////////////////////////////// 84 85 86 87 GroupTransform::GroupTransform() 88 : m_impl(new GroupTransform::Impl) 89 { 90 } 91 92 TransformRcPtr GroupTransform::createEditableCopy() const 93 { 94 GroupTransformRcPtr transform = GroupTransform::Create(); 95 *(transform->m_impl) = *m_impl; 96 return transform; 97 } 98 99 GroupTransform::~GroupTransform() 100 { 101 delete m_impl; 102 m_impl = NULL; 103 } 104 105 GroupTransform& GroupTransform::operator= (const GroupTransform & rhs) 106 { 107 if(this!=&rhs) 108 { 109 *m_impl = *rhs.m_impl; 110 } 111 return *this; 112 } 113 114 TransformDirection GroupTransform::getDirection() const 115 { 116 return getImpl()->dir_; 117 } 118 119 void GroupTransform::setDirection(TransformDirection dir) 120 { 121 getImpl()->dir_ = dir; 122 } 123 124 int GroupTransform::size() const 125 { 126 return static_cast<int>(getImpl()->vec_.size()); 127 } 128 129 ConstTransformRcPtr GroupTransform::getTransform(int index) const 130 { 131 if(index < 0 || index >= (int)getImpl()->vec_.size()) 132 { 133 std::ostringstream os; 134 os << "Invalid transform index " << index << "."; 135 throw Exception(os.str().c_str()); 136 } 137 138 return getImpl()->vec_[index]; 139 } 140 141 void GroupTransform::push_back(const ConstTransformRcPtr& transform) 142 { 143 getImpl()->vec_.push_back(transform->createEditableCopy()); 144 } 145 146 void GroupTransform::clear() 147 { 148 getImpl()->vec_.clear(); 149 } 150 151 bool GroupTransform::empty() const 152 { 153 return getImpl()->vec_.empty(); 154 } 155 156 std::ostream& operator<< (std::ostream& os, const GroupTransform& groupTransform) 157 { 158 os << "<GroupTransform "; 159 os << "direction=" << TransformDirectionToString(groupTransform.getDirection()) << ", "; 160 os << "transforms="; 161 for(int i=0; i<groupTransform.size(); ++i) 162 { 163 ConstTransformRcPtr transform = groupTransform.getTransform(i); 164 os << "\n\t" << *transform; 165 } 166 os << ">"; 167 return os; 168 } 169 170 171 /////////////////////////////////////////////////////////////////////////// 172 173 174 void BuildGroupOps(OpRcPtrVec & ops, 175 const Config& config, 176 const ConstContextRcPtr & context, 177 const GroupTransform& groupTransform, 178 TransformDirection dir) 179 { 180 TransformDirection combinedDir = CombineTransformDirections(dir, 181 groupTransform.getDirection()); 182 183 if(combinedDir == TRANSFORM_DIR_FORWARD) 184 { 185 for(int i=0; i<groupTransform.size(); ++i) 186 { 187 ConstTransformRcPtr childTransform = groupTransform.getTransform(i); 188 BuildOps(ops, config, context, childTransform, TRANSFORM_DIR_FORWARD); 189 } 190 } 191 else if(combinedDir == TRANSFORM_DIR_INVERSE) 192 { 193 for(int i=groupTransform.size()-1; i>=0; --i) 194 { 195 ConstTransformRcPtr childTransform = groupTransform.getTransform(i); 196 BuildOps(ops, config, context, childTransform, TRANSFORM_DIR_INVERSE); 197 } 198 } 199 } 200 201 } 202 OCIO_NAMESPACE_EXIT 203