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 #include <stdlib.h>
31 
32 #include "amaze_demosaic.hh"
33 #include "../base/processor.hh"
34 #include "../base/roi.hh"
35 #include "../external/librtprocess/src/include/librtprocess.h"
36 
37 //#define RT_EMU 1
38 
39 
AmazeDemosaicPar()40 PF::AmazeDemosaicPar::AmazeDemosaicPar():
41 DemosaicBasePar(16)
42 {
43   set_type( "amaze_demosaic" );
44 }
45 
46 
setProgCancel_dummy(double)47 static bool setProgCancel_dummy(double)
48 {
49   return true;
50 }
51 
52 
amaze_demosaic_PF(VipsRegion * ir,VipsRegion * out,PF::AmazeDemosaicPar * par)53 void PF::amaze_demosaic_PF(VipsRegion* ir, VipsRegion* out, PF::AmazeDemosaicPar* par)
54 {
55   //std::cout<<"amaze_demosaic_PF() called"<<std::endl;
56 
57   //rtengine::RawImageSource rawimg; rawimg.set_image_data( par->get_image_data() ); rawimg.amaze_demosaic( ir, out ); return;
58 
59   int offsx = ir->valid.left;
60   int offsy = ir->valid.top;
61   int rw = ir->valid.width;
62   int rh = ir->valid.height;
63   int w = ir->im->Xsize;
64   int h = ir->im->Ysize;
65   float* p = (float*)VIPS_REGION_ADDR( ir, offsx, offsy );
66   int rowstride = VIPS_REGION_LSKIP(ir) / sizeof(float);
67 
68   /*// Copy the raw pixel data from the input region
69   float* rawbuf = new float[rw*rh];
70   for( int y = 0; y < ir->valid.height; y++ ) {
71     float* ptr = (float*)VIPS_REGION_ADDR( out, out->valid.left, y+out->valid.top );
72     for( int x = 0, xx = 0; x < ir->valid.width; x++, xx+=2 ) {
73 
74     }
75   }*/
76 
77   //librtprocess::array2D<float> rawData( w, h, rw, rh, p, rowstride, offsx, offsy, ARRAY2D_BYREFERENCE );
78   PF::PixelBuffer rawData(p, rw, rh, rowstride, offsy, offsx);
79   PF::rp_roi_rect_t roi_rect = { ir->valid.left, ir->valid.top, ir->valid.width, ir->valid.height };
80   PF::rp_roi_rect_t roi_rect_in = { 0, 0, ir->valid.width, ir->valid.height };
81   PF::rp_roi_t* roi = PF::rp_roi_new_from_data( &roi_rect, &roi_rect_in, 2, rowstride, 1, p );
82   if( false && offsx < 20 && offsy < 20 ) {
83     std::cout<<"top= "<<ir->valid.top<<std::endl;
84     std::cout<<"left="<<ir->valid.left<<std::endl;
85     std::cout<<"roi->data[0]["<<ir->valid.top<<"]["<<ir->valid.left<<"="<<roi->data[0][ir->valid.top][ir->valid.left]<<std::endl;
86     std::cout<<"p[0]="<<p[0]<<std::endl;
87     std::cout<<"p[1]="<<p[1]<<std::endl;
88     std::cout<<"p[2]="<<p[2]<<std::endl;
89     std::cout<<"p[3]="<<p[3]<<std::endl;
90 
91     std::cout<<"amaze_demosaic_PF: RAW image = "<<ir->im<<std::endl;
92     std::cout<<"amaze_demosaic_PF: RAW size = "<<w<<" x "<<h<<std::endl;
93     std::cout<<"amaze_demosaic_PF: input region = "<<rw<<" x "<<rh<<" + "<<offsx<<" + "<<offsy<<std::endl;
94     std::cout<<"amaze_demosaic_PF: rowstride = "<<rowstride<<std::endl;
95   }
96 
97   offsx = out->valid.left;
98   offsy = out->valid.top;
99   rw = out->valid.width;
100   rh = out->valid.height;
101   w = out->im->Xsize;
102   h = out->im->Ysize;
103   rowstride = rw;
104 
105   float* pr = new float[rw*rh];
106   float* pg = new float[rw*rh];
107   float* pb = new float[rw*rh];
108   //librtprocess::array2D<float> red( w, h, rw, rh, pr, rowstride, offsx, offsy, ARRAY2D_BYREFERENCE );
109   //librtprocess::array2D<float> green( w, h, rw, rh, pg, rowstride, offsx, offsy, ARRAY2D_BYREFERENCE );
110   //librtprocess::array2D<float> blue( w, h, rw, rh, pb, rowstride, offsx, offsy, ARRAY2D_BYREFERENCE );
111   PF::PixelBuffer red(pr, rw, rh, rowstride, offsy, offsx);
112   PF::PixelBuffer green(pg, rw, rh, rowstride, offsy, offsx);
113   PF::PixelBuffer blue(pb, rw, rh, rowstride, offsy, offsx);
114 
115   if( false && offsx < 20 && offsy < 20 ) {
116     std::cout<<"amaze_demosaic_PF: output image = "<<out->im<<std::endl;
117     std::cout<<"amaze_demosaic_PF: output size = "<<w<<" x "<<h<<std::endl;
118     std::cout<<"amaze_demosaic_PF: output region = "<<rw<<" x "<<rh<<" + "<<offsx<<" + "<<offsy<<std::endl;
119     std::cout<<"amaze_demosaic_PF: rowstride = "<<rowstride<<std::endl;
120   }
121 
122   int filters = par->get_image_data()->idata.filters;
123   unsigned cfarray[2][2];
124   PF::init_CFA(filters, cfarray);
125 
126   std::function<bool(double)> setProgCancel = setProgCancel_dummy;
127 
128   float initGain = 1;
129   int border = 16;
130   float inputScale = 1;
131   float outputScale = 1;
132   amaze_demosaic(w, h, offsx, offsy, rw, rh,
133       roi->data[0], red.get_rows(), green.get_rows(), blue.get_rows(), cfarray,
134       setProgCancel, initGain, border, inputScale, outputScale);
135 
136   // Copy back the pixel data into the output region
137   int x, xx, y;
138   for( y = 0; y < out->valid.height; y++ ) {
139     float* ptr = (float*)VIPS_REGION_ADDR( out, out->valid.left, y+out->valid.top );
140     for( x = 0, xx = 0; x < out->valid.width; x++, xx+=3 ) {
141       ptr[xx]   = red[y+out->valid.top][x+out->valid.left];
142       ptr[xx+1] = green[y+out->valid.top][x+out->valid.left];
143       ptr[xx+2] = blue[y+out->valid.top][x+out->valid.left];
144     }
145   }
146 
147   PF::rp_roi_free(roi);
148 
149   delete [] pr;
150   delete [] pg;
151   delete [] pb;
152 }
153 
154