/src/freeimage-svn/FreeImage/trunk/Source/LibRawLite/src/postprocessing/dcraw_process.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2021 LibRaw LLC (info@libraw.org) |
3 | | * |
4 | | LibRaw is free software; you can redistribute it and/or modify |
5 | | it under the terms of the one of two licenses as you choose: |
6 | | |
7 | | 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 |
8 | | (See file LICENSE.LGPL provided in LibRaw distribution archive for details). |
9 | | |
10 | | 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 |
11 | | (See file LICENSE.CDDL provided in LibRaw distribution archive for details). |
12 | | |
13 | | */ |
14 | | |
15 | | #include "../../internal/libraw_cxx_defs.h" |
16 | | |
17 | | int LibRaw::dcraw_process(void) |
18 | 0 | { |
19 | 0 | int quality, i; |
20 | |
|
21 | 0 | int iterations = -1, dcb_enhance = 1, noiserd = 0; |
22 | 0 | float preser = 0; |
23 | 0 | float expos = 1.0; |
24 | |
|
25 | 0 | CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW); |
26 | | // CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE); |
27 | | |
28 | 0 | try |
29 | 0 | { |
30 | |
|
31 | 0 | int no_crop = 1; |
32 | |
|
33 | 0 | if (~O.cropbox[2] && ~O.cropbox[3]) |
34 | 0 | no_crop = 0; |
35 | |
|
36 | 0 | libraw_decoder_info_t di; |
37 | 0 | get_decoder_info(&di); |
38 | |
|
39 | 0 | bool is_bayer = (imgdata.idata.filters || P1.colors == 1); |
40 | 0 | int subtract_inline = |
41 | 0 | !O.bad_pixels && !O.dark_frame && is_bayer && !IO.zero_is_bad; |
42 | |
|
43 | 0 | int rc = raw2image_ex(subtract_inline); // allocate imgdata.image and copy data! |
44 | 0 | if (rc != LIBRAW_SUCCESS) |
45 | 0 | return rc; |
46 | | |
47 | | // Adjust sizes |
48 | | |
49 | 0 | int save_4color = O.four_color_rgb; |
50 | |
|
51 | 0 | if (IO.zero_is_bad) |
52 | 0 | { |
53 | 0 | remove_zeroes(); |
54 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES); |
55 | 0 | } |
56 | |
|
57 | 0 | if (O.bad_pixels && no_crop) |
58 | 0 | { |
59 | 0 | bad_pixels(O.bad_pixels); |
60 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS); |
61 | 0 | } |
62 | |
|
63 | 0 | if (O.dark_frame && no_crop) |
64 | 0 | { |
65 | 0 | subtract(O.dark_frame); |
66 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME); |
67 | 0 | } |
68 | | /* pre subtract black callback: check for it above to disable subtract |
69 | | * inline */ |
70 | |
|
71 | 0 | if (callbacks.pre_subtractblack_cb) |
72 | 0 | (callbacks.pre_subtractblack_cb)(this); |
73 | |
|
74 | 0 | quality = 2 + !IO.fuji_width; |
75 | |
|
76 | 0 | if (O.user_qual >= 0) |
77 | 0 | quality = O.user_qual; |
78 | |
|
79 | 0 | if (!subtract_inline || !C.data_maximum) |
80 | 0 | { |
81 | 0 | adjust_bl(); |
82 | 0 | subtract_black_internal(); |
83 | 0 | } |
84 | |
|
85 | 0 | if (!(di.decoder_flags & LIBRAW_DECODER_FIXEDMAXC)) |
86 | 0 | adjust_maximum(); |
87 | |
|
88 | 0 | if (O.user_sat > 0) |
89 | 0 | C.maximum = O.user_sat; |
90 | |
|
91 | 0 | if (P1.is_foveon) |
92 | 0 | { |
93 | 0 | if (load_raw == &LibRaw::x3f_load_raw) |
94 | 0 | { |
95 | | // Filter out zeroes |
96 | 0 | for (int q = 0; q < S.height * S.width; q++) |
97 | 0 | { |
98 | 0 | for (int c = 0; c < 4; c++) |
99 | 0 | if ((short)imgdata.image[q][c] < 0) |
100 | 0 | imgdata.image[q][c] = 0; |
101 | 0 | } |
102 | 0 | } |
103 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE); |
104 | 0 | } |
105 | |
|
106 | 0 | if (O.green_matching && !O.half_size) |
107 | 0 | { |
108 | 0 | green_matching(); |
109 | 0 | } |
110 | |
|
111 | 0 | if (callbacks.pre_scalecolors_cb) |
112 | 0 | (callbacks.pre_scalecolors_cb)(this); |
113 | |
|
114 | 0 | if (!O.no_auto_scale) |
115 | 0 | { |
116 | 0 | scale_colors(); |
117 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS); |
118 | 0 | } |
119 | |
|
120 | 0 | if (callbacks.pre_preinterpolate_cb) |
121 | 0 | (callbacks.pre_preinterpolate_cb)(this); |
122 | |
|
123 | 0 | pre_interpolate(); |
124 | |
|
125 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE); |
126 | |
|
127 | 0 | if (O.dcb_iterations >= 0) |
128 | 0 | iterations = O.dcb_iterations; |
129 | 0 | if (O.dcb_enhance_fl >= 0) |
130 | 0 | dcb_enhance = O.dcb_enhance_fl; |
131 | 0 | if (O.fbdd_noiserd >= 0) |
132 | 0 | noiserd = O.fbdd_noiserd; |
133 | | |
134 | | /* pre-exposure correction callback */ |
135 | |
|
136 | 0 | if (O.exp_correc > 0) |
137 | 0 | { |
138 | 0 | expos = O.exp_shift; |
139 | 0 | preser = O.exp_preser; |
140 | 0 | exp_bef(expos, preser); |
141 | 0 | } |
142 | |
|
143 | 0 | if (callbacks.pre_interpolate_cb) |
144 | 0 | (callbacks.pre_interpolate_cb)(this); |
145 | | |
146 | | /* post-exposure correction fallback */ |
147 | 0 | if (P1.filters && !O.no_interpolation) |
148 | 0 | { |
149 | 0 | if (noiserd > 0 && P1.colors == 3 && P1.filters > 1000) |
150 | 0 | fbdd(noiserd); |
151 | |
|
152 | 0 | if (P1.filters > 1000 && callbacks.interpolate_bayer_cb) |
153 | 0 | (callbacks.interpolate_bayer_cb)(this); |
154 | 0 | else if (P1.filters == 9 && callbacks.interpolate_xtrans_cb) |
155 | 0 | (callbacks.interpolate_xtrans_cb)(this); |
156 | 0 | else if (quality == 0) |
157 | 0 | lin_interpolate(); |
158 | 0 | else if (quality == 1 || P1.colors > 3) |
159 | 0 | vng_interpolate(); |
160 | 0 | else if (quality == 2 && P1.filters > 1000) |
161 | 0 | ppg_interpolate(); |
162 | 0 | else if (P1.filters == LIBRAW_XTRANS) |
163 | 0 | { |
164 | | // Fuji X-Trans |
165 | 0 | xtrans_interpolate(quality > 2 ? 3 : 1); |
166 | 0 | } |
167 | 0 | else if (quality == 3) |
168 | 0 | ahd_interpolate(); // really don't need it here due to fallback op |
169 | 0 | else if (quality == 4) |
170 | 0 | dcb(iterations, dcb_enhance); |
171 | | |
172 | 0 | else if (quality == 11) |
173 | 0 | dht_interpolate(); |
174 | 0 | else if (quality == 12) |
175 | 0 | aahd_interpolate(); |
176 | | // fallback to AHD |
177 | 0 | else |
178 | 0 | { |
179 | 0 | ahd_interpolate(); |
180 | 0 | imgdata.process_warnings |= LIBRAW_WARN_FALLBACK_TO_AHD; |
181 | 0 | } |
182 | |
|
183 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_INTERPOLATE); |
184 | 0 | } |
185 | 0 | if (IO.mix_green) |
186 | 0 | { |
187 | 0 | for (P1.colors = 3, i = 0; i < S.height * S.width; i++) |
188 | 0 | imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1; |
189 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN); |
190 | 0 | } |
191 | |
|
192 | 0 | if (callbacks.post_interpolate_cb) |
193 | 0 | (callbacks.post_interpolate_cb)(this); |
194 | 0 | else if (!P1.is_foveon && P1.colors == 3 && O.med_passes > 0) |
195 | 0 | { |
196 | 0 | median_filter(); |
197 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER); |
198 | 0 | } |
199 | |
|
200 | 0 | if (O.highlight == 2) |
201 | 0 | { |
202 | 0 | blend_highlights(); |
203 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS); |
204 | 0 | } |
205 | |
|
206 | 0 | if (O.highlight > 2) |
207 | 0 | { |
208 | 0 | recover_highlights(); |
209 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS); |
210 | 0 | } |
211 | |
|
212 | 0 | if (O.use_fuji_rotate) |
213 | 0 | { |
214 | 0 | fuji_rotate(); |
215 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE); |
216 | 0 | } |
217 | |
|
218 | 0 | if (!libraw_internal_data.output_data.histogram) |
219 | 0 | { |
220 | 0 | libraw_internal_data.output_data.histogram = |
221 | 0 | (int(*)[LIBRAW_HISTOGRAM_SIZE])malloc( |
222 | 0 | sizeof(*libraw_internal_data.output_data.histogram) * 4); |
223 | 0 | } |
224 | | #ifndef NO_LCMS |
225 | | if (O.camera_profile) |
226 | | { |
227 | | apply_profile(O.camera_profile, O.output_profile); |
228 | | SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE); |
229 | | } |
230 | | #endif |
231 | |
|
232 | 0 | if (callbacks.pre_converttorgb_cb) |
233 | 0 | (callbacks.pre_converttorgb_cb)(this); |
234 | |
|
235 | 0 | convert_to_rgb(); |
236 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB); |
237 | |
|
238 | 0 | if (callbacks.post_converttorgb_cb) |
239 | 0 | (callbacks.post_converttorgb_cb)(this); |
240 | |
|
241 | 0 | if (O.use_fuji_rotate) |
242 | 0 | { |
243 | 0 | stretch(); |
244 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH); |
245 | 0 | } |
246 | 0 | O.four_color_rgb = save_4color; // also, restore |
247 | |
|
248 | 0 | return 0; |
249 | 0 | } |
250 | 0 | catch (const std::bad_alloc&) |
251 | 0 | { |
252 | 0 | recycle(); |
253 | 0 | return LIBRAW_UNSUFFICIENT_MEMORY; |
254 | 0 | } |
255 | 0 | catch (const LibRaw_exceptions& err) |
256 | 0 | { |
257 | 0 | EXCEPTION_HANDLER(err); |
258 | 0 | } |
259 | 0 | } |