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 BlendScreen: 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   Default
43  */
44 template<typename T, colorspace_t CS, int CHMIN, int CHMAX>
45 class BlendScreen<T, CS, CHMIN, CHMAX, false>:
46   public BlendBase<T, CS, CHMIN, CHMAX, false>
47 {
48   int ch, pos;
49   T ibottom;
50   typename FormatInfo<T>::PROMOTED ptop, screen;
51   typename FormatInfo<T>::PROMOTED psum;
52 public:
BlendScreen()53   BlendScreen(): BlendBase<T, CS, CHMIN, CHMAX, false>(), psum(FormatInfo<T>::MAX + FormatInfo<T>::MIN) {}
blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int &)54   void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& /*xomap*/)
55   {
56     pos = x;
57     //psum = FormatInfo<T>::MAX + FormatInfo<T>::MIN;
58     for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) {
59       //ptop = psum - top[pos];
60       //ibottom = psum - bottom[pos];
61       screen = psum - ((psum-top[pos])*(psum-bottom[pos])/FormatInfo<T>::RANGE);
62       //std::cout<<"bottom="<<(int)bottom[pos]<<"  top="<<(int)top[pos]<<"  psum="<<(int)psum<<"  screen="<<(int)screen<<std::endl;
63       //std::cout<<"  (psum-top[pos])="<<(int)(psum-top[pos])<<"  (psum-bottom[pos])="<<(int)(psum-bottom[pos])
64       //       <<"  range="<<(int)FormatInfo<T>::RANGE<<"    ((psum-top[pos])*(psum-bottom[pos])/FormatInfo<T>::RANGE)="
65       //       <<(int)((psum-top[pos])*(psum-bottom[pos])/FormatInfo<T>::RANGE)<<std::endl;
66       clip( opacity*screen + (1.0f-opacity)*bottom[pos], out[pos] );
67     }
68   }
69 };
70 
71 template<typename T, colorspace_t CS, int CHMIN, int CHMAX>
72 class BlendScreen<T, CS, CHMIN, CHMAX, true>:
73   public BlendBase<T, CS, CHMIN, CHMAX, true>
74 {
75   int ch, pos;
76   T ibottom;
77   typename FormatInfo<T>::PROMOTED ptop, screen;
78   typename FormatInfo<T>::PROMOTED psum;
79 public:
blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int & xomap)80   void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& xomap)
81   {
82     //int i = x;
83     float opacity_real = opacity*(this->pmap[xomap]+FormatInfo<T>::MIN)/(FormatInfo<T>::RANGE);
84     xomap += 1;
85 
86     pos = x;
87     psum = FormatInfo<T>::MAX + FormatInfo<T>::MIN;
88     for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) {
89       ptop = psum - top[pos];
90       ibottom = psum - bottom[pos];
91       screen = psum - (ptop*ibottom/FormatInfo<T>::RANGE);
92       clip( opacity_real*screen + (1.0f-opacity_real)*bottom[pos], out[pos] );
93     }
94   }
95 };
96