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 BlendMultiply: 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 template<typename T, colorspace_t CS, int CHMIN, int CHMAX> 43 class BlendMultiply<T, CS, CHMIN, CHMAX, false>: 44 public BlendBase<T, CS, CHMIN, CHMAX, false> 45 { 46 int ch, pos; 47 typename FormatInfo<T>::PROMOTED ptop; 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 pos = x; 52 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) { 53 //ptop = top[pos]; 54 ptop = ((typename FormatInfo<T>::PROMOTED)top[pos])*bottom[pos]/FormatInfo<T>::MAX; 55 clip( opacity*ptop + (1.0f-opacity)*bottom[pos], out[pos] ); 56 //std::cout<<" out="<<(int)out[pos]<<std::endl; 57 } 58 } 59 }; 60 61 62 63 template<typename T, colorspace_t CS, int CHMIN, int CHMAX> 64 class BlendMultiply<T, CS, CHMIN, CHMAX, true>: 65 public BlendBase<T, CS, CHMIN, CHMAX, true> 66 { 67 int ch, pos; 68 typename FormatInfo<T>::PROMOTED ptop; 69 float opacity_real; 70 public: blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int & xomap)71 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& xomap) 72 { 73 opacity_real = opacity*(this->pmap[xomap]+FormatInfo<T>::MIN)/(FormatInfo<T>::RANGE); 74 xomap += 1; 75 76 pos = x; 77 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) { 78 //ptop = top[pos]; 79 ptop = ((typename FormatInfo<T>::PROMOTED)top[pos])*bottom[pos]/FormatInfo<T>::MAX; 80 clip( opacity_real*ptop + (1.0f-opacity_real)*bottom[pos], out[pos] ); 81 //std::cout<<" out="<<(int)out[pos]<<std::endl; 82 } 83 } 84 }; 85 86 87 88 template<colorspace_t CS, int CHMIN, int CHMAX> 89 class BlendMultiply<float, CS, CHMIN, CHMAX, false>: 90 public BlendBase<float, CS, CHMIN, CHMAX, false> 91 { 92 int ch, pos; 93 public: blend(const float & opacity,float * bottom,float * top,float * out,const int & x,int &)94 void blend(const float& opacity, float* bottom, float* top, float* out, const int& x, int& /*xomap*/) 95 { 96 pos = x; 97 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) { 98 out[pos] = opacity*top[pos]*bottom[pos] + (1.0f-opacity)*bottom[pos]; 99 } 100 } 101 }; 102 103 104 105 template<colorspace_t CS, int CHMIN, int CHMAX> 106 class BlendMultiply<float, CS, CHMIN, CHMAX, true>: 107 public BlendBase<float, CS, CHMIN, CHMAX, true> 108 { 109 int ch, pos; 110 float opacity_real; 111 public: blend(const float & opacity,float * bottom,float * top,float * out,const int & x,int & xomap)112 void blend(const float& opacity, float* bottom, float* top, float* out, const int& x, int& xomap) 113 { 114 opacity_real = opacity*this->pmap[xomap]; 115 xomap += 1; 116 117 pos = x; 118 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) { 119 out[pos] = opacity_real*top[pos]*bottom[pos] + (1.0f-opacity_real)*bottom[pos]; 120 } 121 } 122 }; 123 124 125 126 /* 127 Greyscale colorspace 128 */ 129 130 template<typename T, int CHMIN, int CHMAX> 131 class BlendMultiply<T, PF_COLORSPACE_GRAYSCALE, CHMIN, CHMAX, false>: 132 public BlendBase<T, PF_COLORSPACE_GRAYSCALE, CHMIN, CHMAX, false> 133 { 134 typename FormatInfo<T>::PROMOTED ptop; 135 public: blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int &)136 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& /*xomap*/) 137 { 138 ptop = top[x]; 139 ptop *= bottom[x]; 140 clip( opacity*ptop/FormatInfo<T>::RANGE + (1.0f-opacity)*bottom[x], out[x] ); 141 } 142 }; 143 144 template<typename T, int CHMIN, int CHMAX> 145 class BlendMultiply<T, PF_COLORSPACE_GRAYSCALE, CHMIN, CHMAX, true>: 146 public BlendBase<T, PF_COLORSPACE_GRAYSCALE, CHMIN, CHMAX, true> 147 { 148 typename FormatInfo<T>::PROMOTED ptop; 149 public: blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int & xomap)150 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& xomap) 151 { 152 float opacity_real = opacity*(this->pmap[xomap]+FormatInfo<T>::MIN)/(FormatInfo<T>::RANGE); 153 xomap += 1; 154 ptop = top[x]; 155 ptop *= bottom[x]; 156 clip( opacity_real*ptop/FormatInfo<T>::RANGE + (1.0f-opacity_real)*bottom[x], out[x] ); 157 } 158 }; 159 160 161 template<int CHMIN, int CHMAX> 162 class BlendMultiply<float, PF_COLORSPACE_GRAYSCALE, CHMIN, CHMAX, false>: 163 public BlendBase<float, PF_COLORSPACE_GRAYSCALE, CHMIN, CHMAX, false> 164 { 165 public: blend(const float & opacity,float * bottom,float * top,float * out,const int & x,int &)166 void blend(const float& opacity, float* bottom, float* top, float* out, const int& x, int& /*xomap*/) 167 { 168 out[x] = opacity*top[x]*bottom[x] + (1.0f-opacity)*bottom[x]; 169 } 170 }; 171 172 template<int CHMIN, int CHMAX> 173 class BlendMultiply<float, PF_COLORSPACE_GRAYSCALE, CHMIN, CHMAX, true>: 174 public BlendBase<float, PF_COLORSPACE_GRAYSCALE, CHMIN, CHMAX, true> 175 { 176 public: blend(const float & opacity,float * bottom,float * top,float * out,const int & x,int & xomap)177 void blend(const float& opacity, float* bottom, float* top, float* out, const int& x, int& xomap) 178 { 179 float opacity_real = opacity*this->pmap[xomap]; 180 xomap += 1; 181 out[x] = opacity_real*top[x]*bottom[x] + (1.0f-opacity_real)*bottom[x]; 182 } 183 }; 184 185 186