File indexing completed on 2025-01-05 03:57:05

0001 /* -*- C++ -*-
0002  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
0003  *
0004  LibRaw is free software; you can redistribute it and/or modify
0005  it under the terms of the one of two licenses as you choose:
0006 
0007 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0008    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0009 
0010 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0011    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0012 
0013  */
0014 
0015 #include "../../internal/libraw_cxx_defs.h"
0016 
0017 int LibRaw::dcraw_process(void)
0018 {
0019   int quality, i;
0020 
0021   int iterations = -1, dcb_enhance = 1, noiserd = 0;
0022   float preser = 0;
0023   float expos = 1.0;
0024 
0025   CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
0026   //    CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
0027 
0028   try
0029   {
0030 
0031     int no_crop = 1;
0032 
0033     if (~O.cropbox[2] && ~O.cropbox[3])
0034       no_crop = 0;
0035 
0036     libraw_decoder_info_t di;
0037     get_decoder_info(&di);
0038 
0039     bool is_bayer = (imgdata.idata.filters || P1.colors == 1);
0040     int subtract_inline =
0041         !O.bad_pixels && !O.dark_frame && is_bayer && !IO.zero_is_bad;
0042 
0043     int rc = raw2image_ex(subtract_inline); // allocate imgdata.image and copy data!
0044     if (rc != LIBRAW_SUCCESS)
0045         return rc;
0046 
0047     // Adjust sizes
0048 
0049     int save_4color = O.four_color_rgb;
0050 
0051     if (IO.zero_is_bad)
0052     {
0053       remove_zeroes();
0054       SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
0055     }
0056 
0057     if (O.bad_pixels && no_crop)
0058     {
0059       bad_pixels(O.bad_pixels);
0060       SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
0061     }
0062 
0063     if (O.dark_frame && no_crop)
0064     {
0065       subtract(O.dark_frame);
0066       SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
0067     }
0068     /* pre subtract black callback: check for it above to disable subtract
0069      * inline */
0070 
0071     if (callbacks.pre_subtractblack_cb)
0072       (callbacks.pre_subtractblack_cb)(this);
0073 
0074     quality = 2 + !IO.fuji_width;
0075 
0076     if (O.user_qual >= 0)
0077       quality = O.user_qual;
0078 
0079     if (!subtract_inline || !C.data_maximum)
0080     {
0081       adjust_bl();
0082       subtract_black_internal();
0083     }
0084 
0085     if (!(di.decoder_flags & LIBRAW_DECODER_FIXEDMAXC))
0086       adjust_maximum();
0087 
0088     if (O.user_sat > 0)
0089       C.maximum = O.user_sat;
0090 
0091     if (P1.is_foveon)
0092     {
0093       if (load_raw == &LibRaw::x3f_load_raw)
0094       {
0095         // Filter out zeroes
0096         for (int q = 0; q < S.height * S.width; q++)
0097         {
0098           for (int c = 0; c < 4; c++)
0099             if ((short)imgdata.image[q][c] < 0)
0100               imgdata.image[q][c] = 0;
0101         }
0102       }
0103       SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE);
0104     }
0105 
0106     if (O.green_matching && !O.half_size)
0107     {
0108       green_matching();
0109     }
0110 
0111     if (callbacks.pre_scalecolors_cb)
0112       (callbacks.pre_scalecolors_cb)(this);
0113 
0114     if (!O.no_auto_scale)
0115     {
0116       scale_colors();
0117       SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS);
0118     }
0119 
0120     if (callbacks.pre_preinterpolate_cb)
0121       (callbacks.pre_preinterpolate_cb)(this);
0122 
0123     pre_interpolate();
0124 
0125     SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
0126 
0127     if (O.dcb_iterations >= 0)
0128       iterations = O.dcb_iterations;
0129     if (O.dcb_enhance_fl >= 0)
0130       dcb_enhance = O.dcb_enhance_fl;
0131     if (O.fbdd_noiserd >= 0)
0132       noiserd = O.fbdd_noiserd;
0133 
0134     /* pre-exposure correction callback */
0135 
0136     if (O.exp_correc > 0)
0137     {
0138       expos = O.exp_shift;
0139       preser = O.exp_preser;
0140       exp_bef(expos, preser);
0141     }
0142 
0143     if (callbacks.pre_interpolate_cb)
0144       (callbacks.pre_interpolate_cb)(this);
0145 
0146     /* post-exposure correction fallback */
0147     if (P1.filters && !O.no_interpolation)
0148     {
0149       if (noiserd > 0 && P1.colors == 3 && P1.filters > 1000)
0150         fbdd(noiserd);
0151 
0152       if (P1.filters > 1000 && callbacks.interpolate_bayer_cb)
0153         (callbacks.interpolate_bayer_cb)(this);
0154       else if (P1.filters == 9 && callbacks.interpolate_xtrans_cb)
0155         (callbacks.interpolate_xtrans_cb)(this);
0156       else if (quality == 0)
0157         lin_interpolate();
0158       else if (quality == 1 || P1.colors > 3)
0159         vng_interpolate();
0160       else if (quality == 2 && P1.filters > 1000)
0161         ppg_interpolate();
0162       else if (P1.filters == LIBRAW_XTRANS)
0163       {
0164         // Fuji X-Trans
0165         xtrans_interpolate(quality > 2 ? 3 : 1);
0166       }
0167       else if (quality == 3)
0168         ahd_interpolate(); // really don't need it here due to fallback op
0169       else if (quality == 4)
0170         dcb(iterations, dcb_enhance);
0171 
0172       else if (quality == 11)
0173         dht_interpolate();
0174       else if (quality == 12)
0175         aahd_interpolate();
0176       // fallback to AHD
0177       else
0178       {
0179         ahd_interpolate();
0180         imgdata.process_warnings |= LIBRAW_WARN_FALLBACK_TO_AHD;
0181       }
0182 
0183       SET_PROC_FLAG(LIBRAW_PROGRESS_INTERPOLATE);
0184     }
0185     if (IO.mix_green)
0186     {
0187       for (P1.colors = 3, i = 0; i < S.height * S.width; i++)
0188         imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
0189       SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
0190     }
0191 
0192     if (callbacks.post_interpolate_cb)
0193       (callbacks.post_interpolate_cb)(this);
0194     else if (!P1.is_foveon && P1.colors == 3 && O.med_passes > 0)
0195     {
0196       median_filter();
0197       SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
0198     }
0199 
0200     if (O.highlight == 2)
0201     {
0202       blend_highlights();
0203       SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
0204     }
0205 
0206     if (O.highlight > 2)
0207     {
0208       recover_highlights();
0209       SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
0210     }
0211 
0212     if (O.use_fuji_rotate)
0213     {
0214       fuji_rotate();
0215       SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
0216     }
0217 
0218     if (!libraw_internal_data.output_data.histogram)
0219     {
0220       libraw_internal_data.output_data.histogram =
0221           (int(*)[LIBRAW_HISTOGRAM_SIZE])malloc(
0222               sizeof(*libraw_internal_data.output_data.histogram) * 4);
0223     }
0224 #ifndef NO_LCMS
0225     if (O.camera_profile)
0226     {
0227       apply_profile(O.camera_profile, O.output_profile);
0228       SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
0229     }
0230 #endif
0231 
0232     if (callbacks.pre_converttorgb_cb)
0233       (callbacks.pre_converttorgb_cb)(this);
0234 
0235     convert_to_rgb();
0236     SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
0237 
0238     if (callbacks.post_converttorgb_cb)
0239       (callbacks.post_converttorgb_cb)(this);
0240 
0241     if (O.use_fuji_rotate)
0242     {
0243       stretch();
0244       SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
0245     }
0246     O.four_color_rgb = save_4color; // also, restore
0247 
0248     return 0;
0249   }
0250   catch (const std::bad_alloc&)
0251   {
0252       recycle();
0253       return LIBRAW_UNSUFFICIENT_MEMORY;
0254   }
0255   catch (const LibRaw_exceptions& err)
0256   {
0257     EXCEPTION_HANDLER(err);
0258   }
0259 }