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 "../base/processor.hh"
33 #include "lmmse_demosaic.hh"
34 
35 //#define RT_EMU 1
36 
37 
LMMSEDemosaicPar()38 PF::LMMSEDemosaicPar::LMMSEDemosaicPar():
39   OpParBase()
40 {
41   set_demand_hint( VIPS_DEMAND_STYLE_SMALLTILE );
42   set_type( "amaze_demosaic" );
43 }
44 
45 
build(std::vector<VipsImage * > & in,int first,VipsImage * imap,VipsImage * omap,unsigned int & level)46 VipsImage* PF::LMMSEDemosaicPar::build(std::vector<VipsImage*>& in, int first,
47 				     VipsImage* imap, VipsImage* omap,
48 				     unsigned int& level)
49 {
50   void *data;
51   size_t data_length;
52 
53   if( in.size()<1 || in[0]==NULL ) return NULL;
54 
55   int border = 10;
56 
57   //VipsImage **t = (VipsImage **)
58   //  vips_object_local_array( VIPS_OBJECT( in[0] ), 12 );
59   VipsImage* t[12];
60 
61   //  TOP BAND
62   int i0 = 0;
63   // Extract an horizontal top band at (0,1) and with size (in[0]->Xsize,border)
64   if( vips_crop(in[0], &t[i0], 0, 1, in[0]->Xsize, border, NULL) ) {
65     std::cout<<"LMMSEDemosaicPar::build(): vip_crop(#1) failed"<<std::endl;
66     return NULL;
67   }
68   //PF_UNREF( in[0], "LMMSEDemosaicPar::build(): in[0] unref #1" );
69   // Flip the band vertically
70   if( vips_flip(t[i0], &t[i0+1], VIPS_DIRECTION_VERTICAL, NULL) ) {
71     std::cout<<"LMMSEDemosaicPar::build(): vip_flip(#1) failed"<<std::endl;
72     return NULL;
73   }
74   PF_UNREF( t[i0], "LMMSEDemosaicPar::build(): t[i0] unref #1" );
75   // Put the vertical band above the original image
76   if( vips_join(t[i0+1], in[0], &t[i0+2], VIPS_DIRECTION_VERTICAL, NULL) ) {
77     std::cout<<"LMMSEDemosaicPar::build(): vip_join(#1) failed"<<std::endl;
78     return NULL;
79   }
80   //PF_UNREF( in[0], "LMMSEDemosaicPar::build(): in[0] unref #1-2" );
81   PF_UNREF( t[i0+1], "LMMSEDemosaicPar::build(): t[i0+1] unref #1" );
82 
83 
84   //  BOTTOM BAND
85   i0 += 3;
86   // Extract an horizontal bottom band at (0,in[0]->Ysize-border-2) and with size (in[0]->Xsize,border)
87   if( vips_crop(in[0], &t[i0], 0, in[0]->Ysize-border-1, in[0]->Xsize, border, NULL) ) {
88     std::cout<<"LMMSEDemosaicPar::build(): vip_crop(#2) failed"<<std::endl;
89     return NULL;
90   }
91   //PF_UNREF( in[0], "LMMSEDemosaicPar::build(): in[0] unref #2" );
92   // Flip the band vertically
93   if( vips_flip(t[i0], &t[i0+1], VIPS_DIRECTION_VERTICAL, NULL) ) {
94     std::cout<<"LMMSEDemosaicPar::build(): vip_flip(#2) failed"<<std::endl;
95     return NULL;
96   }
97   PF_UNREF( t[i0], "LMMSEDemosaicPar::build(): t[i0] unref #2" );
98   // Put the vertical band below the previously joined image
99   if( vips_join(t[i0-1], t[i0+1], &t[i0+2], VIPS_DIRECTION_VERTICAL, NULL) ) {
100     std::cout<<"LMMSEDemosaicPar::build(): vip_join(#2) failed"<<std::endl;
101     return NULL;
102   }
103   PF_UNREF( t[i0-1], "LMMSEDemosaicPar::build(): t[i0-1] unref #2" );
104   PF_UNREF( t[i0+1], "LMMSEDemosaicPar::build(): t[i0+1] unref #2" );
105 
106 
107   //  LEFT BAND
108   i0 += 3;
109   // Extract a vertical left band at (1,0) and with size (border,t[i0-1]->Ysize)
110   //PF_PRINT_REF( t[i0-1], "LMMSEDemosaicPar::build(): t[i0-1] refcount before crop" );
111   if( vips_crop(t[i0-1], &t[i0], 1, 0, border, t[i0-1]->Ysize, NULL) ) {
112     std::cout<<"LMMSEDemosaicPar::build(): vip_crop(#3) failed"<<std::endl;
113     return NULL;
114   }
115   //PF_PRINT_REF( t[i0-1], "LMMSEDemosaicPar::build(): t[i0-1] refcount after crop" );
116   //PF_UNREF( t[i0-1], "LMMSEDemosaicPar::build(): t[i0-1] unref #3" );
117   // Flip the band horizontally
118   if( vips_flip(t[i0], &t[i0+1], VIPS_DIRECTION_HORIZONTAL, NULL) ) {
119     std::cout<<"LMMSEDemosaicPar::build(): vip_flip(#3) failed"<<std::endl;
120     return NULL;
121   }
122   PF_UNREF( t[i0], "LMMSEDemosaicPar::build(): t[i0] unref #3" );
123   // Put the vertical band left of the previously joined image
124   if( vips_join(t[i0+1], t[i0-1], &t[i0+2], VIPS_DIRECTION_HORIZONTAL, NULL) ) {
125     std::cout<<"LMMSEDemosaicPar::build(): vip_join(#3) failed"<<std::endl;
126     return NULL;
127   }
128   PF_UNREF( t[i0-1], "LMMSEDemosaicPar::build(): t[i0-1] unref #3-2" );
129   PF_UNREF( t[i0+1], "LMMSEDemosaicPar::build(): t[i0+1] unref #3" );
130 
131 
132   //  RIGHT BAND
133   i0 += 3;
134   // Extract a vertical right band at (t[i0-1]->Xsize-2,0) and with size (border,t[i0-1]->Ysize)
135   if( vips_crop(t[i0-1], &t[i0], t[i0-1]->Xsize-border-1, 0, border, t[i0-1]->Ysize, NULL) ) {
136     std::cout<<"LMMSEDemosaicPar::build(): vip_crop(#4) failed"<<std::endl;
137     return NULL;
138   }
139   //PF_UNREF( t[i0-1], "LMMSEDemosaicPar::build(): t[i0-1] unref #4" );
140   // Flip the band horizontally
141   if( vips_flip(t[i0], &t[i0+1], VIPS_DIRECTION_HORIZONTAL, NULL) ) {
142     std::cout<<"LMMSEDemosaicPar::build(): vip_flip(#4) failed"<<std::endl;
143     return NULL;
144   }
145   PF_UNREF( t[i0], "LMMSEDemosaicPar::build(): t[i0] unref #4" );
146   // Put the vertical band right of the previously joined image
147   if( vips_join(t[i0-1], t[i0+1], &t[i0+2], VIPS_DIRECTION_HORIZONTAL, NULL) ) {
148     std::cout<<"LMMSEDemosaicPar::build(): vip_join(#4) failed"<<std::endl;
149     return NULL;
150   }
151   PF_UNREF( t[i0-1], "LMMSEDemosaicPar::build(): t[i0-1] unref #4-2" );
152   PF_UNREF( t[i0+1], "LMMSEDemosaicPar::build(): t[i0+1] unref #4" );
153 
154   //std::cout<<"i0+2="<<i0+2<<std::endl;
155 
156   // Copy to extended image
157   VipsImage* extended;
158   if( vips_copy(t[i0+2], &extended, NULL) ) {
159     std::cout<<"LMMSEDemosaicPar::build(): vip_copy(#1) failed"<<std::endl;
160     return NULL;
161   }
162   //PF_UNREF( in[0], "LMMSEDemosaicPar::build(): in[0] after vips_copy()" );
163   PF_UNREF( t[i0+2], "LMMSEDemosaicPar::build(): t[i0+2] after vips_copy()" );
164 
165   set_image_hints( extended );
166 
167   std::vector<VipsImage*> in2; in2.push_back(extended);
168   VipsImage* img = OpParBase::build( in2, first, NULL, NULL, level );
169   PF_UNREF( extended, "LMMSEDemosaicPar::build(): extended unref" );
170   if( !img ) return NULL;
171 
172   VipsImage* cropped = img;
173   /**/
174   int result;
175   result = vips_crop(img, &cropped, border, border, in[0]->Xsize, in[0]->Ysize, NULL);
176   PF_UNREF( img, "LMMSEDemosaicPar::build(): img unref" )
177   if( result ) {
178     std::cout<<"LMMSEDemosaicPar::build(): vip_crop() failed"<<std::endl;
179     return NULL;
180   }
181   /**/
182 
183   VipsImage* out;
184   int bands = 3;
185   VipsCoding coding = VIPS_CODING_NONE;
186   VipsInterpretation interpretation = VIPS_INTERPRETATION_RGB;
187   VipsBandFormat format = VIPS_FORMAT_FLOAT;
188   vips_copy( cropped, &out,
189 	     "format", format,
190 	     "bands", bands,
191 	     "coding", coding,
192 	     "interpretation", interpretation,
193 	     NULL );
194   //sprintf(tifname,"/tmp/level_%d-2.tif",(int)levels.size());
195   //vips_image_write_to_file( out, tifname );
196   //g_object_unref( img );
197   PF_UNREF( cropped, "PF::LMMSEDemosaicPar::build(): cropped unref" );
198 
199   return out;
200 }
201 
202