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 "hotpixels.hh"
31 
HotPixelsPar()32 PF::HotPixelsPar::HotPixelsPar():
33   OpParBase(),
34   hotp_enable( "hotp_enable", this, false ),
35   hotp_threshold("hotp_threshold",this,0.05),
36   hotp_strength("hotp_strength",this,0.25),
37   hotp_permissive( "hotp_permissive", this, false ),
38   hotp_markfixed( "hotp_markfixed", this, false )
39 {
40   set_type("hotpixels" );
41 
42   pixels_fixed = 0;
43 }
44 
build(std::vector<VipsImage * > & in,int first,VipsImage * imap,VipsImage * omap,unsigned int & level)45 VipsImage* PF::HotPixelsPar::build(std::vector<VipsImage*>& in, int first,
46 				     VipsImage* imap, VipsImage* omap,
47 				     unsigned int& level)
48 {
49   void *data;
50   size_t data_length;
51 
52   if( in.size()<1 || in[0]==NULL ) return NULL;
53 
54   if( !hotp_enable.get() ) {
55     PF_REF( in[0], "HotPixelsPar::build(): in[0] ref when disabled" );
56     return in[0];
57   }
58 
59   size_t blobsz;
60   if( PF_VIPS_IMAGE_GET_BLOB( in[0], "raw_image_data", &image_data, &blobsz ) ) {
61     std::cout<<"HotPixelsPar::build(): could not extract raw_image_data."<<std::endl;
62     return NULL;
63   }
64   if( blobsz != sizeof(dcraw_data_t) ) {
65     std::cout<<"HotPixelsPar::build(): wrong raw_image_data size."<<std::endl;
66     return NULL;
67   }
68 
69   int border = 2;
70 
71   VipsImage* t[12];
72 
73   //  TOP BAND
74   int i0 = 0;
75   // Extract an horizontal top band at (0,1) and with size (in[0]->Xsize,border)
76   if( vips_crop(in[0], &t[i0], 0, 1, in[0]->Xsize, border, NULL) ) {
77     std::cout<<"HotPixelsPar::build(): vip_crop(#1) failed"<<std::endl;
78     return NULL;
79   }
80 
81   // Flip the band vertically
82   if( vips_flip(t[i0], &t[i0+1], VIPS_DIRECTION_VERTICAL, NULL) ) {
83     std::cout<<"HotPixelsPar::build(): vip_flip(#1) failed"<<std::endl;
84     return NULL;
85   }
86   PF_UNREF( t[i0], "HotPixelsPar::build(): t[i0] unref #1" );
87   // Put the vertical band above the original image
88   if( vips_join(t[i0+1], in[0], &t[i0+2], VIPS_DIRECTION_VERTICAL, NULL) ) {
89     std::cout<<"HotPixelsPar::build(): vip_join(#1) failed"<<std::endl;
90     return NULL;
91   }
92   PF_UNREF( t[i0+1], "HotPixelsPar::build(): t[i0+1] unref #1" );
93 
94 
95   //  BOTTOM BAND
96   i0 += 3;
97   // Extract an horizontal bottom band at (0,in[0]->Ysize-border-2) and with size (in[0]->Xsize,border)
98   if( vips_crop(in[0], &t[i0], 0, in[0]->Ysize-border-2, in[0]->Xsize, border, NULL) ) {
99     std::cout<<"HotPixelsPar::build(): vip_crop(#2) failed"<<std::endl;
100     return NULL;
101   }
102 
103   // Flip the band vertically
104   if( vips_flip(t[i0], &t[i0+1], VIPS_DIRECTION_VERTICAL, NULL) ) {
105     std::cout<<"HotPixelsPar::build(): vip_flip(#2) failed"<<std::endl;
106     return NULL;
107   }
108   PF_UNREF( t[i0], "HotPixelsPar::build(): t[i0] unref #2" );
109   // Put the vertical band below the previously joined image
110   if( vips_join(t[i0-1], t[i0+1], &t[i0+2], VIPS_DIRECTION_VERTICAL, NULL) ) {
111     std::cout<<"HotPixelsPar::build(): vip_join(#2) failed"<<std::endl;
112     return NULL;
113   }
114   PF_UNREF( t[i0-1], "HotPixelsPar::build(): t[i0-1] unref #2" );
115   PF_UNREF( t[i0+1], "HotPixelsPar::build(): t[i0+1] unref #2" );
116 
117 
118   //  LEFT BAND
119   i0 += 3;
120   // Extract a vertical left band at (1,0) and with size (border,t[i0-1]->Ysize)
121 
122   if( vips_crop(t[i0-1], &t[i0], 1, 0, border, t[i0-1]->Ysize, NULL) ) {
123     std::cout<<"HotPixelsPar::build(): vip_crop(#3) failed"<<std::endl;
124     return NULL;
125   }
126 
127   // Flip the band horizontally
128   if( vips_flip(t[i0], &t[i0+1], VIPS_DIRECTION_HORIZONTAL, NULL) ) {
129     std::cout<<"HotPixelsPar::build(): vip_flip(#3) failed"<<std::endl;
130     return NULL;
131   }
132   PF_UNREF( t[i0], "HotPixelsPar::build(): t[i0] unref #3" );
133   // Put the vertical band left of the previously joined image
134   if( vips_join(t[i0+1], t[i0-1], &t[i0+2], VIPS_DIRECTION_HORIZONTAL, NULL) ) {
135     std::cout<<"HotPixelsPar::build(): vip_join(#3) failed"<<std::endl;
136     return NULL;
137   }
138   PF_UNREF( t[i0-1], "HotPixelsPar::build(): t[i0-1] unref #3-2" );
139   PF_UNREF( t[i0+1], "HotPixelsPar::build(): t[i0+1] unref #3" );
140 
141 
142   //  RIGHT BAND
143   i0 += 3;
144   // Extract a vertical right band at (t[i0-1]->Xsize-2,0) and with size (border,t[i0-1]->Ysize)
145   if( vips_crop(t[i0-1], &t[i0], t[i0-1]->Xsize-border-2, 0, border, t[i0-1]->Ysize, NULL) ) {
146     std::cout<<"HotPixelsPar::build(): vip_crop(#4) failed"<<std::endl;
147     return NULL;
148   }
149 
150   // Flip the band horizontally
151   if( vips_flip(t[i0], &t[i0+1], VIPS_DIRECTION_HORIZONTAL, NULL) ) {
152     std::cout<<"HotPixelsPar::build(): vip_flip(#4) failed"<<std::endl;
153     return NULL;
154   }
155   PF_UNREF( t[i0], "HotPixelsPar::build(): t[i0] unref #4" );
156   // Put the vertical band right of the previously joined image
157   if( vips_join(t[i0-1], t[i0+1], &t[i0+2], VIPS_DIRECTION_HORIZONTAL, NULL) ) {
158     std::cout<<"HotPixelsPar::build(): vip_join(#4) failed"<<std::endl;
159     return NULL;
160   }
161   PF_UNREF( t[i0-1], "HotPixelsPar::build(): t[i0-1] unref #4-2" );
162   PF_UNREF( t[i0+1], "HotPixelsPar::build(): t[i0+1] unref #4" );
163 
164   // Copy to extended image
165   VipsImage* extended;
166   if( vips_copy(t[i0+2], &extended, NULL) ) {
167     std::cout<<"HotPixelsPar::build(): vip_copy(#1) failed"<<std::endl;
168     return NULL;
169   }
170   PF_UNREF( t[i0+2], "HotPixelsPar::build(): t[i0+2] after vips_copy()" );
171 
172   set_image_hints( extended );
173 
174   std::vector<VipsImage*> in2; in2.push_back(extended);
175   VipsImage* img = OpParBase::build( in2, first, NULL, NULL, level );
176   PF_UNREF( extended, "HotPixelsPar::build(): extended unref" );
177   if( !img ) return NULL;
178 
179   VipsImage* cropped = img;
180 
181   int result;
182   result = vips_crop(img, &cropped, border, border, in[0]->Xsize, in[0]->Ysize, NULL);
183   PF_UNREF( img, "HotPixelsPar::build(): img unref" )
184   if( result ) {
185     std::cout<<"HotPixelsPar::build(): vip_crop() failed"<<std::endl;
186     return NULL;
187   }
188 
189 
190   return cropped;
191 }
192