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