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 class BlurBilateralBlurPar: public OpParBase 31 { 32 int padding; 33 public: BlurBilateralBlurPar()34 BlurBilateralBlurPar(): 35 OpParBase(), padding(2) 36 { 37 set_type( "blur_bilateral_blur" ); 38 set_default_name( _("blilateral blur blur") ); 39 } 40 41 has_intensity()42 bool has_intensity() { return false; } has_opacity()43 bool has_opacity() { return false; } needs_caching()44 bool needs_caching() { return false; } 45 get_padding()46 int get_padding() { return padding; } 47 48 49 50 /* Function to derive the output area from the input area 51 */ transform(const VipsRect * rin,VipsRect * rout,int)52 virtual void transform(const VipsRect* rin, VipsRect* rout, int /*id*/) 53 { 54 int pad = padding; 55 rout->left = rin->left+pad; 56 rout->top = rin->top+pad; 57 rout->width = rin->width-pad*2; 58 rout->height = rin->height-pad*2; 59 } 60 61 /* Function to derive the area to be read from input images, 62 based on the requested output area 63 */ transform_inv(const VipsRect * rout,VipsRect * rin,int)64 virtual void transform_inv(const VipsRect* rout, VipsRect* rin, int /*id*/) 65 { 66 int pad = padding; 67 rin->left = rout->left-pad; 68 rin->top = rout->top-pad; 69 rin->width = rout->width+pad*2; 70 rin->height = rout->height+pad*2; 71 //std::cout<<"BlurBilateralBlurPar::transform_inv(): ireg="<<rin->width<<"x"<<rin->height 72 // <<"+"<<rin->left<<","<<rin->top<<std::endl; 73 //std::cout<<" oreg="<<rout->width<<"x"<<rout->height<<"+"<<rout->left<<","<<rout->top<<std::endl; 74 } 75 build(std::vector<VipsImage * > & in,int first,VipsImage * imap,VipsImage * omap,unsigned int & level)76 VipsImage* build(std::vector<VipsImage*>& in, int first, 77 VipsImage* imap, VipsImage* omap, 78 unsigned int& level) 79 { 80 VipsImage* srcimg = NULL; 81 if( in.size() > 0 ) srcimg = in[0]; 82 VipsImage* out = srcimg; 83 if( !out ) return NULL; 84 set_image_hints(srcimg); 85 VipsImage* blurred = OpParBase::build( in, first, NULL, NULL, level ); 86 87 return blurred; 88 } 89 }; 90 91 92 93 template < OP_TEMPLATE_DEF > 94 class BlurBilateralBlurProc 95 { 96 public: render(VipsRegion ** ireg,int n,int in_first,VipsRegion * imap,VipsRegion * omap,VipsRegion * oreg,OpParBase * par)97 void render(VipsRegion** ireg, int n, int in_first, 98 VipsRegion* imap, VipsRegion* omap, 99 VipsRegion* oreg, OpParBase* par) 100 { 101 std::cout<<"BlurBilateralBlurProc::render() called"<<std::endl; 102 } 103 }; 104 105 template < OP_TEMPLATE_DEF_CS_SPEC > 106 class BlurBilateralBlurProc< OP_TEMPLATE_IMP_CS_SPEC(PF_COLORSPACE_MULTIBAND) > 107 { 108 public: render(VipsRegion ** ireg,int n,int in_first,VipsRegion * imap,VipsRegion * omap,VipsRegion * oreg,OpParBase * par)109 void render(VipsRegion** ireg, int n, int in_first, 110 VipsRegion* imap, VipsRegion* omap, 111 VipsRegion* oreg, OpParBase* par) 112 { 113 if( ireg[0] == NULL ) return; 114 115 BlurBilateralBlurPar* opar = dynamic_cast<BlurBilateralBlurPar*>(par); 116 if( !opar ) return; 117 118 VipsRect *r = &oreg->valid; 119 int width = r->width; 120 int height = r->height; 121 int y; 122 VipsImage* srcimg = ireg[0]->im; 123 124 if( false && r->left<10000 && r->top<10000 ) { 125 std::cout<<"BlurBilateralBlurProc::render(): ireg="<<ireg[0]->valid.width<<"x"<<ireg[0]->valid.height 126 <<"+"<<ireg[0]->valid.left<<","<<ireg[0]->valid.top<<std::endl; 127 std::cout<<" oreg="<<r->width<<"x"<<r->height<<"+"<<r->left<<","<<r->top<<std::endl; 128 } 129 130 int verb = 0; 131 //if(ireg[0]->valid.left==0 && ireg[0]->valid.top==0) verb = 1; 132 dt_bilateral_t* dt_b = (dt_bilateral_t *)malloc(sizeof(dt_bilateral_t)); 133 dt_b->size_x = ireg[0]->valid.width; 134 dt_b->size_y = ireg[0]->valid.height; 135 dt_b->size_z = ireg[0]->im->Bands; 136 dt_b->buf = (float*)malloc(dt_b->size_x * dt_b->size_y * dt_b->size_z * sizeof(float)); 137 138 T* pin = (T*)VIPS_REGION_ADDR( ireg[0], ireg[0]->valid.left, ireg[0]->valid.top ); 139 T* pout = (T*)VIPS_REGION_ADDR( oreg, r->left, r->top ); 140 int ilskip = VIPS_REGION_LSKIP( ireg[0] ) / sizeof(T); 141 int olskip = VIPS_REGION_LSKIP( oreg ) / sizeof(T); 142 int ilsz = VIPS_REGION_SIZEOF_LINE(ireg[0]); 143 int olsz = VIPS_REGION_SIZEOF_LINE(oreg); 144 int lsz = dt_b->size_x * dt_b->size_z; 145 146 T* p = dt_b->buf; 147 for( y = 0; y < ireg[0]->valid.height; y++ ) { 148 pin = (T*)VIPS_REGION_ADDR( ireg[0], ireg[0]->valid.left, ireg[0]->valid.top + y ); 149 memcpy(p, pin, lsz * sizeof(float) ); 150 p += lsz; 151 } 152 153 dt_bilateral_blur(dt_b); 154 155 p = dt_b->buf + 2*lsz + 2*dt_b->size_z; 156 for( y = 0; y < height; y++ ) { 157 pin = (T*)VIPS_REGION_ADDR( ireg[0], r->left, r->top + y ); 158 pout = (T*)VIPS_REGION_ADDR( oreg, r->left, r->top + y ); 159 memcpy(pout, p, olsz ); 160 p += lsz; 161 } 162 163 free(dt_b->buf); free(dt_b); 164 } 165 }; 166