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 FAST_DEMOSAIC_XTRANS_H 31 #define FAST_DEMOSAIC_XTRANS_H 32 33 #include <string> 34 35 //#include <libraw/libraw.h> 36 37 #include "../base/operation.hh" 38 #include "../base/rawmatrix.hh" 39 40 41 #include <cstring> 42 43 namespace PF 44 { 45 46 class FastDemosaicXTransPar: public OpParBase 47 { 48 bool normalize; 49 50 public: 51 FastDemosaicXTransPar(); has_intensity()52 bool has_intensity() { return false; } has_opacity()53 bool has_opacity() { return false; } needs_input()54 bool needs_input() { return true; } 55 do_normalize()56 bool do_normalize() { return normalize; } set_normalize(bool n)57 void set_normalize( bool n ) { normalize = n; } 58 set_image_hints(VipsImage * img)59 void set_image_hints( VipsImage* img ) 60 { 61 if( !img ) return; 62 OpParBase::set_image_hints( img ); 63 rgb_image( get_xsize(), get_ysize() ); 64 set_demand_hint( VIPS_DEMAND_STYLE_FATSTRIP ); 65 } 66 67 /* Function to derive the output area from the input area 68 */ transform(const VipsRect * rin,VipsRect * rout,int)69 virtual void transform(const VipsRect* rin, VipsRect* rout, int /*id*/) 70 { 71 rout->left = rin->left+5; 72 rout->top = rin->top+5; 73 rout->width = rin->width-10; 74 rout->height = rin->height-10; 75 } 76 77 /* Function to derive the area to be read from input images, 78 based on the requested output area 79 */ transform_inv(const VipsRect * rout,VipsRect * rin,int)80 virtual void transform_inv(const VipsRect* rout, VipsRect* rin, int /*id*/) 81 { 82 rin->left = rout->left-5; 83 rin->top = rout->top-5; 84 rin->width = rout->width+10; 85 rin->height = rout->height+10; 86 } 87 88 89 90 VipsImage* build(std::vector<VipsImage*>& in, int first, 91 VipsImage* imap, VipsImage* omap, 92 unsigned int& level); 93 }; 94 95 96 97 template < OP_TEMPLATE_DEF > 98 class FastDemosaicXTransProc 99 { 100 public: render(VipsRegion ** in,int n,int in_first,VipsRegion * imap,VipsRegion * omap,VipsRegion * out,FastDemosaicXTransPar * par)101 void render(VipsRegion** in, int n, int in_first, 102 VipsRegion* imap, VipsRegion* omap, 103 VipsRegion* out, FastDemosaicXTransPar* par) 104 { 105 //fast_demosaic( in, n, in_first, 106 // imap, omap, out, par ); 107 } 108 }; 109 110 111 #define fcol(r,c) ((int)(rawData[r].color(c))) 112 113 114 template < OP_TEMPLATE_DEF_TYPE_SPEC > 115 class FastDemosaicXTransProc< OP_TEMPLATE_IMP_TYPE_SPEC(float) > 116 { 117 public: render(VipsRegion ** ir,int n,int in_first,VipsRegion * imap,VipsRegion * omap,VipsRegion * oreg,FastDemosaicXTransPar * par)118 void render(VipsRegion** ir, int n, int in_first, 119 VipsRegion* imap, VipsRegion* omap, 120 VipsRegion* oreg, FastDemosaicXTransPar* par) 121 { 122 VipsRect *r = &oreg->valid; 123 int width = r->width; 124 int height = r->height; 125 126 //#ifndef NDEBUG 127 if(r->left==0)std::cout<<"fast_demosaic_xtrans(): left="<<r->left<<" top="<<r->top<<std::endl; 128 //#endif 129 130 VipsRect r_img = {0, 0, ir[in_first]->im->Xsize, ir[in_first]->im->Ysize}; 131 132 VipsRect r_raw = {r->left - 5, r->top - 5, r->width + 10, r->height + 10}; 133 vips_rect_intersectrect (&r_raw, &r_img, &r_raw); 134 135 PF::RawMatrix rawData; 136 rawData.init( r_raw.width, r_raw.height, r_raw.top, r_raw.left ); 137 for( int y = 0; y < r_raw.height; y++ ) { 138 PF::raw_pixel_t* ptr = ir ? (PF::raw_pixel_t*)VIPS_REGION_ADDR( ir[0], r_raw.left, y+r_raw.top ) : NULL; 139 rawData.set_row( y+r_raw.top, ptr ); 140 } 141 142 int left = r->left; 143 int right = r->left + width - 1; 144 int top = r->top; 145 int bottom = r->top + height - 1; 146 147 for(int row = top; row <= bottom; row++) { 148 float* ptr = (float*)VIPS_REGION_ADDR( oreg, left, row ); 149 for(int col = left, x = 0; col <= right; col++, x+= 3) { 150 float sum[3] = {0.f}; 151 152 for(int v = -1; v <= 1; v++) { 153 for(int h = -1; h <= 1; h++) { 154 sum[fcol(row + v, col + h)] += rawData[row + v][(col + h)]; 155 } 156 } 157 158 switch(fcol(row, col)) { 159 case 0: 160 ptr[x] = rawData[row][col]; 161 ptr[x+1] = sum[1] * 0.2f; 162 ptr[x+2] = sum[2] * 0.33333333f; 163 break; 164 165 case 1: 166 ptr[x] = sum[0] * 0.5f; 167 ptr[x+1] = rawData[row][col]; 168 ptr[x+2] = sum[2] * 0.5f; 169 break; 170 171 case 2: 172 ptr[x] = sum[0] * 0.33333333f; 173 ptr[x+1] = sum[1] * 0.2f; 174 ptr[x+2] = rawData[row][col]; 175 break; 176 } 177 if( par->do_normalize() ) { 178 ptr[x] /= 65535.f; 179 ptr[x+1] /= 65535.f; 180 ptr[x+2] /= 65535.f; 181 } 182 if( row < 10 && col < 10 ) 183 std::cout<<"r="<<row<<" c="<<col<<" raw=" 184 <<rawData[row][col]<<" rgb="<<ptr[x]<<","<<ptr[x+1]<<","<<ptr[x+2]<<std::endl; 185 } 186 } 187 188 } 189 }; 190 191 192 ProcessorBase* new_fast_demosaic_xtrans(); 193 } 194 195 196 #endif 197