1 /* 2 */ 3 4 /* 5 6 Copyright (C) 2014 Ferrero Andrea 7 8 This program is free software: you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation, either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20 21 22 */ 23 24 /* 25 26 These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/ 27 28 */ 29 30 31 32 template<typename T, colorspace_t colorspace, int CHMIN, int CHMAX, bool has_omap> 33 class BlendNormal: public BlendBase<T, colorspace, CHMIN, CHMAX, has_omap> 34 { 35 public: blend(const float &,T *,T *,T *,const int &,int &)36 void blend(const float& /*opacity*/, T* /*bottom*/, T* /*top*/, 37 T* /*out*/, const int& /*x*/, int& /*xomap*/) {} 38 }; 39 40 41 /* 42 Greyscale colorspace 43 */ 44 template<typename T, int CHMIN, int CHMAX> 45 class BlendNormal<T, PF_COLORSPACE_GRAYSCALE, CHMIN, CHMAX, false>: 46 public BlendBase<T, PF_COLORSPACE_GRAYSCALE, CHMIN, CHMAX, false> 47 { 48 public: blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int &)49 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& /*xomap*/) 50 { 51 out[x] = (T)(opacity*top[x] + (1.0f-opacity)*bottom[x]); 52 } 53 }; 54 55 template<typename T, int CHMIN, int CHMAX> 56 class BlendNormal<T, PF_COLORSPACE_GRAYSCALE, CHMIN, CHMAX, true>: 57 public BlendBase<T, PF_COLORSPACE_GRAYSCALE, CHMIN, CHMAX, true> 58 { 59 public: blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int & xomap)60 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& xomap) 61 { 62 float opacity_real = opacity*(this->pmap[xomap]+FormatInfo<T>::MIN)/(FormatInfo<T>::RANGE); 63 xomap += 1; 64 out[x] = (T)(opacity_real*top[x] + (1.0f-opacity_real)*bottom[x]); 65 } 66 }; 67 68 69 /* 70 RGB colorspace 71 */ 72 template<typename T, int CHMIN, int CHMAX> 73 class BlendNormal<T, PF_COLORSPACE_RGB, CHMIN, CHMAX, false>: 74 public BlendBase<T, PF_COLORSPACE_RGB, CHMIN, CHMAX, false> 75 { 76 int ch, pos; 77 public: blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int &)78 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& /*xomap*/) 79 { 80 pos = x; 81 // The target channel(s) get blended 82 //std::cout<<"x: "<<x<<" opacity: "<<opacity<<std::endl; 83 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) { 84 //std::cout<<"pos: "<<pos<<" bottom: "<<(int)bottom[pos]<<" top: "<<(int)top[pos]; 85 out[pos] = (T)(opacity*top[pos] + (1.0f-opacity)*bottom[pos]); 86 //std::cout<<" out: "<<(int)out[pos]<<std::endl; 87 } 88 89 /* 90 int i = x; 91 //std::cout<<" in: "<<(int)in[i]<<" out: "<<(int)out[i]<<std::endl; 92 out[i] = (T)(opacity*out[i] + (1.0f-opacity)*in[i]); 93 //std::cout<<" in: "<<(int)in[i]<<" out: "<<(int)out[i]<<std::endl; 94 i++; 95 out[i] = (T)(opacity*out[i] + (1.0f-opacity)*in[i]); 96 i++; 97 out[i] = (T)(opacity*out[i] + (1.0f-opacity)*in[i]); 98 */ 99 } 100 }; 101 102 template<typename T, int CHMIN, int CHMAX> 103 class BlendNormal<T, PF_COLORSPACE_RGB, CHMIN, CHMAX, true>: 104 public BlendBase<T, PF_COLORSPACE_RGB, CHMIN, CHMAX, true> 105 { 106 int ch, pos; 107 public: blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int & xomap)108 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& xomap) 109 { 110 //int i = x; 111 float opacity_real = opacity*(this->pmap[xomap]+FormatInfo<T>::MIN)/(FormatInfo<T>::RANGE); 112 xomap += 1; 113 114 pos = x; 115 // The target channel(s) get blended 116 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) 117 out[pos] = (T)(opacity_real*top[pos] + (1.0f-opacity_real)*bottom[pos]); 118 119 /* 120 out[i] = (T)(opacity_real*out[i] + (1.0f-opacity_real)*in[i]); 121 i += 1; 122 out[i] = (T)(opacity_real*out[i] + (1.0f-opacity_real)*in[i]); 123 i += 1; 124 out[i] = (T)(opacity_real*out[i] + (1.0f-opacity_real)*in[i]); 125 */ 126 } 127 }; 128 129 130 /* 131 LAB colorspace 132 */ 133 template<typename T, int CHMIN, int CHMAX> 134 class BlendNormal<T, PF_COLORSPACE_LAB, CHMIN, CHMAX, false>: 135 public BlendBase<T, PF_COLORSPACE_LAB, CHMIN, CHMAX, false> 136 { 137 int ch, pos; 138 public: blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int &)139 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& /*xomap*/) 140 { 141 pos = x; 142 // The target channel(s) get blended 143 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) 144 out[pos] = (T)(opacity*top[pos] + (1.0f-opacity)*bottom[pos]); 145 146 /* 147 int i = x; 148 out[i] = (T)(opacity*out[i] + (1.0f-opacity)*in[i]); 149 i++; 150 out[i] = (T)(opacity*out[i] + (1.0f-opacity)*in[i]); 151 i++; 152 out[i] = (T)(opacity*out[i] + (1.0f-opacity)*in[i]); 153 */ 154 } 155 }; 156 157 template<typename T, int CHMIN, int CHMAX> 158 class BlendNormal<T, PF_COLORSPACE_LAB, CHMIN, CHMAX, true>: 159 public BlendBase<T, PF_COLORSPACE_LAB, CHMIN, CHMAX, true> 160 { 161 int ch, pos; 162 public: blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int & xomap)163 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& xomap) 164 { 165 //int i = x; 166 float opacity_real = opacity*(this->pmap[xomap]+FormatInfo<T>::MIN)/(FormatInfo<T>::RANGE); 167 xomap += 1; 168 169 pos = x; 170 // The target channel(s) get blended 171 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) 172 out[pos] = (T)(opacity_real*top[pos] + (1.0f-opacity_real)*bottom[pos]); 173 174 /* 175 out[i] = (T)(opacity_real*out[i] + (1.0f-opacity_real)*in[i]); 176 i += 1; 177 out[i] = (T)(opacity_real*out[i] + (1.0f-opacity_real)*in[i]); 178 i += 1; 179 out[i] = (T)(opacity_real*out[i] + (1.0f-opacity_real)*in[i]); 180 */ 181 } 182 }; 183 184 185 /* 186 CMYK colorspace 187 */ 188 template<typename T, int CHMIN, int CHMAX> 189 class BlendNormal<T, PF_COLORSPACE_CMYK, CHMIN, CHMAX, false>: 190 public BlendBase<T, PF_COLORSPACE_CMYK, CHMIN, CHMAX, false> 191 { 192 int ch, pos; 193 public: blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int &)194 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& /*xomap*/) 195 { 196 pos = x; 197 // The target channel(s) get blended 198 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) 199 out[pos] = (T)(opacity*top[pos] + (1.0f-opacity)*bottom[pos]); 200 201 /* 202 int i = x; 203 out[i] = (T)(opacity*out[i] + (1.0f-opacity)*in[i]); 204 i++; 205 out[i] = (T)(opacity*out[i] + (1.0f-opacity)*in[i]); 206 i++; 207 out[i] = (T)(opacity*out[i] + (1.0f-opacity)*in[i]); 208 i++; 209 out[i] = (T)(opacity*out[i] + (1.0f-opacity)*in[i]); 210 */ 211 } 212 }; 213 214 template<typename T, int CHMIN, int CHMAX> 215 class BlendNormal<T, PF_COLORSPACE_CMYK, CHMIN, CHMAX, true>: 216 public BlendBase<T, PF_COLORSPACE_CMYK, CHMIN, CHMAX, true> 217 { 218 int ch, pos; 219 public: blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int & xomap)220 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& xomap) 221 { 222 //int i = x; 223 float opacity_real = opacity*(this->pmap[xomap]+FormatInfo<T>::MIN)/(FormatInfo<T>::RANGE); 224 xomap += 1; 225 226 pos = x; 227 // The target channel(s) get blended 228 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) 229 out[pos] = (T)(opacity_real*top[pos] + (1.0f-opacity_real)*bottom[pos]); 230 231 /* 232 out[i] = (T)(opacity_real*out[i] + (1.0f-opacity_real)*in[i]); 233 i += 1; 234 out[i] = (T)(opacity_real*out[i] + (1.0f-opacity_real)*in[i]); 235 i += 1; 236 out[i] = (T)(opacity_real*out[i] + (1.0f-opacity_real)*in[i]); 237 i += 1; 238 out[i] = (T)(opacity_real*out[i] + (1.0f-opacity_real)*in[i]); 239 */ 240 } 241 }; 242