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 class BlurBilateralSlicePar: public OpParBase 32 { 33 float sigma_s; 34 float sigma_r; 35 float ss, sr; 36 37 float scale_x, scale_y; 38 int full_width, full_height; 39 40 public: BlurBilateralSlicePar()41 BlurBilateralSlicePar(): 42 OpParBase(), sigma_s(0), sigma_r(0) 43 { 44 set_type( "blur_bilateral_slice" ); 45 set_default_name( _("blilateral blur slice") ); 46 } 47 48 //void set_iterations( int i ) { iterations.set( i ); } set_full_width(int w)49 void set_full_width( int w ) { full_width = w; } set_full_height(int h)50 void set_full_height( int h ) { full_height = h; } 51 set_sigma_s(float s)52 void set_sigma_s( float s ) { sigma_s = s; } set_sigma_r(float s)53 void set_sigma_r( float s ) { sigma_r = s; } 54 get_ss()55 float get_ss() { return ss; } get_sr()56 float get_sr() { return sr; } 57 get_sigma_s()58 float get_sigma_s() { return sigma_s; } get_sigma_r()59 float get_sigma_r() { return sigma_r; } 60 has_intensity()61 bool has_intensity() { return false; } has_opacity()62 bool has_opacity() { return true; } needs_caching()63 bool needs_caching() { return true; } 64 65 66 /* Function to derive the output area from the input area 67 */ transform(const VipsRect * rin,VipsRect * rout,int)68 virtual void transform(const VipsRect* rin, VipsRect* rout, int /*id*/) 69 { 70 rout->left = rin->left*scale_x; 71 rout->top = rin->top*scale_y; 72 rout->width = rin->width*scale_x; 73 rout->height = rin->height*scale_y; 74 } 75 76 /* Function to derive the area to be read from input images, 77 based on the requested output area 78 */ transform_inv(const VipsRect * rout,VipsRect * rin,int id)79 virtual void transform_inv(const VipsRect* rout, VipsRect* rin, int id) 80 { 81 if( id == 0 ) { 82 float _w = roundf(rout->width / ss); 83 float _h = roundf(rout->height / ss); 84 float _l = roundf(rout->left / ss); 85 float _t = roundf(rout->top / ss); 86 rin->left = _l - 2; //CLAMPS((int)_l, 0, 6000) - 1; 87 rin->top = _t - 2; //CLAMPS((int)_t, 0, 6000) - 1; 88 rin->width = _w + 5; //CLAMPS((int)_w, 4, 6000) + 3; 89 rin->height = _h + 5; //CLAMPS((int)_h, 4, 6000) + 3; 90 //rin->left = rout->left/scale_x; 91 //rin->top = rout->top/scale_y; 92 //rin->width = rout->width/scale_x; 93 //rin->height = rout->height/scale_y; 94 } else { 95 rin->left = rout->left; 96 rin->top = rout->top; 97 rin->width = rout->width; 98 rin->height = rout->height; 99 } 100 if( false ) { 101 std::cout<<"BlurBilateralSlicePar::transform_inv(): id="<<id<<" ss="<<ss<<", ireg="<<rin->width<<"x"<<rin->height 102 <<"+"<<rin->left<<","<<rin->top<<std::endl; 103 std::cout<<" oreg="<<rout->width<<"x"<<rout->height<<"+"<<rout->left<<","<<rout->top<<std::endl; 104 } 105 } 106 build(std::vector<VipsImage * > & in,int first,VipsImage * imap,VipsImage * omap,unsigned int & level)107 VipsImage* build(std::vector<VipsImage*>& in, int first, 108 VipsImage* imap, VipsImage* omap, 109 unsigned int& level) 110 { 111 VipsImage* srcimg = NULL; 112 if( in.size() > 0 ) srcimg = in[0]; 113 VipsImage* out = srcimg; 114 if( !out ) return NULL; 115 116 ss = sigma_s; 117 sr = sigma_r; 118 119 out = OpParBase::build( in, first, imap, omap, level ); 120 121 return out; 122 } 123 }; 124 125 126 127 template < OP_TEMPLATE_DEF > 128 class BlurBilateralSliceProc 129 { 130 public: render(VipsRegion ** ireg,int n,int in_first,VipsRegion * imap,VipsRegion * omap,VipsRegion * oreg,OpParBase * par)131 void render(VipsRegion** ireg, int n, int in_first, 132 VipsRegion* imap, VipsRegion* omap, 133 VipsRegion* oreg, OpParBase* par) 134 { 135 std::cout<<"BlurBilateralSliceProc::render() called"<<std::endl; 136 } 137 }; 138 139 template < OP_TEMPLATE_DEF_CS_SPEC > 140 class BlurBilateralSliceProc< OP_TEMPLATE_IMP_CS_SPEC(PF_COLORSPACE_GRAYSCALE) > 141 { 142 public: render(VipsRegion ** ireg,int n,int in_first,VipsRegion * imap,VipsRegion * omap,VipsRegion * oreg,OpParBase * par)143 void render(VipsRegion** ireg, int n, int in_first, 144 VipsRegion* imap, VipsRegion* omap, 145 VipsRegion* oreg, OpParBase* par) 146 { 147 if( ireg[0] == NULL ) return; 148 149 BlurBilateralSlicePar* opar = dynamic_cast<BlurBilateralSlicePar*>(par); 150 if( !opar ) return; 151 152 VipsRect *r = &oreg->valid; 153 int width = r->width; 154 int height = r->height; 155 int x, y; 156 VipsImage* srcimg = ireg[0]->im; 157 158 if( false && r->left<10000 && r->top<10000 ) { 159 std::cout<<"BlurBilateralSliceProc::render(): ireg[0]="<<ireg[0]->valid.width<<"x"<<ireg[0]->valid.height 160 <<"+"<<ireg[0]->valid.left<<","<<ireg[0]->valid.top 161 //<<" ireg[1]="<<ireg[1]->valid.width<<"x"<<ireg[1]->valid.height 162 //<<"+"<<ireg[1]->valid.left<<","<<ireg[1]->valid.top 163 <<std::endl; 164 std::cout<<" oreg="<<r->width<<"x"<<r->height<<"+"<<r->left<<","<<r->top<<std::endl; 165 } 166 167 T* pin = (T*)VIPS_REGION_ADDR( ireg[0], ireg[0]->valid.left+2, ireg[0]->valid.top+2 ); 168 T* pin2 = (T*)VIPS_REGION_ADDR( ireg[1], r->left, r->top ); 169 T* pout = (T*)VIPS_REGION_ADDR( oreg, r->left, r->top ); 170 int ilskip = VIPS_REGION_LSKIP( ireg[1] ) / sizeof(T); 171 int lskip = VIPS_REGION_LSKIP( ireg[0] ) / sizeof(T); 172 int olskip = VIPS_REGION_LSKIP( oreg ) / sizeof(T); 173 174 int verb = 0; 175 //if(ireg[0]->valid.left<1000 && ireg[0]->valid.top<1000) verb = 1; 176 dt_bilateral_t* dt_b = dt_bilateral_init(width, height, 177 opar->get_ss(), opar->get_sr(), verb); 178 dt_b->buf = pin; 179 dt_bilateral_slice(dt_b, pin2, pout, ilskip, lskip, olskip, -1); 180 //std::cout<<"pout[0]="<<*pout<<std::endl; 181 182 /* 183 for( y = 0; y < height; y++ ) { 184 pout = (T*)VIPS_REGION_ADDR( oreg, r->left, r->top + y ); 185 for( x = 0; x < width; x++ ) { 186 pout[x] = 60; 187 } 188 } 189 */ 190 191 dt_bilateral_free(dt_b); 192 } 193 }; 194