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 BlendOverlay: 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 template<typename T, colorspace_t CS, int CHMIN, int CHMAX> 42 class BlendOverlay<T, CS, CHMIN, CHMAX, false>: 43 public BlendBase<T, CS, CHMIN, CHMAX, false> 44 { 45 int ch, pos; 46 T ibottom; 47 typename FormatInfo<T>::PROMOTED ptop, overlay; 48 typename FormatInfo<T>::PROMOTED psum; 49 public: BlendOverlay()50 BlendOverlay(): 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 &)51 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& /*xomap*/) 52 { 53 pos = x; 54 //psum = FormatInfo<T>::MAX + FormatInfo<T>::MIN; 55 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) { 56 if( bottom[pos] < FormatInfo<T>::HALF ) 57 overlay = (((typename FormatInfo<T>::PROMOTED)top[pos])*bottom[pos]/FormatInfo<T>::MAX)*2; 58 else 59 overlay = psum - ((psum-top[pos])*(psum-bottom[pos])/FormatInfo<T>::RANGE)*2; 60 61 clip( opacity*overlay + (1.0f-opacity)*bottom[pos], out[pos] ); 62 } 63 } 64 }; 65 66 template<typename T, colorspace_t CS, int CHMIN, int CHMAX> 67 class BlendOverlay<T, CS, CHMIN, CHMAX, true>: 68 public BlendBase<T, CS, CHMIN, CHMAX, true> 69 { 70 int ch, pos; 71 T ibottom; 72 typename FormatInfo<T>::PROMOTED ptop, overlay; 73 typename FormatInfo<T>::PROMOTED psum; 74 float opacity_real; 75 public: BlendOverlay()76 BlendOverlay(): BlendBase<T, CS, CHMIN, CHMAX, true>(), psum(FormatInfo<T>::MAX + FormatInfo<T>::MIN) {} blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int & xomap)77 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& xomap) 78 { 79 //int i = x; 80 opacity_real = opacity*(this->pmap[xomap]+FormatInfo<T>::MIN)/(FormatInfo<T>::RANGE); 81 xomap += 1; 82 83 pos = x; 84 //psum = FormatInfo<T>::MAX + FormatInfo<T>::MIN; 85 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) { 86 if( bottom[pos] < FormatInfo<T>::HALF ) 87 overlay = (((typename FormatInfo<T>::PROMOTED)top[pos])*bottom[pos]/FormatInfo<T>::MAX)*2; 88 else 89 overlay = psum - ((psum-top[pos])*(psum-bottom[pos])/FormatInfo<T>::RANGE)*2; 90 clip( opacity_real*overlay + (1.0f-opacity_real)*bottom[pos], out[pos] ); 91 } 92 } 93 }; 94 95 96 97 98 99 100 /** 101 * Overlay blend implemented using GIMP definition: 102 * 103 * gimp_composite_overlay_any_any_any_generic: 104 * @ctx: The compositing context. 105 * 106 * Perform an RGB[A] overlay operation between the pixel sources 107 * ctx->A and ctx->B, using the generalised algorithm: 108 * 109 * D = A * (A + (2 * B) * (255 - A)) 110 * 111 **/ 112 template<typename T, colorspace_t colorspace, int CHMIN, int CHMAX, bool has_omap> 113 class BlendOverlayGimp: public BlendBase<T, colorspace, CHMIN, CHMAX, has_omap> 114 { 115 public: blend(const float &,T *,T *,T *,const int &,int &)116 void blend(const float& /*opacity*/, T* /*bottom*/, T* /*top*/, 117 T* /*out*/, const int& /*x*/, int& /*xomap*/) {} 118 }; 119 120 121 template<typename T, colorspace_t CS, int CHMIN, int CHMAX> 122 class BlendOverlayGimp<T, CS, CHMIN, CHMAX, false>: 123 public BlendBase<T, CS, CHMIN, CHMAX, false> 124 { 125 int ch, pos; 126 T ibottom; 127 typename FormatInfo<T>::PROMOTED ptop, overlay; 128 typename FormatInfo<T>::PROMOTED psum; 129 float nbottom, ntop, noverlay; 130 public: BlendOverlayGimp()131 BlendOverlayGimp(): 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 &)132 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& /*xomap*/) 133 { 134 pos = x; 135 //psum = FormatInfo<T>::MAX + FormatInfo<T>::MIN; 136 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) { 137 ntop = ( ((float)top[pos])+FormatInfo<T>::MIN )/FormatInfo<T>::RANGE; 138 nbottom = ( ((float)bottom[pos])+FormatInfo<T>::MIN )/FormatInfo<T>::RANGE; 139 noverlay = nbottom * (nbottom + (ntop*2.0f)*(1.0f-nbottom)); 140 overlay = (typename FormatInfo<T>::PROMOTED)(noverlay * FormatInfo<T>::RANGE - FormatInfo<T>::MIN); 141 clip( opacity*overlay + (1.0f-opacity)*bottom[pos], out[pos] ); 142 } 143 } 144 }; 145 146 template<typename T, colorspace_t CS, int CHMIN, int CHMAX> 147 class BlendOverlayGimp<T, CS, CHMIN, CHMAX, true>: 148 public BlendBase<T, CS, CHMIN, CHMAX, true> 149 { 150 int ch, pos; 151 T ibottom; 152 typename FormatInfo<T>::PROMOTED ptop, overlay; 153 typename FormatInfo<T>::PROMOTED psum; 154 float nbottom, ntop, noverlay; 155 float opacity_real; 156 public: BlendOverlayGimp()157 BlendOverlayGimp(): BlendBase<T, CS, CHMIN, CHMAX, true>(), psum(FormatInfo<T>::MAX + FormatInfo<T>::MIN) {} blend(const float & opacity,T * bottom,T * top,T * out,const int & x,int & xomap)158 void blend(const float& opacity, T* bottom, T* top, T* out, const int& x, int& xomap) 159 { 160 //int i = x; 161 opacity_real = opacity*(this->pmap[xomap]+FormatInfo<T>::MIN)/(FormatInfo<T>::RANGE); 162 xomap += 1; 163 164 pos = x; 165 //psum = FormatInfo<T>::MAX + FormatInfo<T>::MIN; 166 for( ch=CHMIN; ch<=CHMAX; ch++, pos++ ) { 167 ntop = ( ((float)top[pos])+FormatInfo<T>::MIN )/FormatInfo<T>::RANGE; 168 nbottom = ( ((float)bottom[pos])+FormatInfo<T>::MIN )/FormatInfo<T>::RANGE; 169 noverlay = nbottom * (nbottom + (ntop*2.0f)*(1.0f-nbottom)); 170 overlay = (typename FormatInfo<T>::PROMOTED)(noverlay * FormatInfo<T>::RANGE - FormatInfo<T>::MIN); 171 clip( opacity_real*overlay + (1.0f-opacity_real)*bottom[pos], out[pos] ); 172 } 173 } 174 }; 175