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