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