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