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