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 #ifndef PF_CLIP_WARNING_H 31 #define PF_CLIP_WARNING_H 32 33 #include <string.h> 34 #include <string> 35 36 #include "../base/processor.hh" 37 38 39 namespace PF 40 { 41 42 class ClippingWarningPar: public OpParBase 43 { 44 bool highlights_warning_enabled, shadows_warning_enabled; 45 public: 46 ClippingWarningPar(); 47 set_highlights_warning(bool flag)48 void set_highlights_warning( bool flag ) { highlights_warning_enabled = flag; } get_highlights_warning()49 bool get_highlights_warning() { return highlights_warning_enabled; } set_shadows_warning(bool flag)50 void set_shadows_warning( bool flag ) { shadows_warning_enabled = flag; } get_shadows_warning()51 bool get_shadows_warning() { return shadows_warning_enabled; } 52 has_intensity()53 bool has_intensity() { return false; } has_opacity()54 bool has_opacity() { return false; } needs_input()55 bool needs_input() { return true; } 56 }; 57 58 59 60 template < OP_TEMPLATE_DEF > 61 class ClippingWarning 62 { 63 public: render(VipsRegion ** ireg,int n,int in_first,VipsRegion * imap,VipsRegion * omap,VipsRegion * oreg,OpParBase * par)64 void render(VipsRegion** ireg, int n, int in_first, 65 VipsRegion* imap, VipsRegion* omap, 66 VipsRegion* oreg, OpParBase* par) 67 { 68 VipsRect *r = &oreg->valid; 69 int line_size = r->width * oreg->im->Bands; //layer->in_all[0]->Bands; 70 int height = r->height; 71 72 T* p; 73 T* pout; 74 int x, y; 75 76 for( y = 0; y < height; y++ ) { 77 p = (T*)VIPS_REGION_ADDR( ireg[in_first], r->left, r->top + y ); 78 pout = (T*)VIPS_REGION_ADDR( oreg, r->left, r->top + y ); 79 memcpy( pout, p, sizeof(T)*line_size ); 80 } 81 } 82 }; 83 84 85 template < OP_TEMPLATE_DEF_CS_SPEC > 86 class ClippingWarning< OP_TEMPLATE_IMP_CS_SPEC(PF_COLORSPACE_RGB) > 87 { 88 public: render(VipsRegion ** ireg,int n,int in_first,VipsRegion * imap,VipsRegion * omap,VipsRegion * oreg,OpParBase * par)89 void render(VipsRegion** ireg, int n, int in_first, 90 VipsRegion* imap, VipsRegion* omap, 91 VipsRegion* oreg, OpParBase* par) 92 { 93 VipsRect *r = &oreg->valid; 94 int line_size = r->width * oreg->im->Bands; //layer->in_all[0]->Bands; 95 int width = r->width; 96 int height = r->height; 97 98 ClippingWarningPar* opar = dynamic_cast<ClippingWarningPar*>( par ); 99 if( !opar ) return; 100 101 T max = static_cast<T>( 0.999f*PF::FormatInfo<T>::RANGE + PF::FormatInfo<T>::MIN ); 102 T min = static_cast<T>( 0.001f*PF::FormatInfo<T>::RANGE + PF::FormatInfo<T>::MIN ); 103 104 T* p; 105 T* pin; 106 T* pout; 107 typename PF::FormatInfo<T>::PROMOTED avg; 108 int x, y; 109 110 for( y = 0; y < height; y++ ) { 111 p = (T*)VIPS_REGION_ADDR( ireg[in_first], r->left, r->top + y ); 112 pout = (T*)VIPS_REGION_ADDR( oreg, r->left, r->top + y ); 113 for( x=0; x < line_size; x+=3 ) { 114 //avg = p[x]; avg += p[x+1]; avg += p[x+2]; avg /= 3; 115 if( opar->get_shadows_warning() && MIN3(p[x],p[x+1],p[x+2])<=min ) { 116 pout[x] = static_cast<T>( 0.2f*PF::FormatInfo<T>::RANGE + PF::FormatInfo<T>::MIN ); 117 pout[x+1] = static_cast<T>( 0.8f*PF::FormatInfo<T>::RANGE + PF::FormatInfo<T>::MIN ); 118 pout[x+2] = static_cast<T>( 1.0f*PF::FormatInfo<T>::RANGE + PF::FormatInfo<T>::MIN ); 119 } else if( opar->get_highlights_warning() && MAX3(p[x],p[x+1],p[x+2])>=max ) { 120 pout[x] = static_cast<T>( 1.0f*PF::FormatInfo<T>::RANGE + PF::FormatInfo<T>::MIN ); 121 pout[x+1] = 0; 122 pout[x+2] = 0; 123 } else { 124 pout[x] = p[x]; 125 pout[x+1] = p[x+1]; 126 pout[x+2] = p[x+2]; 127 } 128 } 129 } 130 } 131 }; 132 133 134 135 136 137 ProcessorBase* new_clipping_warning(); 138 } 139 140 #endif 141 142 143