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