| /* -*- C++ -*- |
| * Copyright 2019-2025 LibRaw LLC (info@libraw.org) |
| * |
| |
| LibRaw is free software; you can redistribute it and/or modify |
| it under the terms of the one of two licenses as you choose: |
| |
| 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 |
| (See file LICENSE.LGPL provided in LibRaw distribution archive for details). |
| |
| 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 |
| (See file LICENSE.CDDL provided in LibRaw distribution archive for details). |
| |
| */ |
| |
| #include "third_party/libraw/internal/libraw_cxx_defs.h" |
| #ifdef USE_RAWSPEED3 |
| #include "rawspeed3_capi.h" |
| #endif |
| |
| static void cleargps(libraw_gps_info_t *q) |
| { |
| for (int i = 0; i < 3; i++) |
| q->latitude[i] = q->longitude[i] = q->gpstimestamp[i] = 0.f; |
| q->altitude = 0.f; |
| q->altref = q->latref = q->longref = q->gpsstatus = q->gpsparsed = 0; |
| } |
| |
| LibRaw::LibRaw(unsigned int flags) : memmgr(1024) |
| { |
| double aber[4] = {1, 1, 1, 1}; |
| double gamm[6] = {0.45, 4.5, 0, 0, 0, 0}; |
| unsigned greybox[4] = {0, 0, UINT_MAX, UINT_MAX}; |
| unsigned cropbox[4] = {0, 0, UINT_MAX, UINT_MAX}; |
| ZERO(imgdata); |
| |
| cleargps(&imgdata.other.parsed_gps); |
| ZERO(libraw_internal_data); |
| ZERO(callbacks); |
| |
| _rawspeed_camerameta = _rawspeed_decoder = NULL; |
| _rawspeed3_handle = NULL; |
| dnghost = NULL; |
| dngnegative = NULL; |
| dngimage = NULL; |
| _x3f_data = NULL; |
| |
| #ifdef USE_RAWSPEED |
| _rawspeed_camerameta = make_camera_metadata(); |
| #endif |
| callbacks.data_cb = (flags & LIBRAW_OPTIONS_NO_DATAERR_CALLBACK) |
| ? NULL |
| : &default_data_callback; |
| callbacks.exif_cb = NULL; // no default callback |
| callbacks.makernotes_cb = NULL; |
| callbacks.pre_identify_cb = NULL; |
| callbacks.post_identify_cb = NULL; |
| callbacks.pre_subtractblack_cb = callbacks.pre_scalecolors_cb = |
| callbacks.pre_preinterpolate_cb = callbacks.pre_interpolate_cb = |
| callbacks.interpolate_bayer_cb = callbacks.interpolate_xtrans_cb = |
| callbacks.post_interpolate_cb = callbacks.pre_converttorgb_cb = |
| callbacks.post_converttorgb_cb = NULL; |
| |
| memmove(&imgdata.params.aber, &aber, sizeof(aber)); |
| memmove(&imgdata.params.gamm, &gamm, sizeof(gamm)); |
| memmove(&imgdata.params.greybox, &greybox, sizeof(greybox)); |
| memmove(&imgdata.params.cropbox, &cropbox, sizeof(cropbox)); |
| |
| imgdata.params.bright = 1; |
| imgdata.params.use_camera_matrix = 1; |
| imgdata.params.user_flip = -1; |
| imgdata.params.user_black = -1; |
| imgdata.params.user_cblack[0] = imgdata.params.user_cblack[1] = |
| imgdata.params.user_cblack[2] = imgdata.params.user_cblack[3] = -1000001; |
| imgdata.params.user_sat = -1; |
| imgdata.params.user_qual = -1; |
| imgdata.params.output_color = 1; |
| imgdata.params.output_bps = 8; |
| imgdata.params.use_fuji_rotate = 1; |
| imgdata.params.use_p1_correction = 1; |
| imgdata.params.exp_shift = 1.0; |
| imgdata.params.auto_bright_thr = LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD; |
| imgdata.params.adjust_maximum_thr = LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD; |
| imgdata.rawparams.use_rawspeed = 1; |
| imgdata.rawparams.use_dngsdk = LIBRAW_DNG_DEFAULT; |
| imgdata.params.no_auto_scale = 0; |
| imgdata.params.no_interpolation = 0; |
| imgdata.rawparams.specials = 0; /* was inverted : LIBRAW_PROCESSING_DP2Q_INTERPOLATERG | LIBRAW_PROCESSING_DP2Q_INTERPOLATEAF; */ |
| imgdata.rawparams.options = LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT; |
| imgdata.rawparams.sony_arw2_posterization_thr = 0; |
| imgdata.rawparams.max_raw_memory_mb = LIBRAW_MAX_ALLOC_MB_DEFAULT; |
| imgdata.params.green_matching = 0; |
| imgdata.rawparams.custom_camera_strings = 0; |
| imgdata.rawparams.coolscan_nef_gamma = 1.0f; |
| imgdata.parent_class = this; |
| imgdata.progress_flags = 0; |
| imgdata.color.dng_levels.baseline_exposure = -999.f; |
| imgdata.color.dng_levels.LinearResponseLimit = 1.0f; |
| MN.hasselblad.nIFD_CM[0] = |
| MN.hasselblad.nIFD_CM[1] = -1; |
| MN.kodak.ISOCalibrationGain = 1.0f; |
| _exitflag = 0; |
| tls = new LibRaw_TLS; |
| tls->init(); |
| } |
| |
| LibRaw::~LibRaw() |
| { |
| recycle(); |
| delete tls; |
| #ifdef USE_RAWSPEED3 |
| if (_rawspeed3_handle) |
| rawspeed3_close(_rawspeed3_handle); |
| _rawspeed3_handle = NULL; |
| #endif |
| |
| #ifdef USE_RAWSPEED |
| if (_rawspeed_camerameta) |
| { |
| clear_camera_metadata(_rawspeed_camerameta); |
| _rawspeed_camerameta = NULL; |
| } |
| #endif |
| } |
| |
| void x3f_clear(void *); |
| |
| void LibRaw::recycle() |
| { |
| recycle_datastream(); |
| #define FREE(a) \ |
| do \ |
| { \ |
| if (a) \ |
| { \ |
| free(a); \ |
| a = NULL; \ |
| } \ |
| } while (0) |
| |
| FREE(imgdata.image); |
| |
| // explicit cleanup of afdata allocations; entire array is zeroed below |
| for (int i = 0; i < LIBRAW_AFDATA_MAXCOUNT; i++) |
| FREE(MN.common.afdata[i].AFInfoData); |
| |
| FREE(imgdata.thumbnail.thumb); |
| FREE(libraw_internal_data.internal_data.meta_data); |
| FREE(libraw_internal_data.output_data.histogram); |
| FREE(libraw_internal_data.output_data.oprof); |
| FREE(imgdata.color.profile); |
| FREE(imgdata.rawdata.ph1_cblack); |
| FREE(imgdata.rawdata.ph1_rblack); |
| FREE(imgdata.rawdata.raw_alloc); |
| FREE(imgdata.idata.xmpdata); |
| |
| parseCR3_Free(); |
| |
| #undef FREE |
| |
| ZERO(imgdata.sizes); |
| imgdata.sizes.raw_inset_crops[0].cleft = imgdata.sizes.raw_inset_crops[1].cleft = 0xffff; |
| imgdata.sizes.raw_inset_crops[0].ctop = imgdata.sizes.raw_inset_crops[1].ctop = 0xffff; |
| |
| ZERO(imgdata.idata); |
| ZERO(imgdata.color); |
| ZERO(imgdata.lens); |
| ZERO(imgdata.other); |
| ZERO(imgdata.rawdata); |
| ZERO(imgdata.shootinginfo); |
| ZERO(imgdata.thumbnail); |
| ZERO(imgdata.thumbs_list); |
| ZERO(MN); |
| cleargps(&imgdata.other.parsed_gps); |
| ZERO(libraw_internal_data); |
| |
| imgdata.lens.makernotes.FocalUnits = 1; |
| imgdata.lens.makernotes.LensID = LIBRAW_LENS_NOT_SET; |
| imgdata.shootinginfo.DriveMode = -1; |
| imgdata.shootinginfo.FocusMode = -1; |
| imgdata.shootinginfo.MeteringMode = -1; |
| imgdata.shootinginfo.AFPoint = -1; |
| imgdata.shootinginfo.ExposureMode = -1; |
| imgdata.shootinginfo.ExposureProgram = -1; |
| imgdata.shootinginfo.ImageStabilization = -1; |
| |
| imgdata.color.dng_levels.baseline_exposure = -999.f; |
| imgdata.color.dng_levels.LinearResponseLimit = 1.f; |
| imgdata.color.dng_color[0].illuminant = |
| imgdata.color.dng_color[1].illuminant = LIBRAW_WBI_None; |
| for (int i = 0; i < 4; i++) imgdata.color.dng_levels.analogbalance[i] = 1.0f; |
| |
| MN.canon.DefaultCropAbsolute.l = -1; |
| MN.canon.DefaultCropAbsolute.t = -1; |
| MN.canon.AutoLightingOptimizer = 3; // 'off' value |
| |
| MN.fuji.WB_Preset = 0xffff; |
| MN.fuji.ExpoMidPointShift = -999.f; |
| MN.fuji.DynamicRange = 0xffff; |
| MN.fuji.FilmMode = 0xffff; |
| MN.fuji.DynamicRangeSetting = 0xffff; |
| MN.fuji.DevelopmentDynamicRange = 0xffff; |
| MN.fuji.AutoDynamicRange = 0xffff; |
| MN.fuji.DRangePriority = 0xffff; |
| MN.fuji.FocusMode = 0xffff; |
| MN.fuji.AFMode = 0xffff; |
| MN.fuji.FocusPixel[0] = MN.fuji.FocusPixel[1] = 0xffff; |
| MN.fuji.FocusSettings = 0xffffffff; |
| MN.fuji.AF_C_Settings = 0xffffffff; |
| MN.fuji.FocusWarning = 0xffff; |
| for (int i = 0; i < 3; i++) MN.fuji.ImageStabilization[i] = 0xffff; |
| MN.fuji.DriveMode = -1; |
| MN.fuji.ImageCount = -1; |
| MN.fuji.AutoBracketing = -1; |
| MN.fuji.SequenceNumber = -1; |
| MN.fuji.SeriesLength = -1; |
| MN.fuji.PixelShiftOffset[0] = MN.fuji.PixelShiftOffset[1] = -999.f; |
| |
| MN.hasselblad.nIFD_CM[0] = MN.hasselblad.nIFD_CM[1] = -1; |
| |
| MN.kodak.BlackLevelTop = 0xffff; |
| MN.kodak.BlackLevelBottom = 0xffff; |
| MN.kodak.ISOCalibrationGain = 1.0f; |
| |
| MN.nikon.SensorHighSpeedCrop.cleft = 0xffff; |
| MN.nikon.SensorHighSpeedCrop.ctop = 0xffff; |
| |
| MN.olympus.FocusMode[0] = 0xffff; |
| MN.olympus.AutoFocus = 0xffff; |
| MN.olympus.AFPoint = 0xffff; |
| MN.olympus.AFResult = 0xffff; |
| MN.olympus.AFFineTune = 0xff; |
| for (int i = 0; i < 3; i++) { |
| MN.olympus.AFFineTuneAdj[i] = -32768; |
| MN.olympus.SpecialMode[i] = 0xffffffff; |
| } |
| MN.olympus.ZoomStepCount = 0xffff; |
| MN.olympus.FocusStepCount = 0xffff; |
| MN.olympus.FocusStepInfinity = 0xffff; |
| MN.olympus.FocusStepNear = 0xffff; |
| MN.olympus.FocusDistance = -999.0; |
| for (int i = 0; i < 4; i++) MN.olympus.AspectFrame[i] = 0xffff; |
| MN.olympus.StackedImage[0] = 0xffffffff; |
| |
| MN.panasonic.LensManufacturer = 0xffffffff; |
| |
| MN.pentax.FocusMode[0] = |
| MN.pentax.FocusMode[1] = 0xffff; |
| MN.pentax.AFPointSelected[1] = 0xffff; |
| MN.pentax.AFPointSelected_Area = 0xffff; |
| MN.pentax.AFPointsInFocus = 0xffffffff; |
| MN.pentax.AFPointMode = 0xff; |
| |
| MN.ricoh.AFStatus = 0xffff; |
| MN.ricoh.AFAreaMode = 0xffff; |
| MN.ricoh.WideAdapter = 0xffff; |
| MN.ricoh.CropMode = 0xffff; |
| MN.ricoh.NDFilter = 0xffff; |
| MN.ricoh.AutoBracketing = 0xffff; |
| MN.ricoh.MacroMode = 0xffff; |
| MN.ricoh.FlashMode = 0xffff; |
| MN.ricoh.FlashExposureComp = -999.0; |
| MN.ricoh.ManualFlashOutput = -999.0; |
| |
| MN.samsung.ColorSpace[0] = MN.samsung.ColorSpace[1] = -1; |
| |
| MN.sony.CameraType = LIBRAW_SONY_CameraType_UNKNOWN; |
| MN.sony.group2010 = 0; |
| MN.sony.real_iso_offset = 0xffff; |
| MN.sony.ImageCount3_offset = 0xffff; |
| MN.sony.MeteringMode_offset = 0xffff; |
| MN.sony.ExposureProgram_offset = 0xffff; |
| MN.sony.ReleaseMode2_offset = 0xffff; |
| MN.sony.ElectronicFrontCurtainShutter = 0xffffffff; |
| MN.sony.MinoltaCamID = 0xffffffff; |
| MN.sony.RAWFileType = 0xffff; |
| MN.sony.AFAreaModeSetting = 0xff; |
| MN.sony.AFAreaMode = 0xffff; |
| MN.sony.FlexibleSpotPosition[0] = |
| MN.sony.FlexibleSpotPosition[1] = 0xffff; |
| MN.sony.AFPointSelected = MN.sony.AFPointSelected_0x201e = 0xff; |
| MN.sony.AFTracking = 0xff; |
| MN.sony.FocusPosition = 0xffff; |
| MN.sony.LongExposureNoiseReduction = 0xffffffff; |
| MN.sony.Quality = 0xffffffff; |
| MN.sony.HighISONoiseReduction = 0xffff; |
| MN.sony.SonyRawFileType = 0xffff; |
| MN.sony.RawSizeType = 0xffff; |
| MN.sony.AFMicroAdjValue = 0x7f; |
| MN.sony.AFMicroAdjOn = -1; |
| MN.sony.AFMicroAdjRegisteredLenses = 0xff; |
| MN.sony.AspectRatio = -999.f; |
| |
| _exitflag = 0; |
| #ifdef USE_RAWSPEED |
| if (_rawspeed_decoder) |
| { |
| clear_rawspeed_decoder(_rawspeed_decoder); |
| } |
| _rawspeed_decoder = 0; |
| #endif |
| #ifdef USE_RAWSPEED3 |
| if (_rawspeed3_handle) |
| rawspeed3_release(_rawspeed3_handle); |
| #endif |
| #ifdef USE_DNGSDK |
| if (dngnegative) |
| { |
| clear_dng_negative(dngnegative); |
| dngnegative = 0; |
| } |
| if(dngimage) |
| { |
| clear_dng_image(dngimage); |
| dngimage = 0; |
| } |
| #endif |
| #ifdef USE_X3FTOOLS |
| if (_x3f_data) |
| { |
| x3f_clear(_x3f_data); |
| _x3f_data = 0; |
| } |
| #endif |
| |
| memmgr.cleanup(); |
| |
| imgdata.thumbnail.tformat = LIBRAW_THUMBNAIL_UNKNOWN; |
| libraw_internal_data.unpacker_data.thumb_format = LIBRAW_INTERNAL_THUMBNAIL_UNKNOWN; |
| imgdata.progress_flags = 0; |
| |
| load_raw = 0; |
| |
| tls->init(); |
| } |