pax_global_header00006660000000000000000000000064147767323370014535gustar00rootroot0000000000000052 comment=9646d776c7c61976080a8f2be67928df0750493e LibRaw-0.21.4/000077500000000000000000000000001477673233700130015ustar00rootroot00000000000000LibRaw-0.21.4/.clang-format000066400000000000000000000001131477673233700153470ustar00rootroot00000000000000BreakBeforeBraces: Allman ColumnLimit: 120 SortIncludes: false TabWidth: 4 LibRaw-0.21.4/COPYRIGHT000066400000000000000000000022011477673233700142670ustar00rootroot00000000000000 ** LibRaw: Raw images processing library ** Copyright (C) 2008-2021 LibRaw LLC (http://www.libraw.org, 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). LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c LibRaw uses DCB demosaic and FBDD denoise licensed under BSD-like 3-clause license DCB and FBDD are Copyright (C) 2010, Jacek Gozdz (cuniek@kft.umcs.lublin.pl) LibRaw uses X3F library to unpack Foveon Files, licensed BSD-style license Copyright (c) 2010, Roland Karlsson (roland@proxel.se) All rights reserved. LibRaw uses pieces of code from Adobe DNG SDK 1.4, Copyright (c) 2005 Adobe Systems Incorporated, licensed under MIT license LibRaw-0.21.4/Changelog.txt000066400000000000000000003464361477673233700154510ustar00rootroot000000000000002025-04-14 Alex Tutubalin LibRaw 0.21.4-Release * It's just time to mark all the changes made with tag 2025-02-07 Alex Tutubalin * Prevent out-of-buffer access in phase_one_correct() 2025-02-05 Alex Tutubalin * Prevent one-off read in Fuji WB table parsing * Prevent one-off read in phase_one_correct() 2024-09-18 Alex Tutubalin LibRaw 0.21.3-Release * new compile-time define LIBRAW_CALLOC_RAWSTORE If defined: calloc() will be used for all big buffer allocations to prevent uninitialized heap data leak * Small allocations: calloc() instead of malloc() to prevent uninitialized heap data leak * Support for 4-component JPEG-compressed DNG files * CR3-Qstep table: avoid wrong 64-bit code generation * Fixed several bugs related to specially-crafted files processing (thanks to OSS-Fuzz project) 2023-12-19 Alex Tutubalin LibRaw 0.21.2-Release * New compile-defined limit LIBRAW_MAX_PROFILE_SIZE_MB: limits allocation/read size for embedded color profile (default: 256Mb) * Embedded color profile allocation/read size: limited by input file size. * Multiple fixes (mostly inspired by oss-fuzz) to improve library stability and/or input checks. * raw-identify: use fallback if PATH_MAX not available * Disabled color conversion for Canon 16-bit thumbnails * docs/changelog: explained the case when no thumbnail is found in specific file * swapXX renamed to libraw_swapXX to avoid name conflict * better striped thumbnails handling 2023-01-05 Alex Tutubalin LibRaw 0.21.1-Release * fixed typo in panasonic metadata parser 2022-12-18 Alex Tutubalin LibRaw 0.21-Release * Multiple fixes inspired by oss-fuzz project 2022-07-01 Alex Tutubalin LibRaw 0.21-Beta1 == Camera format support == * Phase One/Leaf IIQ-S v2 support * Canon CR3 filmrolls * Canon CRM (movie) files * Tiled bit-packed (and 16-bit unpacked) DNGs * (non-standard) Deflate-compressed integer DNG files are allowed == Camera support == * Canon EOS R3, R7 and R10 * Fujifilm X-H2S, X-T30 II * OM System OM-1 * Leica M11 * Sony A7-IV (ILCE-7M4) * DJI Mavic 3 * Nikon Z9: standard compression formats only == Multiple (resolution) thumbnails support == * New imgdata.thumbs_list data item with data fields: int thumbcount: thumbnail count libraw_thumbnail_item_t thumblist[LIBRAW_THUMBNAIL_MAXCOUNT]: list of thumbnails libraw_thumbnail_item_t fields: enum LibRaw_internal_thumbnail_formats tformat: internal thumbnail format (this is not PPM/JPEG, but internal type related to thumbnail reading/unpacking method) ushort twidth, theight: thumbnail image size. ushort tflip: image rotation (see notes below) unsigned tlength: on-disk data size (not uncompressed for compressed formats) unsigned tmisc: bit depth and channel count: (color << 5) | bitsperpixel INT64 toffset: Thumbnail data offset in file Notes: - Only TIFF-based and CR3 files are parsed for thumbnail list, other formats will have thumbcount = 1. - If no thumbnails are found in file: thumbcount will be set to 1 and thumblist[0] will be initialized with data from thumbnail fields, so LibRaw::unpack_thumb_ex(0) will do the same as LibRaw::unpack_thumb() - Thumbnail image size may be unknown (not recorded in metadata), in this case twidth and theight are zero. Usually small(er) thumbnails will always have twidth/theight filled, while largest one may have these fields set to zero. - Thumbnail rotation (tflip) is filled only for TIFF-based RAWs (if Orientation tag is not present in IFD, default zero value is used) For non-tiff images, tflip is initialized to 0xffff (not known...) - There is no code to select thumbnail based on some criteria (e.g. minimal resolution), it is left to user to implement such a criteria, if needed (see unpack_thumb_ex() call below) - If you want to get largest possible thumbnail: just use old unpack_thumb() call to get it. * new API call: LibRaw::unpack_thumb_ex(int i): Unpacks i-th thumbnail if it exists into imgdata.thumbnail structure i should be non-zero and less then imgdata.thumbs_list.thumbcount. * samples/simple_dcraw.cpp: new -E command line switch to extract all thumbnails from input file(s) == (Experimental) RawSpeed "version 3" (develop branch) support. == Build with -DUSE_RAWSPEED3, see details in RawSpeed3/README.md LibRaw::capabilities will set bit LIBRAW_CAPS_RAWSPEED3 if compiled w/ RawSpeed-v3 support If file was processed (or tried to process) via RawSpeed-v3, these bits are raised in imgdata.process_warnings: LIBRAW_WARN_RAWSPEED3_PROCESSED - processed via RawSpeed v3 LIBRAW_WARN_RAWSPEED3_PROBLEM - not processed (due to exception in RawSpeed library) LIBRAW_WARN_RAWSPEED3_UNSUPPORTED - unsupported file LIBRAW_WARN_RAWSPEED3_NOTLISTED - file not listed in cameras.xml data RawSpeed-v3 support is controlled via libraw_decoder_info.t->flags (LIBRAW_DECODER_TRYRAWSPEED3 bit). The bit is set for: - lossless jpeg decoder - Canon sRAW decoder - lossless compressed and packed-compressed DNG decoders - Pentax decoder - Nikon (compressed) decoder - Phase One Compressed and Hasselblad/Compressed decoders - bitpacked decoder - Panasonic (old 12-bit compression) decoder - Olympus decoder - Sony ARW (v1 and v2) decoders - Samsung (version 1) decoder * (Experimental) Fine control of RawSpeed version selection/use. To enable, build LibRaw with -DUSE_RAWSPEED_BITS LibRaw::capabilities will set bit LIBRAW_CAPS_RAWSPEED_BITS if compiled with this flag. If enabled: imgdata.rawparams.use_rawspeed becomes bit-field (instead of 0/1 off/on) with bits: LIBRAW_RAWSPEEDV1_USE - use RawSpeed Version 1 (if compiled with) LIBRAW_RAWSPEEDV1_FAILONUNKNOWN - do not process unknown files (not listed in RawSpeed v1 camera definitions file) LIBRAW_RAWSPEEDV1_IGNOREERRORS - ignore mirror decoding errors (out of range data,etc) LIBRAW_RAWSPEEDV3_USE - Use RawSpeed Version 3 (if compiled with) LIBRAW_RAWSPEEDV3_FAILONUNKNOWN - do not process unknown files LIBRAW_RAWSPEEDV3_IGNOREERRORS - ignore minor decoding errors == Misc changes/improvements == * New compile time define LIBRAW_OWN_SWAB to use on platforms without swab() in C/C++ runtime * New imgdata.rawparams.options bit: LIBRAW_RAWOPTIONS_CANON_IGNORE_MAKERNOTES_ROTATION If set: image orientation is set based on TIFF/IFD0:Orientation tag, makernotes orientation data is ignored * Nikon makernotes: read NEFCompression tag for HE/HE* files * Nikon orientation tag: more fixed offsets for known cameras * Adobe DNG SDK 1.6 support (meaning, just an additional patch for GPR SDK) * removed LibRaw::memerr(), memory allocation failures are already handled in LibRaw_memmgr::*alloc w/ exception thrown * removed memory error callback, out-of-memory error should be handled via returned error code check, all related parameters (e.g. LibRaw constructor option to not set such callback) is also removed * imgdata.params.adjust_maximum_thr is settable via C-API libraw_set_adjust_maximum_thr(..) * New rawoptions/processing flags for DNG processing if compiled with Adobe DNG SDK: LIBRAW_RAWOPTIONS_DNG_STAGE2_IFPRESENT,LIBRAW_RAWOPTIONS_DNG_STAGE3_IFPRESENT If these flag(s) are set: Stage2/Stage3 processing will be performed only if OpcodeList2/OpcodeList3 tags are present in the input DNG file Old (hard) flags (LIBRAW_RAWOPTIONS_DNG_STAGE2 and LIBRAW_RAWOPTIONS_DNG_STAGE3) are not removed and will force Stage2/3 processing if set (regardless of input file tags) * New imgdata.rawparams.options bit: LIBRAW_RAWOPTIONS_DNG_ADD_MASKS If set: DNG Transparency Masks will be extracted (if selected via shot_select) * New decoder flag: LIBRAW_DECODER_UNSUPPORTED_FORMAT == Bugs fixed == * Fixed possible out-of-buffer read in Nikon orientation tag parser * Windows datastream: fixed logic errors (not showing up in real life) * Out-of-range read-only array access in postprocessing if output_color is set to 0 (raw color) * Minolta Z2 was not recognized correctly on 32-bit systems * Fixed possible buffer overflow in Kodak C330 decoder * dcraw_process(): check for buffer allocation results to avoid NULL deref 2021-10-11 Alex Tutubalin * Camera support: Apple iPhone 13 Pro GoPro HERO10 (if compiled w/ USE_GPR_SDK) Ricoh GR III Sony Xperia 1 III * Fuji RAF files: XMP block extraction * Fixed a typo in LIBRAW_OPTIONS_* flag names (was LIBRAW_OPIONS, old flags names not removed due to compatibility) * samples/raw-identify.cpp: -v flag documented in usage print. 2021-09-14 Alex Tutubalin * Camera support: Fujifilm GFX 50S II Nikon Z fc Sony A7R-IIIA (ILCE-7RM3A), A7R-IVA (ILCE-7RM4A) * API/datastruct Changes: - imgdata.params.shot_select moved to imgdata.rawparams.shot_select (because this is decode-time option, not postprocessing option) - libraw_open_bayer(...) added to C-API - imgdata.makernotes.canon: separate SensorLeftBorder,SensorTopBorder.... (and many other datafields) are united in libraw_area_t (rectangle) groups for crop areas and optical black areas. * src/libraw_cxx.cpp completely removed from source tree to not confuse users. (also all mentions are removed from Makefiles) * Better Olympus makernotes parsing: LiveND mode, Panorama mode tags. * clang-cl compatibility: - defines _MSC_VER, but _forceinline is not supported - warnings eliminated in Windows buffered datastream * Canon/12-bit files: adjust color.linear_max and makernotes.canon values to match data range. 2021-08-04 Alex Tutubalin * Camera support: Sony ZV-E10 * DNG/Floating point: additional metadata check to refuse ambiguous/corrupted files. * DNG/Floating point: correct handling of striped files (never seen in wild) * Rawspeed support: disallow Nikon D6/Compressed processing * Bug fixed: raw_inset_crops[] ctop/cheight was not adjusted right if vendor-specified ctop equals to 1. 2021-07-20 Alex Tutubalin * Camera support: Olympus E-P7 2021-07-08 Alex Tutubalin * Camera support: Panasonic GH5 Mark II Pentax K3 Mark III several phones w/ DNG files (checked) * Camera format support: Panasonic v6/12 bit * Compile-time raw size limits implemented: LIBRAW_MAX_NONDNG_RAW_FILE_SIZE - max file size for non-DNG files (default: 2GB - 1 byte) LIBRAW_MAX_DNG_RAW_FILE_SIZE - max DNG file size limit (4GB-1 if compiled w/ DNG SDK, 2GB-1 otherwise) * ACES output: color conversion changed to provide D65 white point * Fix for Canon 5D Mark II/sRAW1 incorrect camera provided crop 2021-05-07 Alex Tutubalin * Camera support: Fujifilm GFX 100S, X-E4: improved color data Canon EOS M50 Mark II was supported but not listed in camera list DJI Mavic Air 2S GOPRO Hero9 * Support for RaspberryPi HQ camera (if compiled w/ USE_6BY9RPI) * Improved support for RPi V1/V2 cameras: - white balance data extraction - color matrix extracted to imgdata.color.cmatrix to use with use_camera_matrix. - full-size thumbnail/preview support for JPEG+RAW files (raspistill -r) * Fuji GFX100/GFX100S: PixelShift metadata extraction. * RawSpeed (master): fixed bug in old Samsung/compressed decoder, apply this patch to RawSpeed: RawSpeed/rawspeed.samsung-decoder.patch * DCI-P3 and Rec 2020 output colorspaces * Eliminated multiple signed/unsigned mismatch warnings (reported by gcc11) * fixed possible 1-byte stack underrun while handling text tags with zero length * XMP block size in CR3 files limited to 1MB * Preview block size in CR3 files limited to 100MB * Fixed wrong handling of linear DNG files created from Pentax out-of-camera DNGs 2021-02-18 Alex Tutubalin * Improved Phase One Compressed defects masking, thanks to Alexey Danilchenko * Sony ILCE-1/Lossless compressed support 2021-02-16 Alex Tutubalin * Additional fields in libraw_internal_data.unpacker_data: - INT64: exif_offset: base offset of 1st EXIF IFD in file - INT64: ifd0_offset: base offset of 1st TIFF IFD (IFD0) in file - unsigned cr3_exif_length, cr3_ifd0_lenght : CR3-specific length of exif and ifd0 sections. 2021-02-08 Alex Tutubalin * CRX (CR3) decoder: fixed typo in constant; this does not affect any known still photo (CR3) sample(s), but allows to use the decoder with some video (CRM) files. * Imported user-contributed improvements to OpenMP postprocessing (AHD and X-Trans demosaic) * Bugfix: overwrite (wrong) TIFF/Orientation tag value with Metadata/Camera Orientation value for EOS 40D only. 2021-02-04 Alex Tutubalin * imgdata.sizes.raw_inset_crop rearranged: now it is imgdata.sizes.raw_inset_crops[2]: - item at [0] is the same as imgdatra.sizes.raw_inset_crop in previous versions - item at [1] is 'user crop', in particular: -- set by DNG DefaultUserCrop tag -- or set via raw aspect ratio tags (e.g. 16:9 aspect on Fujifilm cameras) raw_inset_crops[1] is filled only if aspect ratio tags provides different aspect ratio compared to raw_inset_crops[0]. There are no flags to check if raw_inset_crops[Nth] is filled; to see if it is filled check the values of: ctop/cleft < 0xffff (0xffff => standard values if not initialized) ctop+cheight <= sizes.raw_height cleft+cwidth <= sizes.raw_width Note: raw_inset_crops may be fooled by metadata (makernotes), use some correctness check before use. * LIBRAW_RAWOPTIONS_USE_DNG_DEFAULT_CROP processing flag removed, DNG DefaultCrop* tags are parsed into raw_inset_crops[0] * new LibRaw call LibRaw::adjust_to_raw_inset_crop(unsigned mask, float maxcrop = 0.55f) Promotes imgdata.sizes.raw_inset_crops[] values to imgdata.sizes.*margin and imgdata.sizes.width/height fields mask: if bit 1 is set: prefer raw_inset_crops[1] if bit 0 is set: prefer raw_inset_crops[0] maxcrop: limits crop to not less than (original width/height)*maxcrop; if raw_inset_crops[i] data results in tighter crop, than this item is ignored. return value: index in raw_inset_crops[] used increased by one, so 0: no changes made 1: [0]th data used 2: [1]th data used Note: this call SHOULD be used after LibRaw::unpack(), otherwise black level calculation from masked area may be fooled resulting in wrong black levels. 2021-01-21 Alex Tutubalin == LibRaw snapshot 202101 == = Camera format support: = Lossy compressed CR3 files Lossy compressed RAF files Uncompressed floating point DNG files (16-24-32 bit) Deflate compressed striped DNG files XMP and HEIF-preview extraction from CR3 files = Camera support = Apple iPhone 12 Max, iPhone 12 Max Pro Canon EOS R5, EOS R6, EOS 850D, EOS-1D X Mark III (lossy compressed files) FujiFilm X-S10 Hasselblad CFV II 50C", Leica M10-R, Q2 Monochrom, S3, SL2-S Nikon Z 5, Z 6 II, Z 7 II Olympus E-M10 Mark IV Panasonic DC-G100 / G110, DC-S5 Sony ILCE-7C (A7C), ILCE-7SM3 (A7S III) Zeiss ZX1 Plus multiple DNG-recording cameraphones/drones/etc. = Almost dropped camera support: = Old/partially supported video/cinema cameras support is available only if LibRaw is compiled with USE_OLD_VIDEOCAMS defined (this #define is converted internally to LIBRAW_OLD_VIDEO_SUPPORT defined). This affects: Arri cameras Canon C500 RED Cine cameras We plan to keep the support in LibRaw 0.21 (if compiled with define mentioned above) and completely drop the support after 0.21. If you're using LibRaw to decode RED Cine files, see LibRaw*datastreams section below (in short: you'll need to use old fstream-based datastream under Windows). Cinema DNG files are not affected by this. = API/ABI changes = * Decoding parameters imgdata.params is split into imgdata.rawparams: parameters used for metadata/raw data decoding imgdata.params: parameters used at postprocessing stage imgdata.params.raw_processing options are split into two sub-options sets imgdata.rawparams.options: raw processing flags, useful for normal operations imgdata.rawparams.specials: special modes (e.g decoding only delta pixels from Sony ARW) Old LIBRAW_PROCESSING_* flags are renamed to LIBRAW_RAWOPTIONS_* and LIBRAW_RAWSPECIAL* LIBRAW_PROCESSING_DP2Q_INTERPOLATE... flags are renamed to LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATE with inverted meaning (with the goal to have zero imgdata.rawparams.specials in normal use). * New processing flag LIBRAW_RAWOPTIONS_PROVIDE_NONSTANDARD_WB If set (default is not), and when applicable, color.cam_mul[] and color.WB_Coeffs/WBCT_Coeffs will contain WB settings for a non-standard workflow. Right now only Sony DSC-F828 is affected: camera-recorded white balance can't be directly applied to raw data because WB is for RGB, while raw data is RGBE. * New processing flag: LIBRAW_RAWOPTIONS_CAMERAWB_FALLBACK_TO_DAYLIGHT If set (default is not), LibRaw::dcraw_process() will fallback to daylight WB (excluding some very specific cases like Canon D30). This is how LibRaw 0.19 (and older) works. If not set: LibRaw::dcraw_process() will fallback to calculated auto WB if camera WB is requested, but appropriate white balance was not found in metadata. * Removed LIBRAW_PROCESSING_SKIP_MAKERNOTES processing flag: with new Windows(-handle) datastreams metadata parsing performance is enough to not skip makernotes parsing. * new output parameter: imgdata.params.output_flags and new enum LibRaw_output_flags Right now the only flag is implemented: LIBRAW_OUTPUT_FLAGS_PPMMETA setting it will result into metadata written to PPM/PGM output file * LibRaw_*datastreams change and corresponding open_file() parameters change LibRaw_file_datastream (based on iostreams) is moved under #ifdef LIBRAW_USE_DEPRECATED_IOSTREAMS_DATASTREAM Standard datastreams are: LibRaw_bigfile_datastream (FILE* based) for POSIX systems LibRaw_bigfile_buffered_datastream - for use with Win32 syscalls API changes: if LIBRAW_USE_DEPRECATED_IOSTREAMS_DATASTREAM is NOT defined, than LibRaw::open_file() and similar calls drops the last INT64 max_buffered_sz parameter which defines automatic selection between iostreams and FILE* based datasteams. Note: LibRaw_bigfile_buffered_datastream does NOT implements make_jas_stream() call, so RED Cine file decoding is not possible with this datastream. Use deprecaded iostreams implementation instead. We plan to keep LIBRAW_USE_DEPRECATED_IOSTREAMS_DATASTREAM up to LibRaw 0.21 and drop in 0.22. * Fuji decoder: fuji_decode_loop/fuji_decode_strip parameters has changed; look into source code for details if you're implementing your own fuji_decode_loop() call in subclass to provide parallel fuji decoding. * Canon CR3 H265 (HEIF) preview limited support: - new format value: LIBRAW_THUMBNAIL_H265 - this thumbnail is NOT extracted by LibRaw::make_mem_thumb() yet; * LibRaw::capabilities Two bits added: LIBRAW_CAPS_ZLIB if compiled with USE_ZLIB LIBRAW_CAPS_JPEG if compiled with USE_JPEG * Windows datastreams: CreateFile2 is used if compiled for UWP. * API-datastruct: clarified behavior with use_camera_wb=1 setting. * identify(): restored the differentiation between fsize and flen. * New compile-time LIBRAW_FORCE_OPENMP to skip compiler version check (if LibRaw user is absolutely sure that OpenMP is supported by compiler) 2020-10-14 Alex Tutubalin * LibRaw 0.20.2 Reverted 0.20.1 change: - const buffer for open_buffer() and open_bayer() calls Because of 0.20.0 ABI break 2020-10-14 Alex Tutubalin * LibRaw 0.20.1 * Improvements: - exif callback is called on EXIF GPS and EXIF Interop IFDs - open_bayer call documented - Canon (ColorDatsSubver==32): parse Specular White instead of hardcoded value * Fixes for normal files processing: - Olympus XZ-1: do not provide linear_max (it is wrong in metadata) - Nikon Z cameras: added space in camera list - raw-identify: fixed wb-preset print - Pentax Optio 33WR: maker index was incorrect - dcraw_emu: corrected help line for -6 option. - raw-identify: corrected range check for color matrices print - use_camera_matrix option: fixed a bug introduced when making compiler more happy. * Fixes for damaged/special crafted files processing: - Fix for truncated CR3 files parsing - DNG metadata merger: all color loops are limited to MIN(4,colors) - Check for marings: should be less than raw image size - Check for xmpdata present in Samsung Lens ID assignment - Check for column range in leaf_hdr decoder - Additional checks in Hasselblad model parser - Fuji rotate: better limits check - DNG files: limit tiff_samples * Not fixes, but makes ASAN/compilers/etc happy: - corrected GPS EXIF output - const buffer for open_buffer() and open_bayer() calls 2020-07-23 Alex Tutubalin * LibRaw 0.20 == Camera Format support == Canon CR3 GoPro (via GPR SDK) Panasonic 14-bit Fujifilm compressed/16bit Rapsberry Pi RAW+JPEG format (if USE_6BY9RPI defined) Foveon X3F support changed: it is supported only if USE_X3FTOOLS defined at build (see below for 'Imported code policy changed') == Camera support (+59, 1131 total) == Canon: PowerShot G5 X Mark II, G7 X Mark III, SX70 HS, EOS R, EOS RP, EOS 90D, EOS 250D, EOS M6 Mark II, EOS M50, EOS M200 EOS 1DX Mark III (lossless files only) DJI Mavic Air, Osmo Action FujiFilm GFX 100, X-A7, X-Pro3, X100V, X-T4 (uncompressed/lossless compressed only), X-T200 GoPro Fusion, HERO5, HERO6, HERO7, HERO8 Hasselblad L1D-20c, X1D II 50C Leica D-LUX7, Q-P, Q2, V-LUX5, C-Lux / CAM-DC25, SL2, M10 Monochrom Nikon D780, Z50, P950 Olympus TG-6, E-M5 Mark III, E-PL10, E-M1 Mark III, Panasonic DC-FZ1000 II, DC-G90, DC-S1, DC-S1R, DC-S1H, DC-TZ95 PhaseOne IQ4 150MP Ricoh GR III Sony A7R IV, A9 II, ILCE-6100, ILCE-6600, RX0 II, RX100 VII Zenit M also multiple smartphones (the tested ones are listed in LibRaw::cameraList) == Source code re-arranged == * dcraw.c is not used in the generation and build processes * dcraw_common.cpp and libraw_cxx.cpp are split into multiple code chunks placed in separate subfolders (decoders/ for raw data decoders, metadata/ for metadata parsers, etc) * dcraw_common.cpp and libraw_cxx.cpp remain to preserve existing build environments (these files are now just a bunch of #include directives). * It is possible to build LibRaw a)without postprocessing functions (dcraw_process() and called function) b)without postprocessing and LibRaw::raw2image() call (and called function). It may be useful to reduce library memory/code footprint. See Makefile.devel.nopp and Makefile.devel.noppr2i for the list of source files needed to build reduced/stripped library. == Normalized make/model == There is a huge number of identical cameras sold under different names, depending on the market (e.g. multiple Panasonic or Canon models) and even some identical cameras sold under different brands (Panasonic -> Leica, Sony -> Hasselblad). To reduce clutter, a normalization mechanism has been implemented in LibRaw: In imgdata.idata: char normalized_make[64]; - primary vendor name (e.g. Panasonic for Leica re-branded cameras) char normalized_model[64]; - primary camera model name unsigned maker_index; - primary vendor name in indexed form (enum LibRaw_cameramaker_index, LIBRAW_CAMERAMAKER_* constant). These fields are always filled upon LibRaw::open_file()/open_buffer() calls. const char* LibRaw::cameramakeridx2maker(int index): converts maker_index to normalized_make. We recommend that you use these normalized names in a variety of data tables (color profiles, etc.) to reduce the number of duplicate entries. New vendor index values will be added strictly to the end of the LibRaw_cameramaker_index table, ensuring that the numbers assigned to vendors that are already known to LibRaw will not change. == DNG frame selection == DNG frames selection code re-worked: - by default all frames w/ the NewSubfileType tag equal to 0 (high-res image) are added to the list of available images (selection performed via imgdata.params.shot_select field, as usual) - the special case for Fuju SuperCCD (SamplesPerPixel == 2) works as before: shot_select=1 will extract second sub-image. - Additional flags to imgdata.params.raw_processing_options: LIBRAW_PROCESSING_DNG_ADD_ENHANCED - will add Enhanced DNG frame (NewSubfileType == 16) to the list of available frames LIBRAW_PROCESSING_DNG_ADD_PREVIEWS - will add previews (NewSubfileType == 1) to the list. - By default, DNG frames are not reordered and are available in same order as in DNG (LibRaw traverses IFD/Sub-IFD trees in deep-first order). To prioritize the largest image, set LIBRAW_PROCESSING_DNG_PREFER_LARGEST_IMAGE bit in imgdata.params.raw_processing_options. - DNG Stage2/Stage3 processing via DNG SDK (request via flags in raw_processing_options) == Imported code policy disclaimer == We've changed the policy regarding 3rd party code imported into LibRaw. We (like other authors of open-source RAW parsers) gladly import support code for various RAW formats from other projects (if the license allows it). This is done to expand camera support. Unfortunately, not all imported code can tolerate truncated or otherwise damaged raw files, as well as arbitrary conditions or arbitrary data; not all authors handle rejecting unexpected input well. LibRaw is now widely used in various projects, including ImageMagick, which, in turn, is often used on web sites to process any input images, including arbitrary data from unknown users. This opens up wide possibilities for exploiting the various vulnerabilities present in the code borrowed from other projects into LibRaw. In order to avoid such security risks, - the borrowed code will no longer compile by default. We are not able to support it in general case, and the authors refuse to add code to reject unexpected input. Thus, if you use some kind of camera for which the support is disabled by default, you need to recompile LibRaw for your specific case. Formats currently affected: X3F (Foveon) file format. Code is imported from Kalpanika X3F tools: https://github.com/Kalpanika/x3f To turn the support on, define USE_X3FTOOLS Rapsberry Pi RAW+JPEG format. Code is imported from https://github.com/6by9/dcraw/, To turn the support on, define USE_6BY9RPI Format support is indicated via LibRaw::capabilities() call with flags: LIBRAW_CAPS_X3FTOOLS - Foveon support LIBRAW_CAPS_RPI6BY9 - RPi RAW+JPEG support == GoPro .gpr format support == GoPro format supported via open-source GPR SDK See README.GoPro.txt for details. == Windows support/Windows unicode (wchar_t*) filenames support == * (old) LibRaw's WIN32 external define split into 3 defines to fine tune compiler/api compatibility: LIBRAW_WIN32_DLLDEFS - use to compile DLLs (__dllimport/__dllexport attributes) LIBRAW_WIN32_UNICODEPATHS - indicates that runtime has calls/datatypes for wchar_t filenames LIBRAW_WIN32_CALLS - use Win32 calls where appropriative (binary mode for files, LibRaw_windows_datastream, _snprintf instead of snprintf, etc). If the (old) WIN32 macro is defined at compile time, all three new defines are defined in libraw.h If not, these defines are defined based on compiler version/libc++ defines * LibRaw::open_file(wchar_t*) is always compiled in under Windows, but if LIBRAW_WIN32_UNICODEPATHS (see above) is not defined, this call will return LIBRAW_NOT_IMPLEMENTED. Use (LibRaw::capabilities() & LIBRAW_CAPS_UNICODEPATHS) on runtime to check that this call was really implemented (or check for #ifdef LIBRAW_WIN32_UNICODEPATHS after #include ) == LibRaw*datastream simplified == * tempbuffer_open, subfile_open are not used, so removed from LibRaw_abstract_datastream and derived classes. * jpeg_src() call implemented using ->read() call and own buffering (16k buffer). * buffering_off() call added. It should be used in derived classes to switch from buffered reads to unbuffered. == minor/unsorted changes == * new flag LIBRAW_WARN_DNGSDK_PROCESSED to indicate decoder used * LibRaw::open() call, max_buf_size special meaning: == 1 => open using bigfile_datastream == 2 => open using file_datastream * Add support for zlib during configure * Fixed multiple problems found by OSS-Fuzz * Lots of changes in imgdata.makernotes (hope someone will document it) * DNG SDK could be used (if enabled) to unpack multi-image DNG files. * DNG whitelevel calculated via BitsPerSample if not set via tags. * DNG: support for LinearDNG w/ BlackLevelRepeat.. pattern * Generic Arri camera format replaced w/ list of specific camera models in supported cameras list. * new samples/rawtextdump sample: allows one to dump (small selection) of RAW data in text format. * samples/raw-identify: * +M/-M params (same as in dcraw_emu) * -L parameter to get file list from a file * -m paramerer to use mmap'ed IO. * -t parameter for timing * samples/dcraw_emu: fixed +M handling * better support for Nikon Coolscan 16-bit NEF files. * Visual Studio project files: re-generated to .vcxproj (Visual Studio 2019), different intermediate folders for different sub-projects to allow 1-step rebuild. * imgdata.makernotes...cameraspecific: removed the vendor name prefix from variables. * Bayer images: ensure that even margins have the same COLOR() for both the active sensor area and the full sensor area. * raw processing flag bit LIBRAW_PROCESSING_CHECK_DNG_ILLUMINANT inverted and renamed to LIBRAW_PROCESSING_DONT_CHECK_DNG_ILLUMINANT. If not set, DNG illuminant will be checked. * New libraw_decoder_t flags: LIBRAW_DECODER_FLATDATA - in-file data could be used as is (if byte order matches), e.g. via mmap() LIBRAW_DECODER_FLAT_BG2_SWAPPED - special flag for Sony ARQ: indicates R-G-G2-B channel order in 4-color data * Camera-recorded image crop data is parsed into imgdata.sizes.raw_inset_crop structure: ctop,cleft,cwidth,cheight - crop size. aspect - LibRawImageAspects enum (3to2, 4to3, etc) * New define LIBRAW_NO_WINSOCK2 to not include winsock2.h on compile * New processing flag LIBRAW_PROCESSING_PROVIDE_NONSTANDARD_WB If set (default is not), and when applicable, color.cam_mul[] and color.WB_Coeffs/WBCT_Coeffs will contain WB settings for a non-standard workflow. Right now only Sony DSC-F828 is affected: camera-recorded white balance can't be directly applied to raw data because WB is for RGB, while raw data is RGBE. * New processing flag: LIBRAW_PROCESSING_CAMERAWB_FALLBACK_TO_DAYLIGHT If set (default is not), LibRaw::dcraw_process() will fallback to daylight WB (excluding some very specific cases like Canon D30). This is how LibRaw 0.19 (and older) works. If not set: LibRaw::dcraw_process() will fallback to calculated auto WB if camera WB is requested, but appropriate white balance was not found in metadata. * Google changes cherry-picked (thanks to Jamie Pinheiro) * speedup: ppg interpolate: const loop invariant * Bugs fixed -Fixed several UBs found by OSS Fuzz -Fixed several problems found by other fuzzers. - Thumbnail size range check (CVE-2020-15503) Thanks to Jennifer Gehrke of Recurity Labs GmbH for problem report. - fixed possible overflows in canon and sigma makernotes parsers - fixed possible buffer overrun in crx (cr3) decoder - fixed memory leak in crx decoder (if compiled with LIBRAW_NO_CR3_MEMPOOL) - fixed possible overrun in Sony SRF and SR2 metadata parsers * Fixed typo in longitude (member of parsed GPS structure), update required for code that uses it. 2019-03-05 Alex Tutubalin * Camera support Canon A560 (CHDK hack) FujiFilm X-T30 Nikon Coolpix A1000 Olympus E-M1X Sony ILCE-6400 Several dng files from phones and drones was tested and added to built-in camera list too. * Multiple names for same Panasonic cameras are processed via aliaces mechanics, no multiple duplicate fields in adobe_coeffs() table * Better makernotes parsing for many cameras * Better parsing of makernotes embedded into DNG files created by Adobe DNG Converter * New imgdata.params.raw_processing_options value: LIBRAW_PROCESSING_ZEROFILTERS_FOR_MONOCHROMETIFFS - If this bit is set - and TIFF file contains SamplesPerPixel == 1 - and filters value was not guessed from metadata parsing LibRaw will assume the file is monochrome, not bayer. This option is needed for monochrome scan processing (Imacon X1 etc). This option may broke old TIF-like RAW files processing (Kodak 760,etc) use with care (it is better to let user choose). 2018-12-12 Alex Tutubalin * Camera support: Canon: PowerShot A480 (CHDK hack), EOS 2000D, EOS 4000D Eyedeas E1 FujiFilm: GFX 50R, XF10, X-T3, X-T100, DBP680 GITUP G3 DUO (16:9 mode only, use custom camera for 4:3) Kodak PIXPRO AZ901 Leica M10-D, M10-P Nikon D3500, Z6, Z7, P1000 Panasonic LX100M2 Pentax K-1 II Sony A7 III, HX95, HX99, RX100-VA, RX100-VI * Fixed long standing bug in remove_zeroes: first two rows/cols was unprocessed * Better parsing for NEF files modified (damaged) by NikonTransfer * Better parsing for floating point DNG black levels (into color.dnglevels.fblack and dng_fcblack[], similar to color.black and color.cblack[] for other formats). * More flexible limit for RAW decoding memory usage: imgdata.params.max_raw_memory_mb (default is LIBRAW_MAX_ALLOC_MB_DEFAULT) * New flags for imgdata.params.raw_processing_options: LIBRAW_PROCESSING_CHECK_DNG_ILLUMINANT - will check DNG illuminant field when selecting color matrix (note: incompatibility with previous versions, so default is not set). LIBRAW_PROCESSING_DNGSDK_ZEROCOPY - will not copy data from Adobe DNG SDK decoded buffer, but use it as is * Switched from auto_ptr to unique_ptr, to get back define LIBRAW_USE_AUTOPTR * dcraw_emu: it is now possible to create output filename in a more flexible manner, via -Z switch: -Z - will output to stdout -Z ext will output into inputfilename.ext -Z .ext will output into inputfilename.inputext.ext 2018-11-22 Alex Tutubalin * Finally: got Sinar 4shot sample, works fine now * OpenMP critical sections for malloc/free; extra #ifdefs removed; bin/dcraw_dist could be built again using Makefile.devel * additional checks in parse_phase_one() * more checks on file offsets/tag len in parse_minolta * more checks in parse_ciff * Mempool check reworked * Old Leaf (16bit/3color/TIFF) support * Fix cameraWB->autoWB fallback * Polaroid x530 channel swap; get metadata pointer for Foveon files * Fixed Secunia Advisory SA86384 - possible infinite loop in unpacked_load_raw() - possible infinite loop in parse_rollei() - possible infinite loop in parse_sinar_ia() Credits: Laurent Delosieres, Secunia Research at Flexera * LibRaw 0.19.1-Release 2018-06-28 Alex Tutubalin * changed wrong fix for Canon D30 white balance * fixed possible stack overrun while reading zero-sized strings * fixed possible integer overflow * LibRaw 0.19.0-Release 2018-06-11 Alex Tutubalin * Sony uncompressed/untiled DNGs: do not set bits-per-sample to 14 bit * Do not change tiff_bps for DNG files * Another possible stack overflow in kodak radc reader * Secunia Advisory SA83507, credits Kasper Leigh Haabb, Secunia Research at Flexera" - parse_qt: possible integer overflow - reject broken/crafted NOKIARAW files * LibRaw 0.19-Beta6 2018-05-10 Alex Tutubalin * Put rogue printf's behind #ifdef DCRAW_VERBOSE * Exceptions was not caught in x3f_new_from_file resulting in x3f handle leak * packed_load_raw(): EOF check on each row * define LIBRAW_USE_CALLOC_INSTEAD_OF_MALLOC to use ::calloc instead of ::malloc in LibRaw_mem_mgr malloc calls; Note: realloc is not changed, so only partial fix * Fixed possible div by zero in EOS D30 WB data parse * U-suffix for filter-var manipulation consts * restored static specifier for utf2char() lost in previous bugfix * Fixed stack overrun in kodak_radc_load_raw * Secunia Advisory SA83050: possible infinite loop in parse_minolta() * LibRaw 0.19-Beta5 2018-05-03 Alex Tutubalin * CVE-2018-10529 fixed: out of bounds read in X3F parser * CVE-2018-10528 fixed: possible stack overrun in X3F parser * LibRaw 0.19-Beta4 2018-04-24 Alex Tutubalin * LibRaw 0.19-Beta3 * fixed lot of bugs reported by ImageMagic/oss-fuzz * fixed several bugs reported by Secunia team (adv 81800, Credit: Laurent Delosieres, Secunia Research at Flexera) 2018-03-22 Alex Tutubalin * LibRaw 0.19-Beta2 * Better handling of broken JPEG thumbnails * Panasonic GH5S/G9-hires decoder, thanks to Alexey Danilchenko Note: ABI has changed due to this patch, so shlib version increased * Fujifilm X-A5/A20 metadata parsing fix * New error code LIBRAW_TOO_BIG: image data size excess LIBRAW_MAX_ALLOC_MB * winsock2 included before windows.h to make MinGW happy 2018-02-23 Alex Tutubalin * LibRaw 0.19-Beta1 * 84 cameras added compared to 0.18 (1014 total): Apple iPhone 8(*), iPhone 8 plus, iPhone X BlackMagic URSA Mini 4k, URSA Mini 4.6k, URSA Mini Pro 4.6k Canon CHDK hack PowerShot A410, A540, D10, ELPH 130 IS, ELPH 160 IS, SD750, SX100 IS,SX130 IS, SX160 IS, SX510 HS, SX10 IS, IXUS 900Ti Canon PowerShot G1 X Mark III, G9 X Mark II, EOS 6D Mark II, EOS 77D, EOS 200D, EOS 800D, EOS M6, EOS M100 Casio EX-ZR4100/5100 DJI Phantom4 Pro/Pro+, Zenmuse X5, Zenmuse X5R FujiFilm S6500fd, GFX 50S, X100f, X-A3, X-A5, X-A10, X-A20, X-E3, X-H1, X-T20 GITUP GIT2P Hasselblad H6D-100c, A6D-100c Huawei P9 (EVA-L09/AL00), Honor6a, Honor9, Mate10 (BLA-L29) Leica CL, M10, TL2 LG V20 (F800K), VS995, Nikon D850, D5600, D7500, Coolpix B700 Olympus E-PL9, E-M10 Mark III, TG-5 OnePlus One, A3303, A5000 Panasonic DMC-FZ45, DMC-FZ72, DC-FZ80/82, DC-G9 (std. res mode only), DC-GF10/GF90, DC-GH5, DC-GX9, DC-GX800/850/GF9, DMC-LX1, DC-ZS70 (DC-TZ90/91/92, DC-T93), DC-TZ100/101/ZS100, DC-TZ200/ZS200 PARROT Bebop 2, Bebop Drone Pentax KP PhaseOne IQ3 100MP Trichromatic Samsung Galaxy Nexus, Galaxy S3, S6 (SM-G920F), S7, S7 Edge, S8 (SM-G950U), Sony A7R III, A9, DSC-RX0, DSC-RX10IV Yi M1 YUNEEC CGO3, CGO3P Xiaoyi YIAC3 (YI 4k) Note(*): for mobile phones with DNG format recording, only really tested cameras are added to supported camera list. Really LibRaw should support any correct DNG. * No more built-in support for LibRaw demosaic packs (GPL2/GPL3). We're unable to support this (very old code), so we'll be happy to transfer this code to some maintainer who wish to work with it. In LibRaw 0.19 we provide extension API: user-settable callbacks to be called in code points where demosaic pack code was called. - int callbacks.pre_identify_cb(void *) => to be called in LibRaw::open_datastream before call to (standard) identify() function. If this call returns 1, this means that RAW file is identified and all metadata fields are set, so no need to run standard identify code. - void callbacks.post_identify_cb(void*) => called just after identify(), but before any cleanup code; - dcraw_process() callbacks are called before dcraw_process phases (name speaks for itself): pre_subtractblack_cb, pre_scalecolors_cb, pre_preinterpolate_cb, pre_interpolate_cb, interpolate_bayer_cb, interpolate_xtrans_cb, post_interpolate_cb, pre_converttorgb_cb, post_converttorgb_cb All these new callbacks are called with (this) as the only arg. To continue LibRaw-demosaic-pack-GPLx support one need to subclass LibRaw, set needed callbacks in (e.g.) constructor code, than these callbacks to be called * Better DNG parser: - support for DefaultCrop Origin/Size tags (add LIBRAW_PROCESSING_USE_DNG_DEFAULT_CROP to raw_processing_options to enable) - better parsing for nested DNG tags (use tag from RAW IFD, fallback to IFD0 if no tag in current IFD) - DNG PreviewColorspace extracted into dng_levels.preview_colorspace * Metadata extraction: - Better extraction of camera measured balance (LIBRAW_WBI_Auto and WBI_Measured), this not the same as 'as shot' if some preset/manual tune is used. - Extraction of camera custom balances (LIBRAW_WBI_CustomN) - Nikon data compression tag extracted into makernotes.nikon.NEFCompression - Hasselblad BaseISO and Gain extracted into makernotes.hasselblad - Canon multishot params extracted into makernotes.canon.multishot - lot of other vendor-specific makernotes data (see data structures definitions for details). * New LibRaw::open_bayer call allows to pass sensor dump w/o metadata directly to LibRaw: virtual int open_bayer(unsigned char *data, unsigned datalen, ushort _raw_width, ushort _raw_height, ushort _left_margin, ushort _top_margin, ushort _right_margin, ushort _bottom_margin, unsigned char procflags, unsigned char bayer_pattern, unsigned unused_bits, unsigned otherflags, unsigned black_level); Parameters: data, datalen - buffer passed width/height/margins - speaks for itself procflags: for 10-bit format: 1: "4 pixels in 5 bytes" packing is used 0: "6 pixels in 8 bytes" packing is used for 16-bit format: 1: Big-endian data bayer_pattern: one of LIBRAW_OPENBAYER_RGGB,LIBRAW_OPENBAYER_BGGR, LIBRAW_OPENBAYER_GRBG,LIBRAW_OPENBAYER_GBRG unused_bits: count of upper zero bits otherflags: Bit 1 - filter (average neighbors) for pixels with values of zero Bits 2-4 - the orientation of the image (0=do not rotate, 3=180, 5=90CCW, 6=90CW) black_level: file black level (it also may be specified via imgdata.params) see samples/openbayer_sample.cpp for usage sample (note, this sample is 'sample only', suited for Kodak KAI-0340 sensor, you'll need change open_bayer() params for your data). * Color data added/updated/fixed for many cameras * Correct data maximum for Fuji X-* cameras * Thumbnail processing: - JPEG thumbnails: if compiled with libjpeg, color count is extracted into imgdata.thumbnail.tcolors - PPM (bitmap) thumbnails: color count is set according to thumbnail IFD tag - PPM16 thumbnails: if LIBRAW_PROCESSING_USE_PPM16_THUMBS set in raw_processing_options, than thumbnail will be extracted as is, not converted to 8 bit. thumbnail.tformat is set to LIBRAW_THUMBNAIL_BITMAP16 in this case. Untested, because it is hard to find RAWs with 16-bit bitmaps. == Compatibility fixes * struct tiff_tag renamed to libraw_tiff_tag * pow64f renamed to libraw_pow64f == Bugs fixed: * COLOR(r,c) works correctly on X-Trans files == Security fixes: Secunia #81000: Credit: Laurent Delosieres, Secunia Research at Flexera * leaf_hdr_load_raw: check for image pointer for demosaiced raw * NOKIARAW parser: check image dimensions readed from file * quicktake_100_load_raw: check width/height limits Secunia #79000: Credit: Laurent Delosieres, Secunia Research at Flexera * All legacy (RGB raw) image loaders checks for imgdata.image is not NULL * kodak_radc_load_raw: check image size before processing * legacy memory allocator: allocate max(widh,raw_width)*max(height,raw_height) Secunia #76000: * Fixed fuji_width handling if file is neither fuji nor DNG * Fixed xtrans interpolate for broken xtrans pattern * Fixed panasonic decoder * LibRaw 0.18.6 Other fixes: * Checks for width+left_margin/height+top_margin not larger than 64k * LIBRAW_MAX_ALLOC_MB define limits maximum image/raw_image allocation (default is 2048 so 2Gb per array) * LibRaw::read_shorts item count is now unsigned * Fixed possible out of bound access in Kodak 65000 loader * CVE-2017-14348: Fix for possible heap overrun in Canon makernotes parser Credit: Henri Salo from Nixu Corporation * Fix for CVE-2017-13735 * CVE-2017-14265: Additional check for X-Trans CFA pattern data * Fixed several errors (Secunia advisory SA75000) * ACES colorspace output option included in dcraw_emu help page * Avoided possible 32-bit overflows in Sony metadata parser * Phase One flat field code called even for half-size 2016-12-27 Alex Tutubalin * Licensing changes: - there is no 'LibRaw Software License 27032010' licensing anymore (and all signed agreements have expired) - LibRaw is now dual-licensed: LGPL 2.1 or CDDL 1.0 * Camera support (+87): Apple: iPad Pro, iPhone SE, iPhone 6s, iPhone 6 plus, iPhone 7, iPhone 7 plus BlackMagic Micro Cinema Camera, URSA, URSA Mini Canon PowerShot G5 X, PowerShot G7 X Mark II, PowerShot G9 X, IXUS 160 (CHDK hack), EOS 5D Mark IV, EOS 80D, EOS 1300D, EOS M10, EOS M5, EOS-1D X Mark II Casio EX-ZR4000/5000 DXO One, FujiFilm X-Pro2, X70, X-E2S, X-T2 Gione E7 GITUP GIT2 Google Pixel,Pixel XL Hasselblad X1D, True Zoom HTC MyTouch 4G, One (A9), One (M9), 10 Huawei P9 Leica M (Typ 262), M-D (Typ 262), S (Typ 007), SL (Typ 601), X-U (Typ 113), TL LG G3, G4 Meizy MX4 Nikon D5, D500, D3400 Olympus E-PL8, E-M10 Mark II, Pen F, SH-3, E-M1-II Panasonic DMC-G8/80/81/85, DMC-GX80/85, DMC-TZ80/81/85/ZS60, DMC-TZ100/101/ZS100,DMC-LX9/10/15, FZ2000/FZ2500 Pentax K-1, K-3 II, K-70 PhaseOne IQ3 100MP RaspberryPi Camera, Camera V2 Ricoh GR II Samsung Galaxy S7, S7 Edge Sigma sd Quattro Sony A7S II, ILCA-68 (A68),ILCE-6300,DSC-RX1R II,DSC-RX10III, DSC-RX100V,ILCA-99M2 (A99-II), a6500 IMX214, IMX219, IMX230, IMX298-mipi 16mp, IMX219-mipi 8mp, Xperia L PtGrey GRAS-50S5C YUNEEC CGO4 Xiaomi MI3, RedMi Note3 Pro * Floating point DNG support: - new data fields: imgdata.rawdata.float_image - bayer float data imgdata.rawdata.float3_image - 3-component float data imgdata.rawdata.float4_image - 4-component float data imgdata.color.fmaximum - float data maximum (calculated from real data, rounded to 1.0 if below 1.0) - new raw processing flag LIBRAW_PROCESSING_CONVERTFLOAT_TO_INT - converts float data to 16-bit integer immediately after decoding with default parameters - new API Calls: int LibRaw::is_floating_point() returns non-zero if RAW file contains floating point data int LibRaw::have_fpdata() returns non-zero if rawdata.float*_image is not null (so FP data has been unpacked but not converted to integrer, see below). LibRaw::convertFloatToInt(float dmin=4096.f, float dmax=32767.f, float dtarget = 16383.f) converts float/float3/float4_image to raw_image/color3/color4_image with or without scaling: - if both real data maximum and metadata maximum are within the range ( >= dmin && <=dmax), float data is just converted to integer - if data is out of the range given above, values are scaled so real data maximum becomes dtarget - if data was rescaled (normalized), scale multiplier is stored in imgdata.color.fnorm * LibRaw can be built with Adobe DNG SDK support to decode exotic DNG formats (e.g. 8 bit). See README.DNGSDK.txt for details * New API calls unsigned LibRaw::capabilities and C-API libraw_capabilities() allows developers to determine LibRaw compile flags at runtime. Returns ORed bit fields: LIBRAW_CAPS_RAWSPEED - LibRaw was compiled with RawSpeed Support LIBRAW_CAPS_DNGSDK - LibRaw was compiled with Adobe DNG SDK LIBRAW_CAPS_DEMOSAICSGPL2, LIBRAW_CAPS_DEMOSAICSGPL3 - LibRaw was compiled with demosaic packs (GPL2/GPL3) * More metadata parsed: - White balance coefficients stored in the raw file are extracted into: int imgdata.color.WBCoeffs[256][4] - array indexed by EXIF lightsource type for example, WBCoeffs[21][..] contains coefficients for D65 lightsource float imgdata.color.WBCT_Coeffs[64][5] contains white balance data specified for given color temperature: WBCT_Coeffs[i][0] contains temperature value, and [1]..[4] are WB coefficients. - DNG analog balance, per-channel black/white level, and forward matrix - vendor specific metadata stored in vendor-specific data structures * new C-API calls: void libraw_set_user_mul(libraw_data_t *lr,int index, float val); void libraw_set_ca_correction(libraw_data_t *lr,int ca_correc, float ca_red, float ca_blue); void libraw_set_cfalinenoise(libraw_data_t *lr,int cfaline, float linenoise); void libraw_set_wf_debanding(libraw_data_t *lr, int wf_debanding, float wfd0, float wfd1, float wfd2, float wfd3); void libraw_set_interpolation_passes(libraw_data_t *lr,int passes); * Existing API changes: imgdata.params fields (all very specific purpose): sony_arw2_options, sraw_ycc, and params.x3f_flags replaced with single bit-field raw_processing_options See LIBRAW_PROCESSING_* bits in documentation. * zlib library is optional Use -DUSE_ZLIB to compile with zlib (to provide deflate DNG support) * libjpeg version: jpeg_mem_src() is mandatory, so use libjpeg-turbo or libjpeg 8+ * Fixes in vng_interpolate to make modern compilers happy * Fixed bug in Sony SR2 files black level * DNG files with BlackLevel both in vendor makernotes and BlackLevel: BlackLevel tag always takes precedence * strlen replaced with strnlen in most cases, added local version of strnlen * ChannelBlackLevel added to canon makernotes * unpack_thumb() data size/offset check against file size 2015-08-15 Alex Tutubalin * LibRaw 0.17 * Fixed dcraw.c ljpeg_start possibly buffer overrun * fixed several bugs detected by using American Fuzzy Lop * C-API extension to support 3DLut Creator * More metadata parsing/extraction: - XMP packet extracted (if exists) - DNG Color information parsed - GPS data (partially) parsed - EXIF/Makernotes parsed for used optics (for both RAW files and DNG converted by Adobe convertor). * Exif/Makernotes parser callback (called for each processed tag) * Sony ARW2.3 decoder: - params.sony_arw2_hack removed, decoded data are always in 0...17k range (note the difference with dcraw!) - Additional processing options for Sony lossy compression technical analysis. * Dcraw 9.26 imported (but some changes not approved because Libraw do it better) with some exceptions: - no Pentax K3-II frame selection code - no built-in JPEG decompressor * Many improvements in data decoding/processing: - Correct decoding of black level values from metadata for many formats, LibRaw do not rely on hardcoded black levels. * 224 camera models added to supported camera list. Some of them are new (released since LibRaw 0.16 come out), some was supported before, but missed from the list. Added cameras are: Alcatel 5035D BlackMagic Pocket Cinema Camera, Production Camera 4k Canon PowerShot A550, A3300 IS, G1 X Mark II, G7 X, SD950, SX60 HS, EOS 7D Mark II, EOS 20Da, EOS 60Da, EOS 1200D, EOS-1D C, 5DS, 5DS R, 750D, 760D, M2, M3, G3 X Casio EX-FC300S, EX-FC400S, EX-Z1080, EX-ZR700, EX-ZR710, EX-ZR750, EX-ZR800, EX-ZR850, EX-ZR1000, EX-ZR1100, ZR1200, ZR1300, EX-ZR1500, EX-100, EX-10 Digital Bolex D16,D16M DJI 4384x3288, Epson R-D1s, R-D1x FujiFilm E505,S1,S205EXR,HS10,HS11,HS22EXR,HS33EXR,HS35EXR,F505EXR,F605EXR,F775EXR,F900EXR,X100T,X30,X-T1,X-T1 Graphite Silver, XQ2, X-A2, X-T10 Hasselblad H5D-60, H5D-50,H5D-50c,H5D-40,H4D-60,H4D-50,H4D-40,H4D-31,H3DII-22,H3DII-31,H3DII-39,H3DII-50,H3D-22,H3D-31,H3D-39,H2D-22,H2D-39,CF-22,CF-31,CF-39,Stellar II,HV HTC UltraPixel Imacon Ixpress 96, 96C, 384, 384C (single shot only),132C, 528C (single shot only) ISG 2020x1520 Ikonoskop A-Cam dII Panchromatic, A-Cam dII Kinefinity KineMINI, KineRAW Mini, KineRAW S35 Kodak DCS460D, S-1 Leaf Credo 50 Lenovo a820 Leica Digital-Modul-R, D-Lux (Typ 109), M (Typ 240), Monochrom (Typ 240), M-E, M-P, R8, S, T (Typ 701), X (Typ 113), X2, X-E (Typ 102), V-Lux (Typ 114), Monochrom (Typ 246), Q Matrix 4608x3288 Nikon D4s, D600, D610, D750, D800, D800E, D810, D3300, D5500, Df, 1 J4, 1 S2, 1 V3, Coolpix P340, Coolscan NEF, D7200, 1 J5,D810A Nokia 1200x1600 Olympus E-450, E-600, E-PL6, E-PL7, E-M1, E-M10, E-M5 Mark II, SP565UZ, STYLUS1s, SH-2, TG-4, AIR-A01 Panasonic DMC-CM1, DMC-FZ7, DMC-FZ70, DMC-FZ1000, DMC-GF7, DMC-GH4, AG-GH4, DMC-GM1s, DMC-GM5, DMC-LX100, DMC-TZ60/61/SZ40, DMC-TZ70, FZ300/330, GX8 Pentax GR, K110D, K-01, K-S1, Q, QS-1, 645Z, K-S2, K3 II PhaseOne IQ250, IQ260, IQ260 Achromatic, IQ280, Achromatic+, P 20+, P 21, P 25+, P 30+, P 40+ Ricoh GXR MOUNT A12, GXR MOUNT A16 24-85mm F3.5-5.5, GXR, S10 24-72mm F2.5-4.4 VC, GXR, GR A12 50mm F2.5 MACRO, GXR, GR LENS A12 28mm F2.5, GXR, GXR P10 Samsung GX-1L, NX1, NX5, NX1000, NX1100, NX30, NX300, NX300M, NX3000, NX mini, Galaxy S3, Galaxy Nexus, NX500 Sigma dp1 Quattro, dp2 Quattro, dp3 Quattro, dp0 Quattro Sinar eMotion 22, eMotion 54, eSpirit 65, eMotion 75, eVolution 75, Sinarback 54 Sony A7 II, A7S, ILCA-77M2 (A77-II), ILCE-3000, ILCE-5000, ILCE-5100, ILCE-6000, ILCE-QX1, DSC-RX100III, DSLR-A560, NEX-VG20, NEX-VG30, NEX-VG900, IMX135-mipi 13mp, IMX135-QCOM, IMX072-mipi, RX100-IV, A7R-II, RX10-II * Fujifilm F700/S20Pro second frame support 2014-02-01 Alex Tutubalin * Updated Oly E-M10 & Panasonic TZ60/61 color data * Updated foveon SD9-14 white level * Support for 1x1 BlackLevelRepeatDim 2014-01-31 Alex Tutubalin * imported dcraw 1.461: fixed error in BlackLevelDim handling * Accurate work with pattern black-level (cblack[6+]) * Support for Olympus E-M10 and Fujifilm X-T1 * Adjusted possible maximum value for Sigma SD9 small raws 2014-01-27 Alex Tutubalin * dcraw 1.460: Nikon D3300, Panasonic DMC-TZ61, Sony ILCE-5000 2014-01-25 Alex Tutubalin * PhaseOne IQ250 support (both compressed and uncompressed) 2014-01-21 Alex Tutubalin * imgdata.params.sony_arw2_hack removed. It always on for ARW2-files. * New imgdata.params.sony_arw2_options processing flags Values: LIBRAW_SONYARW2_NONE - normal processing LIBRAW_SONYARW2_BASEONLY - BASE pixels outputeed, delta pixels set to 0 LIBRAW_SONYARW2_DELTAONLY - Delta pixels written to raw data, base pixels zeroed LIBRAW_SONYARW2_DELTAZEROBASE - Only deltas written without base offset 2014-01-20 Alex Tutubalin * Imported dcraw 9.20: - Support for DNG BlackLevelRepeatDim tags - imgdata.color.cblack[] holds variable BlackLevel for DNG files (up to ~4k values) - imgdata.params.use_camera_matrix is now ON by default. Set it to 3 if you want to force use of DNG embedded matrix. - Tone curve for Canon RMF format supported - Color data for Canon C500 * Additional camera support: Alcatel 5035D DJI 4384x3288 Fujifilm F900EXR Kodak 12MP Matrix 4608x3288 Nokia 1200x1600 Olympus E-PL6 Panasonic DMC-FZ7 2014-01-17 Alex Tutubalin * Camera support: Added: Fujifilm XE2, XQ1 Color data updated: Nikon D4 1 AW1/J3, Fuji X-M2 Fixes: Nikon D610 visible image area, Canon A3300 bayer pattern * RawSpeed support: enabled processing for cameras, unknown to RawSpeed * Fixed error in LibRaw::unpack_thumb() * little improve performance in my_strcasestr * Fix compiler errors for VS2012/OpenMP * Fixed typo which prevents to use Demosaic Pack GPL2 * LibRaw 0.16.0-Release 2013-11-15 Alex Tutubalin * New cameras supported Leica C, X VARIO Nikon D5300, D610, Df, 1 AW1 Nokia Lumia 1020, 1520 Olympus STYLUS1 Pentax K-3 Sony RX10, A3000 (ILCE-3000), * Color data updated: Canon S120 Nikon P7800, 1 J3 Olympus E-M1 * Corrected image visible area sizes Canon G16 Sigma pre-Merrill cameras: small and medium-sized RAWs * Better EXIF parsing: - ISO values for new Nikon cameras (D4, D800) - black level extraction for Nikon D5300 - correct Olympus color data conversion * Better Visual Studio compatibility (esp. old versions) * Cmake build: added ws2_32 library for MinGW builds * LibRaw 0.16.0-Beta1 2013-10-22 Alex Tutubalin * Support for new cameras: Sony A7, A7R Panasonic GM1 * Sony RX1R and RX100M2 color data updated. * Sony cameras model name is set by SonyModelID EXIF tag * Sony ARW2: black level and color matrix extracted from EXIF data * Samsung: black level and color matrix extracted from EXIF; Camera multipliers are now extracted correctly even if black is not 0 * Better source compatibility with Mac OS X compilation * Better source compatibility with Win32 compilation * DNG without Compression tag assumed uncompressed * Better X3F-tools based Foveon support: - new Foveon metadata parser based on X3F-tools. So, if LibRaw compiled without demosaic-pack-GPL2, then no dcraw Foveon code used. - Support for Medium resolution RAWs from DPx Merrill and SD1 cameras. RAW data extracted as is (4800x1600 pixels), aspect ratio is set to 0.5, so these RAWs are processed to full-size 4800x3200 RGB. - Support for Foveon thumbnail extraction. Only JPEG and bitmap thumbnails extracted, but 'foveon' (RAW) thumbnails are really not used in production cameras. - New imgdata.params.force_foveon_x3f flag Forces use of x3f-tools based code for Foveon processing if LibRaw compiled with demosaic-pack-GPL2 (and does nothing if LibRaw compiled without this pack). New flag -disadcf added to dcraw_emu sample to use this flag. - LibRaw do not calls exit() on broken Foveon files. * API/ABI changed, so all code using LibRaw should be recompiled. * LibRaw 0.16.0-Alpha3 2013-10-16 Alex Tutubalin * Support for new cameras: Canon S120 (preliminary color data), G16 Fujifilm X-A1 (preliminary color data) Hasselblad Lunar, Stellar Nikon P7800 (preliminary color data) Pentax K50, K500, Q7 Samsung Galaxy NX (EK-GN120) Sony NEX-5T * Updated color data for: Samsung NX300 Sony RX1R Sigma SD1, SD1 Merrill, DPxx (only if non-GPL2 foveon decoder used) * Image dimensions table for Foveon cameras (only if non-GPL2 foveon decoder used) * Fixed memory leak in x3f-tools code (new Foveon decoder) * Fixed DHT-demosaic incompatibility with MS VisualStudio in OpenMP directives * Additional image size checks. * LibRaw 0.16-Alpha2 2013-09-22 Alex Tutubalin * Support for new cameras: Baumer TXG14 Blackmagic Cinema Canon EOS 70D, C500 Fujifilm X-M1 Nikon D5200 Olympus E-P5,E-M1 OmniVision OV5647 (Raspberry Pi) Panasonic LF1, GX7, GF6 Richon GR Samsung NX300, NX1100, NX2000 Sony RX100II, RX1R, NEX-3N * Support for Foveon sensor based on X3F code by Roland Karlsson BSD-like license, so included in main LibRaw code. No 'foveon interpolation', so no way to get good colors from old Sigma cameras (SD9, SD14, Polaroid x530). For modern Foveon cameras one may try to create ICC profile (not supplied). TODO: thumbnail extraction, fast cancellation Old foveon_*_load_raw (from dcraw) code is used if compiled with LIBRAW_DEMOSAIC_PACK_GPL2 * API Changes: + New parameters in imgdata.params: - imgdata.params.no_interpolation - disables interpolation step in LibRaw::dcraw_process() call. - imgdata.params.no_auto_scale - disables call to scale_colors() in LibRaw::dcraw_process() call. - imgdata.params.sraw_ycc - disables Canon sRAW YCbCr to RGB conversion in LibRaw::unpack() call (use for RAW analyzers + New Fuji X-Trans handling: - imgdata.iparams.filters value is now 9 for Fuji X-Trans (instead of 2) - imgdata.iparams.xtrans[6][6] matrix contains row/col to color mapping for Fuji X-Trans sensor. + LibRaw::setCancelFlag() - use for fast decoder termination + LibRaw_abstract_datastream::make_byte_buffer() call is not needed more. + New demosaic code: DHT Demosaic by Anton Petrusevich Set params.user_qual=11 to use. + New demosaic code: Modified AHD Demosaic by Anton Petrusevich Set params.user_qual=12 to use. + New C-API call libraw_COLOR(libraw_data_t *t, int row,int col) (so LibRaw::COLOR(row,col) exposed to C-API users) * Removed faster lossless jpeg decoder ported from RawSpeed library some years ago. Build LibRaw with RawSpeed to get fast decoding. * Fixed decoding error for some Canon sRAW files. * Disabled RawSpeed's bad pixel processing if RawSpeed used. * EOS M and EOS 70D added to unique Canon ID table * Canon EOS model name normalized by unique ID table * Backported 0.15.4 input data checks * Support for CMake builds * Updated RawSpeed supported camera list * Internals changed, so all code using LibRaw should be recompiled. * LibRaw 0.16.0-Alpha1 2013-05-23 Alex Tutubalin LibRaw 0.15-Release New camera/format support: * Adobe DNG: fast Load DNG (LightRoom 4.x), support for lossy-compressed DNG (LR 4.x, requires libjpeg 6+) * Canon: G1 X, SX220 HS, EOS 5D Mark III, EOS 650D, EOS 1D-X, 100D (Rebel SL1), 700D (Rebel T5i), 6D, EOS M, G15, S110, SX50 * Casio: EX-ZR100,EX-Z8 * Fujifilm: X-S1, HS30EXR, X1-Pro,X-E1, X20, X100S, SL1000, HS50EXR, F800EXR, XF1 * Leica: D-LUX6 and V-LUX4 * Nikon: D4, D3200, D800, D800E, 1 J2, 1 V2, D600, 1 J3, 1 S1, Coolpix A, Coolpix P330, Coolpix P7700, D7100 * Olympus: E-M5, XZ-2, XZ-10, E-PL5, E-PM2 * Panasonic: G5, G6, DMC-GF5, FZ200, GH3, LX7 * Pentax: MX-1, K-5 II, K-5 IIs, K-30, Q10 * Samsung: EX2F, NX20, NX210, support for the new firmware for NX100 * Sigma: SD15, SD1, SD1 Merill, DP1, DP1S, DP1X, DP2, DP2S, DP2X (only with Demosaic-pack-GPL2) * Sony: SLT-A58, RX-1, SLT-A99, NEX-5R, NEX-6, NEX-F3, SLT-A37, SLT-A57 * Multishot files: Imacon Ixpress 39Mpix API changes: 1. dcraw_process() can now be called several times with different parameters without re-opening and unpacking the file for second and consecutive calls to dcraw_process 2. deleted (nobody uses those) - LibRaw::dcraw_document_mode_processing (and respective C-API) - imgdata.color.color_flags data field 3. LibRaw::unpack() now decodes data into different buffers, the buffer depends on the raw data type - imgdata.rawdata.raw_image - 1 color component per pixel, for b/w and Bayer type sensors - imgdata.rawdata.color3_image - 3 color components per pixel, sRAW/mRAW files, RawSpeed decoding - imgdata.rawdata.color4_image - 4 components per pixel, the 4th component can be void 4. Support for compiling with RawSpeed library, http://rawstudio.org/blog/?p=800 details are in README.RawSpeed 5. Suppression of banding 6. New API calls - recycle_datastream(), - open_file(wchar_t*) (Win32) 2012-04-05 Alex Tutubalin * Casio EX-Z500 support * (possible) I/O exceptions on file open caught in open_datastream * Fixed possible read-after-buffer in Sony ARW2 decoder * Fixed mingw32 errors when compiling LibRaw_windows_datastream * Makefile.msvc: support of OpenMP and LCMS (uncomment to use) * Fixed decoding of some Leaf Aptus II files * LibRaw 0.14.6-Release 2011-12-24 Alex Tutubalin * Fixed bug (uninitialized variable) in SMAL format decoding. * Imported new dcraw 9.12 (1.446): support for Leica V-LUX 3, updated color data for Canon S100, Fujifilm X10, Nikon 1 J1/V1, Panasonic GX1, Samsung NX200, Sony NEX-7 * LibRaw 0.14.5-Release 2011-12-12 Alex Tutubalin * Fixes to Panasonic/Leica file parser to prevent crash on broken jpegs. * Fixes to include order in src/libraw_datastream.cpp to better compile with KDEWIN * Floating-point DNGs are rejected on early processing stage. * Support for new cameras: Canon S100, Fuji X10, Panasonic GX1, Samsung NX200, Sony NEX-7. * LibRaw 0.14.4-Release 2011-10-26 Alex Tutubalin * Bug fixes in black level subtraction code for PhaseOne files * New API call LibRaw::get_internal_data_pointer() for developers who need access to libraw_internal_data fields (i.e. Fuji SuperCCD layout). * doc/API-overview fixes to reflect 0.14 changes * LibRaw 0.14.3-Release 2011-10-19 Alex Tutubalin * Fixed bug in Canon 1D and 1Ds files decoding. * New decoder information bit DECODER_HASRAWCURVE * LibRaw 0.14.2-Release 2011-10-11 Alex Tutubalin * Imported dcraw 9.11/1.445: + Support for new cameras added: Fujifilm F600EXR, Nikon P7100, Olympus E-PL3 and E-PM1, Panasonic DMC-FZ150, Sony NEX-5N, A65 and A77. + Changed color data for: Olympus E-P3, Panasonic G3 and GF3, PhaseOne H25, P40 and P65, Sony NEX-C3, NEX-5, NEX-3, A35 and A55. + Support for dark frame extraction on Sony cameras. * DCB demosaicing: reserving 6 pixels instead of 3 to suppress colored image frame. * LibRaw 0.14.1-Release 2011-09-21 Alex Tutubalin * Cosmetic changes to make Visual C++/OpenMP more happy * Fix megapixel calculation for postprocessing_benchmark in half mode * Shlib version number increment * LibRaw 0.14.0-Release 2011-09-04 Alex Tutubalin * Fixed bug with Kodak thumbnail extraction * raw2image_ex() always return value * LibRaw 0.14.0-Beta2 2011-09-02 Alex Tutubalin * Cosmetic changes to LibRaw_file_datastream interface * OpenMP speedup of postprocessing steps (up to 50% for half mode and 4-core machine) * LibRaw 0.14.0-Beta1 2011-08-20 Alex Tutubalin * Patch to dcraw_emu for SunStudio compiler compatibility * Fixed crash in unprocessed_raw sample due to uninitialized timestamp variable. * Fixed crash in raw decoding if raw_width/raw_height is less than resulting image width/height. * imgdata.sizes.flip is set from user_flip only on postprocessing and/or adjust_sizes_info_only() * Fixed buffer overrun for some LJPEG-compressed files * Most of LibRaw_datastream function bodies are moved to separate source file * LibRaw_windows_datastream is merged to main sourcetree * LibRaw 0.14.0-Alpha5 2011-08-11 Alex Tutubalin * Imported dcraw 9.10 (1.444), support for new cameras added: ARRIRAW format, Canon SX30 IS, Leica D-LUX 5 and V-LUX2, Olympus E-P3, Panasonic G3 and GF3, Sony NEX-C3 and SLT-A35 * Support for RedOne digital movie cameras (R3D format). To enable this support you should: + install libjasper JPEG2000 support library + compile LibRaw with -DUSE_JASPER compiler switch (./configure will do it for you) + If you use own LibRaw_datastream implementation, you should implement make_jas_stream() call for your datastream. See bottom of src/libraw_cxx.cpp for implementations in datafile and mem-buffer LibRaw streams. * Bugfix: green matching is turned off if output image is shrinked due to wavelet filtering or aberration correction. * fixed open_file()/adjust_sizes_info_only() code path * Removed imgdata.sizes.bottom_margin and right_margin data fields use imgdata.sizes.raw_width - width - left_margin to get right one, the same with bottom_margin. * minor ./configure cleanup * Qmake files and Visual Studio Project files are updated. * New version check macros: For use at runtime checks: LIBRAW_RUNTIME_CHECK_VERSION_EXACT() - checks that runtime major/minor version numbers are same with compile-time values. LIBRAW_RUNTIME_CHECK_VERSION_NOTLESS() - checks that runtime version is not less that compile-time one. For use at compile-time in preprocessor directives: LIBRAW_COMPILE_CHECK_VERSION_EXACT(major,minor) - Compile-time check that LibRaw version is exact major.minor. LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(major,minor) - Compile-time check that version is not less than major.minor. * all client code should be recompiled due to internals change. * LibRaw 0.14.0-Alpha4 2011-07-19 Alex Tutubalin * New sample samples/postprocessing_benchmark.cpp This sample measures postprocessing speed. All demosaic methods, averaged white balance, median filtering, wavelet filtration, highlight recovery, and cropping are supported. * Removed LibRaw::rotate_fuji_raw() call and corresponding C-API call. * The LibRaw::adjust_sizes_info_only() call may be called repeated and mixed with dcraw_process() call. * Postprocessing speedup and optimization, especially if cropping set. * Cropping works for FujiCCD raws. For the technical reasons, the position of top-left corner of crop area will be rounded to the nearest multiple of 4 (the corner is shifted top-left). * LibRaw 0.14.0-Alpha3 2011-07-15 Alex Tutubalin * imported cropping code from 0.13 branch 2011-07-12 Alex Tutubalin * samples/multirender_test - check for different clip settings 2011-07-11 Alex Tutubalin * New call LibRaw::free_image(), deallocates imgdata.image buffer. Use this call if current postprocessing results are not needed, but it is to early to call recycle() because dcraw_process() may be called later. * New C-API calls libraw_raw2image() - C API for LibRaw::raw2image() libraw_free_image() - C API for LibRaw::free_image() libraw_get_decoder_info() - C API for LibRaw::get_decoder_info() * Bugfix: change of params.user_flip aftee open()/unpack() calls should work. * LibRaw 0.14.0-Alpha2 2011-07-10 Alex Tutubalin * Multiple rendering (LibRaw::dcraw_process() calls) allowed without re-opening RAW file thrfough the sequence of open()/unpack() calls. You should be able to change any processing parameters (except shot_select parameter) between dcraw_process() calls. + New sample in samples/multirender_test.cpp: renders data 4 times: in half and full modes with different white balance settings. + Unprocessed RAW data is stored in separate data buffer: (2 bytes per pixel for all Bayer-pattern images, 8 bytes per pixel for Foveon, sRAW, and other full-color raw formats), so now LibRaw uses 25% more memory for full processing of most common Bayer images; while for just unpack memory is reduced 4 times. + New call LibRaw::raw2image() fills imgdata.image array with fresh copy of data. There is no need to call raw2image() separately if you use dcraw_process() or dcraw_document_mode_processing() calls. + New call LibRaw::get_decoder_info() to determine raw data storage layout. See samples/unprocessed_raw.cpp for an example of how to use it. If your code uses usual open()/unpack()/dcraw_process() call sequence, then NOTHING CHANGED: your program should produce same results. For interactive programs you may skip open()/unpack() calls after adjusting processing parameters, so user should see image refreshed much faster. If your code uses raw data (open+unpack calls), you need to call LibRaw::raw2image(), and imgdata.image will contain same bitmap as in LibRaw 0.13.x If you code uses access to masked borders data, you need to rewrite it. See samples/unprocessed_raw.cpp as a sample. Unfortunately, documentation is untouched yet. This problem will be fixed in next Alpha release. Other changes: * No separate imgdata.masked_pixels buffers, Bayer raw formats are read to buffer with borders. So, no ugly add_masked_border_to_bitmap() call. * No filtering_mode parameter. Raw tone curve is applied at unpack() stage; zero pixels removed on postprocessing stage. * unprocessed_raw and 4colors samples are adjusted to use new RAW data storage layout. * all client code should be recompiled due to internals change. * LibRaw 0.14.0-Alpha1 2011-07-03 Alex Tutubalin * Cosmetic cleanup in Libraw_memmgr code * Permit OpenMP support on MS VS2008 * More general mem_image interface: + New call get_mem_image_format returns bitmap size and bit depth + New call copy_mem_image can copy bitmap into buffer with different color order (RGB/BGR) and line stride + dcraw_make_mem_image() uses calls mentioned above + see documentation for info on these function parameters. * libraw/librawwindows.h implements LibRaw_datastream class based on Windows memory mapped files.Win32/64-only Thanks to Linc Brookes. * Fixed parallel make errors in configure/Makefile.am * LibRaw 0.13.6-Release 2011-05-18 Alex Tutubalin * Imported new dcraw 9.08/1.443: + New color data for Canon 600D and 1100D, Fuji S200EXR + New camera supported: Fuji HS20EXR and F550EXR, Kodak Z990, Nikon D5100, Olympus E-PL1s and XZ-1, Samsung NX11, Sony A230 and 290. * LibRaw 0.13.5-Release 2011-04-02 Alex Tutubalin * Imported new dcraw 9.07/1.442: + Support for Canon 600D and 1100D, Hasselblad H4D-60, Olympus E-PL2 * Color data for Leaf Aptus II and Canon Powershot S2 IS * LibRaw 0.13.4-Release 2011-03-30 Alex Tutubalin * Preliminary support for Leaf Aptus II cameras (no color data yet): Leaf Aptus II 6,7,8,10 and 12 are tested, Aptus II 5 should work. * Preliminary support for Fujifilm X100 camera (again, no color data). * Fixed possible after the end of buffer read when working with in-memory data. * Fixed possible loss of JPEG stream sync marks in LJPEG decoder (this bug was found only for Leaf Aptus II RAWs). * LibRaw 0.13.3-Release 2011-03-08 Alex Tutubalin * Fixed broken camera white balance reading for some Sony cameras * LibRaw 0.13.2-Release 2011-02-25 Alex Tutubalin * Sony A390 support (colordata from A380) * Leica D-LUX 4: fixed typo in camera name in colordata 2011-02-15 Alex Tutubalin * New -mem option for dcraw_emu: I/O via allocated buffer * Removed debug printf from LibRaw_memory_buffer code * Preliminary shared library support 2011-02-12 Alex Tutubalin * Added qmake .pro and Visual Studio 2008 sln/vcproj project files 2011-02-07 Alex Tutubalin * dcraw_emu documentation updated * ./configure stuff changed for correct linking on some systems * FBDD denoising is disabled for full-color images and 4-color bayer data (including forced 4-color via four_color_rgb option) * LibRaw 0.13.1-Release 2011-02-05 Alex Tutubalin * ./configure fixes for PACKAGE_REQUIRES * Makefile.msvc: correct compiler flags for demosaic packs * dcraw.c 9.06/1.440 imported: + New camera support: Canon S95, Casio EX-Z1080, Panasonic GF2 and GH2, Samsung NX100, Sony A-580 + New color data for: Canon G12, Nikon D3100, D7000 and P7000, Olympus E-5, Pentax K-r and K-5, Samsung NX10 and WB2000 * green_matching() code is disabled for half-size processing * LibRaw 0.13.0-Release 2011-01-15 Alex Tutubalin * Fallback to old huffman decoder for Sony files with unspecified data length (Sony A100) * Fixed incomplete data fields reset in LibRaw::recycle() * LibRaw 0.13.0-Beta3 2011-01-13 Alex Tutubalin * Better parsing of unknown command-line params in dcraw_emu sample * Brigtness table in ahd_demosaic is calculated in reversed order to prevent possible (very unlikely) multithreaded app problem. * New exposure correction code based on linear-cubic root combination. New working correction range is from 0.25 (-2 stops) to 8 (+3 stops) * LibRaw 0.13.0-Beta2 2011-01-10 Alex Tutubalin * Fixed file extension in half_mt.c sample 2011-01-10 Alex Tutubalin * Three patches provided by Jacques Desmis: - Exposure correction before demosaic (demosaic pack GPL3) - OpenMP speed-up in median filters (demosaic pack GPL2) - OpenMP speed-up in green equilibration (demosaic pack GPL3) * Merged 0.12.2-0.12.3 changes: - Patches for ./configure system for better LCMS2 support - Patches for ./configure system - math.h included before any other includes to make KDE compile with Visual C++ happy - Fuji FinePix S5500 size adjusted to ignore (rare?) garbage at top of frame. * all client code should be recompiled due to internals change. * LibRaw 0.13.0-Beta1 2010-12-22 Alex Tutubalin * Zero copy huffman buffer for LibRaw_buffer_datastream * Fixed memory leak in compressed NEFs handling * LibRaw 0.13.0-Alpha2 2010-12-20 Alex Tutubalin * Demosaic-pack-GPL3 changes: + New noise reduction methods before demosaic - Banding suppression - High-frequency noise suppression - Green channel equalization + New chromatic aberration correction. All three methods are written by Emil Martinec for Raw Therapee. Adapted to LibRaw by Jacques Desmis * Merged Foveon code fix from LibRaw 0.12.1 * LJPEG decompressor speed-up (about 1.5 times for Canon cameras and slightly less for others). Some ideas are from RawSpeed library. * all client code should be recompiled due to internals change. * LibRaw 0.13.0-Alpha1 2010-12-12 Alex Tutubalin * Thread-safe and demosaic packs support for MinGW build * Demosaic packs support for MS VC build * LibRaw 0.12.0-Release 2010-12-09 Alex Tutubalin * Fixed bug in add_masked_borders_to_bitmap() call for cameras with odd pixels border. * New command line options for unprocessed_raw sample: -B - subtract black level, -M - add masked pixels to bitmap. * Foveon-sensor cameras added to supported camera list if compiled with demosaic pack GPL2 * LibRaw 0.12.0-Beta4 2010-12-05 Alex Tutubalin * Demosaic packs support in Makefile.dist * Foveon support in LibRaw demosaic pack GPL2 * all client code should be recompiled due to internals change. * LibRaw 0.12.0-Beta3 2010-11-27 Alex Tutubalin * Fixed allocation bug in lmmse_interpolation (demosaic-pack-GPL2) * In LMMSE and AMaZE interpolators allocation changed to calloc to make valgrind happy with uninitialized values * Changes in distribution-making scripts * LibRaw 0.12.0-Beta2 2010-11-21 Alex Tutubalin * Fixes to green_matching code by Sergey Pavlov 2010-11-20 Alex Tutubalin * Update for new demosaic-pack-GPL3 * LibRaw 0.12.0-Beta1 2010-11-19 Alex Tutubalin * Demosaic pack(s) supported via ./configure 2010-11-17 Alex Tutubalin * LCMS2 support * afd_interpolate(2,1) instead of (5,0) * dcraw_emu sample command line keys added and reordered to reflect changes in LibRaw 0.12. * Nikon P7000: color matrix data and black level patch for ISO >=400 Thanks to Gunnar Thorburn * Support for several industrial cameras based on Sony ICX 625/655 sensor: JAI BB500CL/GE, SVS625CL, ptGrey GRAS-50S5C Thanks to kaare 2010-11-15 Alex Tutubalin * Several demosaic algorithms, found in other open-source RAW processing packages are implemented in LibRaw. 1) DCB demosaic and FBDD denoise by Jacek Gozdz are included in main LibRaw source. 2) GPL2 demosaic pack with these demosaic methods: * AFD and LMMSE implementations from PerfectRaw by Manuel Llorens * VCD, Modified AHD, post-demosaic refinemend and median filters by Paul Lee 3) GPL3 demosaic pack with AMaZe interpolation by Emil Martinec See more details in README.demosaic-packs * Current implementation of dcraw_emu sample allows only selection of demosaic method (via -q) options. All other parameters change will be implemented later. * LibRaw 0.12-alpha1 2010-11-11 Alex Tutubalin * Imported 0.11(2) version changes: + Fixed dcraw_emu command line processing code + OpenMP is completely disabled on MacOS X if compiled with -pthread due to well-known MacOS problem. + dcraw 9.05 (1.439) imported, many new cameras supported: Canon: G12, SX120, 60D, Hasselblad H4D, Nokia X2, Olympus E-5, Nikon: D3100, D7000, P7000, Panasonic: FZ40, FZ100, LX5, Pentax: K-r, K-5, 645D, Samsung GX20, WB2000 * LibRaw 0.12-alpha0 2010-11-08 Alex Tutubalin * Fixes for Sun Studio compiler compatibility * Fixes for Visual Studio 2010 compatibility * All russian-language files are converted to UTF-8 * LibRaw 0.11.0-Release 2010-10-18 Alex Tutubalin * Disabled OpenMP for wavelet_denoise under Mac OS X * More Visual C++ 2003 warnings cleaned in libraw/*h files * LibRaw 0.11-Beta7 2010-10-16 Alex Tutubalin * internal/dcraw_fileio.c can be compiled with -DDCRAW_VERBOSE again * fixed comment style in libraw_datastream.h * LibRaw 0.11-Beta6 2010-10-15 Alex Tutubalin * New changes to I/O layer. Three LibRaw_*datastream clasees are exists: + LibRaw_buffer_datastream - buffer reaging + LibRaw_file_datastream - file reading using iostreams (large files are no supported on some systems) + LibRaw_bigfile_datastream - FILE*-based file I/O * file/bigfile_datastream is selected automatically by LibRaw::open_file based on input file size. By default, files larger than 250Mb are opened using bigfile interface, you may change this behaviour by using second optional parameter of open_file() * There is no way to use default parameter values in C API, so new call libraw_open_file_ex added with two parameters (file name and minimal file size for bigfile_datastream use). * all client code should be recompiled due to internals change. * All LibRaw_abstract_datastream functions are virtual again. You may (again) use your own I/O layer. * new -d key for dcraw_emu sample: print timings of processing stages * simple_dcraw sample simplified: no mmap code * LibRaw 0.11-Beta5 2010-10-08 Alex Tutubalin * Fixed bug in exception handling in OpenMP sections in AHD interpolation code. * LibRaw_datastreams are now C++ iostreams based instead of old plain FILE* calls. LibRaw::open_file() in multithreaded programs are WAY faster on many OSes (Linux, Windows, MacOSX) because of no extra locks. * all client code should be recompiled due to internals change. * LibRaw 0.11-Beta4 2010-10-01 Alex Tutubalin * Fixed bug in LibRaw::dcraw_process() code: for half_size processing, params.four_color_rgb was set to 1 internally and not returned back after postprocessing. * Several Visual Studio 2003 compatibility fixes * AHD interpolation refactored. Now it is about 10% faster than dcraw in single-process mode and up to 1.5 times faster on 4-core and OpenMP (total execution time counted, not AHD itself) Thanks to Adam Hooper * AHD interpolation refactored. Now it is about 10% faster than dcraw in single-process mode and up to 1.5 times faster on 4-core and OpenMP (total execution time counted, not AHD itself) Thanks to Adam Hooper * LibRaw 0.11-Beta3 2010-09-07 Alex Tutubalin * Phase One files: LibRaw::unpack() sets colordata.black to approximately correct value. * Fixed minor error in setting colordata.maximum value for Phase One files. * LibRaw::subtract_black() sets colordata.black and colordata.cblack[] to zero to preserve data integrity. * LibRaw 0.11-Beta2 2010-09-04 Alex Tutubalin * It is now possible to crop output image on postprocessing stage (dcraw_process). Coordinates and size of the output box are set via imgdata.params.cropbox[4] parameter. Look into LibRaw documentation for more details. + New fatal error code LIBRAW_BAD_CROP + New dcraw_emu sample command line switch: -B x y w h (sets cropbox) Thanks to Patrick and Jan. * Processing pipeline has changed: the black level is subtracted from data on postprocessing stage either automatically (on dcraw_process() stage) or by special LibRaw API call: + New API calls: LibRaw::subtract_black() (C++ API) and libraw_subtract_black (C API). If you use dcraw_process() or dcraw_document_mode_processing() calls YOU DON'T NEED to call subtract_black() directly. + The raw preprocessing mode LIBRAW_FILTERING_NOBLACKS is deprecated and removed from LibRaw. * New ./configure script. Use ./configure -h for usage details. Thanks to Siddhesh Poyarekar * New API cals static LibRaw::dcraw_clear_mem() (C++ API) and libraw_dcraw_clear_mem(..) (C API). This calls are used to free memory, allocated by dcraw_make_mem_image() and dcraw_make_mem_thumb() instead of free() call. In some cases LibRaw and calling process have different memory managers, so free() of make_mem_image() data results to program crash (especially in Win32/VisualStudio environment). * LibRaw::free() is now private instead of public (again). * Minor changes and bugfixes: + Memory allocation exceptions (std::bad_alloc) are caught, so LibRaw API calls will return reasonable error codes instead of C++ exception (possibly unhandled). This problem is very unlikely to see in wild: if application cannot allocate small data for internal structure, it will always fail on allocation for RAW image data. + WIN32/VisualStudio 2008/2010: fopen,fscanf and sscanf calls in Libraw_datastream code are changed to *_s (secure) ones. + Debug print removed from fatal error handler. + Mmaped I/O for dcraw_emu sample is turned on via -E switch now (because old -B switch is used for setting cropbox). * all client code should be recompiled due to structures size change * LibRaw 0.11-Beta1 2010-07-31 Alex Tutubalin * dcraw 9.04 (1.438) imported: changes in tiff metadata parser, fixed a typo in Canon A720 model name * small patch in Sony ARW2 unpacking code to make valgrind happy * LibRaw 0.10.0-Beta3. 2010-07-05 Alex Tutubalin * dcraw 9.03 (1.437) imported: + New cameras: Canon SX20, Nikon D3s, Olympus E-P2, Panasoni DMC-GF1, Samsung EX1, Sony A450 + Color data changed for some cameras * LibRaw 0.10.0-Beta2. 2010-06-06 Alex Tutubalin * dcraw 9.01 (1.434) imported: + Separate black levels for each color channel. + New cameras: Canon 550D, Casio EX-Z1050, Fuji HS10/HS11, Kodak Z981, Panasonic G2 and G10, Phase One P65, Samsung NX-10 and WB550, Sony NEX-3 and NEX-5. + Fixed file descriptor leak in dark frame subtraction processing * Fixed dcraw 9.01's bug in DNG black level processing * Preliminary support for Sony A450 camera. * New command-line switch -h in mem_image sample (half_size support) * Some patches by Johannes Hanika (darktable author): + OpenMP speedup for PPG-interpolation + green_matching - suppress of 'color maze' on cameras with different green channel sensitivity. This option is turns on by filed with same name in imgdata.params * all client code should be recompiled due to structures size change * LibRaw::free() is now public instead of private. * LibRaw 0.10.0-Beta1. 2010-05-15 Alex Tutubalin * Fixed bug in 8-bit RAW processing code * LibRaw 0.9.1-Release 2010-04-26 Alex Tutubalin * OpenMP support: OpenMP is possible under MinGW (untested) * LibRaw 0.9.0-Release 2010-04-21 Alex Tutubalin * Finally fixed inconsistency in Fuji files processing * New COLOR(row,col) call to get bayer color index in image[] array * Old FC() call is deprecated and will be removed in future releases * unprocessed_raw sample switched to COLOR() call * LibRaw 0.9.0-Beta5 2010-04-10 Alex Tutubalin * Fixed bug in unpacking DNG files made from Fuji RAFs. * LibRaw 0.9.0-Beta4 2010-04-09 Alex Tutubalin * Fixed typecast error (problem reported only on gcc 4.2.1/32bit) in CRW files processing. * C++ API call LibRaw::adjust_maximum() is now deprecated and de-documented, use params.adjust_maximum_thr instead (on by default) * C-API call libraw_adjust_maximum() removed. * New postprocessing parameter params.adjust_maximum_thr This parameter replaces LibRaw::adjust_maximum(), but more flexible Defaults are reasonable (0.75, same as in old adjust_maximum), look into documentation for more details. * Removed last OpenMP warning * dcraw_emu's -c parameter now wants numeric (float) argument. This value is assigned to params.adjust_maximum_thr. Use -c 0.0 for dcraw compatibility. * all client code should be recompiled due to structures size change * LibRaw 0.9.0-Beta3 2010-03-29 Alex Tutubalin * Fixed a bug in channel_maximum[] calculation for Panasonic cameras. * channel_maximum[] data now calculated for ALL cameras. * OpenMP warnings suppressed. * Documented the -c command-line switch for dcraw_emu sample. * Removed extra messages from dcraw_emu sample. * LibRaw 0.9.0-Beta2 2010-03-28 Alex Tutubalin New licensing: * Triple licensing (selected by LibRaw user): + LGPL 2.1 (http://www.gnu.org/licenses/lgpl-2.1.html) + CDDL 1.0 (http://www.opensource.org/licenses/cddl1.txt) + LibRaw Software License (27 March 2010 version) (http://www.libraw.org/data/LICENSE.LibRaw.pdf) * There is no separate LibRaw-Lite and LibRaw-Commercial versions, only single LibRaw. Current LibRaw-Lite and LibRaw-Commercial users should switch to LibRaw without loss of functionality. It is possible to change licensig too (e.g. from LGPL to CDDL for LibRaw-Lite users and from LibRaw License to LGPL or CDDL for LibRaw-Commercial users). * No Foveon support :( It is not possible to get good color from Foveon sensors with *any* converter. So, there is no need to support these cameras. Dcraw's Foveon-processing code is too strict licensed (GPL), so we choose to drop it. New Features: * New data field colordata.channel_maximum[4] - per channel data maximum (calculated for most cameras, 0 for others). * New call LibRaw::adjust_maximum() (and libraw_adjust_maximum() in C API). This call changes hardcoded colordata.maximum value to calculated at unpack stage. This helps suppress false color in highlights (magenta clouds and so). * New command line parameter -c for dcraw_emu sample. Calls adjust_maximum() for each processed file. * all client code should be recompiled due to structures size change * LibRaw 0.9.0-Beta1 2010-02-06 Alex Tutubalin * Fixed ambiguity in pow/sqrt calls (to make Sun C++ compiler happy) * OpenMP is not supported under MS Visual Studio * Masked a bug in RIFF format parser * LibRaw 0.8.6 2009-12-30 Alex Tutubalin * Fixed bug in simple_dcraw sample parameters processing * Imported dcraw 8.99 (1.432): + New cameras: Canon: 1D mk IV, Canon S90; Casio Z750, Nikon D3S, Pentax K-x, Sony A-500/550, Fuji S200EXR + New color data for Canon G11 and Sony A850 + Changes in Canon sRAW processing + Changes in Kodak metadata processing + Changes in uncompressed Fuji files processing (FinePix S5xxx) * LibRaw 0.8.5 2009-11-21 Alex Tutubalin + Fixed a bug in processing of uncompressed Phase One files * LibRaw 0.8.4 2009-10-24 Alex Tutubalin + Imported dcraw 8.98/1.431: * New Cameras: Canon 7D, Panasonic GF1, Sony A850 and A380, Casio Z850, Nikon D300s + changes in libraw_datastream.h to make compilers more happy * LibRaw 0.8.3 2009-09-02 Alex Tutubalin + Fixed bug in Hasselblad .3FR unpacking code * Imported dcraw 8.97/1.428: Nikon D3000 image width fix * LibRaw 0.8.2 2009-08-31 Alex Tutubalin + Enum LibRaw_thumbnail_formats (LIBRAW_IMAGE_*) values changed to match values in enum LibRaw_image_formats (LIBRAW_THUMBNAIL_*). You need to recompile all sources using these constants. 2009-08-30 Alex Tutubalin * Imported dcraw 8.97/1.427: + new cameras: Canon A470, Canon G11 (without color data), Nikon D3000, Olympus E-P1, Panasonic DMC-FZ35/FZ38 + some changes in decoding code. * Fixes for Microsoft Visual C++ 6.0 compatibility * C-API dcraw_make_mem_thumb() call finally exported in API * LibRaw 0.8.1 2009-08-24 Alex Tutubalin * Imported dcraw 8.96/1.426 + New cameras: Casio EX-Z60 and EX-Z75, Kodak Z980, Nikon D5000, Olympus X200, D560Z,C350Z,E620, Pentax K7, Sony A330. + New color data for many cameras + Generalized unpacker code for Canon and Casio P&S cameras * LibRaw 0.8.0-Release 2009-08-13 Alex Tutubalin * RAW files larger than 2Gb are supported on: - Unix (all supported: FreeBSD, MacOS X, Linux) - Windows (with C runtime version >= 8.0) * bzero replaced with memset to make Solaris users happy * All applications on 32-bit systems should be recompiled due to data structures size changes. * Minor fixes in windows makefile * LibRaw 0.8.0-Beta5 2009-07-21 Alex Tutubalin * Imported dcraw 8.95 (1.425): + new huffman tree code + New cameras supported: AGFAPHOTO DC-833m, Casio EX-S20, Phase One P65, Samsung S850 + Removed hardcoded white-balance data for many P&S cameras. It is recommended to set params.use_camera_wb to 1 for safe WB. * Fixes for Nikon D5000 files: no pink stripe at right side of frame * C-wrapper: added missed calls libraw_dcraw_make_mem_image libraw_dcraw_ make_mem_thumb * Minor fixes to make non-gcc compilers more happy * Internal structures changed, full recompilation of all client code is needed. * LibRaw 0.8.0-Beta4 2009-06-08 Alex Tutubalin * Fixes: gamma curve processing was not performed in dcraw_write_mem_image() * Fixes: gamma curve processing was not performed for Kodak thumbnails * LibRaw 0.8.0-Beta3 2009-06-05 Alex Tutubalin * Fixes in documentation: params.gamm[] described more precisely * Fixes in version number, 0.8-beta1 was mistakenly 0.0.0-beta1 * LibRaw 0.8.0-Beta2 2009-06-04 Alex Tutubalin * Imported dcraw 8.94 (1.423): + New camera support: Canon: SX1, 500D/Rebel T1i, A570, A590, SX110 Kodak Z1015, Motorola PIXL, Olympus E30, Panasonic DMC-GH1 + Improved color data for Nikon D3X + New gamma curve model + Many changes in RAW unpacking code + Canon cameras: black level is not subtracted if set params.document_mode > 1 * API changed: params.gamma_16bit field removed. Gamma curve is set via params.gamm[0]/gamm[1] values (see documentation and samples for details) * LibRaw::identify() split to avoid MS VS2008 bug (too many nested blocks) * Samples: dcraw_emu and mem_image samples supports new dcraw 16bit/gamma semantics: -6: set 16 bit output -4: set 16 bit output and linear gamma curve and no auto brightness * LibRaw 0.8.0-Beta1 2009-04-28 Alex Tutubalin * Identify sample renamed to raw-identify (name conflict with ImageMagic) * Copyright notice changes * Many compiler warnings removed 2009-04-07 Alex Tutubalin * More accurate types conversion in libraw_datastream.h * New postprocessing parameter auto_bright_thr: set portion of clipped pixels for auto brightening code (instead of dcraw-derived hardcoded 1%) * -U option for dcraw_emu sample sets auto_bright_thr parameter * all client code should be recompiled due to structures size change * LibRaw 0.7.2-Release 2009-03-22 Alex Tutubalin * Fixed typo in OpenMP support code * MinGW support * dcraw source is included in distribution * LibRaw 0.7.1-Release 2009-03-15 Alex Tutubalin * Fuji SuperCCD RAWs: color channels unshuffled on RAW read stage (moved from postprocessing stage) * LibRaw 0.7.0-Release 2009-03-13 Alex Tutubalin * dcraw 8.93/1.421 imported: + more accurate pentax dSLR support + fixes in Kodak 620x/720x identification + faster identification procedure for some formats. * LibRaw 0.7.0-Beta5 2009-03-08 Alex Tutubalin * dcraw 8.92/1.420 imported: + user-specified gamma curve + Pentax K2000/Km support + Changes in Canon sRAW processing (support for 5D2 fw 1.07) * all client code should be recompiled * LibRaw 0.7.0-Beta4 2009-02-13 Alex Tutubalin * bugfix: 4channels sample finally subtracts black by default * dcraw 8.91/1.419 imported: + fixes in RIFF files parsing * LibRaw 0.7.0-Beta3 2009-02-12 Alex Tutubalin * Black level was not calculated for Canon RAWs in some filtering modes * 4channels sample prints calculated black level (scaled if autoscaling used). Also output file names for this sample now includes color channel name (R/G/B/G2 or C/M/Y/G) * LibRaw 0.7.0-Beta2 2009-02-09 Alex Tutubalin * New sample 4channels: splits RAW color channels into four separate TIFFs * LibRaw 0.7.0-Beta1 2009-02-07 Alex Tutubalin * Fixed bug in external jpeg metadata reading code. * Cleaned some C++ warnings * dcraw 8.91/1.418 imported + Hasselblad V96C support * You need to clean and recompile client code which uses LibRaw_*_datastream classes. * LibRaw 0.7.0-Alpha6 2009-01-30 Alex Tutubalin * New data input framework is created. It is possible now to easyly implement your own data input interface for LibRaw (e.g. for reading RAW data from network data stream) * All older programs using previous LibRaw versions are compatible at source code level. * LibRaw can read RAW data from memory buffer via new LibRaw::open_buffer() API call (implemented on top of new input framework). This call used in sample application dcraw_emu and simple_dcraw (with -B command-line switch) to test new API. * Error handling callback functions now can be called with NULL filename passed (if underlying data stream object does not know file name). So, client error handling callbacks should work with NULL filename. * All client code should be recompiled * Imported dcraw 8.90/1.417: + Support for loading White Balance data from Sony ARW files edited with Sony IDC software. * LibRaw 0.7.0-Alpha5 2009-01-17 Alex Tutubalin * Raw filtering mode LIBRAW_FILTERING_NOPOSTPROCESS has renamed to LIBRAW_FILTERING_NORAWCURVE for better reflect its purpose. This filtering_mode bit turns off tone curve applying on RAW data on bayer-pattern cameras with raw tone curve: + Adobe DNG (only RAW with bayer pattern) + Nikon compressed NEF + Some Kodak cameras + Sony A700/A900 (tone curve applied to 8-bit raws) * unprocessed_raw sample: added command-line key -N, this key turns on LIBRAW_FILTERING_NORAWCURVE filtering mode. * New scheme of Fuji RAW processing (introduced in 0.7-Alpha3) supports DNG files generated from Fuji RAF. * Imported dcraw 8.90/1.416: + better support for Samsung S85 + fixed possible integer overflow in wavelet denoising code * LibRaw 0.7.0-Alpha4 2009-01-14 Alex Tutubalin * Black mask extraction supported for all files with bayer data (one component per pixel). Black mask data not available for multi-component data (Foveon, Canon sRAW, Sinar 4-shot, Kodak YCC/YRGB). * Black level subtraction can be turned off for all bayer cameras (added support for PhaseOne backs). * Fujifilm camera processing model changed: + RAW data is extracted without 45-degree rotation + dcraw-compatible rotation is performed on postptocessing stage + it is possible to rotate RAW data without postprocessing by LibRaw::rotate_fuji_raw() call. * New filtering mode setting: LIBRAW_FILTERING_NOPOSTPROCESS This bits turns off RAW tone curve processing based on tone curve readed from RAW metadata. This mode supported only for PhaseOne backs now (to be supported on all relevant cameras in nearest future releases) * Black level data (got from RAW data) are stored for PhaseOne backs. * Black level subtraction bug (derived from dcraw) fixed for PhaseOne files. * Fixed processing of -s parameter for dcraw_emu sample * Parameter -s N (select shot number) added to unprocessed_raw sample. * Imported dcraw 8.90/1.414: + changes in QuickTake 100 metadata processing + changes in external jpeg processing code + Samsung S85 support * All client code should be recompiled * LibRaw 0.7.0-Alpha3 released 2009-01-10 Alex Tutubalin * Fixed bug in add_masked_borders: crash if output dimensions is already larger than raw dimensions * Fixed out of bounds in samples/unprocessed_raw.cpp for files with non-square pixels * LibRaw 0.7.0-Alpha2 released 2009-01-08 Alex Tutubalin * Fixed bug in 0.7.0-a0: black frame size has not reset, so in batch processing there is an error in black frame size for files without black frame. * Implemented reading of black/masked pixels data for near all cameras with masked pixels, exclding: + Canon sRAW, Leaf (MOS), Sinar 4-shot - more than one color component in black frame (redesign of black frame data structures required). + Fuji SuperCCD: need to design right methods of extraction (should we rotate and resize black pixels as active ones??) * Tested for most dSLR data formats with masked pixels: 7 of 9 untested formats are from old P&S cameras. * New call LibRaw::unpack_function_name() returns unpack function name (useful for testers only) * New identify sample parameters (useful for test-suite builders to check test coverage): -u - print unpack function name -f - print masked frame size These parameters works only for identify run without -v parameter * Imported dcraw 8.89/1.411 + changes in Panasonic FZ50 files parsing * LibRaw 0.7.0-Alpha1 released 2009-01-05 Alex Tutubalin * It is possible to turn off RAW data filtration (black level subtraction, zero pixels averaging): + supported on all cameras except Foveon and Phase One + filtraction controlled by new parameter "filtering_mode" + it is possible to expand API by filtering procedures built for specific camera model. * Black border (masked pixels) extraction: + API (data structures) for storing black mask. + Black mask extraction supported only for limited list of data formats: - Canon .CRW, .CR2 (with exception of sRAW),A600, A5 - Adobe DNG (both converted RAW and native DNG) - Nikon NEF (compressed only) this list to be expanded in future LibRaw versions * New call add_masked_borders_to_bitmap makes full bitmap 'masked border' + image * Usage sample for functionality listed above: samples/unprocessed_raw * Imported dcraw 8.89/1.410: + fixed bugs in Hasselblad .fff decoding + fixes in Imacon metadata decoding * Documentation changes * All client code should be recompiled * LibRaw 0.7.0-Alpha0 2009-01-01 Alex Tutubalin * Fixed a bug (filedescriptor and buffer memory leak) in thumbnail extraction when called before metadata analysis. Thanks to Albert Astalis Cid. * LibRaw 0.6.4 Release 2008-12-11 Alex Tutubalin * Imported new edition of dcraw 8.89 (version 1.409) * Nikon NEF decoding changed * LibRaw 0.6.3 Release 2008-12-03 Alex Tutubalin * fixed bug in Panasonic .RW2 processing (only for thread-safe version, single-threaded version was not affected) * All client code should be recompiled * LibRaw 0.6.2 Release 2008-12-03 Alex Tutubalin * Imported dcraw 8.89 (version 1.407) * New cameras: Canon G10 & 5D Mk2, Leaf AFi 7, Leica D-LUX4, Panasonic FX150 & G1, Fujifilm IS Pro, * Changed camera support (color conversion tables): Canon 50D, Nikon D90 & P6000, Panasonic LX3 & FZ28, Sony A900 * LibRaw 0.6.2 beta 2008-09-25 Alex Tutubalin * Added new data field float LibRaw::imgdata.color.cam_xyz[4][3]. This field contains constant table (different for each camera) for Camera RGB->XYZ conversion. * All client code should be recompiled * LibRaw 0.6.1 Release 2008-09-18 Alex Tutubalin * dcraw 8.88 imported: - new cameras (Canon 50D, Sony A900, Nikon D90 & P6000, Panasonic LX3 FZ28) - new method of black point subtraction for Canon cameras, preliminary banding suppression. * Stack memory usage lowered (some thread data moved to dynamic memory) * some patches for MSVC compatibility * LibRaw 0.6.0 Release 2008-09-16 Alex Tutubalin * Enum definitions changed to make gcc -pedantic happy * Compiler/preprocessor flags does not affects LibRaw class field set (i.e. structure for thread local storage is always allocated) * Default library compilation mode (i.e. sources imported in another project) is thread-safe 2008-09-14 Alex Tutubalin * OpenMP support for most CPU consuming steps of processing: ahd_interpolation. wavelet_denoise 10-30% speed-up of full processing pipe on 2-core CPU OpenMP supported only on gcc (Linux/FreeBSD and Mac OS X) * LibRaw 0.6.0-Beta-1 2008-09-10 Alex Tutubalin * All set_**handler accepts additional void* pointer, which should point to callback private data. This pointer passed to user callback when it called. * LibRaw 0.6.0-alpha5 * All client code should be recompiled 2008-09-10 Alex Tutubalin * New processing stages in enum LibRaw_progress: LIBRAW_PROGRESS_BAD_PIXELS LIBRAW_PROGRESS_DARK_FRAME (reserved stages LIBRAW_PROGRESS_RESERVED_PRE1-PRE2 has removed) * libraw_strprogress() - convert progress code into string * Added progress/cancellation user callbacks + new fatal error code: CANCELLED_BY_CALLBACK + sample usage in samples/dcraw_emu.cpp (try run it with -v -v -v opts) * LibRaw 0.6.0-alpha4 * All client code should be recompiled 2008-09-08 Alex Tutubalin * ICC-profiles support (same as in dcraw) + input/output profiles (specified as path to 'icc' file or 'embed' for embedded input profile) + additional warnings + LCMS library used * support of bad pixel map (caller should specify path to bad pixel file in dcraw-compatible format) * dark frame subtraction support (caller should supply path to 16-bit PGM map). samples/simple_dcraw.cpp - -4 option added for dark frame file generation * support of bad pixeld map (dcraw-compatible format) * the dcraw_emu sample supports all new features (ICC, dark frame, bad pixels) * libraw/libraw_version.h, defines, calls and macros for version checks: + LibRaw::version(), LibRaw::versionNumber(), LIBRAW_CHECK_VERSION() * List of supported cameras: + LibRaw::cameraCount() + LibRaw::cameraList() * fixed error in adjust_sizes_info_only * documentation changes * LibRaw 0.6.0-alpha3 2008-09-07 Alex Tutubalin * samples/mem_image.c - bitwise equal output with dcraw -4 (PPMs outputted with network byte order) * LibRaw 0.6.0-alpha2 2008-09-06 Alex Tutubalin * Added calls dcraw_make_mem_image and dcraw_make_mem_image: + functions (and supporting code) + documentation changed + new sample code samples/mem_image.cpp * Added processing parameter LibRaw::imgdata.params.gamma_16bit (set to 1 to make gamma correction for 16-bit output) * LibRaw 0.6.0-alpha1 2008-08-28 Alex Tutubalin * dcraw 1.404 (8.87) imported: - 6 new cameras supported (Canon 1000D, A720, SD300; Nikon D700, Oly E-520,Kodak C603) * Licensing changed to GPL v2 2008-05-02 Alex Tutubalin * mmap/malloc+read IO-layer removed due to no performance gain. FILE I/O returned 2008-05-02 Alex Tutubalin * dcraw 1.403 imported - changes in ljpeg decompression (index values cut to 12 bit) - changes in parse_foveon() jpeg thumbnail extraction * LibRaw 0.5.3 released 2008-04-24 Alex Tutubalin * Linux build of samples/identify fixed * documentation editorial * LibRaw 0.5.2 released 2008-04-21 Alex Tutubalin * All documentation translated to English * English changelog started :) * minor bug (include path) fixed in samples/half_mt * LibRaw 0.5.1 released LibRaw-0.21.4/DEVELOPER-NOTES000066400000000000000000000012111477673233700151320ustar00rootroot00000000000000 === Notes for LibRaw contributor === 0. Repository LibRaw public repository is located on GitHub URL: http://github.com/LibRaw/LibRaw - main page git://github.com/LibRaw/LibRaw.git - git URL If you wish to participate in LibRaw development please use GitHub fork. LibRaw distribution files are prepared by ./mkdist.sh script This script - generates ./configure script from autotools stuff - removes developer Makefile - fetches 'Official' dcraw.c from Dave Coffin's site - removes itself Feel free to contact us (info@libraw.org or Contact form on www.libraw.org) if you have any questions or suggestions. LibRaw-0.21.4/GoPro/000077500000000000000000000000001477673233700140275ustar00rootroot00000000000000LibRaw-0.21.4/GoPro/dng-sdk-1_4-allow-VC5-validate.diff000066400000000000000000000006741477673233700220760ustar00rootroot00000000000000diff --git a/source/dng_ifd.cpp b/source/dng_ifd.cpp index 174f18f..2974323 100644 --- a/source/dng_ifd.cpp +++ b/source/dng_ifd.cpp @@ -3168,6 +3168,7 @@ bool dng_ifd::IsValidDNG (dng_shared &shared, case ccUncompressed: break; + case 9: /* VC5 compression support */ case ccJPEG: { @@ -3202,7 +3203,7 @@ bool dng_ifd::IsValidDNG (dng_shared &shared, break; } - + case ccLossyJPEG: { LibRaw-0.21.4/GoPro/dng-sdk-1_6-hide-ccVc5-definitiion.diff000066400000000000000000000010241477673233700227370ustar00rootroot00000000000000diff --git a/gpr_sdk/private/gpr_read_image.cpp b/gpr_sdk/private/gpr_read_image.cpp index c611b3f..9200a5b 100644 --- a/gpr_sdk/private/gpr_read_image.cpp +++ b/gpr_sdk/private/gpr_read_image.cpp @@ -68,8 +68,10 @@ gpr_read_image::gpr_read_image( gpr_buffer_auto* vc5_buffer ) : _vc5_buffer(vc5_ } #if GPR_WRITING || GPR_READING +#ifndef qDNG_1_6 const int ccVc5 = 9; // Vc5 compression type #endif +#endif void gpr_read_image::ReadTile (dng_host &host, const dng_ifd &ifd, LibRaw-0.21.4/GoPro/dng-sdk-allow-VC5-validate.diff000066400000000000000000000006741477673233700215150ustar00rootroot00000000000000diff --git a/source/dng_ifd.cpp b/source/dng_ifd.cpp index 174f18f..2974323 100644 --- a/source/dng_ifd.cpp +++ b/source/dng_ifd.cpp @@ -3168,6 +3168,7 @@ bool dng_ifd::IsValidDNG (dng_shared &shared, case ccUncompressed: break; + case 9: /* VC5 compression support */ case ccJPEG: { @@ -3202,7 +3203,7 @@ bool dng_ifd::IsValidDNG (dng_shared &shared, break; } - + case ccLossyJPEG: { LibRaw-0.21.4/GoPro/gpr_read_image.cpp.diff000066400000000000000000000022051477673233700203660ustar00rootroot00000000000000--- gpr_read_image.cpp.orig 2019-08-30 12:20:00.326653300 +0300 +++ gpr_read_image.cpp 2019-08-31 10:43:26.568184100 +0300 @@ -67,6 +67,10 @@ fDecodeVC5 = true; } void gpr_read_image::ReadTile (dng_host &host, const dng_ifd &ifd, dng_stream &stream, @@ -77,7 +81,8 @@ uint32 tileByteCount, AutoPtr &compressedBuffer, AutoPtr &uncompressedBuffer, - AutoPtr &subTileBlockBuffer) + AutoPtr &subTileBlockBuffer, + bool usingMultipleThreads) { if( ifd.fCompression == ccVc5 ) @@ -122,7 +127,8 @@ tileByteCount, compressedBuffer, uncompressedBuffer, - subTileBlockBuffer); + subTileBlockBuffer, + usingMultipleThreads); } } LibRaw-0.21.4/GoPro/gpr_read_image.h.diff000066400000000000000000000010011477673233700200240ustar00rootroot00000000000000--- gpr_read_image.h.orig 2019-08-30 12:20:00.326653300 +0300 +++ gpr_read_image.h 2019-08-30 20:56:11.138246800 +0300 @@ -56,7 +56,8 @@ uint32 tileByteCount, AutoPtr &compressedBuffer, AutoPtr &uncompressedBuffer, - AutoPtr &subTileBlockBuffer); + AutoPtr &subTileBlockBuffer, + bool usingMultipleThreads ); }; #endif // GPR_READING LibRaw-0.21.4/INSTALL000066400000000000000000000021161477673233700140320ustar00rootroot00000000000000 ========= Installing LibRaw ======== I. Installation steps 1. Unpack the distribution file: $ tar xzvf LibRaw-0.xx.yy.tar.gz 2. Go to LibRaw folder and run ./configure and make: $ cd LibRaw-0.xx.yy $ ./configure [...optional args...] $ make 3. install by run make install as root: $ sudo make install If you're using Github snapshot, create ./configure script: autoreconf --install before using it (you'll need autotools installed). Alternatively, you may use pre-created Makefiles (Makefile.dist for Unix, Makefile.msvc for Windows/VisualStudio) and add/remove options by editing these Makefiles II. ./configure options --enable-openmp --disable-openmp Enable/disable OpenMP support if compiler supports it. OpenMP is enabled by default. --enable-lcms --disable-lcms Enable/disable LCMS color engine support. If enabled, ./configure will try to find lcms library. Both LCMS-1.x and LCMS-2.x are supported LCMS support is enabled by default --enable-examples --disable-examples Enables/disables examples compilation and installation. Enabled by default LibRaw-0.21.4/LICENSE.CDDL000066400000000000000000000410121477673233700145110ustar00rootroot00000000000000COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 1. Definitions. 1.1. Contributor means each individual or entity that creates or contributes to the creation of Modifications. 1.2. Contributor Version means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. 1.3. Covered Software means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. 1.4. Executable means the Covered Software in any form other than Source Code. 1.5. Initial Developer means the individual or entity that first makes Original Software available under this License. 1.6. Larger Workmeans a work which combines Covered Software or portions thereof with code not governed by the terms of this License. 1.7. License means this document. 1.8. Licensable means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. 1.9. Modifications means the Source Code and Executable form of any of the following: A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; B. Any new file that contains any part of the Original Software or previous Modification; or C. Any new file that is contributed or otherwise made available under the terms of this License. 1.10. Original Software means the Source Code and Executable form of computer software code that is originally released under this License. 1.11. Patent Claims means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. 1.12. Source Code means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. 1.13. You (or Your) means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, You includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, control means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants. 2.1. The Initial Developer Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof); (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License; (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. 2.2. Contributor Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). (c) The licenses granted in Sections 2.2(a) and 2.2(b) areeffective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. 3. Distribution Obligations. 3.1. Availability of Source Code. Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. 3.2. Modifications. The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. 3.3. Required Notices. You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. 3.4. Application of Additional Terms. You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. 3.5. Distribution of Executable Versions. You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipients rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. 3.6. Larger Works. You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. 4. Versions of the License. 4.1. New Versions. Sun Microsystems, Inc. is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. 4.2. Effect of New Versions. You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. 4.3. Modified Versions. When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. 5. DISCLAIMER OF WARRANTY. COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN AS IS BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 6. TERMINATION. 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as Participant) alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. 6.3. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. 7. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTYS NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 8. U.S. GOVERNMENT END USERS. The Covered Software is a commercial item, as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of commercial computer software (as that term is defined at 48 C.F.R. 252.227-7014(a)(1)) and commercial computer software documentation as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. 9. MISCELLANEOUS. This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdictions conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. 10. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. ---------------------------------------------------------------- NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL): This code is released under the CDDL and shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California. ---------------------------------------------------------------- LibRaw-0.21.4/LICENSE.LGPL000066400000000000000000000575051477673233700145570ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS LibRaw-0.21.4/LibRaw.pro000066400000000000000000000007451477673233700147110ustar00rootroot00000000000000TEMPLATE=subdirs CONFIG+=ordered SUBDIRS= \ buildfiles/dcraw_emu.pro \ buildfiles/libraw.pro \ buildfiles/postprocessing_benchmark.pro \ buildfiles/dcraw_half.pro \ # buildfiles/half_mt.pro \ buildfiles/mem_image.pro \ buildfiles/raw-identify.pro \ buildfiles/simple_dcraw.pro \ buildfiles/multirender_test.pro \ buildfiles/unprocessed_raw.pro \ buildfiles/4channels.pro \ buildfiles/rawtextdump.pro \ buildfiles/openbayer_sample.pro CONFIG-=qt LibRaw-0.21.4/LibRaw.sln000066400000000000000000000170321477673233700147020ustar00rootroot00000000000000Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30011.22 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dcraw_emu", "buildfiles\dcraw_emu.vcxproj", "{48688DB8-559A-3DE2-ADDE-5BD27BFEDDA2}" ProjectSection(ProjectDependencies) = postProject {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libraw", "buildfiles\libraw.vcxproj", "{A71D2131-F425-381F-8A9A-29D60132A046}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "postprocessing_benchmark", "buildfiles\postprocessing_benchmark.vcxproj", "{5C66A8FA-D211-3E2F-A2F1-0C3C665689CC}" ProjectSection(ProjectDependencies) = postProject {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dcraw_half", "buildfiles\dcraw_half.vcxproj", "{C6EACFA3-9FC5-393B-BCF6-2874B05E4581}" ProjectSection(ProjectDependencies) = postProject {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mem_image", "buildfiles\mem_image.vcxproj", "{BF8A2750-B847-3BA6-9EAF-05F43380F46C}" ProjectSection(ProjectDependencies) = postProject {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raw-identify", "buildfiles\raw-identify.vcxproj", "{7C4F61DB-717E-36C9-B20E-36F8E218AB51}" ProjectSection(ProjectDependencies) = postProject {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_dcraw", "buildfiles\simple_dcraw.vcxproj", "{AD1E31D8-A022-3672-982F-C8280A0D6458}" ProjectSection(ProjectDependencies) = postProject {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multirender_test", "buildfiles\multirender_test.vcxproj", "{30D21208-219A-3AA8-ADCF-E6B1FFAF6A73}" ProjectSection(ProjectDependencies) = postProject {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unprocessed_raw", "buildfiles\unprocessed_raw.vcxproj", "{1333E21E-D3B5-3640-9A4D-D8955082B855}" ProjectSection(ProjectDependencies) = postProject {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "4channels", "buildfiles\4channels.vcxproj", "{F68CBE78-B27A-3A05-BCD3-293E8CAC1C52}" ProjectSection(ProjectDependencies) = postProject {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rawtextdump", "buildfiles\rawtextdump.vcxproj", "{53A1E3F0-8032-348E-B3BF-3E540A45005F}" ProjectSection(ProjectDependencies) = postProject {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openbayer_sample", "buildfiles\openbayer_sample.vcxproj", "{EF67FEF1-4B19-3765-A660-9F8E9333DEF3}" ProjectSection(ProjectDependencies) = postProject {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {48688DB8-559A-3DE2-ADDE-5BD27BFEDDA2}.Debug|x64.ActiveCfg = Debug|x64 {48688DB8-559A-3DE2-ADDE-5BD27BFEDDA2}.Debug|x64.Build.0 = Debug|x64 {48688DB8-559A-3DE2-ADDE-5BD27BFEDDA2}.Release|x64.ActiveCfg = Release|x64 {48688DB8-559A-3DE2-ADDE-5BD27BFEDDA2}.Release|x64.Build.0 = Release|x64 {A71D2131-F425-381F-8A9A-29D60132A046}.Debug|x64.ActiveCfg = Debug|x64 {A71D2131-F425-381F-8A9A-29D60132A046}.Debug|x64.Build.0 = Debug|x64 {A71D2131-F425-381F-8A9A-29D60132A046}.Release|x64.ActiveCfg = Release|x64 {A71D2131-F425-381F-8A9A-29D60132A046}.Release|x64.Build.0 = Release|x64 {5C66A8FA-D211-3E2F-A2F1-0C3C665689CC}.Debug|x64.ActiveCfg = Debug|x64 {5C66A8FA-D211-3E2F-A2F1-0C3C665689CC}.Debug|x64.Build.0 = Debug|x64 {5C66A8FA-D211-3E2F-A2F1-0C3C665689CC}.Release|x64.ActiveCfg = Release|x64 {5C66A8FA-D211-3E2F-A2F1-0C3C665689CC}.Release|x64.Build.0 = Release|x64 {C6EACFA3-9FC5-393B-BCF6-2874B05E4581}.Debug|x64.ActiveCfg = Debug|x64 {C6EACFA3-9FC5-393B-BCF6-2874B05E4581}.Debug|x64.Build.0 = Debug|x64 {C6EACFA3-9FC5-393B-BCF6-2874B05E4581}.Release|x64.ActiveCfg = Release|x64 {C6EACFA3-9FC5-393B-BCF6-2874B05E4581}.Release|x64.Build.0 = Release|x64 {BF8A2750-B847-3BA6-9EAF-05F43380F46C}.Debug|x64.ActiveCfg = Debug|x64 {BF8A2750-B847-3BA6-9EAF-05F43380F46C}.Debug|x64.Build.0 = Debug|x64 {BF8A2750-B847-3BA6-9EAF-05F43380F46C}.Release|x64.ActiveCfg = Release|x64 {BF8A2750-B847-3BA6-9EAF-05F43380F46C}.Release|x64.Build.0 = Release|x64 {7C4F61DB-717E-36C9-B20E-36F8E218AB51}.Debug|x64.ActiveCfg = Debug|x64 {7C4F61DB-717E-36C9-B20E-36F8E218AB51}.Debug|x64.Build.0 = Debug|x64 {7C4F61DB-717E-36C9-B20E-36F8E218AB51}.Release|x64.ActiveCfg = Release|x64 {7C4F61DB-717E-36C9-B20E-36F8E218AB51}.Release|x64.Build.0 = Release|x64 {AD1E31D8-A022-3672-982F-C8280A0D6458}.Debug|x64.ActiveCfg = Debug|x64 {AD1E31D8-A022-3672-982F-C8280A0D6458}.Debug|x64.Build.0 = Debug|x64 {AD1E31D8-A022-3672-982F-C8280A0D6458}.Release|x64.ActiveCfg = Release|x64 {AD1E31D8-A022-3672-982F-C8280A0D6458}.Release|x64.Build.0 = Release|x64 {30D21208-219A-3AA8-ADCF-E6B1FFAF6A73}.Debug|x64.ActiveCfg = Debug|x64 {30D21208-219A-3AA8-ADCF-E6B1FFAF6A73}.Debug|x64.Build.0 = Debug|x64 {30D21208-219A-3AA8-ADCF-E6B1FFAF6A73}.Release|x64.ActiveCfg = Release|x64 {30D21208-219A-3AA8-ADCF-E6B1FFAF6A73}.Release|x64.Build.0 = Release|x64 {1333E21E-D3B5-3640-9A4D-D8955082B855}.Debug|x64.ActiveCfg = Debug|x64 {1333E21E-D3B5-3640-9A4D-D8955082B855}.Debug|x64.Build.0 = Debug|x64 {1333E21E-D3B5-3640-9A4D-D8955082B855}.Release|x64.ActiveCfg = Release|x64 {1333E21E-D3B5-3640-9A4D-D8955082B855}.Release|x64.Build.0 = Release|x64 {F68CBE78-B27A-3A05-BCD3-293E8CAC1C52}.Debug|x64.ActiveCfg = Debug|x64 {F68CBE78-B27A-3A05-BCD3-293E8CAC1C52}.Debug|x64.Build.0 = Debug|x64 {F68CBE78-B27A-3A05-BCD3-293E8CAC1C52}.Release|x64.ActiveCfg = Release|x64 {F68CBE78-B27A-3A05-BCD3-293E8CAC1C52}.Release|x64.Build.0 = Release|x64 {53A1E3F0-8032-348E-B3BF-3E540A45005F}.Debug|x64.ActiveCfg = Debug|x64 {53A1E3F0-8032-348E-B3BF-3E540A45005F}.Debug|x64.Build.0 = Debug|x64 {53A1E3F0-8032-348E-B3BF-3E540A45005F}.Release|x64.ActiveCfg = Release|x64 {53A1E3F0-8032-348E-B3BF-3E540A45005F}.Release|x64.Build.0 = Release|x64 {EF67FEF1-4B19-3765-A660-9F8E9333DEF3}.Debug|x64.ActiveCfg = Debug|x64 {EF67FEF1-4B19-3765-A660-9F8E9333DEF3}.Debug|x64.Build.0 = Debug|x64 {EF67FEF1-4B19-3765-A660-9F8E9333DEF3}.Release|x64.ActiveCfg = Release|x64 {EF67FEF1-4B19-3765-A660-9F8E9333DEF3}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {FB319846-66B9-4F61-8285-5EA4D2F09634} EndGlobalSection EndGlobal LibRaw-0.21.4/Makefile.am000066400000000000000000000120641477673233700150400ustar00rootroot00000000000000# autoconf macros ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS=subdir-objects LIBRAW_SHLIB_VER = @LIBRAW_SHLIB_VERSION@ LIBRAW_RELEASE_VER = @LIBRAW_RELEASE_VERSION@ # Headers nobase_include_HEADERS = libraw/libraw.h \ libraw/libraw_alloc.h \ libraw/libraw_const.h \ libraw/libraw_datastream.h \ libraw/libraw_internal.h \ libraw/libraw_types.h \ libraw/libraw_version.h # Docs doc_DATA = COPYRIGHT \ LICENSE.CDDL \ LICENSE.LGPL \ Changelog.txt # pkg-config .pc files pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libraw.pc libraw_r.pc # Libraries lib_LTLIBRARIES = lib/libraw.la lib/libraw_r.la lib_libraw_a_CPPFLAGS = -DLIBRAW_NOTHREADS -w lib_libraw_a_SOURCES = src/libraw_c_api.cpp \ src/libraw_datastream.cpp src/decoders/canon_600.cpp \ src/decoders/crx.cpp src/decoders/decoders_dcraw.cpp \ src/decoders/decoders_libraw_dcrdefs.cpp \ src/decoders/decoders_libraw.cpp src/decoders/dng.cpp \ src/decoders/fp_dng.cpp src/decoders/fuji_compressed.cpp \ src/decoders/generic.cpp src/decoders/kodak_decoders.cpp \ src/decoders/load_mfbacks.cpp src/decoders/smal.cpp \ src/decoders/unpack_thumb.cpp src/decoders/unpack.cpp \ src/demosaic/aahd_demosaic.cpp src/demosaic/ahd_demosaic.cpp \ src/demosaic/dcb_demosaic.cpp src/demosaic/dht_demosaic.cpp \ src/demosaic/misc_demosaic.cpp src/demosaic/xtrans_demosaic.cpp \ src/integration/dngsdk_glue.cpp src/integration/rawspeed_glue.cpp\ src/metadata/adobepano.cpp src/metadata/canon.cpp \ src/metadata/ciff.cpp src/metadata/cr3_parser.cpp \ src/metadata/epson.cpp src/metadata/exif_gps.cpp \ src/metadata/fuji.cpp src/metadata/identify_tools.cpp \ src/metadata/identify.cpp src/metadata/kodak.cpp \ src/metadata/leica.cpp src/metadata/makernotes.cpp \ src/metadata/mediumformat.cpp src/metadata/minolta.cpp \ src/metadata/misc_parsers.cpp src/metadata/nikon.cpp \ src/metadata/normalize_model.cpp src/metadata/olympus.cpp \ src/metadata/hasselblad_model.cpp \ src/metadata/p1.cpp src/metadata/pentax.cpp src/metadata/samsung.cpp \ src/metadata/sony.cpp src/metadata/tiff.cpp \ src/postprocessing/aspect_ratio.cpp \ src/postprocessing/dcraw_process.cpp src/postprocessing/mem_image.cpp \ src/postprocessing/postprocessing_aux.cpp \ src/postprocessing/postprocessing_utils_dcrdefs.cpp \ src/postprocessing/postprocessing_utils.cpp \ src/preprocessing/ext_preprocess.cpp src/preprocessing/raw2image.cpp \ src/preprocessing/subtract_black.cpp src/tables/cameralist.cpp \ src/tables/colorconst.cpp src/tables/colordata.cpp \ src/tables/wblists.cpp src/utils/curves.cpp \ src/utils/decoder_info.cpp src/utils/init_close_utils.cpp \ src/utils/open.cpp src/utils/phaseone_processing.cpp \ src/utils/read_utils.cpp src/utils/thumb_utils.cpp \ src/utils/utils_dcraw.cpp src/utils/utils_libraw.cpp \ src/write/apply_profile.cpp src/write/file_write.cpp \ src/write/tiff_writer.cpp src/x3f/x3f_parse_process.cpp \ src/x3f/x3f_utils_patched.cpp lib_libraw_r_a_CXXFLAGS = -pthread -w lib_libraw_r_a_CFLAGS = -pthread -w lib_libraw_la_SOURCES = $(lib_libraw_a_SOURCES) lib_libraw_r_la_SOURCES = $(lib_libraw_a_SOURCES) lib_libraw_la_LDFLAGS = -no-undefined -version-info $(LIBRAW_SHLIB_VER) lib_libraw_r_la_LDFLAGS = -no-undefined -version-info $(LIBRAW_SHLIB_VER) # Sample binaries if EXAMPLES bin_PROGRAMS = bin/raw-identify \ bin/unprocessed_raw \ bin/4channels \ bin/rawtextdump \ bin/simple_dcraw \ bin/mem_image \ bin/dcraw_half \ bin/half_mt \ bin/multirender_test \ bin/postprocessing_benchmark \ bin/dcraw_emu endif bin_raw_identify_SOURCES = samples/raw-identify.cpp bin_raw_identify_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) bin_raw_identify_LDADD = lib/libraw.la bin_unprocessed_raw_SOURCES = samples/unprocessed_raw.cpp bin_unprocessed_raw_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) bin_unprocessed_raw_LDADD = lib/libraw.la bin_rawtextdump_SOURCES = samples/rawtextdump.cpp bin_rawtextdump_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) bin_rawtextdump_LDADD = lib/libraw.la bin_4channels_SOURCES = samples/4channels.cpp bin_4channels_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) bin_4channels_LDADD = lib/libraw.la bin_simple_dcraw_SOURCES = samples/simple_dcraw.cpp bin_simple_dcraw_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) bin_simple_dcraw_LDADD = lib/libraw.la bin_multirender_test_SOURCES = samples/multirender_test.cpp bin_multirender_test_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) bin_multirender_test_LDADD = lib/libraw.la bin_postprocessing_benchmark_SOURCES = samples/postprocessing_benchmark.cpp bin_postprocessing_benchmark_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) bin_postprocessing_benchmark_LDADD = lib/libraw.la bin_mem_image_SOURCES = samples/mem_image_sample.cpp bin_mem_image_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) bin_mem_image_LDADD = lib/libraw.la bin_dcraw_half_SOURCES = samples/dcraw_half.c bin_dcraw_half_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) bin_dcraw_half_LDADD = lib/libraw.la bin_half_mt_SOURCES = samples/half_mt.c bin_half_mt_CFLAGS = $(lib_libraw_r_a_CXXFLAGS) bin_half_mt_LDADD = lib/libraw_r.la bin_dcraw_emu_SOURCES = samples/dcraw_emu.cpp bin_dcraw_emu_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) bin_dcraw_emu_LDADD = lib/libraw.la LibRaw-0.21.4/Makefile.devel000066400000000000000000000727661477673233700155610ustar00rootroot00000000000000all: library all_samples CC=clang CXX=clang++ #CC=gcc #CXX=g++ LDADD+=-lz CFLAGS=-DLIBRAW_USE_AUTOPTR CFLAGS+= -g -I. -pedantic -Wno-long-long -Wno-overflow -O3 # macOS dual arch # CFLAGS+=-arch x86_64 -arch arm64 # RawSpeed Support # CFLAGS+=-DUSE_RAWSPEED -I../RawSpeed -I/opt/local/include/libxml2 # LDADD+=-L../RawSpeed/RawSpeed/release -lrawspeed -L/opt/local/include -ljpeg -lxml2 # RAWSPEED_DATA=../RawSpeed/data/cameras.xml # RawSpeed3 Support #CFLAGS+=-DUSE_RAWSPEED3 -DUSE_RAWSPEED_BITS -I./RawSpeed3/ #LDADD+=-L../RawSpeed-v3/release -lrawspeed3 -L/usr/local/lib -ljpeg -lz # DNG SDK Support # CFLAGS+=-DUSE_DNGSDK -I../dng_sdk/source # LDADDD+=-L../dng_sdk/release -ldng -ljpeg -lz # LCMS support # For lcms2 set -DUSE_LCMS2 #CFLAGS+=-DUSE_LCMS2 -I/opt/local/include #LDADD+=-L/opt/local/lib -llcms # Jasper support for RedCine #CFLAGS+=-DUSE_JASPER -I/opt/local/include #LDADD+=-L/opt/local/lib -ljasper # ZLIB support (FP dng) CFLAGS+=-DUSE_ZLIB LDADD+=-lz # JPEG support for DNG and Kodak CFLAGS+=-DUSE_JPEG -I/usr/local/include LDADD+=-L/usr/local/lib -ljpeg # LIBJPEG8: CFLAGS+=-DUSE_JPEG8 CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS HEADERS=libraw/libraw.h libraw/libraw_alloc.h libraw/libraw_const.h \ libraw/libraw_datastream.h libraw/libraw_internal.h \ libraw/libraw_types.h libraw/libraw_version.h \ internal/dcraw_defs.h internal/dcraw_fileio_defs.h internal/defines.h \ internal/dmp_include.h internal/libraw_cameraids.h internal/libraw_cxx_defs.h \ internal/libraw_internal_funcs.h internal/var_defines.h internal/x3f_tools.h LIB_OBJECTS= object/libraw_datastream.o object/libraw_c_api.o \ object/cameralist.o object/fuji_compressed.o \ object/crx.o object/fp_dng.o object/decoders_libraw.o \ object/unpack.o object/unpack_thumb.o \ object/rawspeed_glue.o object/dngsdk_glue.o \ object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ object/decoder_info.o object/open.o object/phaseone_processing.o \ object/thumb_utils.o \ object/tiff_writer.o object/subtract_black.o object/postprocessing_utils.o \ object/dcraw_process.o object/raw2image.o object/mem_image.o \ object/x3f_utils_patched.o object/x3f_parse_process.o \ object/read_utils.o object/curves.o object/utils_dcraw.o \ object/colordata.o \ object/canon_600.o object/decoders_dcraw.o \ object/decoders_libraw_dcrdefs.o object/generic.o \ object/kodak_decoders.o object/dng.o object/smal.o \ object/load_mfbacks.o \ object/sony.o object/nikon.o object/samsung.o object/cr3_parser.o \ object/canon.o object/epson.o object/olympus.o object/leica.o \ object/fuji.o object/adobepano.o object/pentax.o object/p1.o \ object/makernotes.o object/exif_gps.o object/kodak.o \ object/tiff.o object/ciff.o object/mediumformat.o object/minolta.o \ object/identify_tools.o \ object/hasselblad_model.o object/normalize_model.o object/identify.o \ object/misc_parsers.o object/wblists.o \ object/postprocessing_aux.o object/postprocessing_utils_dcrdefs.o \ object/aspect_ratio.o \ object/misc_demosaic.o object/xtrans_demosaic.o object/ahd_demosaic.o \ object/dht_demosaic.o object/aahd_demosaic.o object/dcb_demosaic.o \ object/file_write.o \ object/ext_preprocess.o object/apply_profile.o LIB_MT_OBJECTS= object/libraw_datastream.mt.o object/libraw_c_api.mt.o \ object/cameralist.mt.o object/fuji_compressed.mt.o \ object/crx.mt.o object/fp_dng.mt.o object/decoders_libraw.mt.o \ object/unpack.mt.o object/unpack_thumb.mt.o \ object/rawspeed_glue.mt.o object/dngsdk_glue.mt.o \ object/colorconst.mt.o object/utils_libraw.mt.o \ object/init_close_utils.mt.o \ object/decoder_info.mt.o object/open.mt.o object/phaseone_processing.mt.o \ object/thumb_utils.mt.o \ object/tiff_writer.mt.o object/subtract_black.mt.o \ object/postprocessing_utils.mt.o object/dcraw_process.mt.o \ object/raw2image.mt.o object/mem_image.mt.o \ object/x3f_utils_patched.mt.o object/x3f_parse_process.mt.o \ object/read_utils.mt.o object/curves.mt.o object/utils_dcraw.mt.o \ object/colordata.mt.o \ object/canon_600.mt.o object/decoders_dcraw.mt.o \ object/decoders_libraw_dcrdefs.mt.o object/generic.mt.o \ object/kodak_decoders.mt.o object/dng.mt.o object/smal.mt.o \ object/load_mfbacks.mt.o \ object/sony.mt.o object/nikon.mt.o object/samsung.mt.o \ object/cr3_parser.mt.o object/canon.mt.o object/epson.mt.o \ object/olympus.mt.o object/leica.mt.o \ object/fuji.mt.o object/adobepano.mt.o object/pentax.mt.o object/p1.mt.o \ object/makernotes.mt.o object/exif_gps.mt.o object/kodak.mt.o \ object/tiff.mt.o object/ciff.mt.o object/mediumformat.mt.o \ object/minolta.mt.o \ object/identify_tools.mt.o \ object/hasselblad_model.mt.o object/normalize_model.mt.o object/identify.mt.o \ object/misc_parsers.mt.o object/wblists.mt.o \ object/postprocessing_aux.mt.o object/postprocessing_utils_dcrdefs.mt.o \ object/aspect_ratio.mt.o \ object/misc_demosaic.mt.o object/xtrans_demosaic.mt.o \ object/ahd_demosaic.mt.o object/dht_demosaic.mt.o \ object/aahd_demosaic.mt.o object/dcb_demosaic.mt.o \ object/file_write.mt.o \ object/ext_preprocess.mt.o object/apply_profile.mt.o LR_INCLUDES=libraw/libraw.h libraw/libraw_alloc.h \ libraw/libraw_const.h libraw/libraw_datastream.h \ libraw/libraw_internal.h libraw/libraw_types.h \ libraw/libraw_version.h library: lib/libraw.a lib/libraw_r.a all_samples: bin/raw-identify bin/simple_dcraw bin/dcraw_emu \ bin/dcraw_half bin/half_mt bin/mem_image \ bin/unprocessed_raw bin/4channels bin/multirender_test \ bin/postprocessing_benchmark bin/rawtextdump ## RawSpeed xml file RawSpeed/rawspeed_xmldata.cpp: ${RAWSPEED_DATA} ./rsxml2c.sh ${RAWSPEED_DATA} > RawSpeed/rawspeed_xmldata.cpp ## Samples ## bin/raw-identify: lib/libraw.a samples/raw-identify.cpp $(HEADERS) $(CXX) ${CFLAGS} -o bin/raw-identify samples/raw-identify.cpp -L./lib -lraw -lm ${LDADD} bin/simple_dcraw: lib/libraw.a samples/simple_dcraw.cpp $(HEADERS) $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/simple_dcraw samples/simple_dcraw.cpp -L./lib -lraw -lm ${LDADD} bin/multirender_test: lib/libraw.a samples/multirender_test.cpp $(HEADERS) $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/multirender_test samples/multirender_test.cpp -L./lib -lraw -lm ${LDADD} bin/postprocessing_benchmark: lib/libraw.a samples/postprocessing_benchmark.cpp $(HEADERS) $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/postprocessing_benchmark samples/postprocessing_benchmark.cpp -L./lib -lraw -lm ${LDADD} bin/unprocessed_raw: lib/libraw.a samples/unprocessed_raw.cpp $(HEADERS) $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/unprocessed_raw samples/unprocessed_raw.cpp -L./lib -lraw -lm ${LDADD} bin/rawtextdump: lib/libraw.a samples/rawtextdump.cpp $(HEADERS) ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/rawtextdump samples/rawtextdump.cpp -L./lib -lraw -lm ${LDADD} bin/4channels: lib/libraw.a samples/4channels.cpp $(HEADERS) $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/4channels samples/4channels.cpp -L./lib -lraw -lm ${LDADD} bin/mem_image: lib/libraw.a samples/mem_image_sample.cpp $(HEADERS) $(CXX) ${CFLAGS} -o bin/mem_image samples/mem_image_sample.cpp -L./lib -lraw -lm ${LDADD} bin/dcraw_half: lib/libraw.a samples/dcraw_half.c $(HEADERS) $(CC) ${CFLAGS} -o bin/dcraw_half samples/dcraw_half.c -L./lib -lraw -lm -lstdc++ ${LDADD} bin/half_mt: lib/libraw_r.a samples/half_mt.c $(HEADERS) $(CC) -pthread ${CFLAGS} -o bin/half_mt samples/half_mt.c -L./lib -lraw_r -lm -lstdc++ ${LDADD} bin/dcraw_emu: lib/libraw.a samples/dcraw_emu.cpp $(HEADERS) $(CXX) ${CFLAGS} -o bin/dcraw_emu samples/dcraw_emu.cpp -L./lib -lraw_r -lm ${LDADD} lib/libraw.a: ${LIB_OBJECTS} rm -f lib/libraw.a ar crv lib/libraw.a ${LIB_OBJECTS} ranlib lib/libraw.a lib/libraw_r.a: ${LIB_MT_OBJECTS} rm -f lib/libraw_r.a ar crv lib/libraw_r.a ${LIB_MT_OBJECTS} ranlib lib/libraw_r.a clean: rm -fr bin/*.dSYM rm -f *.o *~ src/*~ samples/*~ internal/*~ libraw/*~ lib/lib*.a bin/[4a-z]* object/*.o object/*.mto dcraw/*~ doc/*~ bin/*~ src/*/*~ ## script-created rules object/libraw_c_api.o: src/libraw_c_api.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_c_api.o src/libraw_c_api.cpp object/libraw_c_api.mt.o: src/libraw_c_api.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/libraw_c_api.mt.o src/libraw_c_api.cpp object/libraw_datastream.o: src/libraw_datastream.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_datastream.o src/libraw_datastream.cpp object/libraw_datastream.mt.o: src/libraw_datastream.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/libraw_datastream.mt.o src/libraw_datastream.cpp object/canon_600.o: src/decoders/canon_600.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon_600.o src/decoders/canon_600.cpp object/canon_600.mt.o: src/decoders/canon_600.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/canon_600.mt.o src/decoders/canon_600.cpp object/crx.o: src/decoders/crx.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp object/crx.mt.o: src/decoders/crx.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/crx.mt.o src/decoders/crx.cpp object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp object/decoders_dcraw.mt.o: src/decoders/decoders_dcraw.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/decoders_dcraw.mt.o src/decoders/decoders_dcraw.cpp object/decoders_libraw_dcrdefs.o: src/decoders/decoders_libraw_dcrdefs.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw_dcrdefs.o src/decoders/decoders_libraw_dcrdefs.cpp object/decoders_libraw_dcrdefs.mt.o: src/decoders/decoders_libraw_dcrdefs.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/decoders_libraw_dcrdefs.mt.o src/decoders/decoders_libraw_dcrdefs.cpp object/decoders_libraw.o: src/decoders/decoders_libraw.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw.o src/decoders/decoders_libraw.cpp object/decoders_libraw.mt.o: src/decoders/decoders_libraw.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/decoders_libraw.mt.o src/decoders/decoders_libraw.cpp object/dng.o: src/decoders/dng.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dng.o src/decoders/dng.cpp object/dng.mt.o: src/decoders/dng.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/dng.mt.o src/decoders/dng.cpp object/fp_dng.o: src/decoders/fp_dng.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fp_dng.o src/decoders/fp_dng.cpp object/fp_dng.mt.o: src/decoders/fp_dng.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/fp_dng.mt.o src/decoders/fp_dng.cpp object/fuji_compressed.o: src/decoders/fuji_compressed.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji_compressed.o src/decoders/fuji_compressed.cpp object/fuji_compressed.mt.o: src/decoders/fuji_compressed.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/fuji_compressed.mt.o src/decoders/fuji_compressed.cpp object/generic.o: src/decoders/generic.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/generic.o src/decoders/generic.cpp object/generic.mt.o: src/decoders/generic.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/generic.mt.o src/decoders/generic.cpp object/kodak_decoders.o: src/decoders/kodak_decoders.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak_decoders.o src/decoders/kodak_decoders.cpp object/kodak_decoders.mt.o: src/decoders/kodak_decoders.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/kodak_decoders.mt.o src/decoders/kodak_decoders.cpp object/load_mfbacks.o: src/decoders/load_mfbacks.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/load_mfbacks.o src/decoders/load_mfbacks.cpp object/load_mfbacks.mt.o: src/decoders/load_mfbacks.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/load_mfbacks.mt.o src/decoders/load_mfbacks.cpp object/smal.o: src/decoders/smal.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/smal.o src/decoders/smal.cpp object/smal.mt.o: src/decoders/smal.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/smal.mt.o src/decoders/smal.cpp object/unpack_thumb.o: src/decoders/unpack_thumb.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack_thumb.o src/decoders/unpack_thumb.cpp object/unpack_thumb.mt.o: src/decoders/unpack_thumb.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/unpack_thumb.mt.o src/decoders/unpack_thumb.cpp object/unpack.o: src/decoders/unpack.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack.o src/decoders/unpack.cpp object/unpack.mt.o: src/decoders/unpack.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/unpack.mt.o src/decoders/unpack.cpp object/aahd_demosaic.o: src/demosaic/aahd_demosaic.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/aahd_demosaic.o src/demosaic/aahd_demosaic.cpp object/aahd_demosaic.mt.o: src/demosaic/aahd_demosaic.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/aahd_demosaic.mt.o src/demosaic/aahd_demosaic.cpp object/ahd_demosaic.o: src/demosaic/ahd_demosaic.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ahd_demosaic.o src/demosaic/ahd_demosaic.cpp object/ahd_demosaic.mt.o: src/demosaic/ahd_demosaic.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/ahd_demosaic.mt.o src/demosaic/ahd_demosaic.cpp object/dcb_demosaic.o: src/demosaic/dcb_demosaic.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcb_demosaic.o src/demosaic/dcb_demosaic.cpp object/dcb_demosaic.mt.o: src/demosaic/dcb_demosaic.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/dcb_demosaic.mt.o src/demosaic/dcb_demosaic.cpp object/dht_demosaic.o: src/demosaic/dht_demosaic.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dht_demosaic.o src/demosaic/dht_demosaic.cpp object/dht_demosaic.mt.o: src/demosaic/dht_demosaic.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/dht_demosaic.mt.o src/demosaic/dht_demosaic.cpp object/misc_demosaic.o: src/demosaic/misc_demosaic.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_demosaic.o src/demosaic/misc_demosaic.cpp object/misc_demosaic.mt.o: src/demosaic/misc_demosaic.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/misc_demosaic.mt.o src/demosaic/misc_demosaic.cpp object/xtrans_demosaic.o: src/demosaic/xtrans_demosaic.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/xtrans_demosaic.o src/demosaic/xtrans_demosaic.cpp object/xtrans_demosaic.mt.o: src/demosaic/xtrans_demosaic.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/xtrans_demosaic.mt.o src/demosaic/xtrans_demosaic.cpp object/dngsdk_glue.o: src/integration/dngsdk_glue.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dngsdk_glue.o src/integration/dngsdk_glue.cpp object/dngsdk_glue.mt.o: src/integration/dngsdk_glue.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/dngsdk_glue.mt.o src/integration/dngsdk_glue.cpp object/rawspeed_glue.o: src/integration/rawspeed_glue.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/rawspeed_glue.o src/integration/rawspeed_glue.cpp object/rawspeed_glue.mt.o: src/integration/rawspeed_glue.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/rawspeed_glue.mt.o src/integration/rawspeed_glue.cpp object/adobepano.o: src/metadata/adobepano.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/adobepano.o src/metadata/adobepano.cpp object/adobepano.mt.o: src/metadata/adobepano.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/adobepano.mt.o src/metadata/adobepano.cpp object/canon.o: src/metadata/canon.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon.o src/metadata/canon.cpp object/canon.mt.o: src/metadata/canon.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/canon.mt.o src/metadata/canon.cpp object/ciff.o: src/metadata/ciff.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ciff.o src/metadata/ciff.cpp object/ciff.mt.o: src/metadata/ciff.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/ciff.mt.o src/metadata/ciff.cpp object/cr3_parser.o: src/metadata/cr3_parser.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cr3_parser.o src/metadata/cr3_parser.cpp object/cr3_parser.mt.o: src/metadata/cr3_parser.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/cr3_parser.mt.o src/metadata/cr3_parser.cpp object/epson.o: src/metadata/epson.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/epson.o src/metadata/epson.cpp object/epson.mt.o: src/metadata/epson.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/epson.mt.o src/metadata/epson.cpp object/exif_gps.o: src/metadata/exif_gps.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/exif_gps.o src/metadata/exif_gps.cpp object/exif_gps.mt.o: src/metadata/exif_gps.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/exif_gps.mt.o src/metadata/exif_gps.cpp object/fuji.o: src/metadata/fuji.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji.o src/metadata/fuji.cpp object/fuji.mt.o: src/metadata/fuji.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/fuji.mt.o src/metadata/fuji.cpp object/identify_tools.o: src/metadata/identify_tools.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify_tools.o src/metadata/identify_tools.cpp object/identify_tools.mt.o: src/metadata/identify_tools.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/identify_tools.mt.o src/metadata/identify_tools.cpp object/identify.o: src/metadata/identify.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify.o src/metadata/identify.cpp object/identify.mt.o: src/metadata/identify.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/identify.mt.o src/metadata/identify.cpp object/kodak.o: src/metadata/kodak.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak.o src/metadata/kodak.cpp object/kodak.mt.o: src/metadata/kodak.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/kodak.mt.o src/metadata/kodak.cpp object/leica.o: src/metadata/leica.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/leica.o src/metadata/leica.cpp object/leica.mt.o: src/metadata/leica.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/leica.mt.o src/metadata/leica.cpp object/makernotes.o: src/metadata/makernotes.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/makernotes.o src/metadata/makernotes.cpp object/makernotes.mt.o: src/metadata/makernotes.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/makernotes.mt.o src/metadata/makernotes.cpp object/mediumformat.o: src/metadata/mediumformat.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mediumformat.o src/metadata/mediumformat.cpp object/mediumformat.mt.o: src/metadata/mediumformat.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/mediumformat.mt.o src/metadata/mediumformat.cpp object/minolta.o: src/metadata/minolta.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/minolta.o src/metadata/minolta.cpp object/minolta.mt.o: src/metadata/minolta.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/minolta.mt.o src/metadata/minolta.cpp object/misc_parsers.o: src/metadata/misc_parsers.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_parsers.o src/metadata/misc_parsers.cpp object/misc_parsers.mt.o: src/metadata/misc_parsers.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/misc_parsers.mt.o src/metadata/misc_parsers.cpp object/nikon.o: src/metadata/nikon.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/nikon.o src/metadata/nikon.cpp object/nikon.mt.o: src/metadata/nikon.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/nikon.mt.o src/metadata/nikon.cpp object/hasselblad_model.o: src/metadata/hasselblad_model.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/hasselblad_model.o src/metadata/hasselblad_model.cpp object/hasselblad_model.mt.o: src/metadata/hasselblad_model.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/hasselblad_model.mt.o src/metadata/hasselblad_model.cpp object/normalize_model.o: src/metadata/normalize_model.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/normalize_model.o src/metadata/normalize_model.cpp object/normalize_model.mt.o: src/metadata/normalize_model.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/normalize_model.mt.o src/metadata/normalize_model.cpp object/olympus.o: src/metadata/olympus.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/olympus.o src/metadata/olympus.cpp object/olympus.mt.o: src/metadata/olympus.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/olympus.mt.o src/metadata/olympus.cpp object/p1.o: src/metadata/p1.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/p1.o src/metadata/p1.cpp object/p1.mt.o: src/metadata/p1.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/p1.mt.o src/metadata/p1.cpp object/pentax.o: src/metadata/pentax.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pentax.o src/metadata/pentax.cpp object/pentax.mt.o: src/metadata/pentax.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/pentax.mt.o src/metadata/pentax.cpp object/samsung.o: src/metadata/samsung.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/samsung.o src/metadata/samsung.cpp object/samsung.mt.o: src/metadata/samsung.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/samsung.mt.o src/metadata/samsung.cpp object/sony.o: src/metadata/sony.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sony.o src/metadata/sony.cpp object/sony.mt.o: src/metadata/sony.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/sony.mt.o src/metadata/sony.cpp object/tiff.o: src/metadata/tiff.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff.o src/metadata/tiff.cpp object/tiff.mt.o: src/metadata/tiff.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/tiff.mt.o src/metadata/tiff.cpp object/aspect_ratio.o: src/postprocessing/aspect_ratio.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/aspect_ratio.o src/postprocessing/aspect_ratio.cpp object/aspect_ratio.mt.o: src/postprocessing/aspect_ratio.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/aspect_ratio.mt.o src/postprocessing/aspect_ratio.cpp object/dcraw_process.o: src/postprocessing/dcraw_process.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcraw_process.o src/postprocessing/dcraw_process.cpp object/dcraw_process.mt.o: src/postprocessing/dcraw_process.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/dcraw_process.mt.o src/postprocessing/dcraw_process.cpp object/mem_image.o: src/postprocessing/mem_image.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mem_image.o src/postprocessing/mem_image.cpp object/mem_image.mt.o: src/postprocessing/mem_image.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/mem_image.mt.o src/postprocessing/mem_image.cpp object/postprocessing_aux.o: src/postprocessing/postprocessing_aux.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_aux.o src/postprocessing/postprocessing_aux.cpp object/postprocessing_aux.mt.o: src/postprocessing/postprocessing_aux.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/postprocessing_aux.mt.o src/postprocessing/postprocessing_aux.cpp object/postprocessing_utils_dcrdefs.o: src/postprocessing/postprocessing_utils_dcrdefs.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_utils_dcrdefs.o src/postprocessing/postprocessing_utils_dcrdefs.cpp object/postprocessing_utils_dcrdefs.mt.o: src/postprocessing/postprocessing_utils_dcrdefs.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/postprocessing_utils_dcrdefs.mt.o src/postprocessing/postprocessing_utils_dcrdefs.cpp object/postprocessing_utils.o: src/postprocessing/postprocessing_utils.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_utils.o src/postprocessing/postprocessing_utils.cpp object/postprocessing_utils.mt.o: src/postprocessing/postprocessing_utils.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/postprocessing_utils.mt.o src/postprocessing/postprocessing_utils.cpp object/raw2image.o: src/preprocessing/raw2image.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/raw2image.o src/preprocessing/raw2image.cpp object/raw2image.mt.o: src/preprocessing/raw2image.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/raw2image.mt.o src/preprocessing/raw2image.cpp object/ext_preprocess.o: src/preprocessing/ext_preprocess.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ext_preprocess.o src/preprocessing/ext_preprocess.cpp object/ext_preprocess.mt.o: src/preprocessing/ext_preprocess.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/ext_preprocess.mt.o src/preprocessing/ext_preprocess.cpp object/subtract_black.o: src/preprocessing/subtract_black.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/subtract_black.o src/preprocessing/subtract_black.cpp object/subtract_black.mt.o: src/preprocessing/subtract_black.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/subtract_black.mt.o src/preprocessing/subtract_black.cpp object/cameralist.o: src/tables/cameralist.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cameralist.o src/tables/cameralist.cpp object/cameralist.mt.o: src/tables/cameralist.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/cameralist.mt.o src/tables/cameralist.cpp object/colorconst.o: src/tables/colorconst.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colorconst.o src/tables/colorconst.cpp object/colorconst.mt.o: src/tables/colorconst.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/colorconst.mt.o src/tables/colorconst.cpp object/colordata.o: src/tables/colordata.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colordata.o src/tables/colordata.cpp object/colordata.mt.o: src/tables/colordata.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/colordata.mt.o src/tables/colordata.cpp object/wblists.o: src/tables/wblists.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/wblists.o src/tables/wblists.cpp object/wblists.mt.o: src/tables/wblists.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/wblists.mt.o src/tables/wblists.cpp object/curves.o: src/utils/curves.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/curves.o src/utils/curves.cpp object/curves.mt.o: src/utils/curves.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/curves.mt.o src/utils/curves.cpp object/decoder_info.o: src/utils/decoder_info.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoder_info.o src/utils/decoder_info.cpp object/decoder_info.mt.o: src/utils/decoder_info.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/decoder_info.mt.o src/utils/decoder_info.cpp object/init_close_utils.o: src/utils/init_close_utils.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/init_close_utils.o src/utils/init_close_utils.cpp object/init_close_utils.mt.o: src/utils/init_close_utils.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/init_close_utils.mt.o src/utils/init_close_utils.cpp object/open.o: src/utils/open.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/open.o src/utils/open.cpp object/open.mt.o: src/utils/open.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/open.mt.o src/utils/open.cpp object/phaseone_processing.o: src/utils/phaseone_processing.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/phaseone_processing.o src/utils/phaseone_processing.cpp object/phaseone_processing.mt.o: src/utils/phaseone_processing.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/phaseone_processing.mt.o src/utils/phaseone_processing.cpp object/read_utils.o: src/utils/read_utils.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/read_utils.o src/utils/read_utils.cpp object/read_utils.mt.o: src/utils/read_utils.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/read_utils.mt.o src/utils/read_utils.cpp object/thumb_utils.o: src/utils/thumb_utils.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/thumb_utils.o src/utils/thumb_utils.cpp object/thumb_utils.mt.o: src/utils/thumb_utils.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/thumb_utils.mt.o src/utils/thumb_utils.cpp object/utils_dcraw.o: src/utils/utils_dcraw.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_dcraw.o src/utils/utils_dcraw.cpp object/utils_dcraw.mt.o: src/utils/utils_dcraw.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/utils_dcraw.mt.o src/utils/utils_dcraw.cpp object/utils_libraw.o: src/utils/utils_libraw.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_libraw.o src/utils/utils_libraw.cpp object/utils_libraw.mt.o: src/utils/utils_libraw.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/utils_libraw.mt.o src/utils/utils_libraw.cpp object/apply_profile.o: src/write/apply_profile.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/apply_profile.o src/write/apply_profile.cpp object/apply_profile.mt.o: src/write/apply_profile.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/apply_profile.mt.o src/write/apply_profile.cpp object/file_write.o: src/write/file_write.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/file_write.o src/write/file_write.cpp object/file_write.mt.o: src/write/file_write.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/file_write.mt.o src/write/file_write.cpp object/tiff_writer.o: src/write/tiff_writer.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff_writer.o src/write/tiff_writer.cpp object/tiff_writer.mt.o: src/write/tiff_writer.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/tiff_writer.mt.o src/write/tiff_writer.cpp object/x3f_parse_process.o: src/x3f/x3f_parse_process.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_parse_process.o src/x3f/x3f_parse_process.cpp object/x3f_parse_process.mt.o: src/x3f/x3f_parse_process.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/x3f_parse_process.mt.o src/x3f/x3f_parse_process.cpp object/x3f_utils_patched.o: src/x3f/x3f_utils_patched.cpp $(HEADERS) ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_utils_patched.o src/x3f/x3f_utils_patched.cpp object/x3f_utils_patched.mt.o: src/x3f/x3f_utils_patched.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/x3f_utils_patched.mt.o src/x3f/x3f_utils_patched.cpp LibRaw-0.21.4/Makefile.devel.nopp000066400000000000000000000275071477673233700165250ustar00rootroot00000000000000all: library all_samples CC=clang CXX=clang++ #CC=gcc #CXX=g++ LDADD+=-lz CFLAGS=-DLIBRAW_USE_AUTOPTR CFLAGS+= -g -I. -pedantic -Wno-long-long -Wno-overflow -O3 # RawSpeed Support # CFLAGS+=-DUSE_RAWSPEED -I../RawSpeed -I/opt/local/include/libxml2 # LDADD+=-L../RawSpeed/RawSpeed/release -lrawspeed -L/opt/local/include -ljpeg -lxml2 # RAWSPEED_DATA=../RawSpeed/data/cameras.xml # DNG SDK Support # CFLAGS+=-DUSE_DNGSDK -I../dng_sdk/source # LDADDD+=-L../dng_sdk/release -ldng -ljpeg -lz # LCMS support # For lcms2 set -DUSE_LCMS2 #CFLAGS+=-DUSE_LCMS2 -I/opt/local/include #LDADD+=-L/opt/local/lib -llcms # Jasper support for RedCine #CFLAGS+=-DUSE_JASPER -I/opt/local/include #LDADD+=-L/opt/local/lib -ljasper # JPEG support for DNG and Kodak CFLAGS+=-DUSE_JPEG -I/usr/local/include LDADD+=-L/usr/local/lib -ljpeg # LIBJPEG8: CFLAGS+=-DUSE_JPEG8 CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS LIB_OBJECTS= object/libraw_datastream.o \ object/cameralist.o object/fuji_compressed.o \ object/crx.o object/fp_dng.o object/decoders_libraw.o \ object/unpack.o object/unpack_thumb.o \ object/rawspeed_glue.o object/dngsdk_glue.o \ object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ object/decoder_info.o object/open.o object/phaseone_processing.o \ object/thumb_utils.o \ object/tiff_writer.o object/subtract_black.o \ object/raw2image.o \ object/x3f_utils_patched.o object/x3f_parse_process.o \ object/read_utils.o object/curves.o object/utils_dcraw.o \ object/colordata.o \ object/canon_600.o object/decoders_dcraw.o \ object/decoders_libraw_dcrdefs.o object/generic.o \ object/kodak_decoders.o object/dng.o object/smal.o \ object/load_mfbacks.o \ object/sony.o object/nikon.o object/samsung.o object/cr3_parser.o \ object/canon.o object/epson.o object/olympus.o object/leica.o \ object/fuji.o object/adobepano.o object/pentax.o object/p1.o \ object/makernotes.o object/exif_gps.o object/kodak.o \ object/tiff.o object/ciff.o object/mediumformat.o object/minolta.o \ object/identify_tools.o \ object/hasselblad_model.o object/normalize_model.o object/identify.o \ object/misc_parsers.o object/wblists.o \ object/file_write.o \ object/ext_preprocess.o \ object/postprocessing_ph.o \ LR_INCLUDES=libraw/libraw.h libraw/libraw_alloc.h \ libraw/libraw_const.h libraw/libraw_datastream.h \ libraw/libraw_internal.h libraw/libraw_types.h \ libraw/libraw_version.h LRLIB=lib/libraw_nopp.a library: $(LRLIB) all_samples: bin/raw-identify bin/unprocessed_raw bin/4channels ## Samples ## bin/raw-identify: $(LRLIB) samples/raw-identify.cpp $(CXX) ${CFLAGS} -o bin/raw-identify samples/raw-identify.cpp -L./lib -lraw_nopp -lm ${LDADD} bin/unprocessed_raw: $(LRLIB) samples/unprocessed_raw.cpp $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/unprocessed_raw samples/unprocessed_raw.cpp -L./lib -lraw_nopp -lm ${LDADD} bin/4channels: $(LRLIB) samples/4channels.cpp $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/4channels samples/4channels.cpp -L./lib -lraw_nopp -lm ${LDADD} $(LRLIB): ${LIB_OBJECTS} rm -f $(LRLIB) ar crv $(LRLIB) ${LIB_OBJECTS} ranlib $(LRLIB) clean: rm -fr bin/*.dSYM rm -f *.o *~ src/*~ samples/*~ internal/*~ libraw/*~ lib/lib*.a bin/[4a-z]* object/*.o dcraw/*~ doc/*~ bin/*~ src/*/*~ ## script-created rules object/libraw_c_api.o: src/libraw_c_api.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_c_api.o src/libraw_c_api.cpp object/libraw_datastream.o: src/libraw_datastream.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_datastream.o src/libraw_datastream.cpp object/canon_600.o: src/decoders/canon_600.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon_600.o src/decoders/canon_600.cpp object/crx.o: src/decoders/crx.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp object/decoders_libraw_dcrdefs.o: src/decoders/decoders_libraw_dcrdefs.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw_dcrdefs.o src/decoders/decoders_libraw_dcrdefs.cpp object/decoders_libraw.o: src/decoders/decoders_libraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw.o src/decoders/decoders_libraw.cpp object/dng.o: src/decoders/dng.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dng.o src/decoders/dng.cpp object/fp_dng.o: src/decoders/fp_dng.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fp_dng.o src/decoders/fp_dng.cpp object/fuji_compressed.o: src/decoders/fuji_compressed.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji_compressed.o src/decoders/fuji_compressed.cpp object/generic.o: src/decoders/generic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/generic.o src/decoders/generic.cpp object/kodak_decoders.o: src/decoders/kodak_decoders.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak_decoders.o src/decoders/kodak_decoders.cpp object/load_mfbacks.o: src/decoders/load_mfbacks.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/load_mfbacks.o src/decoders/load_mfbacks.cpp object/smal.o: src/decoders/smal.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/smal.o src/decoders/smal.cpp object/unpack_thumb.o: src/decoders/unpack_thumb.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack_thumb.o src/decoders/unpack_thumb.cpp object/unpack.o: src/decoders/unpack.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack.o src/decoders/unpack.cpp object/dngsdk_glue.o: src/integration/dngsdk_glue.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dngsdk_glue.o src/integration/dngsdk_glue.cpp object/rawspeed_glue.o: src/integration/rawspeed_glue.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/rawspeed_glue.o src/integration/rawspeed_glue.cpp object/adobepano.o: src/metadata/adobepano.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/adobepano.o src/metadata/adobepano.cpp object/canon.o: src/metadata/canon.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon.o src/metadata/canon.cpp object/ciff.o: src/metadata/ciff.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ciff.o src/metadata/ciff.cpp object/cr3_parser.o: src/metadata/cr3_parser.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cr3_parser.o src/metadata/cr3_parser.cpp object/epson.o: src/metadata/epson.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/epson.o src/metadata/epson.cpp object/exif_gps.o: src/metadata/exif_gps.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/exif_gps.o src/metadata/exif_gps.cpp object/fuji.o: src/metadata/fuji.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji.o src/metadata/fuji.cpp object/identify_tools.o: src/metadata/identify_tools.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify_tools.o src/metadata/identify_tools.cpp object/identify.o: src/metadata/identify.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify.o src/metadata/identify.cpp object/kodak.o: src/metadata/kodak.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak.o src/metadata/kodak.cpp object/leica.o: src/metadata/leica.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/leica.o src/metadata/leica.cpp object/makernotes.o: src/metadata/makernotes.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/makernotes.o src/metadata/makernotes.cpp object/mediumformat.o: src/metadata/mediumformat.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mediumformat.o src/metadata/mediumformat.cpp object/minolta.o: src/metadata/minolta.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/minolta.o src/metadata/minolta.cpp object/misc_parsers.o: src/metadata/misc_parsers.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_parsers.o src/metadata/misc_parsers.cpp object/nikon.o: src/metadata/nikon.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/nikon.o src/metadata/nikon.cpp object/hasselblad_model.o: src/metadata/hasselblad_model.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/hasselblad_model.o src/metadata/hasselblad_model.cpp object/normalize_model.o: src/metadata/normalize_model.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/normalize_model.o src/metadata/normalize_model.cpp object/olympus.o: src/metadata/olympus.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/olympus.o src/metadata/olympus.cpp object/p1.o: src/metadata/p1.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/p1.o src/metadata/p1.cpp object/pentax.o: src/metadata/pentax.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pentax.o src/metadata/pentax.cpp object/samsung.o: src/metadata/samsung.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/samsung.o src/metadata/samsung.cpp object/sony.o: src/metadata/sony.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sony.o src/metadata/sony.cpp object/tiff.o: src/metadata/tiff.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff.o src/metadata/tiff.cpp object/postprocessing_ph.o: src/postprocessing/postprocessing_ph.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_ph.o src/postprocessing/postprocessing_ph.cpp object/raw2image.o: src/preprocessing/raw2image.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/raw2image.o src/preprocessing/raw2image.cpp object/ext_preprocess.o: src/preprocessing/ext_preprocess.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ext_preprocess.o src/preprocessing/ext_preprocess.cpp object/subtract_black.o: src/preprocessing/subtract_black.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/subtract_black.o src/preprocessing/subtract_black.cpp object/cameralist.o: src/tables/cameralist.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cameralist.o src/tables/cameralist.cpp object/colorconst.o: src/tables/colorconst.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colorconst.o src/tables/colorconst.cpp object/colordata.o: src/tables/colordata.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colordata.o src/tables/colordata.cpp object/wblists.o: src/tables/wblists.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/wblists.o src/tables/wblists.cpp object/curves.o: src/utils/curves.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/curves.o src/utils/curves.cpp object/decoder_info.o: src/utils/decoder_info.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoder_info.o src/utils/decoder_info.cpp object/init_close_utils.o: src/utils/init_close_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/init_close_utils.o src/utils/init_close_utils.cpp object/open.o: src/utils/open.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/open.o src/utils/open.cpp object/phaseone_processing.o: src/utils/phaseone_processing.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/phaseone_processing.o src/utils/phaseone_processing.cpp object/read_utils.o: src/utils/read_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/read_utils.o src/utils/read_utils.cpp object/thumb_utils.o: src/utils/thumb_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/thumb_utils.o src/utils/thumb_utils.cpp object/utils_dcraw.o: src/utils/utils_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_dcraw.o src/utils/utils_dcraw.cpp object/utils_libraw.o: src/utils/utils_libraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_libraw.o src/utils/utils_libraw.cpp object/file_write.o: src/write/file_write.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/file_write.o src/write/file_write.cpp object/tiff_writer.o: src/write/tiff_writer.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff_writer.o src/write/tiff_writer.cpp object/x3f_parse_process.o: src/x3f/x3f_parse_process.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_parse_process.o src/x3f/x3f_parse_process.cpp object/x3f_utils_patched.o: src/x3f/x3f_utils_patched.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_utils_patched.o src/x3f/x3f_utils_patched.cpp LibRaw-0.21.4/Makefile.devel.noppr2i000066400000000000000000000272771477673233700171460ustar00rootroot00000000000000all: library all_samples CC=clang CXX=clang++ #CC=gcc #CXX=g++ LDADD+=-lz CFLAGS=-DLIBRAW_USE_AUTOPTR CFLAGS+= -g -I. -pedantic -Wno-long-long -Wno-overflow -O3 # RawSpeed Support # CFLAGS+=-DUSE_RAWSPEED -I../RawSpeed -I/opt/local/include/libxml2 # LDADD+=-L../RawSpeed/RawSpeed/release -lrawspeed -L/opt/local/include -ljpeg -lxml2 # RAWSPEED_DATA=../RawSpeed/data/cameras.xml # DNG SDK Support # CFLAGS+=-DUSE_DNGSDK -I../dng_sdk/source # LDADDD+=-L../dng_sdk/release -ldng -ljpeg -lz # LCMS support # For lcms2 set -DUSE_LCMS2 #CFLAGS+=-DUSE_LCMS2 -I/opt/local/include #LDADD+=-L/opt/local/lib -llcms # Jasper support for RedCine #CFLAGS+=-DUSE_JASPER -I/opt/local/include #LDADD+=-L/opt/local/lib -ljasper # JPEG support for DNG and Kodak CFLAGS+=-DUSE_JPEG -I/usr/local/include LDADD+=-L/usr/local/lib -ljpeg # LIBJPEG8: CFLAGS+=-DUSE_JPEG8 CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS LIB_OBJECTS= object/libraw_datastream.o \ object/cameralist.o object/fuji_compressed.o \ object/crx.o object/fp_dng.o object/decoders_libraw.o \ object/unpack.o object/unpack_thumb.o \ object/rawspeed_glue.o object/dngsdk_glue.o \ object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ object/decoder_info.o object/open.o object/phaseone_processing.o \ object/thumb_utils.o \ object/x3f_utils_patched.o object/x3f_parse_process.o \ object/read_utils.o object/curves.o object/utils_dcraw.o \ object/colordata.o \ object/canon_600.o object/decoders_dcraw.o \ object/decoders_libraw_dcrdefs.o object/generic.o \ object/kodak_decoders.o object/dng.o object/smal.o \ object/load_mfbacks.o \ object/sony.o object/nikon.o object/samsung.o object/cr3_parser.o \ object/canon.o object/epson.o object/olympus.o object/leica.o \ object/fuji.o object/adobepano.o object/pentax.o object/p1.o \ object/makernotes.o object/exif_gps.o object/kodak.o \ object/tiff.o object/ciff.o object/mediumformat.o object/minolta.o \ object/identify_tools.o \ object/hasselblad_model.o object/normalize_model.o object/identify.o \ object/misc_parsers.o object/wblists.o \ object/write_ph.o \ object/postprocessing_ph.o \ object/preprocessing_ph.o \ LR_INCLUDES=libraw/libraw.h libraw/libraw_alloc.h \ libraw/libraw_const.h libraw/libraw_datastream.h \ libraw/libraw_internal.h libraw/libraw_types.h \ libraw/libraw_version.h LRLIB=lib/libraw_noppr2i.a library: $(LRLIB) all_samples: bin/raw-identify ## Samples ## bin/raw-identify: $(LRLIB) samples/raw-identify.cpp $(CXX) ${CFLAGS} -o bin/raw-identify samples/raw-identify.cpp -L./lib -lraw_noppr2i -lm ${LDADD} $(LRLIB): ${LIB_OBJECTS} rm -f $(LRLIB) ar crv $(LRLIB) ${LIB_OBJECTS} ranlib $(LRLIB) clean: rm -fr bin/*.dSYM rm -f *.o *~ src/*~ samples/*~ internal/*~ libraw/*~ lib/lib*.a bin/[4a-z]* object/*.o dcraw/*~ doc/*~ bin/*~ src/*/*~ ## script-created rules object/libraw_c_api.o: src/libraw_c_api.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_c_api.o src/libraw_c_api.cpp object/libraw_datastream.o: src/libraw_datastream.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_datastream.o src/libraw_datastream.cpp object/canon_600.o: src/decoders/canon_600.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon_600.o src/decoders/canon_600.cpp object/crx.o: src/decoders/crx.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp object/decoders_libraw_dcrdefs.o: src/decoders/decoders_libraw_dcrdefs.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw_dcrdefs.o src/decoders/decoders_libraw_dcrdefs.cpp object/decoders_libraw.o: src/decoders/decoders_libraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw.o src/decoders/decoders_libraw.cpp object/dng.o: src/decoders/dng.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dng.o src/decoders/dng.cpp object/fp_dng.o: src/decoders/fp_dng.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fp_dng.o src/decoders/fp_dng.cpp object/fuji_compressed.o: src/decoders/fuji_compressed.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji_compressed.o src/decoders/fuji_compressed.cpp object/generic.o: src/decoders/generic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/generic.o src/decoders/generic.cpp object/kodak_decoders.o: src/decoders/kodak_decoders.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak_decoders.o src/decoders/kodak_decoders.cpp object/load_mfbacks.o: src/decoders/load_mfbacks.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/load_mfbacks.o src/decoders/load_mfbacks.cpp object/smal.o: src/decoders/smal.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/smal.o src/decoders/smal.cpp object/unpack_thumb.o: src/decoders/unpack_thumb.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack_thumb.o src/decoders/unpack_thumb.cpp object/unpack.o: src/decoders/unpack.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack.o src/decoders/unpack.cpp object/dngsdk_glue.o: src/integration/dngsdk_glue.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dngsdk_glue.o src/integration/dngsdk_glue.cpp object/rawspeed_glue.o: src/integration/rawspeed_glue.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/rawspeed_glue.o src/integration/rawspeed_glue.cpp object/adobepano.o: src/metadata/adobepano.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/adobepano.o src/metadata/adobepano.cpp object/canon.o: src/metadata/canon.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon.o src/metadata/canon.cpp object/ciff.o: src/metadata/ciff.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ciff.o src/metadata/ciff.cpp object/cr3_parser.o: src/metadata/cr3_parser.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cr3_parser.o src/metadata/cr3_parser.cpp object/epson.o: src/metadata/epson.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/epson.o src/metadata/epson.cpp object/exif_gps.o: src/metadata/exif_gps.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/exif_gps.o src/metadata/exif_gps.cpp object/fuji.o: src/metadata/fuji.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji.o src/metadata/fuji.cpp object/identify_tools.o: src/metadata/identify_tools.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify_tools.o src/metadata/identify_tools.cpp object/identify.o: src/metadata/identify.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify.o src/metadata/identify.cpp object/kodak.o: src/metadata/kodak.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak.o src/metadata/kodak.cpp object/leica.o: src/metadata/leica.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/leica.o src/metadata/leica.cpp object/makernotes.o: src/metadata/makernotes.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/makernotes.o src/metadata/makernotes.cpp object/mediumformat.o: src/metadata/mediumformat.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mediumformat.o src/metadata/mediumformat.cpp object/minolta.o: src/metadata/minolta.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/minolta.o src/metadata/minolta.cpp object/misc_parsers.o: src/metadata/misc_parsers.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_parsers.o src/metadata/misc_parsers.cpp object/nikon.o: src/metadata/nikon.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/nikon.o src/metadata/nikon.cpp object/hasselblad_model.o: src/metadata/hasselblad_model.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/hasselblad_model.o src/metadata/hasselblad_model.cpp object/normalize_model.o: src/metadata/normalize_model.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/normalize_model.o src/metadata/normalize_model.cpp object/olympus.o: src/metadata/olympus.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/olympus.o src/metadata/olympus.cpp object/p1.o: src/metadata/p1.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/p1.o src/metadata/p1.cpp object/pentax.o: src/metadata/pentax.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pentax.o src/metadata/pentax.cpp object/samsung.o: src/metadata/samsung.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/samsung.o src/metadata/samsung.cpp object/sony.o: src/metadata/sony.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sony.o src/metadata/sony.cpp object/tiff.o: src/metadata/tiff.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff.o src/metadata/tiff.cpp object/preprocessing_ph.o: src/preprocessing/preprocessing_ph.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/preprocessing_ph.o src/preprocessing/preprocessing_ph.cpp object/postprocessing_ph.o: src/postprocessing/postprocessing_ph.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_ph.o src/postprocessing/postprocessing_ph.cpp object/raw2image.o: src/preprocessing/raw2image.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/raw2image.o src/preprocessing/raw2image.cpp object/ext_preprocess.o: src/preprocessing/ext_preprocess.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ext_preprocess.o src/preprocessing/ext_preprocess.cpp object/subtract_black.o: src/preprocessing/subtract_black.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/subtract_black.o src/preprocessing/subtract_black.cpp object/cameralist.o: src/tables/cameralist.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cameralist.o src/tables/cameralist.cpp object/colorconst.o: src/tables/colorconst.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colorconst.o src/tables/colorconst.cpp object/colordata.o: src/tables/colordata.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colordata.o src/tables/colordata.cpp object/wblists.o: src/tables/wblists.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/wblists.o src/tables/wblists.cpp object/curves.o: src/utils/curves.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/curves.o src/utils/curves.cpp object/decoder_info.o: src/utils/decoder_info.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoder_info.o src/utils/decoder_info.cpp object/init_close_utils.o: src/utils/init_close_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/init_close_utils.o src/utils/init_close_utils.cpp object/open.o: src/utils/open.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/open.o src/utils/open.cpp object/phaseone_processing.o: src/utils/phaseone_processing.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/phaseone_processing.o src/utils/phaseone_processing.cpp object/read_utils.o: src/utils/read_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/read_utils.o src/utils/read_utils.cpp object/thumb_utils.o: src/utils/thumb_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/thumb_utils.o src/utils/thumb_utils.cpp object/utils_dcraw.o: src/utils/utils_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_dcraw.o src/utils/utils_dcraw.cpp object/utils_libraw.o: src/utils/utils_libraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_libraw.o src/utils/utils_libraw.cpp object/write_ph.o: src/write/write_ph.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/write_ph.o src/write/write_ph.cpp object/file_write.o: src/write/file_write.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/file_write.o src/write/file_write.cpp object/tiff_writer.o: src/write/tiff_writer.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff_writer.o src/write/tiff_writer.cpp object/x3f_parse_process.o: src/x3f/x3f_parse_process.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_parse_process.o src/x3f/x3f_parse_process.cpp object/x3f_utils_patched.o: src/x3f/x3f_utils_patched.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_utils_patched.o src/x3f/x3f_utils_patched.cpp LibRaw-0.21.4/Makefile.dist000066400000000000000000000700261477673233700154100ustar00rootroot00000000000000all: library all_samples #CFLAGS=-arch i386 -arch x86_64 -O3 -I. -w CFLAGS=-O3 -I. -w CC=gcc CXX=g++ # OpenMP support #CFLAGS+=-fopenmp # RawSpeed Support #CFLAGS+=-pthread -DUSE_RAWSPEED -I../RawSpeed -I/usr/local/include/libxml2 #LDADD+=-L../RawSpeed/RawSpeed -lrawspeed -L/usr/local/lib -ljpeg -lxml2 #RAWSPEED_DATA=../RawSpeed/data/cameras.xml # RawSpeed3 Support #CFLAGS+=-DUSE_RAWSPEED3 -DUSE_RAWSPEED_BITS -I./RawSpeed3/ #LDADD+=-L../RawSpeed-v3/release -lrawspeed3 -L/usr/local/lib -ljpeg -lz # DNG SDK Support # CFLAGS+=-DUSE_DNGSDK -I../dng_sdk/source # LDADDD+=-L../dng_sdk/release -ldng -lXMPCore -ljpeg -lz # Jasper support for RedCine #CFLAGS+=-DUSE_JASPER -I/usr/local/include #LDADD+=-L/usr/local/lib -ljasper # ZLIB support (FP dng) CFLAGS+=-DUSE_ZLIB LDADD+=-lz # JPEG support for lossy DNG #CFLAGS+=-DUSE_JPEG -I/usr/local/include #LDADD+=-L/usr/local/lib -ljpeg # LIBJPEG8: #CFLAGS+=-DUSE_JPEG8 # LCMS support #CFLAGS+=-DUSE_LCMS -I/usr/local/include #LDADD+=-L/usr/local/lib -llcms # LCMS2.x support #CFLAGS+=-DUSE_LCMS2 -I/usr/local/include #LDADD+=-L/usr/local/lib -llcms2 CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS LIB_OBJECTS= object/libraw_datastream.o object/libraw_c_api.o \ object/cameralist.o object/fuji_compressed.o \ object/crx.o object/fp_dng.o object/decoders_libraw.o \ object/unpack.o object/unpack_thumb.o \ object/rawspeed_glue.o object/dngsdk_glue.o \ object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ object/decoder_info.o object/open.o object/phaseone_processing.o \ object/thumb_utils.o \ object/tiff_writer.o object/subtract_black.o object/postprocessing_utils.o \ object/dcraw_process.o object/raw2image.o object/mem_image.o \ object/x3f_utils_patched.o object/x3f_parse_process.o \ object/read_utils.o object/curves.o object/utils_dcraw.o \ object/colordata.o \ object/canon_600.o object/decoders_dcraw.o \ object/decoders_libraw_dcrdefs.o object/generic.o \ object/kodak_decoders.o object/dng.o object/smal.o \ object/load_mfbacks.o \ object/sony.o object/nikon.o object/samsung.o object/cr3_parser.o \ object/canon.o object/epson.o object/olympus.o object/leica.o \ object/fuji.o object/adobepano.o object/pentax.o object/p1.o \ object/makernotes.o object/exif_gps.o object/kodak.o \ object/tiff.o object/ciff.o object/mediumformat.o object/minolta.o \ object/identify_tools.o \ object/hasselblad_model.o object/normalize_model.o object/identify.o \ object/misc_parsers.o object/wblists.o \ object/postprocessing_aux.o object/postprocessing_utils_dcrdefs.o \ object/aspect_ratio.o \ object/misc_demosaic.o object/xtrans_demosaic.o object/ahd_demosaic.o \ object/dht_demosaic.o object/aahd_demosaic.o object/dcb_demosaic.o \ object/file_write.o \ object/ext_preprocess.o object/apply_profile.o LIB_MT_OBJECTS= object/libraw_datastream.mt.o object/libraw_c_api.mt.o \ object/cameralist.mt.o object/fuji_compressed.mt.o \ object/crx.mt.o object/fp_dng.mt.o object/decoders_libraw.mt.o \ object/unpack.mt.o object/unpack_thumb.mt.o \ object/rawspeed_glue.mt.o object/dngsdk_glue.mt.o \ object/colorconst.mt.o object/utils_libraw.mt.o \ object/init_close_utils.mt.o \ object/decoder_info.mt.o object/open.mt.o object/phaseone_processing.mt.o \ object/thumb_utils.mt.o \ object/tiff_writer.mt.o object/subtract_black.mt.o \ object/postprocessing_utils.mt.o object/dcraw_process.mt.o \ object/raw2image.mt.o object/mem_image.mt.o \ object/x3f_utils_patched.mt.o object/x3f_parse_process.mt.o \ object/read_utils.mt.o object/curves.mt.o object/utils_dcraw.mt.o \ object/colordata.mt.o \ object/canon_600.mt.o object/decoders_dcraw.mt.o \ object/decoders_libraw_dcrdefs.mt.o object/generic.mt.o \ object/kodak_decoders.mt.o object/dng.mt.o object/smal.mt.o \ object/load_mfbacks.mt.o \ object/sony.mt.o object/nikon.mt.o object/samsung.mt.o \ object/cr3_parser.mt.o object/canon.mt.o object/epson.mt.o \ object/olympus.mt.o object/leica.mt.o \ object/fuji.mt.o object/adobepano.mt.o object/pentax.mt.o object/p1.mt.o \ object/makernotes.mt.o object/exif_gps.mt.o object/kodak.mt.o \ object/tiff.mt.o object/ciff.mt.o object/mediumformat.mt.o \ object/minolta.mt.o \ object/identify_tools.mt.o \ object/hasselblad_model.o object/normalize_model.mt.o object/identify.mt.o \ object/misc_parsers.mt.o object/wblists.mt.o \ object/postprocessing_aux.mt.o object/postprocessing_utils_dcrdefs.mt.o \ object/aspect_ratio.mt.o \ object/misc_demosaic.mt.o object/xtrans_demosaic.mt.o \ object/ahd_demosaic.mt.o object/dht_demosaic.mt.o \ object/aahd_demosaic.mt.o object/dcb_demosaic.mt.o \ object/file_write.mt.o \ object/ext_preprocess.mt.o object/apply_profile.mt.o LR_INCLUDES=libraw/libraw.h libraw/libraw_alloc.h \ libraw/libraw_const.h libraw/libraw_datastream.h \ libraw/libraw_internal.h libraw/libraw_types.h \ libraw/libraw_version.h library: lib/libraw.a lib/libraw_r.a all_samples: bin/raw-identify bin/simple_dcraw bin/dcraw_emu bin/dcraw_half bin/half_mt bin/mem_image \ bin/unprocessed_raw bin/4channels bin/multirender_test bin/postprocessing_benchmark \ bin/rawtextdump install: library @if [ -d /usr/local/include ] ; then cp -R libraw /usr/local/include/ ; else echo 'no /usr/local/include' ; fi @if [ -d /usr/local/lib ] ; then cp lib/libraw.a lib/libraw_r.a /usr/local/lib/ ; else echo 'no /usr/local/lib' ; fi install-binaries: all_samples @if [ -d /usr/local/bin ] ; then cp bin/[a-z]* /usr/local/bin/ ; else echo 'no /usr/local/bin' ; fi ## RawSpeed xml file RawSpeed/rawspeed_xmldata.cpp: ${RAWSPEED_DATA} ./rsxml2c.sh ${RAWSPEED_DATA} > RawSpeed/rawspeed_xmldata.cpp #binaries bin/raw-identify: lib/libraw.a samples/raw-identify.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/raw-identify samples/raw-identify.cpp -L./lib -lraw -lm ${LDADD} bin/unprocessed_raw: lib/libraw.a samples/unprocessed_raw.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/unprocessed_raw samples/unprocessed_raw.cpp -L./lib -lraw -lm ${LDADD} bin/4channels: lib/libraw.a samples/4channels.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/4channels samples/4channels.cpp -L./lib -lraw -lm ${LDADD} bin/rawtextdump: lib/libraw.a samples/rawtextdump.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/rawtextdump samples/rawtextdump.cpp -L./lib -lraw -lm ${LDADD} bin/simple_dcraw: lib/libraw.a samples/simple_dcraw.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/simple_dcraw samples/simple_dcraw.cpp -L./lib -lraw -lm ${LDADD} bin/multirender_test: lib/libraw.a samples/multirender_test.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/multirender_test samples/multirender_test.cpp -L./lib -lraw -lm ${LDADD} bin/postprocessing_benchmark: lib/libraw.a samples/postprocessing_benchmark.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/postprocessing_benchmark samples/postprocessing_benchmark.cpp -L./lib -lraw -lm ${LDADD} bin/mem_image: lib/libraw.a samples/mem_image_sample.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/mem_image samples/mem_image_sample.cpp -L./lib -lraw -lm ${LDADD} bin/dcraw_half: lib/libraw.a object/dcraw_half.o ${CC} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/dcraw_half object/dcraw_half.o -L./lib -lraw -lm -lstdc++ ${LDADD} bin/half_mt: lib/libraw_r.a object/half_mt.o ${CC} -pthread ${CFLAGS} -o bin/half_mt object/half_mt.o -L./lib -lraw_r -lm -lstdc++ ${LDADD} bin/dcraw_emu: lib/libraw.a samples/dcraw_emu.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/dcraw_emu samples/dcraw_emu.cpp -L./lib -lraw -lm ${LDADD} #objects object/dcraw_half.o: samples/dcraw_half.c ${CC} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcraw_half.o samples/dcraw_half.c object/half_mt.o: samples/half_mt.c ${CC} -c -pthread ${CFLAGS} -o object/half_mt.o samples/half_mt.c lib/libraw.a: ${LIB_OBJECTS} rm -f lib/libraw.a ar crv lib/libraw.a ${LIB_OBJECTS} ranlib lib/libraw.a lib/libraw_r.a: ${LIB_MT_OBJECTS} rm -f lib/libraw_r.a ar crv lib/libraw_r.a ${LIB_MT_OBJECTS} ranlib lib/libraw_r.a clean: rm -fr bin/*.dSYM rm -f *.o *~ src/*~ samples/*~ internal/*~ libraw/*~ lib/lib*.a bin/[4a-z]* object/*o dcraw/*~ doc/*~ bin/*~ src/*/*~ ### generated object/libraw_c_api.o: src/libraw_c_api.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_c_api.o src/libraw_c_api.cpp object/libraw_c_api.mt.o: src/libraw_c_api.cpp ${CXX} -c ${CFLAGS} -o object/libraw_c_api.mt.o src/libraw_c_api.cpp object/libraw_datastream.o: src/libraw_datastream.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_datastream.o src/libraw_datastream.cpp object/libraw_datastream.mt.o: src/libraw_datastream.cpp ${CXX} -c ${CFLAGS} -o object/libraw_datastream.mt.o src/libraw_datastream.cpp object/canon_600.o: src/decoders/canon_600.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon_600.o src/decoders/canon_600.cpp object/canon_600.mt.o: src/decoders/canon_600.cpp ${CXX} -c ${CFLAGS} -o object/canon_600.mt.o src/decoders/canon_600.cpp object/crx.o: src/decoders/crx.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp object/crx.mt.o: src/decoders/crx.cpp ${CXX} -c ${CFLAGS} -o object/crx.mt.o src/decoders/crx.cpp object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp object/decoders_dcraw.mt.o: src/decoders/decoders_dcraw.cpp ${CXX} -c ${CFLAGS} -o object/decoders_dcraw.mt.o src/decoders/decoders_dcraw.cpp object/decoders_libraw_dcrdefs.o: src/decoders/decoders_libraw_dcrdefs.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw_dcrdefs.o src/decoders/decoders_libraw_dcrdefs.cpp object/decoders_libraw_dcrdefs.mt.o: src/decoders/decoders_libraw_dcrdefs.cpp ${CXX} -c ${CFLAGS} -o object/decoders_libraw_dcrdefs.mt.o src/decoders/decoders_libraw_dcrdefs.cpp object/decoders_libraw.o: src/decoders/decoders_libraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw.o src/decoders/decoders_libraw.cpp object/decoders_libraw.mt.o: src/decoders/decoders_libraw.cpp ${CXX} -c ${CFLAGS} -o object/decoders_libraw.mt.o src/decoders/decoders_libraw.cpp object/dng.o: src/decoders/dng.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dng.o src/decoders/dng.cpp object/dng.mt.o: src/decoders/dng.cpp ${CXX} -c ${CFLAGS} -o object/dng.mt.o src/decoders/dng.cpp object/fp_dng.o: src/decoders/fp_dng.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fp_dng.o src/decoders/fp_dng.cpp object/fp_dng.mt.o: src/decoders/fp_dng.cpp ${CXX} -c ${CFLAGS} -o object/fp_dng.mt.o src/decoders/fp_dng.cpp object/fuji_compressed.o: src/decoders/fuji_compressed.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji_compressed.o src/decoders/fuji_compressed.cpp object/fuji_compressed.mt.o: src/decoders/fuji_compressed.cpp ${CXX} -c ${CFLAGS} -o object/fuji_compressed.mt.o src/decoders/fuji_compressed.cpp object/generic.o: src/decoders/generic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/generic.o src/decoders/generic.cpp object/generic.mt.o: src/decoders/generic.cpp ${CXX} -c ${CFLAGS} -o object/generic.mt.o src/decoders/generic.cpp object/kodak_decoders.o: src/decoders/kodak_decoders.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak_decoders.o src/decoders/kodak_decoders.cpp object/kodak_decoders.mt.o: src/decoders/kodak_decoders.cpp ${CXX} -c ${CFLAGS} -o object/kodak_decoders.mt.o src/decoders/kodak_decoders.cpp object/load_mfbacks.o: src/decoders/load_mfbacks.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/load_mfbacks.o src/decoders/load_mfbacks.cpp object/load_mfbacks.mt.o: src/decoders/load_mfbacks.cpp ${CXX} -c ${CFLAGS} -o object/load_mfbacks.mt.o src/decoders/load_mfbacks.cpp object/smal.o: src/decoders/smal.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/smal.o src/decoders/smal.cpp object/smal.mt.o: src/decoders/smal.cpp ${CXX} -c ${CFLAGS} -o object/smal.mt.o src/decoders/smal.cpp object/unpack_thumb.o: src/decoders/unpack_thumb.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack_thumb.o src/decoders/unpack_thumb.cpp object/unpack_thumb.mt.o: src/decoders/unpack_thumb.cpp ${CXX} -c ${CFLAGS} -o object/unpack_thumb.mt.o src/decoders/unpack_thumb.cpp object/unpack.o: src/decoders/unpack.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack.o src/decoders/unpack.cpp object/unpack.mt.o: src/decoders/unpack.cpp ${CXX} -c ${CFLAGS} -o object/unpack.mt.o src/decoders/unpack.cpp object/aahd_demosaic.o: src/demosaic/aahd_demosaic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/aahd_demosaic.o src/demosaic/aahd_demosaic.cpp object/aahd_demosaic.mt.o: src/demosaic/aahd_demosaic.cpp ${CXX} -c ${CFLAGS} -o object/aahd_demosaic.mt.o src/demosaic/aahd_demosaic.cpp object/ahd_demosaic.o: src/demosaic/ahd_demosaic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ahd_demosaic.o src/demosaic/ahd_demosaic.cpp object/ahd_demosaic.mt.o: src/demosaic/ahd_demosaic.cpp ${CXX} -c ${CFLAGS} -o object/ahd_demosaic.mt.o src/demosaic/ahd_demosaic.cpp object/dcb_demosaic.o: src/demosaic/dcb_demosaic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcb_demosaic.o src/demosaic/dcb_demosaic.cpp object/dcb_demosaic.mt.o: src/demosaic/dcb_demosaic.cpp ${CXX} -c ${CFLAGS} -o object/dcb_demosaic.mt.o src/demosaic/dcb_demosaic.cpp object/dht_demosaic.o: src/demosaic/dht_demosaic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dht_demosaic.o src/demosaic/dht_demosaic.cpp object/dht_demosaic.mt.o: src/demosaic/dht_demosaic.cpp ${CXX} -c ${CFLAGS} -o object/dht_demosaic.mt.o src/demosaic/dht_demosaic.cpp object/misc_demosaic.o: src/demosaic/misc_demosaic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_demosaic.o src/demosaic/misc_demosaic.cpp object/misc_demosaic.mt.o: src/demosaic/misc_demosaic.cpp ${CXX} -c ${CFLAGS} -o object/misc_demosaic.mt.o src/demosaic/misc_demosaic.cpp object/xtrans_demosaic.o: src/demosaic/xtrans_demosaic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/xtrans_demosaic.o src/demosaic/xtrans_demosaic.cpp object/xtrans_demosaic.mt.o: src/demosaic/xtrans_demosaic.cpp ${CXX} -c ${CFLAGS} -o object/xtrans_demosaic.mt.o src/demosaic/xtrans_demosaic.cpp object/dngsdk_glue.o: src/integration/dngsdk_glue.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dngsdk_glue.o src/integration/dngsdk_glue.cpp object/dngsdk_glue.mt.o: src/integration/dngsdk_glue.cpp ${CXX} -c ${CFLAGS} -o object/dngsdk_glue.mt.o src/integration/dngsdk_glue.cpp object/rawspeed_glue.o: src/integration/rawspeed_glue.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/rawspeed_glue.o src/integration/rawspeed_glue.cpp object/rawspeed_glue.mt.o: src/integration/rawspeed_glue.cpp ${CXX} -c ${CFLAGS} -o object/rawspeed_glue.mt.o src/integration/rawspeed_glue.cpp object/adobepano.o: src/metadata/adobepano.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/adobepano.o src/metadata/adobepano.cpp object/adobepano.mt.o: src/metadata/adobepano.cpp ${CXX} -c ${CFLAGS} -o object/adobepano.mt.o src/metadata/adobepano.cpp object/canon.o: src/metadata/canon.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon.o src/metadata/canon.cpp object/canon.mt.o: src/metadata/canon.cpp ${CXX} -c ${CFLAGS} -o object/canon.mt.o src/metadata/canon.cpp object/ciff.o: src/metadata/ciff.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ciff.o src/metadata/ciff.cpp object/ciff.mt.o: src/metadata/ciff.cpp ${CXX} -c ${CFLAGS} -o object/ciff.mt.o src/metadata/ciff.cpp object/cr3_parser.o: src/metadata/cr3_parser.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cr3_parser.o src/metadata/cr3_parser.cpp object/cr3_parser.mt.o: src/metadata/cr3_parser.cpp ${CXX} -c ${CFLAGS} -o object/cr3_parser.mt.o src/metadata/cr3_parser.cpp object/epson.o: src/metadata/epson.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/epson.o src/metadata/epson.cpp object/epson.mt.o: src/metadata/epson.cpp ${CXX} -c ${CFLAGS} -o object/epson.mt.o src/metadata/epson.cpp object/exif_gps.o: src/metadata/exif_gps.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/exif_gps.o src/metadata/exif_gps.cpp object/exif_gps.mt.o: src/metadata/exif_gps.cpp ${CXX} -c ${CFLAGS} -o object/exif_gps.mt.o src/metadata/exif_gps.cpp object/fuji.o: src/metadata/fuji.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji.o src/metadata/fuji.cpp object/fuji.mt.o: src/metadata/fuji.cpp ${CXX} -c ${CFLAGS} -o object/fuji.mt.o src/metadata/fuji.cpp object/identify_tools.o: src/metadata/identify_tools.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify_tools.o src/metadata/identify_tools.cpp object/identify_tools.mt.o: src/metadata/identify_tools.cpp ${CXX} -c ${CFLAGS} -o object/identify_tools.mt.o src/metadata/identify_tools.cpp object/identify.o: src/metadata/identify.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify.o src/metadata/identify.cpp object/identify.mt.o: src/metadata/identify.cpp ${CXX} -c ${CFLAGS} -o object/identify.mt.o src/metadata/identify.cpp object/kodak.o: src/metadata/kodak.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak.o src/metadata/kodak.cpp object/kodak.mt.o: src/metadata/kodak.cpp ${CXX} -c ${CFLAGS} -o object/kodak.mt.o src/metadata/kodak.cpp object/leica.o: src/metadata/leica.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/leica.o src/metadata/leica.cpp object/leica.mt.o: src/metadata/leica.cpp ${CXX} -c ${CFLAGS} -o object/leica.mt.o src/metadata/leica.cpp object/makernotes.o: src/metadata/makernotes.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/makernotes.o src/metadata/makernotes.cpp object/makernotes.mt.o: src/metadata/makernotes.cpp ${CXX} -c ${CFLAGS} -o object/makernotes.mt.o src/metadata/makernotes.cpp object/mediumformat.o: src/metadata/mediumformat.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mediumformat.o src/metadata/mediumformat.cpp object/mediumformat.mt.o: src/metadata/mediumformat.cpp ${CXX} -c ${CFLAGS} -o object/mediumformat.mt.o src/metadata/mediumformat.cpp object/minolta.o: src/metadata/minolta.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/minolta.o src/metadata/minolta.cpp object/minolta.mt.o: src/metadata/minolta.cpp ${CXX} -c ${CFLAGS} -o object/minolta.mt.o src/metadata/minolta.cpp object/misc_parsers.o: src/metadata/misc_parsers.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_parsers.o src/metadata/misc_parsers.cpp object/misc_parsers.mt.o: src/metadata/misc_parsers.cpp ${CXX} -c ${CFLAGS} -o object/misc_parsers.mt.o src/metadata/misc_parsers.cpp object/nikon.o: src/metadata/nikon.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/nikon.o src/metadata/nikon.cpp object/nikon.mt.o: src/metadata/nikon.cpp ${CXX} -c ${CFLAGS} -o object/nikon.mt.o src/metadata/nikon.cpp object/hasselblad_model.o: src/metadata/hasselblad_model.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/hasselblad_model.o src/metadata/hasselblad_model.cpp object/hasselblad_model.mt.o: src/metadata/hasselblad_model.cpp ${CXX} -c ${CFLAGS} -o object/hasselblad_model.mt.o src/metadata/hasselblad_model.cpp object/normalize_model.o: src/metadata/normalize_model.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/normalize_model.o src/metadata/normalize_model.cpp object/normalize_model.mt.o: src/metadata/normalize_model.cpp ${CXX} -c ${CFLAGS} -o object/normalize_model.mt.o src/metadata/normalize_model.cpp object/olympus.o: src/metadata/olympus.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/olympus.o src/metadata/olympus.cpp object/olympus.mt.o: src/metadata/olympus.cpp ${CXX} -c ${CFLAGS} -o object/olympus.mt.o src/metadata/olympus.cpp object/p1.o: src/metadata/p1.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/p1.o src/metadata/p1.cpp object/p1.mt.o: src/metadata/p1.cpp ${CXX} -c ${CFLAGS} -o object/p1.mt.o src/metadata/p1.cpp object/pentax.o: src/metadata/pentax.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pentax.o src/metadata/pentax.cpp object/pentax.mt.o: src/metadata/pentax.cpp ${CXX} -c ${CFLAGS} -o object/pentax.mt.o src/metadata/pentax.cpp object/samsung.o: src/metadata/samsung.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/samsung.o src/metadata/samsung.cpp object/samsung.mt.o: src/metadata/samsung.cpp ${CXX} -c ${CFLAGS} -o object/samsung.mt.o src/metadata/samsung.cpp object/sony.o: src/metadata/sony.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sony.o src/metadata/sony.cpp object/sony.mt.o: src/metadata/sony.cpp ${CXX} -c ${CFLAGS} -o object/sony.mt.o src/metadata/sony.cpp object/tiff.o: src/metadata/tiff.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff.o src/metadata/tiff.cpp object/tiff.mt.o: src/metadata/tiff.cpp ${CXX} -c ${CFLAGS} -o object/tiff.mt.o src/metadata/tiff.cpp object/aspect_ratio.o: src/postprocessing/aspect_ratio.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/aspect_ratio.o src/postprocessing/aspect_ratio.cpp object/aspect_ratio.mt.o: src/postprocessing/aspect_ratio.cpp ${CXX} -c ${CFLAGS} -o object/aspect_ratio.mt.o src/postprocessing/aspect_ratio.cpp object/dcraw_process.o: src/postprocessing/dcraw_process.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcraw_process.o src/postprocessing/dcraw_process.cpp object/dcraw_process.mt.o: src/postprocessing/dcraw_process.cpp ${CXX} -c ${CFLAGS} -o object/dcraw_process.mt.o src/postprocessing/dcraw_process.cpp object/mem_image.o: src/postprocessing/mem_image.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mem_image.o src/postprocessing/mem_image.cpp object/mem_image.mt.o: src/postprocessing/mem_image.cpp ${CXX} -c ${CFLAGS} -o object/mem_image.mt.o src/postprocessing/mem_image.cpp object/postprocessing_aux.o: src/postprocessing/postprocessing_aux.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_aux.o src/postprocessing/postprocessing_aux.cpp object/postprocessing_aux.mt.o: src/postprocessing/postprocessing_aux.cpp ${CXX} -c ${CFLAGS} -o object/postprocessing_aux.mt.o src/postprocessing/postprocessing_aux.cpp object/postprocessing_utils_dcrdefs.o: src/postprocessing/postprocessing_utils_dcrdefs.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_utils_dcrdefs.o src/postprocessing/postprocessing_utils_dcrdefs.cpp object/postprocessing_utils_dcrdefs.mt.o: src/postprocessing/postprocessing_utils_dcrdefs.cpp ${CXX} -c ${CFLAGS} -o object/postprocessing_utils_dcrdefs.mt.o src/postprocessing/postprocessing_utils_dcrdefs.cpp object/postprocessing_utils.o: src/postprocessing/postprocessing_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_utils.o src/postprocessing/postprocessing_utils.cpp object/postprocessing_utils.mt.o: src/postprocessing/postprocessing_utils.cpp ${CXX} -c ${CFLAGS} -o object/postprocessing_utils.mt.o src/postprocessing/postprocessing_utils.cpp object/raw2image.o: src/preprocessing/raw2image.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/raw2image.o src/preprocessing/raw2image.cpp object/raw2image.mt.o: src/preprocessing/raw2image.cpp ${CXX} -c ${CFLAGS} -o object/raw2image.mt.o src/preprocessing/raw2image.cpp object/ext_preprocess.o: src/preprocessing/ext_preprocess.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ext_preprocess.o src/preprocessing/ext_preprocess.cpp object/ext_preprocess.mt.o: src/preprocessing/ext_preprocess.cpp ${CXX} -c ${CFLAGS} -o object/ext_preprocess.mt.o src/preprocessing/ext_preprocess.cpp object/subtract_black.o: src/preprocessing/subtract_black.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/subtract_black.o src/preprocessing/subtract_black.cpp object/subtract_black.mt.o: src/preprocessing/subtract_black.cpp ${CXX} -c ${CFLAGS} -o object/subtract_black.mt.o src/preprocessing/subtract_black.cpp object/cameralist.o: src/tables/cameralist.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cameralist.o src/tables/cameralist.cpp object/cameralist.mt.o: src/tables/cameralist.cpp ${CXX} -c ${CFLAGS} -o object/cameralist.mt.o src/tables/cameralist.cpp object/colorconst.o: src/tables/colorconst.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colorconst.o src/tables/colorconst.cpp object/colorconst.mt.o: src/tables/colorconst.cpp ${CXX} -c ${CFLAGS} -o object/colorconst.mt.o src/tables/colorconst.cpp object/colordata.o: src/tables/colordata.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colordata.o src/tables/colordata.cpp object/colordata.mt.o: src/tables/colordata.cpp ${CXX} -c ${CFLAGS} -o object/colordata.mt.o src/tables/colordata.cpp object/wblists.o: src/tables/wblists.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/wblists.o src/tables/wblists.cpp object/wblists.mt.o: src/tables/wblists.cpp ${CXX} -c ${CFLAGS} -o object/wblists.mt.o src/tables/wblists.cpp object/curves.o: src/utils/curves.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/curves.o src/utils/curves.cpp object/curves.mt.o: src/utils/curves.cpp ${CXX} -c ${CFLAGS} -o object/curves.mt.o src/utils/curves.cpp object/decoder_info.o: src/utils/decoder_info.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoder_info.o src/utils/decoder_info.cpp object/decoder_info.mt.o: src/utils/decoder_info.cpp ${CXX} -c ${CFLAGS} -o object/decoder_info.mt.o src/utils/decoder_info.cpp object/init_close_utils.o: src/utils/init_close_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/init_close_utils.o src/utils/init_close_utils.cpp object/init_close_utils.mt.o: src/utils/init_close_utils.cpp ${CXX} -c ${CFLAGS} -o object/init_close_utils.mt.o src/utils/init_close_utils.cpp object/open.o: src/utils/open.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/open.o src/utils/open.cpp object/open.mt.o: src/utils/open.cpp ${CXX} -c ${CFLAGS} -o object/open.mt.o src/utils/open.cpp object/phaseone_processing.o: src/utils/phaseone_processing.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/phaseone_processing.o src/utils/phaseone_processing.cpp object/phaseone_processing.mt.o: src/utils/phaseone_processing.cpp ${CXX} -c ${CFLAGS} -o object/phaseone_processing.mt.o src/utils/phaseone_processing.cpp object/read_utils.o: src/utils/read_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/read_utils.o src/utils/read_utils.cpp object/read_utils.mt.o: src/utils/read_utils.cpp ${CXX} -c ${CFLAGS} -o object/read_utils.mt.o src/utils/read_utils.cpp object/thumb_utils.o: src/utils/thumb_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/thumb_utils.o src/utils/thumb_utils.cpp object/thumb_utils.mt.o: src/utils/thumb_utils.cpp ${CXX} -c ${CFLAGS} -o object/thumb_utils.mt.o src/utils/thumb_utils.cpp object/utils_dcraw.o: src/utils/utils_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_dcraw.o src/utils/utils_dcraw.cpp object/utils_dcraw.mt.o: src/utils/utils_dcraw.cpp ${CXX} -c ${CFLAGS} -o object/utils_dcraw.mt.o src/utils/utils_dcraw.cpp object/utils_libraw.o: src/utils/utils_libraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_libraw.o src/utils/utils_libraw.cpp object/utils_libraw.mt.o: src/utils/utils_libraw.cpp ${CXX} -c ${CFLAGS} -o object/utils_libraw.mt.o src/utils/utils_libraw.cpp object/apply_profile.o: src/write/apply_profile.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/apply_profile.o src/write/apply_profile.cpp object/apply_profile.mt.o: src/write/apply_profile.cpp ${CXX} -c ${CFLAGS} -o object/apply_profile.mt.o src/write/apply_profile.cpp object/file_write.o: src/write/file_write.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/file_write.o src/write/file_write.cpp object/file_write.mt.o: src/write/file_write.cpp ${CXX} -c ${CFLAGS} -o object/file_write.mt.o src/write/file_write.cpp object/tiff_writer.o: src/write/tiff_writer.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff_writer.o src/write/tiff_writer.cpp object/tiff_writer.mt.o: src/write/tiff_writer.cpp ${CXX} -c ${CFLAGS} -o object/tiff_writer.mt.o src/write/tiff_writer.cpp object/x3f_parse_process.o: src/x3f/x3f_parse_process.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_parse_process.o src/x3f/x3f_parse_process.cpp object/x3f_parse_process.mt.o: src/x3f/x3f_parse_process.cpp ${CXX} -c ${CFLAGS} -o object/x3f_parse_process.mt.o src/x3f/x3f_parse_process.cpp object/x3f_utils_patched.o: src/x3f/x3f_utils_patched.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_utils_patched.o src/x3f/x3f_utils_patched.cpp object/x3f_utils_patched.mt.o: src/x3f/x3f_utils_patched.cpp ${CXX} -c ${CFLAGS} -o object/x3f_utils_patched.mt.o src/x3f/x3f_utils_patched.cpp LibRaw-0.21.4/Makefile.mingw000066400000000000000000000403371477673233700155700ustar00rootroot00000000000000all: library all_samples CFLAGS=-O3 -I. -w CC=gcc CXX=g++ # OpenMP support #CFLAGS+=-fopenmp # RawSpeed Support #CFLAGS+=-pthread -DUSE_RAWSPEED -I../RawSpeed -I/usr/local/include/libxml2 #LDADD+=-L../RawSpeed/RawSpeed -lrawspeed -L/usr/local/lib -ljpeg -lxml2 #RAWSPEED_DATA=../RawSpeed/data/cameras.xml # DNG SDK Support # CFLAGS+=-DUSE_DNGSDK -I../dng_sdk/source # LDADDD+=-L../dng_sdk/release -ldng -lXMPCore -ljpeg -lz # Jasper support for RedCine #CFLAGS+=-DUSE_JASPER -I/usr/local/include #LDADD+=-L/usr/local/lib -ljasper # JPEG support for lossy DNG #CFLAGS+=-DUSE_JPEG -I/usr/local/include #LDADD+=-L/usr/local/lib -ljpeg # LIBJPEG8: #CFLAGS+=-DUSE_JPEG8 # LCMS support #CFLAGS+=-DUSE_LCMS -I/usr/local/include #LDADD+=-L/usr/local/lib -llcms # LCMS2.x support #CFLAGS+=-DUSE_LCMS2 -I/usr/local/include #LDADD+=-L/usr/local/lib -llcms2 CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS LIB_OBJECTS= object/libraw_datastream.o object/libraw_c_api.o \ object/cameralist.o object/fuji_compressed.o \ object/crx.o object/fp_dng.o object/decoders_libraw.o \ object/unpack.o object/unpack_thumb.o \ object/rawspeed_glue.o object/dngsdk_glue.o \ object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ object/decoder_info.o object/open.o object/phaseone_processing.o \ object/thumb_utils.o \ object/tiff_writer.o object/subtract_black.o object/postprocessing_utils.o \ object/dcraw_process.o object/raw2image.o object/mem_image.o \ object/x3f_utils_patched.o object/x3f_parse_process.o \ object/read_utils.o object/curves.o object/utils_dcraw.o \ object/colordata.o \ object/canon_600.o object/decoders_dcraw.o \ object/decoders_libraw_dcrdefs.o object/generic.o \ object/kodak_decoders.o object/dng.o object/smal.o \ object/load_mfbacks.o \ object/sony.o object/nikon.o object/samsung.o object/cr3_parser.o \ object/canon.o object/epson.o object/olympus.o object/leica.o \ object/fuji.o object/adobepano.o object/pentax.o object/p1.o \ object/makernotes.o object/exif_gps.o object/kodak.o \ object/tiff.o object/ciff.o object/mediumformat.o object/minolta.o \ object/identify_tools.o \ object/hasselblad_model.o object/normalize_model.o object/identify.o \ object/misc_parsers.o object/wblists.o \ object/postprocessing_aux.o object/postprocessing_utils_dcrdefs.o \ object/aspect_ratio.o \ object/misc_demosaic.o object/xtrans_demosaic.o object/ahd_demosaic.o \ object/dht_demosaic.o object/aahd_demosaic.o object/dcb_demosaic.o \ object/file_write.o \ object/ext_preprocess.o object/apply_profile.o LR_INCLUDES=libraw/libraw.h libraw/libraw_alloc.h \ libraw/libraw_const.h libraw/libraw_datastream.h \ libraw/libraw_internal.h libraw/libraw_types.h \ libraw/libraw_version.h library: lib/libraw.a all_samples: bin/raw-identify bin/simple_dcraw bin/dcraw_emu bin/dcraw_half bin/mem_image \ bin/unprocessed_raw bin/4channels bin/multirender_test bin/postprocessing_benchmark \ bin/rawtextdump install: library @if [ -d /usr/local/include ] ; then cp -R libraw /usr/local/include/ ; else echo 'no /usr/local/include' ; fi @if [ -d /usr/local/lib ] ; then cp lib/libraw.a lib/libraw_r.a /usr/local/lib/ ; else echo 'no /usr/local/lib' ; fi install-binaries: all_samples @if [ -d /usr/local/bin ] ; then cp bin/[a-z]* /usr/local/bin/ ; else echo 'no /usr/local/bin' ; fi #binaries bin/raw-identify: lib/libraw.a samples/raw-identify.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/raw-identify samples/raw-identify.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} bin/unprocessed_raw: lib/libraw.a samples/unprocessed_raw.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/unprocessed_raw samples/unprocessed_raw.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} bin/4channels: lib/libraw.a samples/4channels.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/4channels samples/4channels.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} bin/rawtextdump: lib/libraw.a samples/rawtextdump.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/rawtextdump samples/rawtextdump.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} bin/simple_dcraw: lib/libraw.a samples/simple_dcraw.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/simple_dcraw samples/simple_dcraw.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} bin/multirender_test: lib/libraw.a samples/multirender_test.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/multirender_test samples/multirender_test.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} bin/postprocessing_benchmark: lib/libraw.a samples/postprocessing_benchmark.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/postprocessing_benchmark samples/postprocessing_benchmark.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} bin/mem_image: lib/libraw.a samples/mem_image_sample.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/mem_image samples/mem_image_sample.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} bin/dcraw_half: lib/libraw.a object/dcraw_half.o ${CC} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/dcraw_half object/dcraw_half.o -L./lib -lraw -lws2_32 -lm -lstdc++ ${LDADD} bin/dcraw_emu: lib/libraw.a samples/dcraw_emu.cpp ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/dcraw_emu samples/dcraw_emu.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} #objects object/dcraw_half.o: samples/dcraw_half.c ${CC} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcraw_half.o samples/dcraw_half.c object/half_mt.o: samples/half_mt.c ${CC} -c -pthread ${CFLAGS} -o object/half_mt.o samples/half_mt.c lib/libraw.a: ${LIB_OBJECTS} rm -f lib/libraw.a ar crv lib/libraw.a ${LIB_OBJECTS} ranlib lib/libraw.a lib/libraw_r.a: ${LIB_MT_OBJECTS} rm -f lib/libraw_r.a ar crv lib/libraw_r.a ${LIB_MT_OBJECTS} ranlib lib/libraw_r.a clean: rm -fr bin/*.dSYM rm -f *.o *~ src/*~ samples/*~ internal/*~ libraw/*~ lib/lib*.a bin/[4a-z]* object/*o dcraw/*~ doc/*~ bin/*~ src/*/*~ ### generated object/libraw_c_api.o: src/libraw_c_api.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_c_api.o src/libraw_c_api.cpp object/libraw_datastream.o: src/libraw_datastream.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_datastream.o src/libraw_datastream.cpp object/canon_600.o: src/decoders/canon_600.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon_600.o src/decoders/canon_600.cpp object/crx.o: src/decoders/crx.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp object/decoders_libraw_dcrdefs.o: src/decoders/decoders_libraw_dcrdefs.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw_dcrdefs.o src/decoders/decoders_libraw_dcrdefs.cpp object/decoders_libraw.o: src/decoders/decoders_libraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw.o src/decoders/decoders_libraw.cpp object/dng.o: src/decoders/dng.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dng.o src/decoders/dng.cpp object/fp_dng.o: src/decoders/fp_dng.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fp_dng.o src/decoders/fp_dng.cpp object/fuji_compressed.o: src/decoders/fuji_compressed.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji_compressed.o src/decoders/fuji_compressed.cpp object/generic.o: src/decoders/generic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/generic.o src/decoders/generic.cpp object/kodak_decoders.o: src/decoders/kodak_decoders.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak_decoders.o src/decoders/kodak_decoders.cpp object/load_mfbacks.o: src/decoders/load_mfbacks.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/load_mfbacks.o src/decoders/load_mfbacks.cpp object/smal.o: src/decoders/smal.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/smal.o src/decoders/smal.cpp object/unpack_thumb.o: src/decoders/unpack_thumb.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack_thumb.o src/decoders/unpack_thumb.cpp object/unpack.o: src/decoders/unpack.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack.o src/decoders/unpack.cpp object/aahd_demosaic.o: src/demosaic/aahd_demosaic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/aahd_demosaic.o src/demosaic/aahd_demosaic.cpp object/ahd_demosaic.o: src/demosaic/ahd_demosaic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ahd_demosaic.o src/demosaic/ahd_demosaic.cpp object/dcb_demosaic.o: src/demosaic/dcb_demosaic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcb_demosaic.o src/demosaic/dcb_demosaic.cpp object/dht_demosaic.o: src/demosaic/dht_demosaic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dht_demosaic.o src/demosaic/dht_demosaic.cpp object/misc_demosaic.o: src/demosaic/misc_demosaic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_demosaic.o src/demosaic/misc_demosaic.cpp object/xtrans_demosaic.o: src/demosaic/xtrans_demosaic.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/xtrans_demosaic.o src/demosaic/xtrans_demosaic.cpp object/dngsdk_glue.o: src/integration/dngsdk_glue.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dngsdk_glue.o src/integration/dngsdk_glue.cpp object/rawspeed_glue.o: src/integration/rawspeed_glue.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/rawspeed_glue.o src/integration/rawspeed_glue.cpp object/adobepano.o: src/metadata/adobepano.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/adobepano.o src/metadata/adobepano.cpp object/canon.o: src/metadata/canon.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon.o src/metadata/canon.cpp object/ciff.o: src/metadata/ciff.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ciff.o src/metadata/ciff.cpp object/cr3_parser.o: src/metadata/cr3_parser.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cr3_parser.o src/metadata/cr3_parser.cpp object/epson.o: src/metadata/epson.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/epson.o src/metadata/epson.cpp object/exif_gps.o: src/metadata/exif_gps.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/exif_gps.o src/metadata/exif_gps.cpp object/fuji.o: src/metadata/fuji.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji.o src/metadata/fuji.cpp object/identify_tools.o: src/metadata/identify_tools.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify_tools.o src/metadata/identify_tools.cpp object/identify.o: src/metadata/identify.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify.o src/metadata/identify.cpp object/kodak.o: src/metadata/kodak.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak.o src/metadata/kodak.cpp object/leica.o: src/metadata/leica.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/leica.o src/metadata/leica.cpp object/makernotes.o: src/metadata/makernotes.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/makernotes.o src/metadata/makernotes.cpp object/mediumformat.o: src/metadata/mediumformat.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mediumformat.o src/metadata/mediumformat.cpp object/minolta.o: src/metadata/minolta.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/minolta.o src/metadata/minolta.cpp object/misc_parsers.o: src/metadata/misc_parsers.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_parsers.o src/metadata/misc_parsers.cpp object/nikon.o: src/metadata/nikon.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/nikon.o src/metadata/nikon.cpp object/hasselblad_model.o: src/metadata/hasselblad_model.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/hasselblad_model.o src/metadata/hasselblad_model.cpp object/normalize_model.o: src/metadata/normalize_model.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/normalize_model.o src/metadata/normalize_model.cpp object/olympus.o: src/metadata/olympus.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/olympus.o src/metadata/olympus.cpp object/p1.o: src/metadata/p1.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/p1.o src/metadata/p1.cpp object/pentax.o: src/metadata/pentax.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pentax.o src/metadata/pentax.cpp object/samsung.o: src/metadata/samsung.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/samsung.o src/metadata/samsung.cpp object/sony.o: src/metadata/sony.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sony.o src/metadata/sony.cpp object/tiff.o: src/metadata/tiff.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff.o src/metadata/tiff.cpp object/aspect_ratio.o: src/postprocessing/aspect_ratio.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/aspect_ratio.o src/postprocessing/aspect_ratio.cpp object/dcraw_process.o: src/postprocessing/dcraw_process.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcraw_process.o src/postprocessing/dcraw_process.cpp object/mem_image.o: src/postprocessing/mem_image.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mem_image.o src/postprocessing/mem_image.cpp object/postprocessing_aux.o: src/postprocessing/postprocessing_aux.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_aux.o src/postprocessing/postprocessing_aux.cpp object/postprocessing_utils_dcrdefs.o: src/postprocessing/postprocessing_utils_dcrdefs.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_utils_dcrdefs.o src/postprocessing/postprocessing_utils_dcrdefs.cpp object/postprocessing_utils.o: src/postprocessing/postprocessing_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_utils.o src/postprocessing/postprocessing_utils.cpp object/raw2image.o: src/preprocessing/raw2image.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/raw2image.o src/preprocessing/raw2image.cpp object/ext_preprocess.o: src/preprocessing/ext_preprocess.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ext_preprocess.o src/preprocessing/ext_preprocess.cpp object/subtract_black.o: src/preprocessing/subtract_black.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/subtract_black.o src/preprocessing/subtract_black.cpp object/cameralist.o: src/tables/cameralist.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cameralist.o src/tables/cameralist.cpp object/colorconst.o: src/tables/colorconst.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colorconst.o src/tables/colorconst.cpp object/colordata.o: src/tables/colordata.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colordata.o src/tables/colordata.cpp object/wblists.o: src/tables/wblists.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/wblists.o src/tables/wblists.cpp object/curves.o: src/utils/curves.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/curves.o src/utils/curves.cpp object/decoder_info.o: src/utils/decoder_info.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoder_info.o src/utils/decoder_info.cpp object/init_close_utils.o: src/utils/init_close_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/init_close_utils.o src/utils/init_close_utils.cpp object/open.o: src/utils/open.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/open.o src/utils/open.cpp object/phaseone_processing.o: src/utils/phaseone_processing.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/phaseone_processing.o src/utils/phaseone_processing.cpp object/read_utils.o: src/utils/read_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/read_utils.o src/utils/read_utils.cpp object/thumb_utils.o: src/utils/thumb_utils.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/thumb_utils.o src/utils/thumb_utils.cpp object/utils_dcraw.o: src/utils/utils_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_dcraw.o src/utils/utils_dcraw.cpp object/utils_libraw.o: src/utils/utils_libraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_libraw.o src/utils/utils_libraw.cpp object/apply_profile.o: src/write/apply_profile.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/apply_profile.o src/write/apply_profile.cpp object/file_write.o: src/write/file_write.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/file_write.o src/write/file_write.cpp object/tiff_writer.o: src/write/tiff_writer.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff_writer.o src/write/tiff_writer.cpp object/x3f_parse_process.o: src/x3f/x3f_parse_process.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_parse_process.o src/x3f/x3f_parse_process.cpp object/x3f_utils_patched.o: src/x3f/x3f_utils_patched.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_utils_patched.o src/x3f/x3f_utils_patched.cpp LibRaw-0.21.4/Makefile.msvc000066400000000000000000000756051477673233700154250ustar00rootroot00000000000000# Additional compiler flags (OpenMP, SSEx, AVX, ...) #COPT_OPT=/arch:SSE2 /arch:AVX # Compile with RawSpeed support #CFLAGS_RAWSPEED=/DUSE_RAWSPEED /I"..\\RawSpeed" /I"..\\RawSpeed\include" /I"..\\RawSpeed\include\libjpeg" #LDFLAGS_RAWSPEED=..\RawSpeed\lib\rawspeed.lib ..\RawSpeed\lib\libxml2.lib ..\RawSpeed\lib\iconv.lib ..\RawSpeed\lib\charset.lib ..\RawSpeed\lib\turbojpeg-static.lib # Compile with DNG SDK support #CFLAGS_DNG=/DUSE_DNGSDK /I"..\\dng_sdk\\source" #LDFLAGS_DNG=..\\dng_sdk\\release\\libdng.lib ..\\dng_sdk\\release\\XMPCore.lib # you may also need to specify zlib.lib and jpeg.lib in the line above # LCMS 1.x support #LCMS_DEF=/DUSE_LCMS /DCMS_DLL /I..\lcms-1.19\include #LCMS_LIB=..\lcms-1.19\bin\lcms.lib # LCMS 2.x support #LCMS_DEF=/DUSE_LCMS2 /DCMS_DLL /I..\lcms2-2.3\include #LCMS_LIB=..\lcms2-2.3\bin\lcms2_dll.lib # JPEG support for DNG #JPEG_DEF=/DUSE_JPEG /I..\jpeg-8d #JPEG_LIB=..\jpeg-8d\Release\jpeg.lib SAMPLES=bin\raw-identify.exe bin\simple_dcraw.exe bin\dcraw_emu.exe bin\dcraw_half.exe \ bin\half_mt.exe bin\mem_image.exe bin\unprocessed_raw.exe bin\4channels.exe \ bin\multirender_test.exe bin\postprocessing_benchmark.exe bin\openbayer_sample.exe \ bin\rawtextdump.exe LIBSTATIC=lib\libraw_static.lib DLL=bin\libraw.dll LIBDLL=lib\libraw.lib all: $(DLL) $(LIBSTATIC) $(SAMPLES) $(LIBDLL): $(DLL) # Guess LIBPATH from $INCLUDE LIB_OBJECTS= object\libraw_datastream_st.obj object\libraw_c_api_st.obj \ object\cameralist_st.obj object\fuji_compressed_st.obj \ object\crx_st.obj object\fp_dng_st.obj object\decoders_libraw_st.obj \ object\unpack_st.obj object\unpack_thumb_st.obj \ object\rawspeed_glue_st.obj object\dngsdk_glue_st.obj \ object\colorconst_st.obj object\utils_libraw_st.obj object\init_close_utils_st.obj \ object\decoder_info_st.obj object\open_st.obj object\phaseone_processing_st.obj \ object\thumb_utils_st.obj \ object\tiff_writer_st.obj object\subtract_black_st.obj object\postprocessing_utils_st.obj \ object\dcraw_process_st.obj object\raw2image_st.obj object\mem_image_st.obj \ object\x3f_utils_patched_st.obj object\x3f_parse_process_st.obj \ object\read_utils_st.obj object\curves_st.obj object\utils_dcraw_st.obj \ object\colordata_st.obj \ object\canon_600_st.obj object\decoders_dcraw_st.obj \ object\decoders_libraw_dcrdefs_st.obj object\generic_st.obj \ object\kodak_decoders_st.obj object\dng_st.obj object\smal_st.obj \ object\load_mfbacks_st.obj \ object\sony_st.obj object\nikon_st.obj object\samsung_st.obj object\cr3_parser_st.obj \ object\canon_st.obj object\epson_st.obj object\olympus_st.obj object\leica_st.obj \ object\fuji_st.obj object\adobepano_st.obj object\pentax_st.obj object\p1_st.obj \ object\makernotes_st.obj object\exif_gps_st.obj object\kodak_st.obj \ object\tiff_st.obj object\ciff_st.obj object\mediumformat_st.obj object\minolta_st.obj \ object\identify_tools_st.obj \ object\hasselblad_model_st.obj object\normalize_model_st.obj object\identify_st.obj \ object\misc_parsers_st.obj object\wblists_st.obj \ object\postprocessing_aux_st.obj object\postprocessing_utils_dcrdefs_st.obj \ object\aspect_ratio_st.obj \ object\misc_demosaic_st.obj object\xtrans_demosaic_st.obj object\ahd_demosaic_st.obj \ object\dht_demosaic_st.obj object\aahd_demosaic_st.obj object\dcb_demosaic_st.obj \ object\file_write_st.obj \ object\ext_preprocess_st.obj object\apply_profile_st.obj DLL_OBJECTS= object\libraw_datastream.obj object\libraw_c_api.obj \ object\cameralist.obj object\fuji_compressed.obj \ object\crx.obj object\fp_dng.obj object\decoders_libraw.obj \ object\unpack.obj object\unpack_thumb.obj \ object\rawspeed_glue.obj object\dngsdk_glue.obj \ object\colorconst.obj object\utils_libraw.obj \ object\init_close_utils.obj \ object\decoder_info.obj object\open.obj object\phaseone_processing.obj \ object\thumb_utils.obj \ object\tiff_writer.obj object\subtract_black.obj \ object\postprocessing_utils.obj object\dcraw_process.obj \ object\raw2image.obj object\mem_image.obj \ object\x3f_utils_patched.obj object\x3f_parse_process.obj \ object\read_utils.obj object\curves.obj object\utils_dcraw.obj \ object\colordata.obj \ object\canon_600.obj object\decoders_dcraw.obj \ object\decoders_libraw_dcrdefs.obj object\generic.obj \ object\kodak_decoders.obj object\dng.obj object\smal.obj \ object\load_mfbacks.obj \ object\sony.obj object\nikon.obj object\samsung.obj \ object\cr3_parser.obj object\canon.obj object\epson.obj \ object\olympus.obj object\leica.obj \ object\fuji.obj object\adobepano.obj object\pentax.obj object\p1.obj \ object\makernotes.obj object\exif_gps.obj object\kodak.obj \ object\tiff.obj object\ciff.obj object\mediumformat.obj \ object\minolta.obj \ object\identify_tools.obj \ object\hasselblad_model.obj object\normalize_model.obj object\identify.obj \ object\misc_parsers.obj object\wblists.obj \ object\postprocessing_aux.obj object\postprocessing_utils_dcrdefs.obj \ object\aspect_ratio.obj \ object\misc_demosaic.obj object\xtrans_demosaic.obj \ object\ahd_demosaic.obj object\dht_demosaic.obj \ object\aahd_demosaic.obj object\dcb_demosaic.obj \ object\file_write.obj \ object\ext_preprocess.obj object\apply_profile.obj CC=cl.exe COPT=/EHsc /MP /MD /I. /DWIN32 /O2 /W0 /nologo $(COPT_OPT) $(CFLAGSG2) $(CFLAGSG3) $(LCMS_DEF) $(JPEG_DEF) $(CFLAGS_RAWSPEED) $(CFLAGS_DNG) LINKLIB=$(LIBDLL) $(LDFLAGS_RAWSPEED) $(LDFLAGS_DNG) # Samples - default to dynamic (DLL) link, uncomment next lines #CFLAGS2=/DLIBRAW_NODLL #LINKLIB=$(LIBSTATIC) bin\raw-identify.exe: $(LINKLIB) samples\raw-identify.cpp $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\raw-identify.exe" /Fo"object\\" samples\raw-identify.cpp $(LINKLIB) bin\unprocessed_raw.exe: $(LINKLIB) samples\unprocessed_raw.cpp $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\unprocessed_raw.exe" /Fo"object\\" samples\unprocessed_raw.cpp $(LINKLIB) ws2_32.lib bin\4channels.exe: $(LINKLIB) samples\4channels.cpp $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\4channels.exe" /Fo"object\\" samples\4channels.cpp $(LINKLIB) bin\rawtextdump.exe: $(LINKLIB) samples\rawtextdump.cpp $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\rawtextdump.exe" /Fo"object\\" samples\rawtextdump.cpp $(LINKLIB) bin\simple_dcraw.exe: $(LINKLIB) samples\simple_dcraw.cpp $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\simple_dcraw.exe" /Fo"object\\" samples\simple_dcraw.cpp $(LINKLIB) bin\postprocessing_benchmark.exe: $(LINKLIB) samples\postprocessing_benchmark.cpp $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\postprocessing_benchmark.exe" /Fo"object\\" samples\postprocessing_benchmark.cpp $(LINKLIB) bin\multirender_test.exe: $(LINKLIB) samples\multirender_test.cpp $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\multirender_test.exe" /Fo"object\\" samples\multirender_test.cpp $(LINKLIB) bin\openbayer_sample.exe: $(LINKLIB) samples\openbayer_sample.cpp $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\openbayer_sample.exe" /Fo"object\\" samples\openbayer_sample.cpp $(LINKLIB) bin\mem_image.exe: $(LINKLIB) samples\mem_image_sample.cpp $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\mem_image.exe" /Fo"object\\" samples\mem_image_sample.cpp $(LINKLIB) bin\dcraw_emu.exe: $(LINKLIB) samples\dcraw_emu.cpp $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\dcraw_emu.exe" /Fo"object\\" samples\dcraw_emu.cpp $(LINKLIB) bin\dcraw_half.exe: $(LINKLIB) samples\dcraw_half.c $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\dcraw_half.exe" /Fo"object\\" samples\dcraw_half.c $(LINKLIB) bin\half_mt.exe: $(LINKLIB) samples\half_mt_win32.c $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\half_mt.exe" /Fo"object\\" samples\half_mt_win32.c $(LINKLIB) # DLL build $(DLL): $(DLL_OBJECTS) -del /f $(DLL) $(LIBDLL) cl $(COPT) /LD $(DLL_OBJECTS) $(LDFLAGS_RAWSPEED) $(LDFLAGS_DNG) $(LCMS_LIB) $(JPEG_LIB) /link /out:"$(DLL)" /implib:"$(LIBDLL)" # LIBRARY BUILD $(LIBSTATIC): $(LIB_OBJECTS) -del /f $(LIBSTATIC) lib /OUT:$(LIBSTATIC) /LTCG $(LIB_OBJECTS) # clean clean: -del $(LIBSTATIC) $(LIBDLL) lib\*.exp -del $(LIB_OBJECTS) $(DLL_OBJECTS) -del object\*.o -del $(DLL) $(SAMPLES) # OBJ generation rules object\canon_600_st.obj: src\decoders\canon_600.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\canon_600_st.obj" /c src\decoders\canon_600.cpp object\canon_600.obj: src\decoders\canon_600.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\canon_600.obj" /c src\decoders\canon_600.cpp object\crx_st.obj: src\decoders\crx.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\crx_st.obj" /c src\decoders\crx.cpp object\crx.obj: src\decoders\crx.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\crx.obj" /c src\decoders\crx.cpp object\decoders_dcraw_st.obj: src\decoders\decoders_dcraw.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\decoders_dcraw_st.obj" /c src\decoders\decoders_dcraw.cpp object\decoders_dcraw.obj: src\decoders\decoders_dcraw.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\decoders_dcraw.obj" /c src\decoders\decoders_dcraw.cpp object\decoders_libraw_dcrdefs_st.obj: src\decoders\decoders_libraw_dcrdefs.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\decoders_libraw_dcrdefs_st.obj" /c src\decoders\decoders_libraw_dcrdefs.cpp object\decoders_libraw_dcrdefs.obj: src\decoders\decoders_libraw_dcrdefs.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\decoders_libraw_dcrdefs.obj" /c src\decoders\decoders_libraw_dcrdefs.cpp object\decoders_libraw_st.obj: src\decoders\decoders_libraw.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\decoders_libraw_st.obj" /c src\decoders\decoders_libraw.cpp object\decoders_libraw.obj: src\decoders\decoders_libraw.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\decoders_libraw.obj" /c src\decoders\decoders_libraw.cpp object\dng_st.obj: src\decoders\dng.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\dng_st.obj" /c src\decoders\dng.cpp object\dng.obj: src\decoders\dng.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\dng.obj" /c src\decoders\dng.cpp object\fp_dng_st.obj: src\decoders\fp_dng.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\fp_dng_st.obj" /c src\decoders\fp_dng.cpp object\fp_dng.obj: src\decoders\fp_dng.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\fp_dng.obj" /c src\decoders\fp_dng.cpp object\fuji_compressed_st.obj: src\decoders\fuji_compressed.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\fuji_compressed_st.obj" /c src\decoders\fuji_compressed.cpp object\fuji_compressed.obj: src\decoders\fuji_compressed.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\fuji_compressed.obj" /c src\decoders\fuji_compressed.cpp object\generic_st.obj: src\decoders\generic.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\generic_st.obj" /c src\decoders\generic.cpp object\generic.obj: src\decoders\generic.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\generic.obj" /c src\decoders\generic.cpp object\kodak_decoders_st.obj: src\decoders\kodak_decoders.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\kodak_decoders_st.obj" /c src\decoders\kodak_decoders.cpp object\kodak_decoders.obj: src\decoders\kodak_decoders.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\kodak_decoders.obj" /c src\decoders\kodak_decoders.cpp object\load_mfbacks_st.obj: src\decoders\load_mfbacks.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\load_mfbacks_st.obj" /c src\decoders\load_mfbacks.cpp object\load_mfbacks.obj: src\decoders\load_mfbacks.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\load_mfbacks.obj" /c src\decoders\load_mfbacks.cpp object\smal_st.obj: src\decoders\smal.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\smal_st.obj" /c src\decoders\smal.cpp object\smal.obj: src\decoders\smal.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\smal.obj" /c src\decoders\smal.cpp object\unpack_thumb_st.obj: src\decoders\unpack_thumb.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\unpack_thumb_st.obj" /c src\decoders\unpack_thumb.cpp object\unpack_thumb.obj: src\decoders\unpack_thumb.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\unpack_thumb.obj" /c src\decoders\unpack_thumb.cpp object\unpack_st.obj: src\decoders\unpack.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\unpack_st.obj" /c src\decoders\unpack.cpp object\unpack.obj: src\decoders\unpack.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\unpack.obj" /c src\decoders\unpack.cpp object\aahd_demosaic_st.obj: src\demosaic\aahd_demosaic.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\aahd_demosaic_st.obj" /c src\demosaic\aahd_demosaic.cpp object\aahd_demosaic.obj: src\demosaic\aahd_demosaic.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\aahd_demosaic.obj" /c src\demosaic\aahd_demosaic.cpp object\ahd_demosaic_st.obj: src\demosaic\ahd_demosaic.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\ahd_demosaic_st.obj" /c src\demosaic\ahd_demosaic.cpp object\ahd_demosaic.obj: src\demosaic\ahd_demosaic.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\ahd_demosaic.obj" /c src\demosaic\ahd_demosaic.cpp object\dcb_demosaic_st.obj: src\demosaic\dcb_demosaic.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\dcb_demosaic_st.obj" /c src\demosaic\dcb_demosaic.cpp object\dcb_demosaic.obj: src\demosaic\dcb_demosaic.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\dcb_demosaic.obj" /c src\demosaic\dcb_demosaic.cpp object\dht_demosaic_st.obj: src\demosaic\dht_demosaic.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\dht_demosaic_st.obj" /c src\demosaic\dht_demosaic.cpp object\dht_demosaic.obj: src\demosaic\dht_demosaic.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\dht_demosaic.obj" /c src\demosaic\dht_demosaic.cpp object\misc_demosaic_st.obj: src\demosaic\misc_demosaic.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\misc_demosaic_st.obj" /c src\demosaic\misc_demosaic.cpp object\misc_demosaic.obj: src\demosaic\misc_demosaic.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\misc_demosaic.obj" /c src\demosaic\misc_demosaic.cpp object\xtrans_demosaic_st.obj: src\demosaic\xtrans_demosaic.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\xtrans_demosaic_st.obj" /c src\demosaic\xtrans_demosaic.cpp object\xtrans_demosaic.obj: src\demosaic\xtrans_demosaic.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\xtrans_demosaic.obj" /c src\demosaic\xtrans_demosaic.cpp object\dngsdk_glue_st.obj: src\integration\dngsdk_glue.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\dngsdk_glue_st.obj" /c src\integration\dngsdk_glue.cpp object\dngsdk_glue.obj: src\integration\dngsdk_glue.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\dngsdk_glue.obj" /c src\integration\dngsdk_glue.cpp object\rawspeed_glue_st.obj: src\integration\rawspeed_glue.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\rawspeed_glue_st.obj" /c src\integration\rawspeed_glue.cpp object\rawspeed_glue.obj: src\integration\rawspeed_glue.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\rawspeed_glue.obj" /c src\integration\rawspeed_glue.cpp object\adobepano_st.obj: src\metadata\adobepano.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\adobepano_st.obj" /c src\metadata\adobepano.cpp object\adobepano.obj: src\metadata\adobepano.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\adobepano.obj" /c src\metadata\adobepano.cpp object\canon_st.obj: src\metadata\canon.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\canon_st.obj" /c src\metadata\canon.cpp object\canon.obj: src\metadata\canon.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\canon.obj" /c src\metadata\canon.cpp object\ciff_st.obj: src\metadata\ciff.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\ciff_st.obj" /c src\metadata\ciff.cpp object\ciff.obj: src\metadata\ciff.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\ciff.obj" /c src\metadata\ciff.cpp object\cr3_parser_st.obj: src\metadata\cr3_parser.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\cr3_parser_st.obj" /c src\metadata\cr3_parser.cpp object\cr3_parser.obj: src\metadata\cr3_parser.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\cr3_parser.obj" /c src\metadata\cr3_parser.cpp object\epson_st.obj: src\metadata\epson.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\epson_st.obj" /c src\metadata\epson.cpp object\epson.obj: src\metadata\epson.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\epson.obj" /c src\metadata\epson.cpp object\exif_gps_st.obj: src\metadata\exif_gps.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\exif_gps_st.obj" /c src\metadata\exif_gps.cpp object\exif_gps.obj: src\metadata\exif_gps.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\exif_gps.obj" /c src\metadata\exif_gps.cpp object\fuji_st.obj: src\metadata\fuji.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\fuji_st.obj" /c src\metadata\fuji.cpp object\fuji.obj: src\metadata\fuji.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\fuji.obj" /c src\metadata\fuji.cpp object\identify_tools_st.obj: src\metadata\identify_tools.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\identify_tools_st.obj" /c src\metadata\identify_tools.cpp object\identify_tools.obj: src\metadata\identify_tools.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\identify_tools.obj" /c src\metadata\identify_tools.cpp object\identify_st.obj: src\metadata\identify.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\identify_st.obj" /c src\metadata\identify.cpp object\identify.obj: src\metadata\identify.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\identify.obj" /c src\metadata\identify.cpp object\kodak_st.obj: src\metadata\kodak.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\kodak_st.obj" /c src\metadata\kodak.cpp object\kodak.obj: src\metadata\kodak.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\kodak.obj" /c src\metadata\kodak.cpp object\leica_st.obj: src\metadata\leica.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\leica_st.obj" /c src\metadata\leica.cpp object\leica.obj: src\metadata\leica.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\leica.obj" /c src\metadata\leica.cpp object\makernotes_st.obj: src\metadata\makernotes.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\makernotes_st.obj" /c src\metadata\makernotes.cpp object\makernotes.obj: src\metadata\makernotes.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\makernotes.obj" /c src\metadata\makernotes.cpp object\mediumformat_st.obj: src\metadata\mediumformat.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\mediumformat_st.obj" /c src\metadata\mediumformat.cpp object\mediumformat.obj: src\metadata\mediumformat.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\mediumformat.obj" /c src\metadata\mediumformat.cpp object\minolta_st.obj: src\metadata\minolta.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\minolta_st.obj" /c src\metadata\minolta.cpp object\minolta.obj: src\metadata\minolta.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\minolta.obj" /c src\metadata\minolta.cpp object\misc_parsers_st.obj: src\metadata\misc_parsers.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\misc_parsers_st.obj" /c src\metadata\misc_parsers.cpp object\misc_parsers.obj: src\metadata\misc_parsers.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\misc_parsers.obj" /c src\metadata\misc_parsers.cpp object\nikon_st.obj: src\metadata\nikon.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\nikon_st.obj" /c src\metadata\nikon.cpp object\nikon.obj: src\metadata\nikon.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\nikon.obj" /c src\metadata\nikon.cpp object\hasselblad_model_st.obj: src\metadata\hasselblad_model.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\hasselblad_model_st.obj" /c src\metadata\hasselblad_model.cpp object\hasselblad_model.obj: src\metadata\hasselblad_model.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\hasselblad_model.obj" /c src\metadata\hasselblad_model.cpp object\normalize_model_st.obj: src\metadata\normalize_model.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\normalize_model_st.obj" /c src\metadata\normalize_model.cpp object\normalize_model.obj: src\metadata\normalize_model.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\normalize_model.obj" /c src\metadata\normalize_model.cpp object\olympus_st.obj: src\metadata\olympus.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\olympus_st.obj" /c src\metadata\olympus.cpp object\olympus.obj: src\metadata\olympus.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\olympus.obj" /c src\metadata\olympus.cpp object\p1_st.obj: src\metadata\p1.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\p1_st.obj" /c src\metadata\p1.cpp object\p1.obj: src\metadata\p1.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\p1.obj" /c src\metadata\p1.cpp object\pentax_st.obj: src\metadata\pentax.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\pentax_st.obj" /c src\metadata\pentax.cpp object\pentax.obj: src\metadata\pentax.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\pentax.obj" /c src\metadata\pentax.cpp object\samsung_st.obj: src\metadata\samsung.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\samsung_st.obj" /c src\metadata\samsung.cpp object\samsung.obj: src\metadata\samsung.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\samsung.obj" /c src\metadata\samsung.cpp object\sony_st.obj: src\metadata\sony.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\sony_st.obj" /c src\metadata\sony.cpp object\sony.obj: src\metadata\sony.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\sony.obj" /c src\metadata\sony.cpp object\tiff_st.obj: src\metadata\tiff.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\tiff_st.obj" /c src\metadata\tiff.cpp object\tiff.obj: src\metadata\tiff.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\tiff.obj" /c src\metadata\tiff.cpp object\aspect_ratio_st.obj: src\postprocessing\aspect_ratio.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\aspect_ratio_st.obj" /c src\postprocessing\aspect_ratio.cpp object\aspect_ratio.obj: src\postprocessing\aspect_ratio.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\aspect_ratio.obj" /c src\postprocessing\aspect_ratio.cpp object\dcraw_process_st.obj: src\postprocessing\dcraw_process.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\dcraw_process_st.obj" /c src\postprocessing\dcraw_process.cpp object\dcraw_process.obj: src\postprocessing\dcraw_process.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\dcraw_process.obj" /c src\postprocessing\dcraw_process.cpp object\mem_image_st.obj: src\postprocessing\mem_image.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\mem_image_st.obj" /c src\postprocessing\mem_image.cpp object\mem_image.obj: src\postprocessing\mem_image.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\mem_image.obj" /c src\postprocessing\mem_image.cpp object\postprocessing_aux_st.obj: src\postprocessing\postprocessing_aux.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\postprocessing_aux_st.obj" /c src\postprocessing\postprocessing_aux.cpp object\postprocessing_aux.obj: src\postprocessing\postprocessing_aux.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\postprocessing_aux.obj" /c src\postprocessing\postprocessing_aux.cpp object\postprocessing_utils_dcrdefs_st.obj: src\postprocessing\postprocessing_utils_dcrdefs.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\postprocessing_utils_dcrdefs_st.obj" /c src\postprocessing\postprocessing_utils_dcrdefs.cpp object\postprocessing_utils_dcrdefs.obj: src\postprocessing\postprocessing_utils_dcrdefs.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\postprocessing_utils_dcrdefs.obj" /c src\postprocessing\postprocessing_utils_dcrdefs.cpp object\postprocessing_utils_st.obj: src\postprocessing\postprocessing_utils.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\postprocessing_utils_st.obj" /c src\postprocessing\postprocessing_utils.cpp object\postprocessing_utils.obj: src\postprocessing\postprocessing_utils.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\postprocessing_utils.obj" /c src\postprocessing\postprocessing_utils.cpp object\ext_preprocess_st.obj: src\preprocessing\ext_preprocess.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\ext_preprocess_st.obj" /c src\preprocessing\ext_preprocess.cpp object\ext_preprocess.obj: src\preprocessing\ext_preprocess.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\ext_preprocess.obj" /c src\preprocessing\ext_preprocess.cpp object\raw2image_st.obj: src\preprocessing\raw2image.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\raw2image_st.obj" /c src\preprocessing\raw2image.cpp object\raw2image.obj: src\preprocessing\raw2image.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\raw2image.obj" /c src\preprocessing\raw2image.cpp object\subtract_black_st.obj: src\preprocessing\subtract_black.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\subtract_black_st.obj" /c src\preprocessing\subtract_black.cpp object\subtract_black.obj: src\preprocessing\subtract_black.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\subtract_black.obj" /c src\preprocessing\subtract_black.cpp object\cameralist_st.obj: src\tables\cameralist.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\cameralist_st.obj" /c src\tables\cameralist.cpp object\cameralist.obj: src\tables\cameralist.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\cameralist.obj" /c src\tables\cameralist.cpp object\colorconst_st.obj: src\tables\colorconst.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\colorconst_st.obj" /c src\tables\colorconst.cpp object\colorconst.obj: src\tables\colorconst.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\colorconst.obj" /c src\tables\colorconst.cpp object\colordata_st.obj: src\tables\colordata.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\colordata_st.obj" /c src\tables\colordata.cpp object\colordata.obj: src\tables\colordata.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\colordata.obj" /c src\tables\colordata.cpp object\wblists_st.obj: src\tables\wblists.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\wblists_st.obj" /c src\tables\wblists.cpp object\wblists.obj: src\tables\wblists.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\wblists.obj" /c src\tables\wblists.cpp object\curves_st.obj: src\utils\curves.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\curves_st.obj" /c src\utils\curves.cpp object\curves.obj: src\utils\curves.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\curves.obj" /c src\utils\curves.cpp object\decoder_info_st.obj: src\utils\decoder_info.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\decoder_info_st.obj" /c src\utils\decoder_info.cpp object\decoder_info.obj: src\utils\decoder_info.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\decoder_info.obj" /c src\utils\decoder_info.cpp object\init_close_utils_st.obj: src\utils\init_close_utils.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\init_close_utils_st.obj" /c src\utils\init_close_utils.cpp object\init_close_utils.obj: src\utils\init_close_utils.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\init_close_utils.obj" /c src\utils\init_close_utils.cpp object\open_st.obj: src\utils\open.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\open_st.obj" /c src\utils\open.cpp object\open.obj: src\utils\open.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\open.obj" /c src\utils\open.cpp object\phaseone_processing_st.obj: src\utils\phaseone_processing.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\phaseone_processing_st.obj" /c src\utils\phaseone_processing.cpp object\phaseone_processing.obj: src\utils\phaseone_processing.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\phaseone_processing.obj" /c src\utils\phaseone_processing.cpp object\read_utils_st.obj: src\utils\read_utils.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\read_utils_st.obj" /c src\utils\read_utils.cpp object\read_utils.obj: src\utils\read_utils.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\read_utils.obj" /c src\utils\read_utils.cpp object\thumb_utils_st.obj: src\utils\thumb_utils.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\thumb_utils_st.obj" /c src\utils\thumb_utils.cpp object\thumb_utils.obj: src\utils\thumb_utils.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\thumb_utils.obj" /c src\utils\thumb_utils.cpp object\utils_dcraw_st.obj: src\utils\utils_dcraw.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\utils_dcraw_st.obj" /c src\utils\utils_dcraw.cpp object\utils_dcraw.obj: src\utils\utils_dcraw.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\utils_dcraw.obj" /c src\utils\utils_dcraw.cpp object\utils_libraw_st.obj: src\utils\utils_libraw.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\utils_libraw_st.obj" /c src\utils\utils_libraw.cpp object\utils_libraw.obj: src\utils\utils_libraw.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\utils_libraw.obj" /c src\utils\utils_libraw.cpp object\apply_profile_st.obj: src\write\apply_profile.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\apply_profile_st.obj" /c src\write\apply_profile.cpp object\apply_profile.obj: src\write\apply_profile.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\apply_profile.obj" /c src\write\apply_profile.cpp object\file_write_st.obj: src\write\file_write.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\file_write_st.obj" /c src\write\file_write.cpp object\file_write.obj: src\write\file_write.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\file_write.obj" /c src\write\file_write.cpp object\tiff_writer_st.obj: src\write\tiff_writer.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\tiff_writer_st.obj" /c src\write\tiff_writer.cpp object\tiff_writer.obj: src\write\tiff_writer.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\tiff_writer.obj" /c src\write\tiff_writer.cpp object\x3f_parse_process_st.obj: src\x3f\x3f_parse_process.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\x3f_parse_process_st.obj" /c src\x3f\x3f_parse_process.cpp object\x3f_parse_process.obj: src\x3f\x3f_parse_process.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\x3f_parse_process.obj" /c src\x3f\x3f_parse_process.cpp object\x3f_utils_patched_st.obj: src\x3f\x3f_utils_patched.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\x3f_utils_patched_st.obj" /c src\x3f\x3f_utils_patched.cpp object\x3f_utils_patched.obj: src\x3f\x3f_utils_patched.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\x3f_utils_patched.obj" /c src\x3f\x3f_utils_patched.cpp object\libraw_c_api_st.obj: src\libraw_c_api.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\libraw_c_api_st.obj" /c src\libraw_c_api.cpp object\libraw_c_api.obj: src\libraw_c_api.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\libraw_c_api.obj" /c src\libraw_c_api.cpp object\libraw_datastream_st.obj: src\libraw_datastream.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\libraw_datastream_st.obj" /c src\libraw_datastream.cpp object\libraw_datastream.obj: src\libraw_datastream.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\libraw_datastream.obj" /c src\libraw_datastream.cpp LibRaw-0.21.4/README.DNGSDK.txt000066400000000000000000000044131477673233700154520ustar00rootroot00000000000000LibRaw can decode most common DNG formats (Bayer/Linear, 16-bit integer and floating point) by itself (you need to use zlib for deflate decompression support and libjpeg for lossy compressed DNGs). Some rare flavours of DNG files (e.g. for 8-bit files) are not implemented in LibRaw. These files never come from camera or DNG files created by Adobe DNG Converter, but created by some processing software that uses DNG as intermediate format. To decode such files you need to compile LibRaw with Adobe DNG SDK. This SDK to be used internally, standard LibRaw API remains untouched (you may specify what kinds of DNG files you want to decode via Adobe code, see below). To build LibRaw with DNG SDK specify USE_DNGSDK in defines and adjust include/linker path settings to point to DNG SDK's include and library folders. DNG SDK Version compatibility: - Since LibRaw 0.20, DNG SDK 1.4 is required (DNG SDK 1.5 may work too, but have not tested w/ LibRaw). - There are several DNG SDK 1.4 versions circulated, the oldest known is dated May 2012, you'll need the last one (dated June 2015). - This version is available from Adobe site: http://download.adobe.com/pub/adobe/dng/dng_sdk_1_4.zip In your application * create dng_host object (or derived object, e.g. with multithreaded) entity in your program; * pass it to LibRaw via LibRaw::set_dng_host(dng_host *) call to enable DNG SDK use on runtime * adjust imgdata.rawparams.use_dngsdk parameter with one of this values (ORed bitwise): LIBRAW_DNG_NONE - do not use DNG SDK for DNG processing LIBRAW_DNG_FLOAT - process floating point DNGs via Adobe DNG SDK LIBRAW_DNG_LINEAR - process 'linear DNG' (i.e. demosaiced) LIBRAW_DNG_DEFLATE - process DNGs compressed with deflate (gzip) LIBRAW_DNG_XTRANS - process Fuji X-Trans DNGs (6x6 CFA) LIBRAW_DNG_OTHER - process other files (so usual 2x2 bayer) LIBRAW_DNG_8BIT - process 8bit DNGs (e.g. JPEG compressed ones) Default value for this field: LIBRAW_DNG_DEFAULT=LIBRAW_DNG_FLOAT|LIBRAW_DNG_LINEAR|LIBRAW_DNG_DEFLATE | LIBRAW_DNG_8BIT You also may use this macro to pass all supported DNGs to Adobe SDK: LIBRAW_DNG_ALL = LIBRAW_DNG_FLOAT|LIBRAW_DNG_LINEAR|LIBRAW_DNG_XTRANS|LIBRAW_DNG_OTHER | LIBRAW_DNG_8BIT LibRaw-0.21.4/README.GoPro.txt000066400000000000000000000104151477673233700155250ustar00rootroot00000000000000GoPro HERO/Fusion .GPR files are DNG files by nature, but with own wavelet-based codec. GoPro provides GPR SDK for reading these files, available at https://github.com/gopro/gpr LibRaw is able to use this GPR SDK to read GoPro HERO/Fusion files. To enable this support: 1. Build GPR SDK (see NOTES section below) 2. Build LibRaw with -DUSE_DNGSDK and -DUSE_GPRSDK compiler flags (you'll need to adjust INCLUDE path and linker flags to add GPR SDK files to compile/link). NOTES: I. GPR SDK comes with (patched) Adobe DNG SDK source (v1.4 but outdated). This DNG SDK is *NOT* compatible with LibRaw since 0.20 due to internals change . II. So, you need to patch latest Adobe DNG SDK v1.4 (dated 2015), this version is available from Adobe: http://download.adobe.com/pub/adobe/dng/dng_sdk_1_4.zip or use Adobe DNG SDK v1.6 (most likely, this apply for v1.5 too, but not tested/checked): a) For Adobe DNG SDK v1.4 you'll need to enable dng_ifd.fCompression value == 9 in dng_ifd::IsValidCFA() call Use provided patch: LibRaw/GoPro/dng-sdk-1_4-allow-VC5-validate.diff (it may not apply to any Adobe DNG SDK version, if so apply it by hands). This compression type is already handled (passed via validation) in Adobe DNG SDK v1.6 b) Adobe DNG SDK v1.6 defines the ccVc5 constant in dng_tag_values.h so GPR SDK's gpr_read_image.cpp will not compile due to constant redefinition so use provided patch: LibRaw/GoPro/dng-sdk-1_6-hide-ccVc5-definitiion.diff to use Adobe's definitiion c) Newer (than supplied w/ GPR SDK) Adobe SDK versions changes dng_read_image::ReadTile interface, please apply patches LibRaw/GoPro/gpr_read_image.cpp.diff and LibRaw/GoPro/gpr_read_image.h.diff to your GPR SDK code d) GPR SDK's gpr_sdk/private/gpr.cpp uses own (added) dng_host method GetGPMFPayload so it will not compile with Adobes (not patched) dng_host.h LibRaw does not use high-level interface provided by gpr.cpp, so possible problem solutions are: - either compile GPR SDK without gpr_sdk/private/gpr.cpp file - or provide GPR's dng_host.h while building GPR SDK. (in our software we use 1st method). See Note VII below for detailed GPR SDK build instructions w/ Cmake III. LibRaw uses private gpr_read_image() interface So you'll need to add PATH_TO/gpr_sdk/gpr_sdk/private to -I compiler flags. IV. -DUSE_GPRSDK LibRaw build flag requires -DUSE_DNGSDK. LibRaw will not compile if USE_GPRSDK is set, but USE_DNGSDK is not V. LibRaw will use DNG SDK to unpack GoPro files even if imgdata.params.use_dng_sdk is set to 0. VI. If LibRaw is built with -DUSE_GPRSDK, LibRaw::capabilities will return LIBRAW_CAPS_GPRSDK flag. VII. GPR SDK build using cmake (contributed by our user, great thanks) 1. replace gopro's toplevel CMakeLists.txt with this one (this builds only a subset of the libraries): ------------------------------------ # minimum required cmake version cmake_minimum_required( VERSION 3.5 FATAL_ERROR ) set(CMAKE_SUPPRESS_REGENERATION true) set(CMAKE_C_FLAGS "-std=c99") # project name project( gpr ) option(DNGINCLUDEDIR "Adobe DNG toolkit include directory") INCLUDE_DIRECTORIES( ${DNGINCLUDEDIR} ) # DNG toolkit requires C++11 minimum: set_property(GLOBAL PROPERTY CXX_STANDARD 17) # add needed subdirectories add_subdirectory( "source/lib/common" ) add_subdirectory( "source/lib/vc5_common" ) add_subdirectory( "source/lib/vc5_decoder" ) add_subdirectory( "source/lib/gpr_sdk" ) set_property(TARGET gpr_sdk PROPERTY CXX_STANDARD 17) IF (WIN32) TARGET_COMPILE_DEFINITIONS( gpr_sdk PUBLIC -DqWinOS=1 -DqMacOS=0 -DqLinux=0) ELSEIF (APPLE) TARGET_COMPILE_DEFINITIONS( gpr_sdk PUBLIC -DqWinOS=0 -DqMacOS=1 -DqLinux=0) ELSE() TARGET_COMPILE_DEFINITIONS( gpr_sdk PUBLIC -DqWinOS=0 -DqMacOS=0 -DqLinux=1) ENDIF() ---------------------------------------- 2. apply the two patches of README.GoPro.txt section II b. the patch of section IIa is not needed with libdng1.5. 3. delete these two files: /source/lib/gpr_sdk/private/gpr.cpp /source/lib/gpr_sdk/private/gpr_image_writer.cpp 4. run CMAKE with -DDNGINCLUDEDIR, pointing to the headers from Adobe dng 1.5. 5. build. You get 4 libraries "gpr_sdk", "vc5_common", "vc5_decoder", "common", the rest is ignored. LibRaw-0.21.4/README.RawSpeed.txt000066400000000000000000000046271477673233700162210ustar00rootroot00000000000000================= Compile LibRaw with RawSpeed support ======================== 0) RawSpeed version: LibRaw supports 'master' version of RawSpeed library: https://github.com/darktable-org/rawspeed/tree/master Although this version is really outdated, newer versions does not looks stable enough for production use (for example, this critical issue not fixed for 10+ months: https://github.com/darktable-org/rawspeed/issues/100 ) 1) Prerequisites To build RawSpeed you need libxml2, iconv, and JPEG library installed on your system. 2) Build RawSpeed: -- consult http://rawstudio.org/blog/?p=800 for details -- Win32: you need POSIX Threads for Win32 installed on your system (http://sources.redhat.com/pthreads-win32/) -- use provided RawSpeed/rawspeed.samsung-decoder.patch to fix old Samsung decoder bug -- you may use qmake .pro files supplied in LibRaw distribution (RawSpeed/rawspeed.qmake-pro-files.patch) Adjust path to libraries/includes according to your setup. -- Win32: you need to add __declspec(..) to external C++ classes. Use patch provided with LibRaw (RawSpeed/rawspeed.win32-dll.patch) -- Unix: you need to define rawspeed_get_number_of_processor_cores() call For most unix systems (Linux, MacOS X 10.4+, FreeBSD) patch provided with LibRaw (RawSpeed/rawspeed.cpucount-unix.patch) should work. 3) Build LibRaw with RawSpeed support: Win32: --Uncomment CFLAGS_RAWSPEED and LDFLAGS_RAWSPEED lines in Makefile.msvc. Adjust paths to libraries/includes if needed. -- run nmake -f Makefile.msvc Unix/MacOS: -- Uncomment CFLAGS/LDADD lines in RawSpeed section in Makefile.dist -- Uncomment RAWSPEED_DATA line if you wish to rebuild internal copy of RawSpeed's cameras.xml -- run make -f Makefile.dist Compile options: -- You may specify -DNOSONY_RAWSPEED define if you do not want to use RawSpeed's Sony formats decoder (because result of this decoder is different from LibRaw's built-in decoder) 4) Build/run your Apps with LibRaw+RawSpeed -- Build as usual, no changes required in your apps unless you access LibRaw::imgdata.rawdata.raw_image[] directly -- you may turn off RawSpeed support on runtime by setting imgdata.params.use_rawspeed to 0. -- You'll need all shared libraries you linked to at runtime (libxml2, iconv, LibJPEG, and posix threads on Win32). LibRaw-0.21.4/README.cmake000066400000000000000000000004561477673233700147450ustar00rootroot00000000000000Due to inability to support (user contributed) Cmake scripts, the cmake builds are not officially supported by LibRaw team since October 23, 2014 The scripts are moved to separate github repository github.com:LibRaw/LibRaw-cmake.git Checkout from this repo if you want to use Cmake to build LibRaw. LibRaw-0.21.4/README.demosaic-packs000066400000000000000000000014761477673233700165530ustar00rootroot00000000000000======================= LibRaw demosaic pack(s) =============================== We were forced to stop supporting LibRaw demosaic packs: the contributed code is out of date for several years, initial contributors has no interest in it. We too: we (LibRaw team) focused on RAW decode and metadata extraction, but not on postprocessing (demosaic, noise suppression, etc). So, LibRaw-demosaic-pack-GPLn are abandoned now. We will be happy to convey their support and development to any developer who will show interest. LibRaw 0.19 contains callback calls placed instead of calls to demosaic pack routines. So, adaptation of demosaic packs to new LibRaw should be easy (and, of course, we'll provide some support and/or implement additional callbacks if needed). LibRaw-0.21.4/README.md000066400000000000000000000156651477673233700142750ustar00rootroot00000000000000# LibRaw ## Library for reading and processing of RAW digicam images The LibRaw library provides a simple and unified interface for extracting out of RAW files generated by digital photo cameras the following: * RAW data (_pixel values)_ * Metadata necessary for processing RAW (_geometry, CFA / Bayer pattern, black level, white balance, etc.)_ * Embedded preview / thumbnail. The library is intended for use with programs that work with RAW files, such as: * RAW viewers * RAW converters * RAW data analyzers * Software for stitching and compositing multi-frame aggregates like panoramas and image stacks. Using the LibRaw library allows one to focus on the substantive part of processing the data contained in RAW files, without getting distracted by the wide variety of RAW file and metadata formats, compression algorithms, etc. The library’s development is focused on: * Support for new cameras and formats * Improving extraction of metadata necessary for RAW processing * Providing an interface for reading other types of metadata. Additionally, the LibRaw library offers some basic RAW conversion, intended for cases when such conversion is not the main function of the LibRaw-using application _(for example: a viewer for 500+ graphic file formats, including RAW)._ These methods are inherited from the Dave Coffin’s dcraw.c utility _(see below the “Project history” section);_ their further development is not currently planned, because we do not consider production-quality rendering to be in the scope of LibRaw’s functionality _(the methods are retained for compatibility with prior versions and for rapid-fire testing of RAW support and other aspects)._ ## Licensing The LibRaw library is distributed free of charge and with open-source code subject to two licenses: 1\. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 2\. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 To use the LibRaw library in an application, you can choose the license that better suits your needs. If you modify/add/improve the LibRaw source code, then your patches can only be included into the library’s official source code if you agree to it being distributed under both of the above licenses. We do not guarantee that the licensing will not change in future versions of LibRaw. ## Update policy ### Major/minor releases * Major releases _(for example, 0.20)_ are published once every year and a half to two years. * When the first public beta version of a major release is published, the list of supported cameras and formats is frozen; we try (but do not guarantee) to freeze the API/ABI as well. * The public major release contains only that code which has been sufficiently tested on a wide user base (including in our commercial products). Something very new may not be included in it (but it will probably be included in a public snapshot, see below). * Minor updates _(0.20.1, 0.20.2…)_ do not change the API/ABI and new cameras are not added; generally they are just bugfixes. * Bugfixes are published as soon as possible in the [public GitHub repository](https://github.com/LibRaw/LibRaw). * Minor version increments: these are generally published if a serious error has been fixed, one that potentially affects many library users (for example, a possible stack overflow). ### Public snapshots * Public snapshots are published every 7-9 months in the [public GitHub repository](https://github.com/LibRaw/LibRaw). * These versions contain support for new cameras that was added after the previous major release. The API/ABI of public snapshots is not frozen, and may change. * Public snapshots are always tested on a fairly large user base, and may be considered suitable for use in programs that work with files with known origins (that is, recorded directly by users’ digital cameras). However, public snapshots should not be considered sufficiently reliable for processing files that are specially constructed for vulnerability testing; that is, they should not be used in public services that allow for anonymous processing of files of unknown provenance ## Support and feedback * You can submit a bug report in one of the following ways: * [Issues](https://github.com/LibRaw/LibRaw/issues) on GitHub * The libraw.org [forum](https://www.libraw.org/forum) * [Feedback form](https://www.libraw.org/contact) on libraw.org * E-mail us at [info@libraw.org](mailto:info@libraw.org) * Questions can be asked on the forum, through the feedback form, and via the email indicated above. Please do not use Issues on GitHub for questions; it is intended specifically for problem reports. * We prefer to process additions to the source code via the [Pull Requests](https://github.com/LibRaw/LibRaw/pulls) on GitHub. We cannot guarantee any response to requests submitted via the above methods. If you need a guaranteed response for a bug report and/or for extending technical support, please use the Extended Support option. ## Project history The LibRaw project was launched in 2008, based on the [dcraw.c](https://www.dechifro.org/dcraw/) (Dave Coffin) utility, with its goals being to: * Convert dcraw.c into a library that could be used by other programs, while also somewhat improving the structure of dcraw.c (removing global variables, making it thread-safe, etc.) * Import changes made to dcraw.c * Improve/expand the extraction of metadata. Unfortunately, support for dcraw.c was reduced to a minimum in 2015, and completely ceased in 2018. Since then, support for new cameras (including support for new formats) has been done entirely by the LibRaw team. The code that implements rendering of RAW to RGB is inherited from dcraw.c, without major changes (though a set of changes was implemented to speed up and parallelize this code). In the early-to-mid 2010s, we gladly expanded post-processing implemented in LibRaw, and readily accepted the input of outside developers (new/improved methods for debayerization/demosaicing, systematic noise reduction etc.). Experience has shown that the LibRaw team cannot support this added code on their own, while contributors do not provide support and development of the code they suggest and it ends up abandoned. As such, the majority of the modifications that are implemented by people outside the LibRaw team was moved to the [LibRaw-demosaic-pack-….](https://github.com/LibRaw?tab=repositories), where they remain in their original form (but these projects are still present in our GitHub). Thus, we arrive at our current status, described in the first part of this text. ## Copyrights and Acknowledgements Copyright (C) 2008-2021 LibRaw LLC LibRaw uses code from Dave Coffin’s dcraw.c utility (without RESTRICTED/GPL2 code): Copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net LibRaw uses DCB demosaic code by Jaceck Gozdz distributed under BSD license: Copyright (C) 2010, Jacek Gozdz (mailto:cuniek@kft.umcs.lublin.pl) LibRaw uses Roland Karlsson’s X3F tools source code, licensed under BSD license: Copyright (c) 2010, Roland Karlsson (roland@proxel.se)LibRaw-0.21.4/RawSpeed/000077500000000000000000000000001477673233700145135ustar00rootroot00000000000000LibRaw-0.21.4/RawSpeed/rawspeed.cpucount-unix.patch000066400000000000000000000005571477673233700221750ustar00rootroot00000000000000diff --git a/RawSpeed/Common.cpp b/RawSpeed/Common.cpp index abec232..6990c04 100644 --- a/RawSpeed/Common.cpp +++ b/RawSpeed/Common.cpp @@ -31,5 +31,10 @@ void* _aligned_malloc(size_t bytes, size_t alignment) { else return NULL; } +#include +int rawspeed_get_number_of_processor_cores() +{ + return sysconf( _SC_NPROCESSORS_ONLN ); +} #endif LibRaw-0.21.4/RawSpeed/rawspeed.qmake-pro-files.patch000066400000000000000000000063671477673233700223550ustar00rootroot00000000000000diff --git a/RawSpeed/rawspeed-lib.pro b/RawSpeed/rawspeed-lib.pro new file mode 100644 index 0000000..1599ddf --- /dev/null +++ b/RawSpeed/rawspeed-lib.pro @@ -0,0 +1,42 @@ +TEMPLATE=lib +TARGET=rawspeed + +win32:INCLUDEPATH+=d:/Qt/iconv/include d:/Qt/libxml2/include/libxml2 d:/Qt/pthreads/include d:/Qt/libjpeg-turbo/include +win32:LIBS+=-Ld:/Qt/iconv/lib/x86 -liconv -Ld:/Qt/libxml2/lib/x86 -llibxml2 -Ld:/Qt/pthreads/lib/x86 -lpthreadVC2 -Ld:/Qt/libjpeg-turbo/lib/x86 -ljpeg8 + +unix:INCLUDEPATH+=/usr/local/include /usr/local/include/libxml2 +unix:CONFIG+=staticlib + +INCLUDEPATH+=. + +HEADERS = ArwDecoder.h BitPumpJPEG.h BitPumpMSB.h BitPumpMSB32.h \ + BitPumpPlain.h BlackArea.h ByteStream.h ByteStreamSwap.h \ + Camera.h CameraMetaData.h CameraMetadataException.h \ + CameraSensorInfo.h ColorFilterArray.h Common.h Cr2Decoder.h \ + DngDecoder.h DngDecoderSlices.h DngOpcodes.h FileIOException.h \ + FileMap.h FileReader.h IOException.h LJpegDecompressor.h \ + LJpegPlain.h NefDecoder.h NikonDecompressor.h OrfDecoder.h \ + PefDecoder.h PentaxDecompressor.h Point.h RawDecoder.h \ + RawDecoderException.h RawImage.h RawParser.h Rw2Decoder.h SrwDecoder.h \ + StdAfx.h TiffEntry.h TiffEntryBE.h TiffIFD.h TiffIFDBE.h TiffParser.h \ + TiffParserException.h TiffParserHeaderless.h TiffParserOlympus.h \ + TiffTag.h dlldef.h + +SOURCES = \ + ArwDecoder.cpp BitPumpJPEG.cpp BitPumpMSB.cpp BitPumpMSB32.cpp \ + BitPumpPlain.cpp BlackArea.cpp ByteStream.cpp ByteStreamSwap.cpp \ + Camera.cpp CameraMetaData.cpp CameraMetadataException.cpp \ + CameraSensorInfo.cpp ColorFilterArray.cpp Common.cpp Cr2Decoder.cpp \ + DngDecoder.cpp DngDecoderSlices.cpp DngOpcodes.cpp \ + FileIOException.cpp FileMap.cpp FileReader.cpp IOException.cpp \ + LJpegDecompressor.cpp LJpegPlain.cpp NefDecoder.cpp \ + NikonDecompressor.cpp OrfDecoder.cpp PefDecoder.cpp \ + PentaxDecompressor.cpp RawDecoder.cpp RawDecoderException.cpp \ + RawImage.cpp RawImageDataFloat.cpp RawImageDataU16.cpp RawParser.cpp \ + Rw2Decoder.cpp SrwDecoder.cpp TiffEntry.cpp TiffEntryBE.cpp\ + TiffIFD.cpp TiffIFDBE.cpp TiffParser.cpp TiffParserException.cpp \ + TiffParserHeaderless.cpp TiffParserOlympus.cpp + +DEFINES+=RAWSPEED_BUILDLIB +CONFIG-=qt +win32:QMAKE_CXXFLAGS+=/O2 /arch:SSE2 /fp:fast /MP diff --git a/RawSpeed/rawspeed-test.pro b/RawSpeed/rawspeed-test.pro new file mode 100644 index 0000000..518aa98 --- /dev/null +++ b/RawSpeed/rawspeed-test.pro @@ -0,0 +1,21 @@ +TEMPLATE=app +TARGET=rawspeed-test + +SOURCES=RawSpeed.cpp + +win32:CONFIG(debug,debug|release) { + LIBDIR = debug +} else { + LIBDIR = release +} + + +INCLUDEPATH+=../ + +unix:INCLUDEPATH+=/usr/local/include /usr/local/include/libxml2 +unix:LIBS+=-L. -lrawspeed -L/usr/local/lib -lxml2 -ljpeg +win32:LIBS+=-L$$LIBDIR -llibrawspeed +win32:LIBS+=-Ld:/Qt/iconv/lib/x86 -liconv -Ld:/Qt/libxml2/lib/x86 -llibxml2a -Ld:/Qt/pthreads/lib/x86 -lpthreadVC2 -Ld:/Qt/libjpeg-turbo/lib/x86 -ljpeg8 +win32:INCLUDEPATH+=d:/Qt/iconv/include d:/Qt/libxml2/include/libxml2 d:/Qt/pthreads/include d:/Qt/libjpeg-turbo/include +CONFIG-=qt +CONFIG+=console diff --git a/RawSpeed/rawspeed.pro b/RawSpeed/rawspeed.pro new file mode 100644 index 0000000..df2a0b9 --- /dev/null +++ b/RawSpeed/rawspeed.pro @@ -0,0 +1,3 @@ +TEMPLATE=subdirs +SUBDIRS=rawspeed-lib.pro rawspeed-test.pro + LibRaw-0.21.4/RawSpeed/rawspeed.samsung-decoder.patch000066400000000000000000000033401477673233700224250ustar00rootroot00000000000000diff --git a/RawSpeed/SrwDecoder.cpp b/RawSpeed/SrwDecoder.cpp index fa46499..1aff689 100644 --- a/RawSpeed/SrwDecoder.cpp +++ b/RawSpeed/SrwDecoder.cpp @@ -141,7 +141,7 @@ void SrwDecoder::decodeCompressed( TiffIFD* raw ) // First we decode even pixels for (int c = 0; c < 16; c += 2) { int b = len[(c >> 3)]; - int32 adj = ((int32) bits.getBits(b) << (32-b) >> (32-b)); + int32 adj = b > 0 ? ((int32) bits.getBits(b) << (32-b) >> (32-b)) :0; img[c] = adj + img_up[c]; } // Now we decode odd pixels @@ -149,7 +149,7 @@ void SrwDecoder::decodeCompressed( TiffIFD* raw ) // is beyond me, it will hurt compression a deal. for (int c = 1; c < 16; c += 2) { int b = len[2 | (c >> 3)]; - int32 adj = ((int32) bits.getBits(b) << (32-b) >> (32-b)); + int32 adj = b > 0 ? ((int32) bits.getBits(b) << (32-b) >> (32-b)) :0; img[c] = adj + img_up2[c]; } } else { @@ -158,14 +158,14 @@ void SrwDecoder::decodeCompressed( TiffIFD* raw ) int pred_left = x ? img[-2] : 128; for (int c = 0; c < 16; c += 2) { int b = len[(c >> 3)]; - int32 adj = ((int32) bits.getBits(b) << (32-b) >> (32-b)); + int32 adj = b > 0 ? ((int32) bits.getBits(b) << (32-b) >> (32-b)) :0; img[c] = adj + pred_left; } // Now we decode odd pixels pred_left = x ? img[-1] : 128; for (int c = 1; c < 16; c += 2) { int b = len[2 | (c >> 3)]; - int32 adj = ((int32) bits.getBits(b) << (32-b) >> (32-b)); + int32 adj = b > 0 ? ((int32) bits.getBits(b) << (32-b) >> (32-b)) :0; img[c] = adj + pred_left; } } LibRaw-0.21.4/RawSpeed/rawspeed.uncompressed-color-dng.patch000066400000000000000000000012121477673233700237320ustar00rootroot00000000000000diff --git a/RawSpeed/DngDecoder.cpp b/RawSpeed/DngDecoder.cpp index 56c701b..98f2474 100644 --- a/RawSpeed/DngDecoder.cpp +++ b/RawSpeed/DngDecoder.cpp @@ -216,7 +216,7 @@ RawImage DngDecoder::decodeRawInternal() { if (bps != 8 && bps != 16) big_endian = true; try { - readUncompressedRaw(in, size, pos, width*bps / 8, bps, big_endian ? BitOrder_Jpeg : BitOrder_Plain); + readUncompressedRaw(in, size, pos, mRaw->getCpp()*width*bps / 8, bps, big_endian ? BitOrder_Jpeg : BitOrder_Plain); } catch(IOException &ex) { if (i > 0) mRaw->setError(ex.what()); LibRaw-0.21.4/RawSpeed/rawspeed.win32-dll.patch000066400000000000000000000102441477673233700210610ustar00rootroot00000000000000diff --git a/RawSpeed/Camera.h b/RawSpeed/Camera.h index 7b3045d..4363c1b 100644 --- a/RawSpeed/Camera.h +++ b/RawSpeed/Camera.h @@ -6,6 +6,7 @@ #include #include "BlackArea.h" #include "CameraMetadataException.h" +#include "dlldef.h" /* RawSpeed - RAW file decoder. @@ -30,7 +31,7 @@ namespace RawSpeed { -class Camera +class DllDef Camera { public: Camera(xmlDocPtr doc, xmlNodePtr cur); diff --git a/RawSpeed/CameraMetaData.h b/RawSpeed/CameraMetaData.h index 616b2bb..c6b8031 100644 --- a/RawSpeed/CameraMetaData.h +++ b/RawSpeed/CameraMetaData.h @@ -27,9 +27,10 @@ http://www.klauspost.com */ +#include "dlldef.h" namespace RawSpeed { -class CameraMetaData +class DllDef CameraMetaData { public: CameraMetaData(); diff --git a/RawSpeed/CameraMetadataException.h b/RawSpeed/CameraMetadataException.h index 55a2814..52d5ea1 100644 --- a/RawSpeed/CameraMetadataException.h +++ b/RawSpeed/CameraMetadataException.h @@ -22,10 +22,11 @@ #ifndef CAMERA_METADATA_EXCEPTION_H #define CAMERA_METADATA_EXCEPTION_H +#include "dlldef.h" namespace RawSpeed { -void ThrowCME(const char* fmt, ...); +void DllDef ThrowCME(const char* fmt, ...); class CameraMetadataException : public std::runtime_error diff --git a/RawSpeed/FileMap.h b/RawSpeed/FileMap.h index 5c15918..bcd2a79 100644 --- a/RawSpeed/FileMap.h +++ b/RawSpeed/FileMap.h @@ -25,6 +25,7 @@ */ #include "IOException.h" +#include "dlldef.h" namespace RawSpeed { @@ -36,7 +37,7 @@ namespace RawSpeed { * This can also be done as a MemMap * *****************************/ -class FileMap +class DllDef FileMap { public: FileMap(uint32 _size); // Allocates the data array itself diff --git a/RawSpeed/FileReader.h b/RawSpeed/FileReader.h index 7448ec2..fb42ac0 100644 --- a/RawSpeed/FileReader.h +++ b/RawSpeed/FileReader.h @@ -24,10 +24,11 @@ #include "FileIOException.h" #include "FileMap.h" +#include "dlldef.h" namespace RawSpeed { -class FileReader +class DllDef FileReader { public: FileReader(LPCWSTR filename); diff --git a/RawSpeed/RawDecoder.h b/RawSpeed/RawDecoder.h index a6c4708..b35cae5 100644 --- a/RawSpeed/RawDecoder.h +++ b/RawSpeed/RawDecoder.h @@ -9,6 +9,7 @@ #include "BitPumpPlain.h" #include "CameraMetaData.h" #include "TiffIFD.h" +#include "dlldef.h" /* RawSpeed - RAW file decoder. @@ -48,7 +49,7 @@ class RawDecoderThread RawDecoder* parent; }; -class RawDecoder +class DllDef RawDecoder { public: /* Construct decoder instance - FileMap is a filemap of the file to be decoded */ diff --git a/RawSpeed/RawImage.h b/RawSpeed/RawImage.h index 5741760..74cea96 100644 --- a/RawSpeed/RawImage.h +++ b/RawSpeed/RawImage.h @@ -26,13 +26,15 @@ http://www.klauspost.com */ +#include "dlldef.h" + namespace RawSpeed { class RawImage; class RawImageWorker; typedef enum {TYPE_USHORT16, TYPE_FLOAT32} RawImageType; -class RawImageData +class DllDef RawImageData { friend class RawImageWorker; public: @@ -125,7 +127,7 @@ protected: int end_y; }; - class RawImage { + class DllDef RawImage { public: static RawImage create(RawImageType type = TYPE_USHORT16); static RawImage create(iPoint2D dim, RawImageType type = TYPE_USHORT16, uint32 componentsPerPixel = 1); diff --git a/RawSpeed/RawParser.h b/RawSpeed/RawParser.h index 9ef86e3..1b3cb83 100644 --- a/RawSpeed/RawParser.h +++ b/RawSpeed/RawParser.h @@ -25,10 +25,11 @@ #include "FileMap.h" #include "RawDecoder.h" +#include "dlldef.h" namespace RawSpeed { -class RawParser +class DllDef RawParser { public: RawParser(FileMap* input); diff --git a/RawSpeed/dlldef.h b/RawSpeed/dlldef.h new file mode 100644 index 0000000..c806451 --- /dev/null +++ b/RawSpeed/dlldef.h @@ -0,0 +1,20 @@ +#ifndef DLLDEF_H +#define DLLDEF_H + +#ifdef _WIN32 +#ifdef _MSC_VER +#pragma warning( disable: 4251 ) +#endif +#ifdef RAWSPEED_NODLL +# define DllDef +#else +# ifdef RAWSPEED_BUILDLIB +# define DllDef __declspec( dllexport ) +# else +# define DllDef __declspec( dllimport ) +# endif +#endif +#else +# define DllDef +#endif +#endif LibRaw-0.21.4/RawSpeed/rawspeed_xmldata.cpp000066400000000000000000004757671477673233700205750ustar00rootroot00000000000000const char *_rawspeed_data_xml[]={ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "]>\n", "\n", "\n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " Canon EOS REBEL SL1\n", " Canon EOS Kiss X7\n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " Canon EOS DIGITAL REBEL XT\n", " Canon EOS Kiss Digital N\n", " Canon EOS 350D\n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " Canon EOS DIGITAL REBEL XSi\n", " Canon EOS Kiss Digital X2\n", " Canon EOS Kiss X2\n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " Canon EOS REBEL T5i\n", " Canon EOS Kiss X7i\n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " Canon EOS REBEL T1i\n", " Canon EOS Kiss X3\n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " Canon EOS REBEL T2i\n", " Canon EOS Kiss X4\n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " Canon EOS REBEL T3i\n", " Canon EOS Kiss X5\n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " Canon EOS REBEL T4i\n", " Canon EOS Kiss X6i\n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " Canon EOS DIGITAL REBEL XS\n", " Canon EOS Kiss Digital F\n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " Canon EOS REBEL T3\n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " Canon EOS REBEL T5\n", " Canon EOS Kiss X70\n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " Canon EOS DIGITAL REBEL XTi\n", " Canon EOS Kiss Digital X\n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " NIKON D800E\n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", "\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\t\t\t\t\n", "\t\t\t\t\t\t\t\t\n", "\t\t\t\t\t\t\t\t\t\t\t\tRED\n", "\t\t\t\t\t\t\t\t\t\t\t\tGREEN\n", "\t\t\t\t\t\t\t\t\t\t\t\tGREEN\n", "\t\t\t\t\t\t\t\t\t\t\t\tBLUE\n", "\t\t\t\t\t\t\t\t\n", "\t\t\t\t\t\t\t\t\n", "\t\t\t\t\t\t\t\t\n", "\t\t\t\t\n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " DMC-FZ38\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " DMC-FZ38\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " DMC-FZ40\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " DMC-FZ40\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " DMC-FZ72\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " DMC-FZ72\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " BLUE\n", " RED\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " GREEN\n", " RED\n", " BLUE\n", " GREEN\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " BLUE\n", " GREEN\n", " GREEN\n", " RED\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " RED\n", " GREEN\n", " GREEN\n", " BLUE\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", 0 }; LibRaw-0.21.4/RawSpeed3/000077500000000000000000000000001477673233700145765ustar00rootroot00000000000000LibRaw-0.21.4/RawSpeed3/README.md000066400000000000000000000130661477673233700160630ustar00rootroot00000000000000# About RawSpeed v3 The current version of the RawSpeed library (https://github.com/darktable-org/rawspeed ) does not have a version number, we call it "version 3" to distinguish it from RawSpeed/master, the version number is taken from darktable 3.x (which uses this library). This library provides faster decoding of some RAW formats (even faster than RawSpeed v1), the difference can be tens of percent (without using OpenMP) for Huffman-compressed files (Canon CR2, Nikon NEF, etc). Unfortunately, the RawSpeed-v3 source code is constantly changing and this is due not so much to the development of the library (support for new cameras, formats, etc.), but to the fact that the current maintainer is using it as an aid in self-development as a programmer. They are extremely reluctant to accept 3rd-party patches to this library, therefore, the fixes necessary for correct work with LibRaw have been added to the LibRaw distribution (see below). All our patches, of course, are suitable only for a specific version (commit-id) of RawSpeed-v3, if you want to use a different version, you will have to adjust them. # Building RawSpeed v3 and C-API wrapper ## Preparing the source 1. Take a specific commit from github https://github.com/darktable-org/rawspeed/commit/de70ef5fbc62cde91009c8cff7a206272abe631e 2. Apply the following patches from LibRaw/RawSpeed3/patches folder: * **01.CameraMeta-extensibility.patch** - allows derived classes from CameraMeta, which allows loading camera descriptions not only from a disk file. * **02.Makernotes-processing.patch** - fixes an error in processing the Makernotes tag. * **03.remove-limits-and-logging.patch** - removes debug printing and file size limits. This patch is optional, but if you are going to decode files from cameras that were not available at the time a particular version of RawSpeed was created, then this patch can be useful. * **04.clang-cl-compatibility.patch -** fixes for compatibility with Microsoft C++ library. ## Building the RawSpeed-v3 library We **do not** offer advice on building RawSpeed3, if you need such advice please contact the maintainer of the library. At a minimum, it **can be** compiled with Clang (XCode) on macOS and clang-cl (MSVC) on Windows. Use your favorite build system. Files for CMake come with RawSpeed, but any other build system can be used (in that case you probably will need to create your own rawspeedconfig.h instead of one created via CMake). In our projects we use RawSpeed-v3 without OpenMP. ## Building the C-API wrapper To simplify the integration with LibRaw, we have implemented a simple wrapper with a C interface, which hides everything unnecessary, thus: * To build LibRaw (with RawSpeed-v3 support) you do not need access to RawSpeed .h-files * When building LibRaw and RawSpeed-v3 using different compilers there is no issue with C++ name mangling. The wrapper sources are in the **LibRaw/RawSpeed3/rawspeed3_c_api folder**, they include four files: 1. **rawspeed3_capi.h** - header file 2. **rawspeed3_capi.cpp** - wrapper sources 3. **rsxml2c.sh** - shell script that will convert RawSpeed/data/cameras.xml to a C++ file containing camera definitions 4. **rawspeed3_capi_test.cpp** - test program for checking the build correctness and operation ability. The wrapper provides simple *decode only* interface (init library, decode RAW passed via buffer, free decoded file buffer, release the library) it is self-documented via comments in the rawspeed3_capi.h file. To make a file with camera definitions, run the command (you can add it to the build system): `sh ./rawspeed3_c_api/rsxml2c.sh < path/to/RawSpeed/data/cameras.xml > rawspeed3_c_api/cameras.cpp` The **rsxml2c.sh** script requires **cat**, **tr**, and **sed** unix command-line utilities installed, there is no specific version requirements. Add the resulting file (LibRaw/RawSpeed3/rawspeed3_c_api/cameras.cpp) and LibRaw/RawSpeed3/rawspeed3_c_api/rawspeed3_capi.cpp, to the build of the RawSpeed-v3 (dynamic) library, which you learned to build in the previous step. If building Windows DLL: rawspeed3_capi.cpp should be compiled with -DRAWSPEED_BUILDLIB to create dll export entries automatically. To check that everything works, you can use the LibRaw/RawSpeed3/rawspeed3_c_api/rawspeed3_capi_test.cpp test program, it should be possible to build it and link with RawSpeed-v3 (+ C-API); and after that this test program should be ready to decode RAW files passed to it from command line. # Building LibRaw with RawSpeed-v3 support When building, specify the following parameters * LibRaw/RawSpeed3/rawspeed3_c_api to the search path for include files * Specify preprocessor flags -DUSE_RAWSPEED3 -DUSE_RAWSPEED_BITS: * USE_RAWSPEED3 enables the use of RawSpeed-v3 * USE_RAWSPEED_BITS enables (a more granulated) control of RawSpeed-v3 / RawSpeed processing * set the RawSpeed-v3 (+ C-API) library, obtained in the previous steps, as an input linker file # Using LibRaw with RawSpeed-v3 Support Use LibRaw as usual. Enable RawSpeed3 use by setting bits in imgdata.rawparams.userawspeed (LIBRAW_RAWSPEEDV3_USE, LIBRAW_RAWSPEEDV3_IGNOREERRORS, LIBRAW_RAWSPEEDV3_FAILONUNKNOWN) If RawSpeed was set as the decoder the following bits will be set in imgdata.processwarnings: * LIBRAW_WARN_RAWSPEED3_PROCESSED - if decoding was successful * LIBRAW_WARN_RAWSPEED3_PROBLEM - if decoding attempt failed (flags and bits are described in LibRaw's Changelog) With RawSpeed-v3, the entire RAW file is read into the memory buffer (as it is with RawSpeed version 1), so it increases LibRaw memory footprint. LibRaw-0.21.4/RawSpeed3/patches/000077500000000000000000000000001477673233700162255ustar00rootroot00000000000000LibRaw-0.21.4/RawSpeed3/patches/01.CameraMeta-extensibility.patch000066400000000000000000000005621477673233700243610ustar00rootroot00000000000000diff --git a/src/librawspeed/metadata/CameraMetaData.h b/src/librawspeed/metadata/CameraMetaData.h index c2f6f1dd..13cab9c9 100644 --- a/src/librawspeed/metadata/CameraMetaData.h +++ b/src/librawspeed/metadata/CameraMetaData.h @@ -41,7 +41,7 @@ struct CameraId { } }; -class CameraMetaData { +class CameraMetaData final { public: CameraMetaData() = default; LibRaw-0.21.4/RawSpeed3/patches/02.Makernotes-processing.patch000066400000000000000000000033501477673233700237510ustar00rootroot00000000000000diff --git a/src/librawspeed/tiff/TiffIFD.cpp b/src/librawspeed/tiff/TiffIFD.cpp index e732eae2..05251dd9 100644 --- a/src/librawspeed/tiff/TiffIFD.cpp +++ b/src/librawspeed/tiff/TiffIFD.cpp @@ -143,6 +143,7 @@ TiffRootIFDOwner TiffIFD::parseMakerNote(NORangesSet* ifds, string make = makeEntry != nullptr ? trimSpaces(makeEntry->getString()) : ""; ByteStream bs = t->getData(); + auto bufbegin = bs.begin() + bs.getPosition(); // helper function for easy setup of ByteStream buffer for the different maker note types // 'rebase' means position 0 of new stream equals current position @@ -159,7 +160,9 @@ TiffRootIFDOwner TiffIFD::parseMakerNote(NORangesSet* ifds, bs.skipBytes(newPosition); }; - if (bs.hasPrefix("AOC\0", 4)) { + if (bs.hasPrefix("LSI1\0", 5)) { // Skip LSI1 makernotes + return std::make_unique(this, ifds, bs, UINT32_MAX); // UINT32_MAX offset => special handling, empty IFD + } else if (bs.hasPrefix("AOC\0", 4)) { setup(false, 6, 4, "Pentax makernote"); } else if (bs.hasPrefix("PENTAX", 6)) { setup(true, 10, 8, "Pentax makernote"); @@ -197,6 +200,12 @@ TiffRootIFDOwner TiffIFD::parseMakerNote(NORangesSet* ifds, } } + auto readed = bs.begin() - bufbegin + bs.getPosition(); + ByteStream bscheck(bs); + const auto IFDSize = 6 + 12 * bscheck.getU16(); + + if(IFDSize > t->count - readed) // IFDSize too big, probably binary Makernotes dir, not TIFF-like, could not be handled by TiffRootIFD reader + return std::make_unique(this, ifds, bs, UINT32_MAX); // // UINT32_MAX offset => special handling, empty IFD // Attempt to parse the rest as an IFD return std::make_unique(this, ifds, bs, bs.getPosition()); } LibRaw-0.21.4/RawSpeed3/patches/03.remove-limits-and-logging.patch000066400000000000000000000262161477673233700244560ustar00rootroot00000000000000diff --git a/src/librawspeed/common/Common.cpp b/src/librawspeed/common/Common.cpp index 8c8c5663..d9b5e463 100644 --- a/src/librawspeed/common/Common.cpp +++ b/src/librawspeed/common/Common.cpp @@ -36,6 +36,7 @@ writeLog(DEBUG_PRIO priority, const char* format, ...) { #else void writeLog(DEBUG_PRIO priority, const char* format, ...) { +#if 0 #ifndef _DEBUG if (priority < DEBUG_PRIO_INFO) #endif // _DEBUG @@ -55,6 +56,7 @@ void writeLog(DEBUG_PRIO priority, const char* format, ...) { if (priority < DEBUG_PRIO_INFO) #endif // _DEBUG fprintf(stdout, "%s", "\n"); +#endif } #endif diff --git a/src/librawspeed/common/RawspeedException.h b/src/librawspeed/common/RawspeedException.h index 33b9cc29..a9f503a7 100644 --- a/src/librawspeed/common/RawspeedException.h +++ b/src/librawspeed/common/RawspeedException.h @@ -45,12 +45,13 @@ template "Don't have thread-local-storage! Exception text may be garbled if used multithreaded" static char buf[bufSize]; #endif - +#if 0 va_list val; va_start(val, fmt); vsnprintf(buf.data(), sizeof(buf), fmt, val); va_end(val); writeLog(DEBUG_PRIO_EXTRA, "EXCEPTION: %s", buf.data()); +#endif throw T(buf.data()); } diff --git a/src/librawspeed/decoders/ArwDecoder.cpp b/src/librawspeed/decoders/ArwDecoder.cpp index f1d5a63c..2025d260 100644 --- a/src/librawspeed/decoders/ArwDecoder.cpp +++ b/src/librawspeed/decoders/ArwDecoder.cpp @@ -186,8 +186,8 @@ RawImage ArwDecoder::decodeRawInternal() { } } - if (width == 0 || height == 0 || height % 2 != 0 || width > 9600 || - height > 6376) + if (width == 0 || height == 0 || height % 2 != 0 /* || width > 9600 || + height > 6376 */) ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); bool arw1 = uint64_t(counts->getU32()) * 8 != width * height * bitPerPixel; @@ -241,7 +241,7 @@ void ArwDecoder::DecodeUncompressed(const TiffIFD* raw) { mRaw->dim = iPoint2D(width, height); - if (width == 0 || height == 0 || width > 9600 || height > 6376) + if (width == 0 || height == 0 /* || width > 9600 || height > 6376 */) ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); if (c2 == 0) diff --git a/src/librawspeed/decoders/IiqDecoder.cpp b/src/librawspeed/decoders/IiqDecoder.cpp index 31c460d9..61b04e1a 100644 --- a/src/librawspeed/decoders/IiqDecoder.cpp +++ b/src/librawspeed/decoders/IiqDecoder.cpp @@ -185,7 +185,7 @@ RawImage IiqDecoder::decodeRawInternal() { } // FIXME: could be wrong. max "active pixels" in "Sensor+" mode - "101 MP" - if (width == 0 || height == 0 || width > 11976 || height > 8854) + if (width == 0 || height == 0 /* || width > 11976 || height > 8854 */) ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); if (split_col > width || split_row > height) diff --git a/src/librawspeed/decoders/MosDecoder.cpp b/src/librawspeed/decoders/MosDecoder.cpp index 9f01a11c..db4b8f50 100644 --- a/src/librawspeed/decoders/MosDecoder.cpp +++ b/src/librawspeed/decoders/MosDecoder.cpp @@ -113,7 +113,7 @@ RawImage MosDecoder::decodeRawInternal() { uint32_t height = raw->getEntry(IMAGELENGTH)->getU32(); // FIXME: could be wrong. max "active pixels" - "80 MP" - if (width == 0 || height == 0 || width > 10328 || height > 7760) + if (width == 0 || height == 0 /* || width > 10328 || height > 7760 */) ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); mRaw->dim = iPoint2D(width, height); diff --git a/src/librawspeed/decoders/NefDecoder.cpp b/src/librawspeed/decoders/NefDecoder.cpp index 222c62f0..7314ca15 100644 --- a/src/librawspeed/decoders/NefDecoder.cpp +++ b/src/librawspeed/decoders/NefDecoder.cpp @@ -214,7 +214,7 @@ void NefDecoder::DecodeUncompressed() { mRaw->dim = iPoint2D(width, height); - if (width == 0 || height == 0 || width > 8288 || height > 5520) + if (width == 0 || height == 0 /* || width > 8288 || height > 5520 */) ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); if (counts->count != offsets->count) { @@ -370,8 +370,8 @@ void NefDecoder::DecodeSNefUncompressed() { uint32_t width = raw->getEntry(IMAGEWIDTH)->getU32(); uint32_t height = raw->getEntry(IMAGELENGTH)->getU32(); - if (width == 0 || height == 0 || width % 2 != 0 || width > 3680 || - height > 2456) + if (width == 0 || height == 0 || width % 2 != 0 /* || width > 3680 || + height > 2456 */) ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); mRaw->dim = iPoint2D(width, height); diff --git a/src/librawspeed/decoders/OrfDecoder.cpp b/src/librawspeed/decoders/OrfDecoder.cpp index 7eb1a901..de557d5f 100644 --- a/src/librawspeed/decoders/OrfDecoder.cpp +++ b/src/librawspeed/decoders/OrfDecoder.cpp @@ -109,7 +109,7 @@ RawImage OrfDecoder::decodeRawInternal() { uint32_t width = raw->getEntry(IMAGEWIDTH)->getU32(); uint32_t height = raw->getEntry(IMAGELENGTH)->getU32(); - if (!width || !height || width % 2 != 0 || width > 10400 || height > 7796) + if (!width || !height || width % 2 != 0 /* || width > 10400 || height > 7796 */ ) ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); mRaw->dim = iPoint2D(width, height); diff --git a/src/librawspeed/decoders/RafDecoder.cpp b/src/librawspeed/decoders/RafDecoder.cpp index 5baf02b9..27e67e7a 100644 --- a/src/librawspeed/decoders/RafDecoder.cpp +++ b/src/librawspeed/decoders/RafDecoder.cpp @@ -79,7 +79,7 @@ RawImage RafDecoder::decodeRawInternal() { } else ThrowRDE("Unable to locate image size"); - if (width == 0 || height == 0 || width > 11808 || height > 8754) + if (width == 0 || height == 0 /* || width > 11808 || height > 8754 */ ) ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); if (raw->hasEntry(FUJI_LAYOUT)) { @@ -334,7 +334,7 @@ int RafDecoder::isCompressed() { } else ThrowRDE("Unable to locate image size"); - if (width == 0 || height == 0 || width > 11808 || height > 8754) + if (width == 0 || height == 0 /* || width > 11808 || height > 8754 */) ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); uint32_t count = raw->getEntry(FUJI_STRIPBYTECOUNTS)->getU32(); diff --git a/src/librawspeed/decoders/RawDecoder.cpp b/src/librawspeed/decoders/RawDecoder.cpp index a69727f6..e5315a42 100644 --- a/src/librawspeed/decoders/RawDecoder.cpp +++ b/src/librawspeed/decoders/RawDecoder.cpp @@ -62,7 +62,7 @@ void RawDecoder::decodeUncompressed(const TiffIFD *rawIFD, BitOrder order) { uint32_t height = rawIFD->getEntry(IMAGELENGTH)->getU32(); uint32_t bitPerPixel = rawIFD->getEntry(BITSPERSAMPLE)->getU32(); - if (width == 0 || height == 0 || width > 5632 || height > 3720) + if (width == 0 || height == 0 /* || width > 5632 || height > 3720 */) ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); mRaw->dim = iPoint2D(width, height); diff --git a/src/librawspeed/decoders/Rw2Decoder.cpp b/src/librawspeed/decoders/Rw2Decoder.cpp index 0e9d111d..a54de998 100644 --- a/src/librawspeed/decoders/Rw2Decoder.cpp +++ b/src/librawspeed/decoders/Rw2Decoder.cpp @@ -72,7 +72,7 @@ RawImage Rw2Decoder::decodeRawInternal() { uint32_t width = raw->getEntry(static_cast(2))->getU16(); if (isOldPanasonic) { - if (width == 0 || height == 0 || width > 4330 || height > 2751) + if (width == 0 || height == 0 /* || width > 4330 || height > 2751 */) ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); TiffEntry *offsets = raw->getEntry(STRIPOFFSETS); diff --git a/src/librawspeed/decompressors/HasselbladDecompressor.cpp b/src/librawspeed/decompressors/HasselbladDecompressor.cpp index 0d650065..aaa70fb5 100644 --- a/src/librawspeed/decompressors/HasselbladDecompressor.cpp +++ b/src/librawspeed/decompressors/HasselbladDecompressor.cpp @@ -41,8 +41,8 @@ HasselbladDecompressor::HasselbladDecompressor(const ByteStream& bs, ThrowRDE("Unexpected component count / data type"); // FIXME: could be wrong. max "active pixels" - "100 MP" - if (mRaw->dim.x == 0 || mRaw->dim.y == 0 || mRaw->dim.x % 2 != 0 || - mRaw->dim.x > 12000 || mRaw->dim.y > 8816) { + if (mRaw->dim.x == 0 || mRaw->dim.y == 0 || mRaw->dim.x % 2 != 0 /* || + mRaw->dim.x > 12000 || mRaw->dim.y > 8816 */) { ThrowRDE("Unexpected image dimensions found: (%u; %u)", mRaw->dim.x, mRaw->dim.y); } diff --git a/src/librawspeed/decompressors/NikonDecompressor.cpp b/src/librawspeed/decompressors/NikonDecompressor.cpp index ca39cd0a..54568243 100644 --- a/src/librawspeed/decompressors/NikonDecompressor.cpp +++ b/src/librawspeed/decompressors/NikonDecompressor.cpp @@ -442,8 +442,8 @@ NikonDecompressor::NikonDecompressor(const RawImage& raw, ByteStream metadata, mRaw->getBpp() != sizeof(uint16_t)) ThrowRDE("Unexpected component count / data type"); - if (mRaw->dim.x == 0 || mRaw->dim.y == 0 || mRaw->dim.x % 2 != 0 || - mRaw->dim.x > 8288 || mRaw->dim.y > 5520) + if (mRaw->dim.x == 0 || mRaw->dim.y == 0 || mRaw->dim.x % 2 != 0 /* || + mRaw->dim.x > 8288 || mRaw->dim.y > 5520 */) ThrowRDE("Unexpected image dimensions found: (%u; %u)", mRaw->dim.x, mRaw->dim.y); diff --git a/src/librawspeed/decompressors/OlympusDecompressor.cpp b/src/librawspeed/decompressors/OlympusDecompressor.cpp index b859b562..dc8aa0bc 100644 --- a/src/librawspeed/decompressors/OlympusDecompressor.cpp +++ b/src/librawspeed/decompressors/OlympusDecompressor.cpp @@ -56,7 +56,7 @@ OlympusDecompressor::OlympusDecompressor(const RawImage& img) : mRaw(img) { const uint32_t w = mRaw->dim.x; const uint32_t h = mRaw->dim.y; - if (w == 0 || h == 0 || w % 2 != 0 || w > 10400 || h > 7792) + if (w == 0 || h == 0 || w % 2 != 0 /* || w > 10400 || h > 7792 */) ThrowRDE("Unexpected image dimensions found: (%u; %u)", w, h); } diff --git a/src/librawspeed/decompressors/PentaxDecompressor.cpp b/src/librawspeed/decompressors/PentaxDecompressor.cpp index 11b1d677..c2adc2e6 100644 --- a/src/librawspeed/decompressors/PentaxDecompressor.cpp +++ b/src/librawspeed/decompressors/PentaxDecompressor.cpp @@ -49,8 +49,8 @@ PentaxDecompressor::PentaxDecompressor(const RawImage& img, mRaw->getBpp() != sizeof(uint16_t)) ThrowRDE("Unexpected component count / data type"); - if (!mRaw->dim.x || !mRaw->dim.y || mRaw->dim.x % 2 != 0 || - mRaw->dim.x > 8384 || mRaw->dim.y > 6208) { + if (!mRaw->dim.x || !mRaw->dim.y || mRaw->dim.x % 2 != 0 /* || + mRaw->dim.x > 8384 || mRaw->dim.y > 6208 */) { ThrowRDE("Unexpected image dimensions found: (%u; %u)", mRaw->dim.x, mRaw->dim.y); } diff --git a/src/librawspeed/decompressors/SonyArw2Decompressor.cpp b/src/librawspeed/decompressors/SonyArw2Decompressor.cpp index 8f935d9c..3cbc7e26 100644 --- a/src/librawspeed/decompressors/SonyArw2Decompressor.cpp +++ b/src/librawspeed/decompressors/SonyArw2Decompressor.cpp @@ -45,7 +45,7 @@ SonyArw2Decompressor::SonyArw2Decompressor(const RawImage& img, const uint32_t w = mRaw->dim.x; const uint32_t h = mRaw->dim.y; - if (w == 0 || h == 0 || w % 32 != 0 || w > 9600 || h > 6376) + if (w == 0 || h == 0 || w % 32 != 0 /* || w > 9600 || h > 6376 */) ThrowRDE("Unexpected image dimensions found: (%u; %u)", w, h); // 1 byte per pixel LibRaw-0.21.4/RawSpeed3/patches/04.clang-cl-compatibility.patch000066400000000000000000000025471477673233700240270ustar00rootroot00000000000000diff --git a/src/librawspeed/common/DefaultInitAllocatorAdaptor.h b/src/librawspeed/common/DefaultInitAllocatorAdaptor.h index 2ff8969e..fa18c312 100644 --- a/src/librawspeed/common/DefaultInitAllocatorAdaptor.h +++ b/src/librawspeed/common/DefaultInitAllocatorAdaptor.h @@ -27,8 +27,12 @@ namespace rawspeed { template , - typename = std::enable_if_t::value>> -class DefaultInitAllocatorAdaptor { +#ifdef _MSC_VER + typename = std::enable_if_t> +#else + typename = std::enable_if_t::value >> +#endif + class DefaultInitAllocatorAdaptor { public: using allocator_traits = std::allocator_traits; diff --git a/src/librawspeed/decompressors/VC5Decompressor.cpp b/src/librawspeed/decompressors/VC5Decompressor.cpp index c498ac3a..de4ae412 100644 --- a/src/librawspeed/decompressors/VC5Decompressor.cpp +++ b/src/librawspeed/decompressors/VC5Decompressor.cpp @@ -398,7 +398,12 @@ VC5Decompressor::VC5Decompressor(ByteStream bs, const RawImage& img) wavelet.height = waveletHeight; wavelet.bands.resize( - &wavelet == channel.wavelets.begin() ? 1 : Wavelet::maxBands); +#ifdef _MSC_VER + Wavelet::maxBands +#else + &wavelet == channel.wavelets.begin() ? 1 : Wavelet::maxBands +#endif + ); } } LibRaw-0.21.4/RawSpeed3/rawspeed3_c_api/000077500000000000000000000000001477673233700176265ustar00rootroot00000000000000LibRaw-0.21.4/RawSpeed3/rawspeed3_c_api/rawspeed3_capi.cpp000066400000000000000000000152071477673233700232300ustar00rootroot00000000000000#include "rawspeed3_capi.h" #include "RawSpeed-API.h" #define HAVE_PUGIXML #include <../pugixml/pugixml.hpp> // for xml_document, xml_pars... extern const char* _rawspeed3_data_xml; class rawspeed3_handle_data { public: rawspeed3_handle_data(const char* cameradefs, bool is_file); void release(); int decodefile(rawspeed3_ret_t* resultp, const void *data, size_t datasize, bool allowunknown); ~rawspeed3_handle_data(); private: std::unique_ptr cameraMeta; std::unique_ptr rawParser; std::unique_ptr rawDecoder; }; /* API calls */ extern "C" { /* void rawspeed3_clearresult(rawspeed3_ret_t* r) Clears (inits) results structure */ DllDef void rawspeed3_clearresult(rawspeed3_ret_t* r) { if(!r) return; r->width = r->height = r->bpp = r->cpp = 0; r->status = rawspeed_inited; r->pitch = r->filters = 0; r->pixeldata = nullptr; } /* rawspeed3_init() Init rawspeed3 Camera, returns: 0 on failure, pointer to data block on success Cameradefs: cameras.xml in string (is_file == false) or file (is_file == true) */ DllDef rawspeed3_handle_t rawspeed3_init(const char* cameradefs, bool is_file) { /* Create rawspeed3_handle_data and return it as void document */ if(!cameradefs) return nullptr; try { /* code */ auto *handle = new rawspeed3_handle_data(cameradefs, is_file); return (void*)handle; } catch(const std::exception& e) { return nullptr; } } /* rawspeed3_initdefault() Init rawspeed3 Cameradefs with built-in cameras.xml (converted to _rawspeed3_data_xml), returns: 0 on failure, pointer to data block on success */ DllDef rawspeed3_handle_t rawspeed3_initdefault() { return rawspeed3_init(_rawspeed3_data_xml,false); } /* rawspeed3_decodefile(..) parse/decode RAW file passed via memory Parameters: handle - rawspeed3_handle_t => handle created by rawspeed3_init() resultp -> pointer to rawspeed3_ret_t to be filled with data -> data buffer with raw file datasize -> size of this buffer allowunknown -> allow to process unknown cameras (not listed in cameras.xml) Return values: 0 -> OK >=1 -> decode error -1 -> Incorrect parameters passed (handle, or data, or datasize) */ DllDef int rawspeed3_decodefile(rawspeed3_handle_t handle, rawspeed3_ret_t* resultp, const void *data, size_t datasize, bool allowunknown) { if(!handle || !resultp || !data || datasize > 2UL * 1024UL * 1024UL * 1024UL) { if(resultp) resultp->status = rawspeed3_param_error; return -1; } rawspeed3_clearresult(resultp); auto *p = static_cast(handle); return p->decodefile(resultp,data,datasize,allowunknown); } /* void rawspeed3_release(rawspeed3_handle_t handle) release internal raw data buffer and error code; */ /* release internal raw data buffer and errmessage (if any) */ DllDef void rawspeed3_release(rawspeed3_handle_t handle) { if(!handle) return; auto *p = static_cast(handle); p->release(); } /* close handle: release all internal data */ DllDef void rawspeed3_close(rawspeed3_handle_t handle) { if(!handle) return; auto *p = static_cast(handle); delete p; } } /* extern "C" */ // == Implementation int rawspeed3_handle_data::decodefile(rawspeed3_ret_t* resultp, const void *data, size_t datasize, bool allowunknown) { if(!cameraMeta) { resultp->status = rawspeed3_not_inited; return rawspeed3_not_inited; } try { rawspeed::Buffer buffer( static_cast(data),datasize); release(); rawParser = std::make_unique(buffer); auto d(rawParser->getDecoder(cameraMeta.get())); if(!d) { resultp->status = rawspeed3_no_decoder; return rawspeed3_no_decoder; } d->applyCrop = false; d->failOnUnknown = !allowunknown; d->interpolateBadPixels = false; d->applyStage1DngOpcodes = false; d->fujiRotate = false; d->applyCrop = false; try { d->checkSupport(cameraMeta.get()); } catch (...) { release(); resultp->status = rawspeed3_not_supported; return resultp->status; } rawspeed::RawImage r = d->mRaw; d->decodeMetaData(cameraMeta.get()); d->checkSupport(cameraMeta.get()); d->decodeRaw(); d->decodeMetaData(cameraMeta.get()); r = d->mRaw; rawDecoder = std::move(d); // we're here w/o exceptions: success const rawspeed::iPoint2D dimUncropped = r->getUncroppedDim(); resultp->width = dimUncropped.x; resultp->height = dimUncropped.y; resultp->filters = r->cfa.getDcrawFilter(); resultp->cpp = r->getCpp(); resultp->bpp = r->getBpp(); resultp->pitch = r->pitch; resultp->pixeldata = r->getDataUncropped(0,0); const auto errors = r->getErrors(); resultp->status = errors.empty()? rawspeed3_ok : rawspeed3_ok_warnings; return resultp->status; /* code */ } catch(...) { resultp->status = rawspeed3_processing_error; return rawspeed3_processing_error; } } namespace rawspeed { class CameraMetaDataFromMem : public CameraMetaData { public: explicit CameraMetaDataFromMem(const char* xmlstring); }; } rawspeed3_handle_data::rawspeed3_handle_data(const char* cameradefs, bool is_file) : rawParser(nullptr) { cameraMeta = is_file ? std::make_unique(cameradefs) : std::make_unique (cameradefs); } rawspeed3_handle_data::~rawspeed3_handle_data() { release(); cameraMeta.reset(); } void rawspeed3_handle_data::release() { if(rawDecoder) rawDecoder.reset(); if (rawParser) rawParser.reset(); } // Camera metadata from mem namespace rawspeed { CameraMetaDataFromMem::CameraMetaDataFromMem(const char* document) { using pugi::xml_node; using pugi::xml_document; using pugi::xml_parse_result; xml_document doc; xml_parse_result result = doc.load_string(document); if (!result) throw "Camera definitions parse error"; for (xml_node camera : doc.child("Cameras").children("Camera")) { const auto* cam = addCamera(std::make_unique(camera)); if (cam == nullptr) continue; // Create cameras for aliases. for (auto i = 0UL; i < cam->aliases.size(); i++) addCamera(std::make_unique(cam, i)); } } } // namespace rawspeed LibRaw-0.21.4/RawSpeed3/rawspeed3_c_api/rawspeed3_capi.h000066400000000000000000000041721477673233700226740ustar00rootroot00000000000000#pragma once #include #include #ifdef _MSC_VER #ifdef RAWSPEED_BUILDLIB #define DllDef __declspec(dllexport) #else #define DllDef __declspec(dllimport) #endif #else #define DllDef #endif #ifdef __cplusplus extern "C" { #endif enum rawspeed3_error_codes { rawspeed_inited = -2, rawspeed3_param_error = -1, rawspeed3_ok = 0, rawspeed3_ok_warnings = 1, rawspeed3_not_inited = 2, rawspeed3_processing_error = 3, rawspeed3_no_decoder = 4, rawspeed3_not_supported = 5, }; typedef void *rawspeed3_handle_t; /* RAW file parsing results */ typedef struct { int status; /* -1: param error, 0 => OK, >=1 error code */ uint16_t width, height, bpp, cpp; unsigned pitch, filters; const void *pixeldata; }rawspeed3_ret_t; /* API calls */ DllDef void rawspeed3_clearresult(rawspeed3_ret_t*); /* rawspeed3_init() Init rawspeed3 Camera, returns: 0 on failure, pointer to data block on success Cameradefs: cameras.xml in string (is_file == false) or file (is_file == true) */ DllDef rawspeed3_handle_t rawspeed3_init(const char* cameradefs, bool is_file); /* init with built-in cameras.xml */ DllDef rawspeed3_handle_t rawspeed3_initdefault(); /* rawspeed3_decodefile(..) parse/decode RAW file passed via memory Parameters: handle - rawspeed3_handle_t => handle created by rawspeed3_init() resultp -> pointer to rawspeed3_ret_t to be filled with data -> data buffer with raw file datasize -> size of this buffer allowunknown -> allow to process unknown cameras (not listed in cameras.xml) Return values: 0 -> OK 1 -> decode warnings (not fatal) >1 -> error code -1 -> Incorrect parameters passed (handle, or data, or datasize) */ DllDef int rawspeed3_decodefile(rawspeed3_handle_t handle, rawspeed3_ret_t* resultp, const void *data, size_t datasize, bool allowunknown); /* release internal raw data buffer */ DllDef void rawspeed3_release(rawspeed3_handle_t handle); /* close handle: release all internal data */ DllDef void rawspeed3_close(rawspeed3_handle_t handle); #ifdef __cplusplus } /* Extern C */ #endif LibRaw-0.21.4/RawSpeed3/rawspeed3_c_api/rawspeed3_capi_test.cpp000066400000000000000000000036711477673233700242710ustar00rootroot00000000000000#include "rawspeed3_capi.h" #include #include #include #include std::vector readfile(char *fn) { std::ifstream is(fn,std::ifstream::binary); if(is) { is.seekg(0, is.end); size_t length = is.tellg(); is.seekg(0, is.beg); std::vector ret; ret.resize(length+1); is.read ((char*)ret.data(),length); is.close(); ret[length] = 0; // zero terminated std::cout << "File: " << fn << " size:" << ret.size() << std::endl; return ret; } else return std::vector(); } int main(int ac, char *av[]) { if(ac < 2) { std::cout << "Usage: " << av[0] << " rawfile rawfile2 ...." << std::endl; return 1; } rawspeed3_handle_t handle = rawspeed3_initdefault(); if(!handle) { std::cerr << "Unable to init rs3" << std::endl; return 2; } for(int i = 1; i < ac; i++) { std::vector rawdata = readfile(av[i]); if (rawdata.size() < 100) { std::cerr << "Input file " << av[i] << " too small or nonexistent" << std::endl; continue; } rawspeed3_ret_t result; int q = rawspeed3_decodefile(handle, &result, rawdata.data(), rawdata.size(), true); if (q >= rawspeed3_ok && q <= rawspeed3_ok_warnings) { std::cout << "File decoded code=" << result.status <<" width=" << result.width << " height=" << result.height << " pitch=" << result.pitch << " filters=" << std::hex << result.filters << std::dec << " channels=" << result.cpp << " bpp=" << result.bpp << std::endl; } else std::cout << "RawSpeed wrapper error code:" << result.status << std::endl; rawspeed3_release(handle); } rawspeed3_close(handle); }LibRaw-0.21.4/RawSpeed3/rawspeed3_c_api/rsxml2c.sh000066400000000000000000000002261477673233700215540ustar00rootroot00000000000000#!/bin/sh echo "const char *_rawspeed3_data_xml=" cat $1 | tr -d '\015' | sed -e 's/\\/\\\\/g;s/"/\\"/g;s/ /\\t/g;s/^/"/;s/$/\\n"/' echo "\"\\0\";" LibRaw-0.21.4/bin/000077500000000000000000000000001477673233700135515ustar00rootroot00000000000000LibRaw-0.21.4/bin/.keep_me000066400000000000000000000000021477673233700151470ustar00rootroot00000000000000 LibRaw-0.21.4/buildfiles/000077500000000000000000000000001477673233700151235ustar00rootroot00000000000000LibRaw-0.21.4/buildfiles/4channels.pro000066400000000000000000000001651477673233700175260ustar00rootroot00000000000000include (libraw-common.pro) win32:LIBS+=libraw.lib unix:LIBS+=-lraw CONFIG-=qt SOURCES=../samples/4channels.cpp LibRaw-0.21.4/buildfiles/4channels.vcxproj000066400000000000000000000222751477673233700204270ustar00rootroot00000000000000 Debug x64 Release x64 {F68CBE78-B27A-3A05-BCD3-293E8CAC1C52} 4channels Qt4VSv1.0 10.0.18362.0 10.0.18362.0 v142 debug-x86_64\ false NotSet Application debug-x86_64\4channels.obj\ 4channels v142 release-x86_64\ false NotSet Application release-x86_64\4channels.obj\ 4channels debug-x86_64\ debug-x86_64\4channels.obj\ 4channels true release-x86_64\ release-x86_64\4channels.obj\ 4channels true false .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) debug-x86_64\4channels.obj\ false ProgramDatabase Sync true debug-x86_64\4channels.obj\ Disabled _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) false MultiThreadedDebugDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) debug-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true true true $(OutDir)\4channels.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) release-x86_64\4channels.obj\ false None Sync true release-x86_64\4channels.obj\ MaxSpeed _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) false MultiThreadedDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) release-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true false true false true $(OutDir)\4channels.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) LibRaw-0.21.4/buildfiles/4channels.vcxproj.filters000066400000000000000000000012551477673233700220710ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files LibRaw-0.21.4/buildfiles/dcraw_emu.pro000066400000000000000000000002201477673233700176050ustar00rootroot00000000000000include (libraw-common.pro) win32:LIBS+=libraw.lib unix:LIBS+=-lraw CONFIG-=qt CONFIG+=debug_and_release SOURCES=../samples/dcraw_emu.cpp LibRaw-0.21.4/buildfiles/dcraw_emu.vcxproj000066400000000000000000000222751477673233700205160ustar00rootroot00000000000000 Debug x64 Release x64 {48688DB8-559A-3DE2-ADDE-5BD27BFEDDA2} dcraw_emu Qt4VSv1.0 10.0.18362.0 10.0.18362.0 v142 debug-x86_64\ false NotSet Application debug-x86_64\dcraw_emu.obj\ dcraw_emu v142 release-x86_64\ false NotSet Application release-x86_64\dcraw_emu.obj\ dcraw_emu debug-x86_64\ debug-x86_64\dcraw_emu.obj\ dcraw_emu true release-x86_64\ release-x86_64\dcraw_emu.obj\ dcraw_emu true false .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) debug-x86_64\dcraw_emu.obj\ false ProgramDatabase Sync true debug-x86_64\dcraw_emu.obj\ Disabled _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) false MultiThreadedDebugDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) debug-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true true true $(OutDir)\dcraw_emu.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) release-x86_64\dcraw_emu.obj\ false None Sync true release-x86_64\dcraw_emu.obj\ MaxSpeed _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) false MultiThreadedDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) release-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true false true false true $(OutDir)\dcraw_emu.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) LibRaw-0.21.4/buildfiles/dcraw_emu.vcxproj.filters000066400000000000000000000012551477673233700221600ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files LibRaw-0.21.4/buildfiles/dcraw_half.pro000066400000000000000000000002171477673233700177370ustar00rootroot00000000000000include (libraw-common.pro) win32:LIBS+=libraw.lib unix:LIBS+=-lraw CONFIG-=qt CONFIG+=debug_and_release SOURCES=../samples/dcraw_half.c LibRaw-0.21.4/buildfiles/dcraw_half.vcxproj000066400000000000000000000223131477673233700206330ustar00rootroot00000000000000 Debug x64 Release x64 {C6EACFA3-9FC5-393B-BCF6-2874B05E4581} dcraw_half Qt4VSv1.0 10.0.18362.0 10.0.18362.0 v142 debug-x86_64\ false NotSet Application debug-x86_64\dcraw_half.obj\ dcraw_half v142 release-x86_64\ false NotSet Application release-x86_64\dcraw_half.obj\ dcraw_half debug-x86_64\ debug-x86_64\dcraw_half.obj\ dcraw_half true release-x86_64\ release-x86_64\dcraw_half.obj\ dcraw_half true false .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) debug-x86_64\dcraw_half.obj\ false ProgramDatabase Sync true debug-x86_64\dcraw_half.obj\ Disabled _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) false MultiThreadedDebugDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) debug-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true true true $(OutDir)\dcraw_half.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) release-x86_64\dcraw_half.obj\ false None Sync true release-x86_64\dcraw_half.obj\ MaxSpeed _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) false MultiThreadedDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) release-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true false true false true $(OutDir)\dcraw_half.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) LibRaw-0.21.4/buildfiles/dcraw_half.vcxproj.filters000066400000000000000000000012541477673233700223030ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files LibRaw-0.21.4/buildfiles/half_mt.pro000066400000000000000000000003101477673233700172510ustar00rootroot00000000000000include (libraw-common.pro) win32:LIBS+=libraw.lib unix:LIBS+=-lraw CONFIG-=qt CONFIG+=debug_and_release win32 { SOURCES=../samples/half_mt_win32.c } else { SOURCES=../samples/half_mt.c } LibRaw-0.21.4/buildfiles/libraw-common-lib.pro000066400000000000000000000010011477673233700211470ustar00rootroot00000000000000win32 { QMAKE_CXXFLAGS+=/MP !contains(QMAKE_HOST.arch, x86_64) { SUFF="x86" } else { ## Windows x64 (64bit) specific build here SUFF="x86_64" } } CONFIG(debug,debug|release) { win32:OUTD=debug-$$SUFF win32:OUTDE=debug-$$SUFF macx:OUTD=debug } else { win32:OUTD=release-$$SUFF win32:OUTDE=release-$$SUFF macx:OUTD=release } INCLUDEPATH+=../ OBJECTS_DIR = $$OUTD/$${TARGET}.obj MOC_DIR = $$OUTD/ RCC_DIR = $$OUTD/ UI_DIR = $$OUTD/ DESTDIR = $$OUTD/ LIBS+=-L$$OUTD CONFIG+=warn_offLibRaw-0.21.4/buildfiles/libraw-common.pro000066400000000000000000000002011477673233700204040ustar00rootroot00000000000000win32:CONFIG+=console win32:LIBS+=libraw.lib unix:LIBS+=-lraw win32-g++: { LIBS += -lws2_32 } include (libraw-common-lib.pro)LibRaw-0.21.4/buildfiles/libraw.pro000066400000000000000000000063071477673233700171330ustar00rootroot00000000000000TEMPLATE=lib TARGET=libraw INCLUDEPATH+=../ include (libraw-common-lib.pro) HEADERS=../libraw/libraw.h \ ../libraw/libraw_alloc.h \ ../libraw/libraw_const.h \ ../libraw/libraw_datastream.h \ ../libraw/libraw_types.h \ ../libraw/libraw_internal.h \ ../libraw/libraw_version.h \ ../internal/defines.h \ ../internal/var_defines.h \ ../internal/libraw_internal_funcs.h \ ../internal/dcraw_defs.h ../internal/dcraw_fileio_defs.h \ ../internal/dmp_include.h ../internal/libraw_cxx_defs.h \ ../internal/x3f_tools.h CONFIG +=precompiled_headers CONFIG-=qt CONFIG+=warn_off CONFIG+=debug_and_release macx: CONFIG+= static x86 x86_64 macx: QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.5 DEFINES+=LIBRAW_BUILDLIB SOURCES+= ../src/libraw_datastream.cpp ../src/decoders/canon_600.cpp \ ../src/decoders/crx.cpp ../src/decoders/decoders_dcraw.cpp \ ../src/decoders/decoders_libraw_dcrdefs.cpp \ ../src/decoders/decoders_libraw.cpp ../src/decoders/dng.cpp \ ../src/decoders/fp_dng.cpp ../src/decoders/fuji_compressed.cpp \ ../src/decoders/generic.cpp ../src/decoders/kodak_decoders.cpp \ ../src/decoders/load_mfbacks.cpp ../src/decoders/smal.cpp \ ../src/decoders/unpack_thumb.cpp ../src/decoders/unpack.cpp \ ../src/demosaic/aahd_demosaic.cpp ../src/demosaic/ahd_demosaic.cpp \ ../src/demosaic/dcb_demosaic.cpp ../src/demosaic/dht_demosaic.cpp \ ../src/demosaic/misc_demosaic.cpp ../src/demosaic/xtrans_demosaic.cpp \ ../src/integration/dngsdk_glue.cpp ../src/integration/rawspeed_glue.cpp \ ../src/metadata/adobepano.cpp ../src/metadata/canon.cpp \ ../src/metadata/ciff.cpp ../src/metadata/cr3_parser.cpp \ ../src/metadata/epson.cpp ../src/metadata/exif_gps.cpp \ ../src/metadata/fuji.cpp ../src/metadata/identify_tools.cpp \ ../src/metadata/hasselblad_model.cpp \ ../src/metadata/identify.cpp ../src/metadata/kodak.cpp \ ../src/metadata/leica.cpp ../src/metadata/makernotes.cpp \ ../src/metadata/mediumformat.cpp ../src/metadata/minolta.cpp \ ../src/metadata/misc_parsers.cpp ../src/metadata/nikon.cpp \ ../src/metadata/normalize_model.cpp ../src/metadata/olympus.cpp \ ../src/metadata/p1.cpp ../src/metadata/pentax.cpp \ ../src/metadata/samsung.cpp ../src/metadata/sony.cpp \ ../src/metadata/tiff.cpp ../src/postprocessing/aspect_ratio.cpp \ ../src/postprocessing/dcraw_process.cpp ../src/postprocessing/mem_image.cpp \ ../src/postprocessing/postprocessing_aux.cpp \ ../src/postprocessing/postprocessing_utils_dcrdefs.cpp \ ../src/postprocessing/postprocessing_utils.cpp \ ../src/preprocessing/ext_preprocess.cpp ../src/preprocessing/raw2image.cpp \ ../src/preprocessing/subtract_black.cpp ../src/tables/cameralist.cpp \ ../src/tables/colorconst.cpp ../src/tables/colordata.cpp \ ../src/tables/wblists.cpp ../src/utils/curves.cpp \ ../src/utils/decoder_info.cpp ../src/utils/init_close_utils.cpp \ ../src/utils/open.cpp ../src/utils/phaseone_processing.cpp \ ../src/utils/read_utils.cpp ../src/utils/thumb_utils.cpp \ ../src/utils/utils_dcraw.cpp ../src/utils/utils_libraw.cpp \ ../src/write/apply_profile.cpp ../src/write/file_write.cpp \ ../src/write/tiff_writer.cpp ../src/x3f/x3f_parse_process.cpp \ ../src/x3f/x3f_utils_patched.cpp \ ../src/libraw_c_api.cpp LibRaw-0.21.4/buildfiles/libraw.vcxproj000066400000000000000000000331631477673233700200260ustar00rootroot00000000000000 Debug x64 Release x64 {A71D2131-F425-381F-8A9A-29D60132A046} libraw Qt4VSv1.0 10.0.18362.0 10.0.18362.0 v142 debug-x86_64\ false NotSet DynamicLibrary debug-x86_64\libraw.obj\ libraw v142 release-x86_64\ false NotSet DynamicLibrary release-x86_64\libraw.obj\ libraw debug-x86_64\ debug-x86_64\libraw.obj\ libraw true release-x86_64\ release-x86_64\libraw.obj\ libraw true false .;..;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) debug-x86_64\libraw.obj\ false ProgramDatabase Sync true debug-x86_64\libraw.obj\ Disabled _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;LIBRAW_BUILDLIB;%(PreprocessorDefinitions) false MultiThreadedDebugDLL true true TurnOffAllWarnings debug-x86_64;%(AdditionalLibraryDirectories) true true true true $(OutDir)\libraw.dll true Windows true Unsigned None 0 _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;LIBRAW_BUILDLIB;_DEBUG;%(PreprocessorDefinitions) .;..;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) release-x86_64\libraw.obj\ false None Sync true release-x86_64\libraw.obj\ MaxSpeed _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;LIBRAW_BUILDLIB;NDEBUG;%(PreprocessorDefinitions) false MultiThreadedDLL true true TurnOffAllWarnings release-x86_64;%(AdditionalLibraryDirectories) true false true true false true $(OutDir)\libraw.dll true Windows true Unsigned None 0 _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;LIBRAW_BUILDLIB;NDEBUG;%(PreprocessorDefinitions) LibRaw-0.21.4/buildfiles/libraw.vcxproj.filters000066400000000000000000000251471477673233700215000ustar00rootroot00000000000000 {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files LibRaw-0.21.4/buildfiles/mem_image.pro000066400000000000000000000002271477673233700175660ustar00rootroot00000000000000include (libraw-common.pro) win32:LIBS+=libraw.lib unix:LIBS+=-lraw CONFIG-=qt CONFIG+=debug_and_release SOURCES=../samples/mem_image_sample.cpp LibRaw-0.21.4/buildfiles/mem_image.vcxproj000066400000000000000000000223041477673233700204610ustar00rootroot00000000000000 Debug x64 Release x64 {BF8A2750-B847-3BA6-9EAF-05F43380F46C} mem_image Qt4VSv1.0 10.0.18362.0 10.0.18362.0 v142 debug-x86_64\ false NotSet Application debug-x86_64\mem_image.obj\ mem_image v142 release-x86_64\ false NotSet Application release-x86_64\mem_image.obj\ mem_image debug-x86_64\ debug-x86_64\mem_image.obj\ mem_image true release-x86_64\ release-x86_64\mem_image.obj\ mem_image true false .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) debug-x86_64\mem_image.obj\ false ProgramDatabase Sync true debug-x86_64\mem_image.obj\ Disabled _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) false MultiThreadedDebugDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) debug-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true true true $(OutDir)\mem_image.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) release-x86_64\mem_image.obj\ false None Sync true release-x86_64\mem_image.obj\ MaxSpeed _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) false MultiThreadedDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) release-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true false true false true $(OutDir)\mem_image.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) LibRaw-0.21.4/buildfiles/mem_image.vcxproj.filters000066400000000000000000000012641477673233700221320ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files LibRaw-0.21.4/buildfiles/multirender_test.pro000066400000000000000000000002271477673233700212370ustar00rootroot00000000000000include (libraw-common.pro) win32:LIBS+=libraw.lib unix:LIBS+=-lraw CONFIG-=qt CONFIG+=debug_and_release SOURCES=../samples/multirender_test.cpp LibRaw-0.21.4/buildfiles/multirender_test.vcxproj000066400000000000000000000224551477673233700221410ustar00rootroot00000000000000 Debug x64 Release x64 {30D21208-219A-3AA8-ADCF-E6B1FFAF6A73} multirender_test Qt4VSv1.0 10.0.18362.0 10.0.18362.0 v142 debug-x86_64\ false NotSet Application debug-x86_64\multirender_test.obj\ multirender_test v142 release-x86_64\ false NotSet Application release-x86_64\multirender_test.obj\ multirender_test debug-x86_64\ debug-x86_64\multirender_test.obj\ multirender_test true release-x86_64\ release-x86_64\multirender_test.obj\ multirender_test true false .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) debug-x86_64\multirender_test.obj\ false ProgramDatabase Sync true debug-x86_64\multirender_test.obj\ Disabled _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) false MultiThreadedDebugDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) debug-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true true true $(OutDir)\multirender_test.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) release-x86_64\multirender_test.obj\ false None Sync true release-x86_64\multirender_test.obj\ MaxSpeed _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) false MultiThreadedDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) release-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true false true false true $(OutDir)\multirender_test.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) LibRaw-0.21.4/buildfiles/multirender_test.vcxproj.filters000066400000000000000000000012641477673233700236030ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files LibRaw-0.21.4/buildfiles/openbayer_sample.pro000066400000000000000000000002211477673233700211650ustar00rootroot00000000000000include (libraw-common.pro) win32:LIBS+=libraw.lib unix:LIBS+=-lraw CONFIG-=qt CONFIG+=debug_and_release SOURCES=../samples/openbayer_sample.cpp LibRaw-0.21.4/buildfiles/openbayer_sample.vcxproj000066400000000000000000000224551477673233700220750ustar00rootroot00000000000000 Debug x64 Release x64 {EF67FEF1-4B19-3765-A660-9F8E9333DEF3} openbayer_sample Qt4VSv1.0 10.0.18362.0 10.0.18362.0 v142 debug-x86_64\ false NotSet Application debug-x86_64\openbayer_sample.obj\ openbayer_sample v142 release-x86_64\ false NotSet Application release-x86_64\openbayer_sample.obj\ openbayer_sample debug-x86_64\ debug-x86_64\openbayer_sample.obj\ openbayer_sample true release-x86_64\ release-x86_64\openbayer_sample.obj\ openbayer_sample true false .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) debug-x86_64\openbayer_sample.obj\ false ProgramDatabase Sync true debug-x86_64\openbayer_sample.obj\ Disabled _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) false MultiThreadedDebugDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) debug-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true true true $(OutDir)\openbayer_sample.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) release-x86_64\openbayer_sample.obj\ false None Sync true release-x86_64\openbayer_sample.obj\ MaxSpeed _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) false MultiThreadedDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) release-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true false true false true $(OutDir)\openbayer_sample.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) LibRaw-0.21.4/buildfiles/openbayer_sample.vcxproj.filters000066400000000000000000000012641477673233700235370ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files LibRaw-0.21.4/buildfiles/postprocessing_benchmark.pro000066400000000000000000000001651477673233700227430ustar00rootroot00000000000000include (libraw-common.pro) CONFIG-=qt CONFIG+=debug_and_release SOURCES=../samples/postprocessing_benchmark.cpp LibRaw-0.21.4/buildfiles/postprocessing_benchmark.vcxproj000066400000000000000000000226551477673233700236460ustar00rootroot00000000000000 Debug x64 Release x64 {5C66A8FA-D211-3E2F-A2F1-0C3C665689CC} postprocessing_benchmark Qt4VSv1.0 10.0.18362.0 10.0.18362.0 v142 debug-x86_64\ false NotSet Application debug-x86_64\postprocessing_benchmark.obj\ postprocessing_benchmark v142 release-x86_64\ false NotSet Application release-x86_64\postprocessing_benchmark.obj\ postprocessing_benchmark debug-x86_64\ debug-x86_64\postprocessing_benchmark.obj\ postprocessing_benchmark true release-x86_64\ release-x86_64\postprocessing_benchmark.obj\ postprocessing_benchmark true false .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) debug-x86_64\postprocessing_benchmark.obj\ false ProgramDatabase Sync true debug-x86_64\postprocessing_benchmark.obj\ Disabled _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) false MultiThreadedDebugDLL true true TurnOffAllWarnings libraw.lib;ws2_32.lib;%(AdditionalDependencies) debug-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true true true $(OutDir)\postprocessing_benchmark.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) release-x86_64\postprocessing_benchmark.obj\ false None Sync true release-x86_64\postprocessing_benchmark.obj\ MaxSpeed _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) false MultiThreadedDLL true true TurnOffAllWarnings libraw.lib;ws2_32.lib;%(AdditionalDependencies) release-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true false true false true $(OutDir)\postprocessing_benchmark.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) LibRaw-0.21.4/buildfiles/postprocessing_benchmark.vcxproj.filters000066400000000000000000000012741477673233700253070ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files LibRaw-0.21.4/buildfiles/raw-identify.pro000066400000000000000000000002231477673233700202440ustar00rootroot00000000000000include (libraw-common.pro) win32:LIBS+=libraw.lib unix:LIBS+=-lraw CONFIG-=qt CONFIG+=debug_and_release SOURCES=../samples/raw-identify.cpp LibRaw-0.21.4/buildfiles/raw-identify.vcxproj000066400000000000000000000223551477673233700211510ustar00rootroot00000000000000 Debug x64 Release x64 {7C4F61DB-717E-36C9-B20E-36F8E218AB51} raw-identify Qt4VSv1.0 10.0.18362.0 10.0.18362.0 v142 debug-x86_64\ false NotSet Application debug-x86_64\raw-identify.obj\ raw-identify v142 release-x86_64\ false NotSet Application release-x86_64\raw-identify.obj\ raw-identify debug-x86_64\ debug-x86_64\raw-identify.obj\ raw-identify true release-x86_64\ release-x86_64\raw-identify.obj\ raw-identify true false .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) debug-x86_64\raw-identify.obj\ false ProgramDatabase Sync true debug-x86_64\raw-identify.obj\ Disabled _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) false MultiThreadedDebugDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) debug-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true true true $(OutDir)\raw-identify.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) release-x86_64\raw-identify.obj\ false None Sync true release-x86_64\raw-identify.obj\ MaxSpeed _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) false MultiThreadedDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) release-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true false true false true $(OutDir)\raw-identify.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) LibRaw-0.21.4/buildfiles/raw-identify.vcxproj.filters000066400000000000000000000012601477673233700226100ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files LibRaw-0.21.4/buildfiles/rawtextdump.pro000066400000000000000000000002141477673233700202260ustar00rootroot00000000000000include (libraw-common.pro) win32:LIBS+=libraw.lib unix:LIBS+=-lraw CONFIG-=qt CONFIG+=debug_and_release SOURCES=../samples/rawtextdump.cpp LibRaw-0.21.4/buildfiles/rawtextdump.vcxproj000066400000000000000000000223351477673233700211310ustar00rootroot00000000000000 Debug x64 Release x64 {53A1E3F0-8032-348E-B3BF-3E540A45005F} rawtextdump Qt4VSv1.0 10.0.18362.0 10.0.18362.0 v142 debug-x86_64\ false NotSet Application debug-x86_64\rawtextdump.obj\ rawtextdump v142 release-x86_64\ false NotSet Application release-x86_64\rawtextdump.obj\ rawtextdump debug-x86_64\ debug-x86_64\rawtextdump.obj\ rawtextdump true release-x86_64\ release-x86_64\rawtextdump.obj\ rawtextdump true false .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) debug-x86_64\rawtextdump.obj\ false ProgramDatabase Sync true debug-x86_64\rawtextdump.obj\ Disabled _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) false MultiThreadedDebugDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) debug-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true true true $(OutDir)\rawtextdump.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) release-x86_64\rawtextdump.obj\ false None Sync true release-x86_64\rawtextdump.obj\ MaxSpeed _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) false MultiThreadedDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) release-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true false true false true $(OutDir)\rawtextdump.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) LibRaw-0.21.4/buildfiles/rawtextdump.vcxproj.filters000066400000000000000000000012571477673233700226000ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files LibRaw-0.21.4/buildfiles/simple_dcraw.pro000066400000000000000000000002231477673233700203130ustar00rootroot00000000000000include (libraw-common.pro) win32:LIBS+=libraw.lib unix:LIBS+=-lraw CONFIG-=qt CONFIG+=debug_and_release SOURCES=../samples/simple_dcraw.cpp LibRaw-0.21.4/buildfiles/simple_dcraw.vcxproj000066400000000000000000000223551477673233700212200ustar00rootroot00000000000000 Debug x64 Release x64 {AD1E31D8-A022-3672-982F-C8280A0D6458} simple_dcraw Qt4VSv1.0 10.0.18362.0 10.0.18362.0 v142 debug-x86_64\ false NotSet Application debug-x86_64\simple_dcraw.obj\ simple_dcraw v142 release-x86_64\ false NotSet Application release-x86_64\simple_dcraw.obj\ simple_dcraw debug-x86_64\ debug-x86_64\simple_dcraw.obj\ simple_dcraw true release-x86_64\ release-x86_64\simple_dcraw.obj\ simple_dcraw true false .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) debug-x86_64\simple_dcraw.obj\ false ProgramDatabase Sync true debug-x86_64\simple_dcraw.obj\ Disabled _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) false MultiThreadedDebugDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) debug-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true true true $(OutDir)\simple_dcraw.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) release-x86_64\simple_dcraw.obj\ false None Sync true release-x86_64\simple_dcraw.obj\ MaxSpeed _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) false MultiThreadedDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) release-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true false true false true $(OutDir)\simple_dcraw.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) LibRaw-0.21.4/buildfiles/simple_dcraw.vcxproj.filters000066400000000000000000000012601477673233700226570ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files LibRaw-0.21.4/buildfiles/unprocessed_raw.pro000066400000000000000000000002261477673233700210500ustar00rootroot00000000000000include (libraw-common.pro) win32:LIBS+=libraw.lib unix:LIBS+=-lraw CONFIG-=qt CONFIG+=debug_and_release SOURCES=../samples/unprocessed_raw.cpp LibRaw-0.21.4/buildfiles/unprocessed_raw.vcxproj000066400000000000000000000224351477673233700217510ustar00rootroot00000000000000 Debug x64 Release x64 {1333E21E-D3B5-3640-9A4D-D8955082B855} unprocessed_raw Qt4VSv1.0 10.0.18362.0 10.0.18362.0 v142 debug-x86_64\ false NotSet Application debug-x86_64\unprocessed_raw.obj\ unprocessed_raw v142 release-x86_64\ false NotSet Application release-x86_64\unprocessed_raw.obj\ unprocessed_raw debug-x86_64\ debug-x86_64\unprocessed_raw.obj\ unprocessed_raw true release-x86_64\ release-x86_64\unprocessed_raw.obj\ unprocessed_raw true false .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) debug-x86_64\unprocessed_raw.obj\ false ProgramDatabase Sync true debug-x86_64\unprocessed_raw.obj\ Disabled _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) false MultiThreadedDebugDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) debug-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true true true $(OutDir)\unprocessed_raw.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) .;..;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) release-x86_64\unprocessed_raw.obj\ false None Sync true release-x86_64\unprocessed_raw.obj\ MaxSpeed _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) false MultiThreadedDLL true true TurnOffAllWarnings ws2_32.lib;libraw.lib;%(AdditionalDependencies) release-x86_64;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true false true false true $(OutDir)\unprocessed_raw.exe true Console true Unsigned None 0 _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) LibRaw-0.21.4/buildfiles/unprocessed_raw.vcxproj.filters000066400000000000000000000012631477673233700234140ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files LibRaw-0.21.4/clist2c.pl000077500000000000000000000002241477673233700147020ustar00rootroot00000000000000#!/usr/bin/perl while (<>) { chomp; s/^\s+//; s/^\s+\*\s+//; s/^\s+//; s/\"/\\\"/g; s/\s+$//; print "\"$_\",\n"; } LibRaw-0.21.4/clist2html.pl000077500000000000000000000021651477673233700154320ustar00rootroot00000000000000#!/usr/bin/perl use Data::Dumper; @makes=( "AgfaPhoto", "Canon", "Casio", "Digital Bolex", "Epson", "Fujifilm", "Imacon", "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica", "Hasselblad", "Nikon", "Nokia", "Olympus", "Pentax", "Phase One", "Ricoh", "Samsung", "Sigma", "Sinar", "Sony" ); MAINLOOP: while(<>) { chomp; $cname = $_; $cname=~s/^\s+//g; $cname=~s/\s+$//g; for my $camera (@makes) { if ($cname=~/\Q$camera\E\s+(.*)/) { $model = $1; push @{$cameralist->{$camera}},$model; next MAINLOOP; } } if($cname=~/(\S+)\s+(.*)/) { ($make,$model) = ($1,$2); push @{$cameralist->{$make}},$model; next MAINLOOP; } push @{$cameralist->{$make}},"NO MODEL"; } my $havenx1=0; print "
    \n"; for my $make (sort keys %$cameralist) { if( $#{$cameralist->{$make}} < 1) { print "
  • $make $cameralist->{$make}->[0]
  • \n"; } else { print "
  • $make\n
      \n"; for my $model (@{$cameralist->{$make}}) { print "
    • $model
    • \n"; } print "
    \n
  • \n"; } } print "
\n"; LibRaw-0.21.4/configure.ac000066400000000000000000000103571477673233700152750ustar00rootroot00000000000000# Initialization AC_INIT([LibRaw], m4_esyscmd([./version.sh]), [info@libraw.org], [], [http://www.libraw.org]) AM_INIT_AUTOMAKE([foreign no-define]) #AM_SILENT_RULES([yes]) AC_CONFIG_MACRO_DIR([m4]) AC_CANONICAL_HOST # Tools to use AC_PROG_CXX AC_PROG_CC AC_PROG_LIBTOOL AC_ENABLE_SHARED AC_ENABLE_STATIC AC_LIBTOOL_WIN32_DLL AC_LIBTOOL_SETUP AC_SUBST(LIBTOOL_DEPS) # Config files to generate AC_CONFIG_FILES([ Makefile libraw.pc libraw_r.pc ]) # check if we want OpenMP support AC_ARG_ENABLE([openmp], [ --enable-openmp Enable OpenMP support], [case "${enableval}" in yes) openmp=true ;; no) openmp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-openmp]) ;; esac],[openmp=true]) if test x$openmp = xtrue ; then AX_OPENMP([ CXXFLAGS="$CXXFLAGS $OPENMP_CFLAGS" CFLAGS="$CFLAGS $OPENMP_CFLAGS" AC_SUBST([PC_OPENMP],[" $OPENMP_CFLAGS"]) ],[ AC_MSG_WARN([OpenMP support cannot be enabled because your system doesn't support it.]) ]) fi # check for libjpeg v8 AC_ARG_ENABLE([jpeg], [ --enable-jpeg Enable JPEG support for Lossy compressed DNG files], [case "${enableval}" in yes) jpeg=true ;; no) jpeg=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-jpeg]) ;; esac],[jpeg=true]) if test x$jpeg = xtrue; then AC_CHECK_LIB([jpeg], [jpeg_mem_src], [ AC_CHECK_HEADERS([jpeglib.h], [ CPPFLAGS="$CPPFLAGS -DUSE_JPEG -DUSE_JPEG8" LIBS="$LIBS -ljpeg" AC_SUBST([PACKAGE_LIBS_PRIVATE],"-ljpeg $PACKAGE_LIBS_PRIVATE") ], AC_MSG_WARN([no jpeg headers found])) ], AC_MSG_WARN([libjpeg not found]) ) fi # check for Jasper (JPEG2000) support AC_ARG_ENABLE([jasper], [ --enable-jasper Enable Jasper (JPEG2000) support for RedCine files], [case "${enableval}" in yes) jasper=true ;; no) jasper=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-jasper]) ;; esac],[jasper=true]) if test x$jasper = xtrue; then AC_CHECK_LIB([jasper], [jas_init], [ AC_CHECK_HEADERS([jasper/jasper.h], [ CPPFLAGS="$CPPFLAGS -DUSE_JASPER" LIBS="$LIBS -ljasper" AC_SUBST([PACKAGE_LIBS_PRIVATE],"-ljasper $PACKAGE_LIBS_PRIVATE") ], AC_MSG_WARN([no jasper headers found])) ], AC_MSG_WARN([libjasper not found]) ) fi # check if we want zlib support AC_ARG_ENABLE([zlib], [ --enable-zlib Enable zlib support for deflate compressed DNG files], [case "${enableval}" in yes) zlib=true ;; no) zlib=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-zlib]) ;; esac],[zlib=true]) if test x$zlib = xtrue; then PKG_CHECK_MODULES([ZLIB],[zlib],[ CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS -DUSE_ZLIB" LIBS="$LIBS $ZLIB_LIBS" AC_SUBST([PACKAGE_REQUIRES],[zlib]) ], AC_MSG_WARN([zlib support cannot be enabled]) ) fi # check if we want LCMS support AC_ARG_ENABLE([lcms], [ --enable-lcms Enable LCMS support], [case "${enableval}" in yes) lcms=true ;; no) lcms=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-lcms]) ;; esac],[lcms=true]) if test x$lcms = xtrue; then PKG_CHECK_MODULES([LCMS2],[lcms2],[ CPPFLAGS="$CPPFLAGS $LCMS2_CFLAGS -DUSE_LCMS2" LIBS="$LIBS $LCMS2_LIBS" AC_SUBST([PACKAGE_REQUIRES],[lcms2]) ],[ PKG_CHECK_MODULES([LCMS],[lcms],[ CPPFLAGS="$CPPFLAGS $LCMS_CFLAGS -DUSE_LCMS" LIBS="$LIBS $LCMS_LIBS" AC_SUBST([PACKAGE_REQUIRES],[lcms]) ],[ AC_MSG_WARN([LCMS support cannot be enabled]) ]) ]) fi # check if we want build examples AC_ARG_ENABLE([examples], [ --enable-examples Enable building of examples], [case "${enableval}" in yes) examples=true ;; no) examples=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-examples]) ;; esac],[examples=true]) AM_CONDITIONAL([EXAMPLES], [test x$examples = xtrue]) LIBS="$LIBS -lm" case "${host_os}" in *mingw32*) LIBS="$LIBS -lws2_32" ;; esac AC_SUBST([LIBRAW_SHLIB_VERSION],m4_esyscmd([./shlib-version.sh])) AC_SUBST([LIBRAW_RELEASE_VERSION],m4_esyscmd([./version.sh])) AC_OUTPUT LibRaw-0.21.4/doc/000077500000000000000000000000001477673233700135465ustar00rootroot00000000000000LibRaw-0.21.4/doc/API-C.html000066400000000000000000000245001477673233700152260ustar00rootroot00000000000000

LibRaw: C API[back to Index]

LibRaw: C API

LibRaw C API is a wrapper around C++ API; therefore, virtually all documentation to C API functions is represented by a set of hyperlinks to the corresponding places in the description of C++ API.

Contents

  1. Initialization and denitialization
  2. Returned values
  3. Data loading
  4. Parameters getters/setters
  5. Auxiliary Functions
  6. Data Postprocessing, Emulation of dcraw Behavior
  7. Writing to Output Files
  8. Writing processing results to memory buffer

Initialization and denitialization

libraw_data_t *libraw_init(unsigned int flags);
The function returns the pointer to the instance of libraw_data_t structure.
The resultant pointer should be passed as the first argument to all C API functions (except for libraw_strerror).
Returns NULL in case of error, pointer to the structure in all other cases.
void libraw_close(libraw_data_t *);
Closes libraw_data_t handler and deallocates all memory.

Returned values

Functions of C API return EINVAL (see errno.h) if the null pointer was passed to them as the first argument. In all other cases, the C++ API return code is returned.

Data Loading from a File/Buffer

int libraw_open_file(libraw_data_t*, const char *)
int libraw_open_file_ex(libraw_data_t*, const char *,INT64 bigfile_size)
WIN32: int libraw_open_wfile(libraw_data_t*, const wchar_t *)
WIN32: int libraw_open_wfile_ex(libraw_data_t*, const wchar_t *,INT64 bigfile_size)
See LibRaw::open_file()
int libraw_open_buffer(libraw_data_t*, void *buffer, size_t bufsize)
See LibRaw::open_buffer()
int libraw_open_bayer(libraw_data_t *lr, unsigned char *data, unsigned datalen, ushort _raw_width, ushort _raw_height, ushort _left_margin, ushort _top_margin, ushort _right_margin, ushort _bottom_margin, unsigned char procflags, unsigned char bayer_battern, unsigned unused_bits, unsigned otherflags, unsigned black_level)
See LibRaw::open_bayer()
int libraw_unpack(libraw_data_t*);
See LibRaw::unpack()
int libraw_unpack_thumb(libraw_data_t*);
See LibRaw::unpack_thumb()
int libraw_unpack_thumb_ex(libraw_data_t*,int);
See LibRaw::unpack_thumb_ex()

Parameters setters/getters

These functions provides interface to imgdata.params, .sizes and .color fields which works regardless of LibRaw versions used when building calling app and the library itself.

  • int libraw_get_raw_height(libraw_data_t *lr);
  • int libraw_get_raw_width(libraw_data_t *lr);
  • int libraw_get_iheight(libraw_data_t *lr);
  • int libraw_get_iwidth(libraw_data_t *lr);
  • float libraw_get_cam_mul(libraw_data_t *lr,int index);
  • float libraw_get_pre_mul(libraw_data_t *lr,int index);
  • float libraw_get_rgb_cam(libraw_data_t *lr,int index1, int index2);
  • libraw_iparams_t *libraw_get_iparams(libraw_data_t *lr);
  • libraw_lensinfo_t *libraw_get_lensinfo(libraw_data_t *lr);
  • libraw_imgother_t *libraw_get_imgother(libraw_data_t *lr);
  • int libraw_get_color_maximum(libraw_data_t *lr);
  • void libraw_set_user_mul(libraw_data_t *lr,int index, float val);
  • void libraw_set_demosaic(libraw_data_t *lr,int value);
  • void libraw_set_adjust_maximum_thr(libraw_data_t *lr,float value);
  • void libraw_set_output_color(libraw_data_t *lr,int value);
  • void libraw_set_output_bps(libraw_data_t *lr,int value);
  • void libraw_set_gamma(libraw_data_t *lr,int index, float value);
  • void libraw_set_no_auto_bright(libraw_data_t *lr,int value);
  • void libraw_set_bright(libraw_data_t *lr,float value);
  • void libraw_set_highlight(libraw_data_t *lr,int value);
  • void libraw_set_fbdd_noiserd(libraw_data_t *lr,int value);

Auxiliary Functions

const char* libraw_version()
See LibRaw::version()
int libraw_versionNumber()
See LibRaw::versionNumber()
See LibRaw::versionNumber()
bool LIBRAW_CHECK_VERSION(major,minor,patch)
See LIBRAW_CHECK_VERSION
unsigned libraw_capabilities()
See LibRaw::capabilities()
int libraw_cameraCount()
See LibRaw::cameraCount()
const char* libraw_cameraList()
See LibRaw::cameraList()
int libraw_get_decoder_info(libraw_data_t*,libraw_decoder_info_t *);
See LibRaw::get_decoder_info()
const char* libraw_unpack_function_name(libraw_data_t*);
See LibRaw::unpack_function_name()
int libraw_COLOR(libraw_data_t*,int row,int col);
See LibRaw::COLOR()
void libraw_subtract_black(libraw_data_t*);
See LibRaw::subtract_black()
void libraw_recycle_datastream(libraw_data_t*);
See LibRaw::recycle_datastream()
void libraw_recycle(libraw_data_t*);
See LibRaw::recycle()
const char *libraw_strerror(int errorcode);
See LibRaw::strerror
const char *libraw_strprogress(enum LibRaw_progress);
See LibRaw::strprogress
void libraw_set_dataerror_handler(libraw_data_t*,data_callback func, void *);
See LibRaw::set_dataerror_handler()
void libraw_set_progress_handler(libraw_data_t*,progress_callback func, void *);
See LibRaw::set_progress_handler()

Data Postprocessing, Emulation of dcraw Behavior

Setting of Parameters

The postprocessing parameters for the calls described below are set, just as for C++ API, via setting of fields in the libraw_output_params_t structure:

 libraw_data_t *ptr = libraw_init(0);
 ptr->params.output_tiff = 1; //  output to TIFF
    

Fields of this structure are described in the documentation to libraw_output_params_t. For notes on their use, see API notes.

Emulation of dcraw Behavior

int libraw_raw2image(libraw_data_t*);
See LibRaw::raw2image
int libraw_free_image(libraw_data_t*);
See LibRaw::free_image
int libraw_adjust_sizes_info_only(libraw_data_t*);
See LibRaw::adjust_sizes_info_only()
int libraw_dcraw_process(libraw_data_t* lr);
See LibRaw::dcraw_process()

Writing to Output Files

int libraw_dcraw_ppm_tiff_writer(libraw_data_t* lr,const char *filename);
See LibRaw::dcraw_ppm_tiff_writer()
int libraw_dcraw_thumb_writer(libraw_data_t* lr,const char *fname);
See LibRaw::dcraw_thumb_writer()

Writing processing results to memory buffer

libraw_processed_image_t *libraw_dcraw_make_mem_image(libraw_data_t* lr,int * errcode)
See LibRaw::dcraw_make_mem_image()
libraw_processed_image_t *libraw_dcraw_make_mem_thumb(libraw_data_t* lr,int * errcode)
See LibRaw::dcraw_make_mem_thumb()
void libraw_dcraw_clear_mem(libraw_processed_image_t *);
See LibRaw::dcraw_clear_mem()

[back to Index]

LibRaw-0.21.4/doc/API-CXX.html000066400000000000000000001441041477673233700155110ustar00rootroot00000000000000

LibRaw C++ API[back to Index]

LibRaw C++ API

Contents

  1. LibRaw Objects
  2. Returned values
  3. Methods Loading Data from a File
  4. Auxiliary Functions
  5. Data Postprocessing: Emulation of dcraw Behavior
  6. Data Output to Files: Emulation of dcraw Behavior
  7. Copying unpacked data into memory buffer
  8. Input layer abstraction

LibRaw Objects

The main LibRaw object (class) is created either without parameters or with flags determining the object behavior.

#include "libraw/libraw.h"
...

LibRaw ImageProcessor(unsigned int flags=0);
...

Flags (several flags are combined via operator |, i.e., bitwise OR):

  • LIBRAW_OPTIONS_NO_DATAERR_CALLBACK: do not set the standard file read error handler (standard handler outputs the error report in stderr).

Three groups of methods are used for image processing

The results of processing are placed in the imgdata field of type libraw_data_t; the same data set contains fields that control the postprocessing and output.

Returned Values

All LibRaw API functions return an integer number in accordance with the return code convention. Please read the descriptions of this convention and LibRaw behavior in cases of fatal errors.

Methods Loading Data from a File

int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)

Opens a datastream with RAW data, reads metadata (EXIF) from it, and fills the following structures:

The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.

Before file opening, recycle() is always called; hence, if several images are processed in the batch mode, there is no need to call recycle() at the end of each processing cycle.

Input data: pointer to object, derived from LibRaw_abstract_datastream class. This object should be initialized and ready to read. This object should be destroyed in calling application after use.

int LibRaw::open_file(const char *filename[,INT64 bigfile_size])

Win32 only: int LibRaw::open_file(const wchar_t *filename[,INT64 bigfile_size])

Creates an LibRaw_file_datastream object, calls open_datastream(). If succeed, sets internal flag which signals to destroy internal datastream object on recycle(). On failure, just created file_datastream destroyed immediately.

Second optional parameter bigfile_size controls background I/O interface used for file operations. For files smaller than bigfile_size the LibRaw_file_datastream will be used and the LibRaw_bigfile_datastream otherwise.

The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.

int LibRaw::open_buffer(void *buffer, size_t bufsize)

Created an LibRaw_buffer_datastream object, calls open_datastream(). If succeed, sets internal flag which signals to destroy internal datastream object on recycle(). On failure, just created file_datastream destroyed immediately.

The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.

int LibRaw::open_bayer(unsigned char *data, unsigned datalen, ushort _raw_width, ushort _raw_height, ushort _left_margin, ushort _top_margin, ushort _right_margin, ushort _bottom_margin, unsigned char procflags, unsigned char bayer_pattern, unsigned unused_bits, unsigned otherflags, unsigned black_level)

Parameters:

  • data, datalen - buffer passed
  • _raw_width/_raw_height/*margin - image size and margins
  • procflags:
    • for 10-bit format:
      • 1: "4 pixels in 5 bytes" packing is used
      • 0: "6 pixels in 8 bytes" packing is used
    • for 16-bit format:
      • 1: Big-endian data
  • bayer_pattern: one of LIBRAW_OPENBAYER_RGGB,LIBRAW_OPENBAYER_BGGR, LIBRAW_OPENBAYER_GRBG,LIBRAW_OPENBAYER_GBRG
  • unused_bits: count of upper zero bits
  • otherflags:
    • Bit 1 - filter (average neighbors) for pixels with values of zero
    • Bits 2-4 - the orientation of the image (0=do not rotate, 3=180, 5=90CCW, 6=90CW)
  • black_level: file black level (it also may be specified via imgdata.params)
See samples/openbayer_sample.cpp for usage sample (note, this sample is 'sample only', suited for Kodak KAI-0340 sensor, you'll need change open_bayer() params for your data).

int LibRaw::unpack(void)

Unpacks the RAW files of the image, calculates the black level (not for all formats). The results are placed in imgdata.image.

Data reading is sometimes (not frequently) affected by settings made in imgdata.params (libraw_output_params_t); see API notes for details.

The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.

int LibRaw::unpack_thumb(void)

int LibRaw::unpack_thumb_ex(int i)

unpack_thumb(): reads (or unpacks) the default (largest) image preview (thumbnail), placing the result into the imgdata.thumbnail.thumb buffer.

unpack_thumb_ex(int i): reads i-th thumbnail (thumbnails list is available in imgdata.thumbs_list structure).

JPEG previews are placed into this buffer without any changes (with the header etc.). Other preview formats are placed into the buffer in the form of the unpacked bitmap image (three components, 8 bits per component).
The thumbnail format is written to the imgdata.thumbnail.tformat field; for the possible values, see description of constants and data structures.

The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.

Auxiliary Functions

Library version check

const char* LibRaw::version()

Returns string representation of LibRaw version in MAJOR.MINOR.PATCH-Status format (i.e. 0.6.0-Alpha2 or 0.6.1-Release).

int LibRaw::versionNumber()

Returns integer representation of LibRaw version. During LibRaw development, the version number is always increase .

bool LIBRAW_CHECK_VERSION(major,minor,patch)

Macro for version check in caller applications. Returns 'true' if current library version is greater or equal to set in macro parameters. This macro executes at runtime (not at compile time) and may be used for checking version of dynamically loaded LibRaw (from DLL/shared library).

List of supported RAW formats (cameras)

int LibRaw::cameraCount()

Returns count of cameras supported.

const char** LibRaw::cameraList()

Returns list of supported cameras. Latest item of list is set to NULL (for easy printing).

int LibRaw::set_rawspeed_camerafile(char *path_to_cameras_xml)

(Only if LibRaw was built with RawSpeed support).

Loads XML file with RawSpeed camera description data (cameras.xml) specified by path_to_cameras_xml. Returns 0 on success, nonzero on error.

int LibRaw::get_decoder_info(libraw_decoder_info_t *)

The function fills libraw_decoder_info_t structure by passed pointer with current raw decoder data.

The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.

const char* LibRaw::unpack_function_name()

Returns function name of file unpacking function. Intended only for LibRaw test suite designers to use in test coverage evaluation.

void LibRaw::setCancelFlag()

This call sets internal fast cancel flags. If set, current Raw decoder will be terminated ASAP. This call is useful if you need to cancel all LibRaw decoders in multithreaded program (e.g. for fast program termination or just for cancel current processing).

void LibRaw::clearCancelFlag()

This call clears internal fast cancel flags, so (early) terminated LibRaw decoder may work again.

int LibRaw::COLOR(int row, int col)

This call returns pixel color (color component number) in bayer pattern at row,col. The returned value is in 0..3 range for 4-component Bayer (RGBG2, CMYG and so on) and in 0..2 range for 3-color data.

Color indexes returned could be used as index in imgdata.idata.cdesc string to get color 'name'.

int LibRaw::error_count()

This call returns count of non-fatal data errors (out of range, etc) occurred in unpack() stage.

int LibRaw::subtract_black()

This call will subtract black level values from RAW data (for suitable RAW data). colordata.data_maximum and colordata.maximum and black level data (colordata.black and colordata.cblack) will be adjusted too.

This call should be used if you postprocess RAW data by your own code. LibRaw postprocessing functions will call subtract_black() by oneself.

The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.

int LibRaw::adjust_to_raw_inset_crop(unsigned mask, float maxcrop = 0.55f)

Promotes imgdata.sizes.raw_inset_crops[] values to imgdata.sizes.*margin and imgdata.sizes.width/height fields

Parameters
mask:

  • if bit 1 is set: prefer raw_inset_crops[1]
  • if bit 0 is set: prefer raw_inset_crops[0]

maxcrop: limits crop to not less than (original width/height)*maxcrop; if raw_inset_crops[i] data results in tighter crop, than this item is ignored.

return value: index in raw_inset_crops[] used increased by one, so

  • 0: no changes made
  • 1: [0]th data used
  • 2: [1]th data used

Note: this call SHOULD be used after LibRaw::unpack(), otherwise black level calculation from masked area may be fooled resulting in wrong black levels.

Support for floating point data

Libraw can read floating point DNG files (no other RAW formats may use floating point) with or without conversion to integer data. Floating point values are stored in imgdata.rawdata buffers:

  • float * float_image (if not NULL) points to floating point bayer data
  • float (*float3_image)[3] (if not NULL) points to floating point 3-channel buffer
  • float (*float4_image)[4] (if not NULL) points to floating point 4-channel buffer

Function calls for floating point support:

  • int LibRaw::is_floating_point(); function will return 1 if file contains floating point data
  • int LibRaw::have_fpdata(); function will return 1 if FP data has read (decoded) into memory and not converted to integer data
  • int LibRaw::convertFloatToInt(float dmin=4096.f, float dmax=32767.f, float dtarget = 16383.f) converts floating point data to integer. If data maximum is out of dmin..dmax range, than data scaled to set maximum to dtarget

Support for YCC formats (Canon sRAW/mRAW and Nikon Small NEF)

       int LibRaw::is_sraw();
int LibRaw::is_nikon_sraw();
int LibRaw::sraw_midpoint()
  • is_sraw() call returns nonzero if current image is YCC-based.
  • is_nikon_sraw() call returns nonzero for Nikon Small NEF files
  • sraw_midpoint() call returns neutral (gray) point for color channels

void LibRaw::set_dng_host(void* p)

If LibRaw is compiled with Adobe DNG SDK support and you wish to use this support:

  • you need to create own dng_host object
  • and pass it to LibRaw object using this function

void LibRaw::recycle_datastream(void)

This call closes input datastream with associated data buffer and unblocks opened file.

void LibRaw::recycle(void)

Frees the allocated data of LibRaw instance, enabling one to process the next file using the same processor. Repeated calls of recycle() are quite possible and do not conflict with anything.

LibRaw::~LibRaw()

Destructor, which consists in calling recycle().

const char* LibRaw::strprogress(enum LibRaw_progress code)

Converts progress stage code to description string (in English).

const char* LibRaw::strerror(int errorcode)

Analog of strerror(3) function: outputs the text descriptions of LibRaw error codes (in English).

Setting Error Notification Functions

In process of RAW conversion LibRaw can call user-setted callback. This callback can be used for:

  • Dynamic status update (progress bar and so on).
  • Cancel of processing (for example, user pressed Cancel button).

Also, work of the library may cause two types of exceptional situations that require notification of the calling application:

  • Memory shortage
  • Data read error.

An application may set its own callbacks that will be called in the cases mentioned above to notify the user (or the calling program).

Progress indication/processing termination

        typedef int (*progress_callback)(void *callback_data,enum LibRaw_progress stage, int iteration, int expected);
void LibRaw::set_progress_handler(progress_callback func,void *callback_data);

LibRaw user can set own callback which will be called 10-50 times during RAW postprocessing by dcraw_process().

This callback may terminate current image processing by returning of non-zero value. In such case all processing will be cancelled immediately and all resources will be returned to system by recycle() call. Current call of dcraw_process() will return error code LIBRAW_CANCELLED_BY_CALLBACK.

Callback parameters:

void *callback_data
void*-pointer, passed as 2nd argument to set_progress_handler(). This pointer should be used to pass additional data to callback (i.e. thread local data and so on).
enum LibRaw_progress stage
Current processing stage. This number can be converted to string by call to LibRaw::strprogress. Not all processing stages are covered by callback calls.
int iteration
Iteration number within current stage (from 0 to expected-1).
int expected
Expected number of iterations on current stage.

Callback should return value of: 0 for continue processing and non-zero for immediate cancel of processing.

 

If LibRaw compiled with OpenMP support, iteration parameter may not always increase within one stage. Out of order callback calls are possible.

Callback code sample:

int my_progress_callback(void *data,enum LibRaw_progress p,int iteration, int expected)
{
char *passed_string = (char *data);
printf("Callback: %s pass %d of %d, data passed: %s\n",libraw_strprogress(p),iteration,expected,passed_string);
if(timeout || key_pressed )
return 1; // cancel processing immediately
else
return 0; // can continue
}

User-specified exif tag parser callback

       typedef void (*exif_parser_callback) (void *context, int tag, int type, int len,unsigned int ord, void *ifp);
void LibRaw::set_exifparser_handler( exif_parser_callback cb,void *context);

Callback to be called on each parsed EXIF/Makernotes tag with parameters:

  • context - pointer to context passed to set_exifparser_handler();
  • tag - EXIF/Makernotes tag value
  • type - TIFF(EXIF) tag type
  • len - tag length
  • ord - byte order (II or MM)
  • void *ifp - pointer to LibRaw_abstract_datastream, positioned to tag data

File Read Error Notifier

        typedef void (*data_callback)(void *callback_data,const char *file, const int offset);
void LibRaw::set_dataerror_handler(data_callback func, void *callback_data);

The user can define his or her own function to be called in the case of error in the input data. It is a void function receiving two parameters:

  • void *callback_data - void*-pointer, passed as 2nd argument to set_progress_handler(). This pointer should be used to pass additional data to callback (i.e. thread local data and so on).
  • file is the name of the RAW file whose processing evoked the file read error. This name can be NULL if underlying data input layer does not know the name. So, if calling application sets own callback, this callback should work with NULL file name.
  • offset is -1 at end-of-file (if LibRaw expects more data) or a positive number equal to the file position (bytes from file beginning) where the unpacking error occurred.

The callback function is intended for information purposes: it notifies the user or the program code that processing is impossible.

If the user does not set his or her own handler, the standard one (output of error message in stderr) will be used.

One can set the null handler by passing NULL to set_dataerror_handler; then no notifier function will be called. The same effect can be achieved by creating a LibRaw object with the LIBRAW_OPTIONS_NO_DATAERR_CALLBACK flag in the constructor.

In the case of error in the input data, processing of the current file is terminated and a notifier is called; all allocated resources are freed, and recycle() is performed. The current call will return LIBRAW_IO_ERROR.
At an attempt to continue data processing, all subsequent calls will return LIBRAW_OUT_OF_ORDER_CALL. Processing of a new file may be started in the usual way, by calling LibRaw::open_file().

Data Postprocessing: Emulation of dcraw Behavior

Instead of writing one's own Bayer pattern postprocessing, one can use the dcraw functions, which are called after the calls of open_file() + unpack() /+ unpack_thumb()/

Parameter Setting

Virtually all parameters that can be set through the dcraw command line are specified by assigning values to fields of the LibRaw::imgdata.params structure. The type of this structure is libraw_output_params_t; all fields are listed and described in sufficient detail in the description of data structures.

int LibRaw::raw2image

This function allocates buffer for postprocessing (imgdata.image) and fills it with data layout compatible with LibRaw 0.13/0.14 and below. If the buffer is already allocated, it will be free()ed and allocated again.

This function should be called only if your code do postprocessing stage. If you use LibRaw's postprocessing calls (see below) you don't need to call raw2image().

The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.

void LibRaw::free_image

This function releases the imgdata.image buffer allocated by raw2image();

This method should be called if current postprocessing results are not needed by the program (e.g. already copied somewhere), but new postprocessing calls (with another settings) are possible, so it is to early to call recycle().

int LibRaw::adjust_sizes_info_only(void)

The function calculates the correct size of the output image (imgdata.sizes.iwidth and imgdata.sizes.iheight) for the following cases:

  • Files from Fuji cameras (with a 45-degree rotation)
  • Files from cameras with non-square pixels
  • Images shot by a rotated camera.

In the aforementioned cases, the function changes the fields of the image output size; note that this change cannot be repeated again.

int LibRaw::dcraw_process(void)

The function emulates the postprocessing capabilities available in dcraw.
Called after calling LibRaw::unpack();

The entire functionality of dcraw (set via the field values in imgdata.params) is supported, except for

  • Dark frame subtraction
  • Work with bad pixels.

The function is intended solely for demonstration and testing purposes; it is assumed that its source code will be used in most real applications as the reference material concerning the order of RAW data processing.

The function returns an integer number in accordance with the error code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.

Data Output to Files: Emulation of dcraw Behavior

In spite of the abundance of libraries for file output in any formats, LibRaw includes calls that emulate the file output provided by dcraw. This is done primarily for easier verification of library work: the resultant files must be binary identical.

int LibRaw::dcraw_ppm_tiff_writer(const char *outfile)

The function outputs the postprocessing results to a file in the PPM/PGM or TIFF format (the format is set via imgdata.params.output_tiff). The results are binary identical to those provided by dcraw.

If "-" is passed as outfile, the function will write to standard output (stdout).

The function returns an integer number in accordance with the error code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.

int LibRaw::dcraw_thumb_writer(const char *thumbfile)

Writes the thumbnail to a file in the PPM format for bitmap thumbnails and in the JPEG format for JPEG thumbnails, i.e., in the format completely identical to the results provided by dcraw.

The function returns an integer number in accordance with the error code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.

Copying unpacked data into memory buffer

There is several function calls for store unpacked data into memory buffer (after using dcraw_process() and so on):

  • get_mem_image_format - get resulting bitmap size and bit depth.
  • copy_mem_image - copy postprocessed data into some memory buffer with different color order and line stride.
  • dcraw_make_mem_image - store processed image data into allocated buffer;
  • dcraw_make_mem_thumb - store extracted thumbnail into buffer as JPEG-file image (for most cameras) or as RGB-bitmap.

For usage primer see samples/mem_image.c sample.

 

void get_mem_image_format(int *widthp, int *heightp, int *colorsp, int *bpp) const - return processing bitmap size

This function returns size of postprocessed image:

  • Image width is returned in *widthp;
  • Bitmap height is returned in *heightp;
  • Image color count is returned in *colorsp;
  • Bits per pixel (8 or 16) is returned in *bpp;

int LibRaw::copy_mem_image(void* scan0, int stride, int bgr) - copies postprocessed bitmap data into buffer

Function parameters:

  • void *scan0 - pointer to buffer to copy data to. The buffer should be at least stride*image_height bytes;
  • int stride - stride of each other image line (row) in bytes. Usually image_width*(bit_per_pixel/8)*image_colors, but may be more if you wish to align image rows to, for example, 8 or 16 or 32 bytes to make CPU more happy.
  • int bgr - pixel copy order. RGB if bgr==0 and BGR otherwise.

The function returns an integer number in accordance with the error code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.

libraw_processed_image_t *dcraw_make_mem_image(int *errorcode=NULL) - store unpacked and processed image into memory buffer as RGB-bitmap

This function allocates memory buffer and stores unpacked-preprocessed image into this buffer. Function returns allocated structure libraw_processed_image_t with filled fields. Always returns data as RGB bitmap (i.e. type field is equal to LIBRAW_IMAGE_BITMAP).

dcraw_process() should be called before dcraw_make_mem_image();

Returns NULL in case of an error. If caller has passed not-NULL value as errorcode parameter, than *errorcode will be set to error code according to error code convention.

NOTE! Memory, allocated for return value will not be fried at destructor or LibRaw::recycle calls. Caller of dcraw_make_mem_image should free this memory by call to LibRaw::dcraw_clear_mem().

libraw_processed_image_t *dcraw_make_mem_thumb(int *errorcode=NULL) - store unpacked thumbnail into memory buffer

This function allocates memory buffer and stores thumbnail data in it. Function returns allocated structure libraw_processed_image_t with filled fields. For most RAW images allocated structure will contains JPEG image (i.e. type field is equal to LIBRAW_IMAGE_JPEG). For some cameras with RGB-bitmap thumbnail (Kodak SLRs) returned structure contains RGB bitmap (type field is equal to LIBRAW_IMAGE_JPEG, see structure description for details).

unpack_thumb() should be called before dcraw_make_mem_thumb();

Returns NULL in case of an error. If caller has passed not-NULL value as errorcode parameter, than *errorcode will be set to error code according to ñ error code convention.

NOTE! Memory, allocated for return value will not be fried at destructor or LibRaw::recycle calls. Caller of dcraw_make_mem_image should free this memory by call to LibRaw::dcraw_clear_mem().

void LibRaw::dcraw_clear_mem(libraw_processed_image_t *)

This function will free the memory allocated by dcraw_make_mem_image or dcraw_make_mem_thumb.

This is static class member, so call syntax should be LibRaw::dcraw_clear_mem(...).

This call translates directly to free() system function, but it is better to use dcraw_clear_mem because LibRaw (DLL) may be compiled with memory manager other than in calling application.

Input layer abstraction

class LibRaw_abstract_datastream - abstract RAW read interface

LibRaw reads RAW-data by calling (virtual) methods of C++ object derived from LibRaw_abstract_datastream. This C++ class does not implement any read, but defines interface to be called. Call to base class methods always results in error.

LibRaw_abstract_datastream class methods

Object verification
virtual int valid()
Checks input datastream validity. Returns 1 on valid stream and 0 if datastream was created on non-valid input parameters (wrong filename for file stream and so on).

Stream read and positioning

This group of methods implements file object (FILE*) semantics.

virtual int read(void * ptr,size_t size, size_t nmemb)
Similar to fread(ptr,size,nmemb,file).
virtual int seek(off_t o, int whence)
Similar to fseek(file,o,whence).
virtual int tell(
Similar to ftell(file).
virtual int get_char()
Similar to getc(file)/fgetc(file).
virtual char* gets(char *s, int n)
Similar to fgets(s,n,file).
virtual int eof()
Similar to feof(file).
virtual int scanf_one(const char *fmt, void *val)
Simplified variant of fscanf(file,fmt,val): format string is always contains one argument to read. So, variable args call is not needed and only one pointer to data passed.
virtual int jpeg_src(void * p);
Initializes read structures in j_decompress_ptr object passed as *p. This object is used by libjpeg for JPEG data reading from datastream.

Returns -1 on error and 0 on success.

virtual void * make_jas_stream();
Creates LibJasper input stream (for JPEG2000 decoding).

returns NULL on error or data pointer on success.

Other methods

This group of methods includes several supplementary calls. These calls are used to temporary switch to another data stream (file and/or memory buffer).

virtual const char* fname()
Returns name of opened file if datastream object knows it (for example, LibRaw_file_datastream used). Filename used in:
  • error notification callbacks;
  • generation of filename of JPEG-file with metadata when needed (i.e. cameras with 'Diag RAW hack').
virtual int subfile_open(const char *fn)
This call temporary switches input to file fn. Returns 0 on success and error code on error.
The function used to read metadata from external JPEG file (on cameras with "Diag RAW hack").
This call is not implemented for LibRaw_buffer_datastream, so external JPEG processing is not possible when buffer datastream used.
This function should be implemented in real input class, base class call always return error.
Working implementation sample can be found in LibRaw_file_datastream implementation in libraw/libraw_datastream.h file.
virtual void subfile_close()
This call switches input stream from temporary open file back to main data stream.
virtual int tempbuffer_open(void *buf, size_t size)
This call temporary switches input to LibRaw_buffer_datastream object, created from buf.
This method is needed for Sony encrypted metadata parser.

This call implemented in base class (LibRaw_abstract_datastream), there is no need to reimplement in in derived classes.
Possible activity of temporary datastream requires very accurate programming when implementing datastreams derived from base LibRaw_abstract_datastream. See below for more details.

virtual void tempbuffer_close()
This call switch input back from temporary datastream to main stream. This call implemented in base LibRaw_abstract_datastream class.

Derived input classes included in LibRaw

There is three "standard" input classes in LibRaw distribution:

LibRaw C++ interface users can implement their own input classes and use them via LibRaw::open_datastream call. Requirements and implementation specifics are described below.

class LibRaw_file_datastream - file input interface

This class implements input from file.

Class methods:

LibRaw_file_datastream(const char *fname)
This constructor creates LibRaw_file_datastream object from file fname.
Unfortunately, C++ constructor cannot return an error. So if bad filename passed (e.g. nonexistent file) object is created as non-valid (valid() call returns zero).

All other class methods are described above.
This class implements all possible methods, including fname() and subfile_open().

class LibRaw_bigfile_datastream - file input interface

This class implements input from file.

Class methods:

LibRaw_bigfile_datastream(const char *fname)
This constructor creates LibRaw_bigfile_datastream object from file fname.
Unfortunately, C++ constructor cannot return an error. So if bad filename passed (e.g. nonexistent file) object is created as non-valid (valid() call returns zero).

The difference between file and bigfile datastreams are obvious from class name: bigfile one supports large files (more than 2Gb) on all supported systems. File one uses streambuf interface which is limited to 2Gb on many systems.

All other class methods are described above.
This class implements all possible methods, including fname() and subfile_open().

class LibRaw_buffer_datastream - memory buffer input interface

This class implements input from memory buffer.

Class methods:

LibRaw_buffer_datastream(void *buffer, size_t bsize)
This constructor creates datastream object from buffer with size bsize.
It is not possibly to verify the pointer passed, so buffer address is checked against 0 and -1 only.

All other class methods are described above.
This class does not implement fname() and subfile_open() calls, so external JPEG metadata parsing is not possible.

Own datastream derived classes

To create own read interface LibRaw user should implement C++ class derived from LibRaw_abstract_datastream with all read methods.
LibRaw standard implementations may be used as reference. See libraw/libraw_datastream.h file for details (all standard LibRaw input classes are implemented using inline functions only).

[back to Index]

LibRaw-0.21.4/doc/API-datastruct.html000066400000000000000000002256471477673233700172410ustar00rootroot00000000000000 LibRaw: Data Structures and Constants

LibRaw: Data Structures and Constants [back to Index]

LibRaw: Data Structures and Constants

LibRaw data structures are defined in header file libraw/libraw_types.h
Constants used in its work are defined in file libraw/libraw_const.h

Contents:

  1. Data structures
    1. libraw_data_t: Main Data Structure in LibRaw
    2. Structure libraw_iparams_t: Main Parameters of the Image
    3. Structure libraw_image_sizes_t: Image Dimensions
    4. Structure libraw_colordata_t: Color Information
    5. Structure libraw_imgother_t: Other Parameters of the Image
    6. Structure libraw_rawdata_t: holds unpacked RAW data
    7. Structure libraw_thumbnail_t: Description of extracted Thumbnail
    8. Structure libraw_thumbnail_list_t: Description of file's thumbnail list
    9. Structure libraw_lensinfo_t - lens data, extracted from EXIF/Makernotes
    10. Structure libraw_raw_unpack_params_t: metadata and raw decoding options and flags
    11. Structure libraw_output_params_t: Management of dcraw-style postprocessing
    12. Structure libraw_callbacks_t: user-settable callbacks
    13. Structure libraw_processed_image_t - result set for dcraw_make_mem_image()/dcraw_make_mem_thumb() functions
  2. Input abstraction layer
  3. Constants
    1. enum LibRaw_errors: Error Codes
    2. enum LibRaw_decoder_flags - RAW data format description
    3. enum LibRaw_progress: Current State of LibRaw Object
    4. enum LibRaw_thumbnail_formats: Thumbnail Data Formats
    5. Nonstandard Situations (Warnings) during RAW Data Processing
    6. enum LibRaw_image_formats - possible types of data, contains in libraw_processed_image_t structure
    7. enum LibRaw_processing_options - flags that affects extracted RAW data
    8. enum LibRaw_rawspecial_t - special raw extraction modes

Data Structures

libraw_data_t: Main Data Structure of LibRaw

Structure libraw_data_t is a "wrapping" for data structures accessible to the user of the library.
When one uses C++ API, it is accessible as LibRaw::imgdata (class_instance.imgdata). The data in this structure appear after a file is opened through open_file (and other open_ calls), except for the image itself (filled by unpack()) and data containing the preview information (filled by calling unpack_thumb()).

Data fields:

unsigned int progress_flags;
This field records the past phases of image processing .
unsigned int process_warnings;
This field records suspicious situations (warnings) that have emerged during image processing.
libraw_iparams_t idata;
The structure describes the main image parameters retrieved from the RAW file. Fields of this structure are described in detail below .
libraw_image_sizes_t sizes;
The structure describes the geometrical parameters of the image. Fields of this structure are described in detail below .
libraw_lensinfo_t lens;
The structure describes lens used for the shot. Fields of this structure are described in detail below .
libraw_makernotes_t makernotes;
The structure contains camera/vendor specific metadata extracted from file. No description provided, sorry, if you're interested in particular tag/camera/vendor - use Exiftool documentation as a reference
libraw_colordata_t color;
The structure contains color data retrieved from the file. Fields of this structure are described in detail below .
libraw_imgother_t other;
Data structure for information purposes: it contains the image parameters that have been extracted from the file but are not needed in further file processing. Fields of this structure are described in detail below .
libraw_thumbnail_t thumbnail;
Data structure containing information on the preview and the preview data themselves. All fields of this structure but thumbnail itself are filled when open_file() is called. Thumbnail read by unpack_thumb() call. The fields are described in detail below .
libraw_rawdata_t rawdata;
Data structure with pointer to raw-data buffer. Details are described below .
ushort (*image)[4];
The memory area that contains the image pixels per se. It is filled when raw2image() or dcraw_process() is called.
libraw_output_params_t params;
Data structure intended for management of image postprocessing (using the dcraw emulator). Fields of this structure are described in detail below .
libraw_callbacks_t callbacks;
user-settable callbacks

Structure libraw_iparams_t: Main Parameters of the Image

char make[64];
Camera manufacturer.
char model[64];
Camera model.
normalized_make[64]
There is a huge number of identical cameras sold under different names, depending on the market (e.g. multiple Panasonic or Canon models) and even some identical cameras sold under different brands (Panasonic -> Leica, Sony -> Hasselblad). normalized_make contains primary vendor name (e.g. Panasonic for Leica re-branded cameras).
normalized_model[64]
Primary camera model name.
unsigned maker_index
Primary vendor name in indexed form (enum LibRaw_cameramaker_index, LIBRAW_CAMERAMAKER_* constant)
char software[64];
Softwary name/version (mostly for DNG files, to distinguish in-camera DNGs from Adobe DNG Converter produced ones).
unsigned raw_count;
Number of RAW images in file (0 means that the file has not been recognized).
unsigned is_foveon;
Nonzero for Sigma Foveon images
unsigned dng_version;
DNG version (for the DNG format).
int colors;
Number of colors in the file.
unsigned filters;
Bit mask describing the order of color pixels in the matrix (0 for full-color images). 32 bits of this field describe 16 pixels (8 rows with two pixels in each, from left to right and from top to bottom). Each two bits have values 0 to 3, which correspond to four possible colors. Convenient work with this field is ensured by the COLOR(row,column) function, which returns the number of the active color for a given pixel.
Values less than 1000 are reserved as special cases:
  • 1 - Leaf Catchlight with 16x16 bayer matrix;
  • 9 - Fuji X-Trans (6x6 matrix)
  • 3..8 and 10..999 - are unused.
char xtrans[6][6];
char xtrans_abs[6][6];
These matrices contains Fuji X-Trans row/col to color mapping. First one is relative to visible area, while second is positioned relative to sensor edges.
char cdesc[5];
Description of colors numbered from 0 to 3 (RGBG,RGBE,GMCY, or GBTG).
unsigned xmplen; char *xmpdata;
XMP packed data length and pointer to extracted XMP packet.

Structure libraw_image_sizes_t: Image Dimensions

Structure libraw_image_sizes_t is a collection of all file data that describe the size of the image.

Data fields:

ushort raw_height, raw_width;
Full size of RAW image (including the frame) in pixels.
ushort height, width;
Size of visible ("meaningful") part of the image (without the frame).
ushort top_margin, left_margin;
Coordinates of the top left corner of the frame (the second corner is calculated from the full size of the image and size of its visible part).
ushort iheight, iwidth;
Size of the output image (may differ from height/width for cameras that require image rotation or have non-square pixels).
unsigned raw_pitch;
Full size of raw data row in bytes .
double pixel_aspect;
Pixel width/height ratio. If it is not unity, scaling of the image along one of the axes is required during output.
int flip;
Image orientation (0 if does not require rotation; 3 if requires 180-deg rotation; 5 if 90 deg counterclockwise, 6 if 90 deg clockwise).
libraw_raw_inset_crop_t raw_inset_crops[2];
(libraw_raw_inset_crop_t: ushort cleft, ctop, cwidth, cheight;)
  • item at[0] contains standard crop data parsed from camera metadata (DNG: DefaultCrop* tags, other formats: vendor specific tags)
  • item at [1] is 'user crop', in particular:
    - set by DNG DefaultUserCrop tag
    - or set via raw aspect ratio tags (e.g. 16:9 aspect on Fujifilm cameras) raw_inset_crops[1] is filled only if aspect ratio tags provides different aspect ratio compared to raw_inset_crops[0].

Structure libraw_colordata_t: Color Information

Structure libraw_colordata_t unites all color data, both retrieved from the RAW file and calculated on the basis of the image itself. For different cameras, there are different ways of color handling.

Data fields:

ushort curve[0x10000];
Camera tone curve. May be read from file as is, or calculated, depending on file format;
unsigned black;
Black level. Depending on the camera, it may be zero (this means that black has been subtracted at the unpacking stage or by the camera itself), calculated at the unpacking stage, read from the RAW file, or hardcoded.
unsigned cblack[4102];
Per-channel black level correction. First 4 values are per-channel correction, next two are black level pattern block size, than cblack[4]*cblack[5] correction values (for indexes [6....6+cblack[4]*cblack[5]).
unsigned data_maximum;
Maximum pixel value in current file. Calculated at raw2image or dcraw_process() calls.
unsigned maximum;
Maximum pixel value. Calculated from the data for most cameras, hardcoded for others. This value may be changed on postprocessing stage (when black subtraction performed) and by automated maximum adjustment (this adjustment performed if params.adjust_maximum_thr is set to nonzero).
unsigned linear_max[4];
Per-channel linear data maximum read from file metadata. If RAW file does not contains this data, linear_max[] is set to zero. Black value is not subtracted
float fmaximum;
Maximum pixel value in real image for floating data files.
float fnorm;
Normalization coefficient used while converting floating point raw data to integer.
ushort white[8][8];
Block of white pixels extracted from files CIFF/CRW. Not extracted for other formats. Used to calculate white balance coefficients.
float cam_xyz[4][3];
Camera RGB - XYZ conversion matrix. This matrix is constant (different for different models). Last row is zero for RGB cameras and non-zero for different color models (CMYG and so on).
float cam_mul[4];
White balance coefficients (as shot). Either read from file or calculated.
float pre_mul[4];
White balance coefficients for daylight (daylight balance). Either read from file, or calculated on the basis of file data, or taken from hardcoded constants.
float cmatrix[3][4];
Camera color data read from RAW file (if any)
float rgb_cam[3][4];
Camera to sRGB conversion matrix
float ccm[3][4];
Camera color correction matrix read from file metadata (uniform matrix if no such data in file)
ph1_t phase_one_data;
Color data block that is read for Phase One cameras.
float flash_used;
float canon_ev;
Fields used for white balance calculations (for some P&S Canon cameras).
char model2[64];
Firmware revision (for some cameras).
char UniqueCameraModel[64],LocalizedCameraModel[64];
Values from DNG tags with same names.
void *profile;
Pointer to the retrieved ICC profile (if it is present in the RAW file).
unsigned profile_length;
Length of ICC profile in bytes.
unsigned black_stat[8];
Black level statistics if calculated from masked area: 4 sum of pixel values, than 4 pixel counts (per channel).
libraw_dng_color_t dng_color[2];
Color data read from DNG: illuminant, calibration matrix and color matrix for two light sources. (see DNG specs for details).
libraw_dng_levels_t dng_levels
DNG black/white levels, analog balance, WB for active IFD. See DNG specs for details.
int WB_Coeffs[256][4]
Index: EXIF color source value, [i][0..3] WB Coeffs
float WBCT_Coeffs[64][5]
Color temperature in [i][0], WB coeffs in [i][1..4]
int as_shot_wb_applied
Set to 1 if WB already applied in camera (multishot modes; small raw)
libraw_P1_color_t P1_color[2]
Phase-one specific color data
unsigned raw_bps
RAW bits per pixel (PhaseOne: Raw format used)
int ExifColorSpace
EXIF color space parsed from EXIF tags: LIBRAW_COLORSPACE_Unknown, LIBRAW_COLORSPACE_sRGB, or LIBRAW_COLORSPACE_Adobe

Structure libraw_imgother_t: Other Parameters of the Image

Data fields:

float iso_speed;
ISO sensitivity.
float shutter;
Shutter speed.
float aperture;
Aperture.
float focal_len;
Focal length.
time_t timestamp;
Date of shooting.
unsigned shot_order;
Serial number of image.
unsigned gpsdata[32];
GPS data (unparsed block, to write to output as is).
libraw_gps_info_t parsed_gps;
Parsed GPS-data: longitude/latitude/altitude and time stamp.
char desc[512];
Image description.
char artist[64];
Author of image.
float FlashEC;
Flash exposure compensation.

Structure libraw_rawdata_t: holds unpacked RAW data

Structure libraw_rawdata_t holds:

  • RAW-data from sensor, read and unpacked by the unpack() call.
  • "backup" copy of color and over data modified during postprocessing. When postprocessing calls repeats, the needed data is restored from this backup.

Data fields:

void *raw_alloc;
Buffer allocated to hold RAW-data
unsigned short *raw_image;
Pointer to buffer with one-component (bayer) data.
unsigned short (*color3_image)[3];
Pointer to 3-component pixel array.
unsigned short (*color4_image)[4];
Pointer to buffer with 4-component pixel data data
float *float_image;
Pointer to buffer with one-component (bayer) data in FP-format.
float (*float3_image)[3];
Pointer to 3-component FP pixel array.
float (*float4_image)[4];
Pointer to buffer with 4-component pixel data data

After call to unpack() only one of these fields is non-NULL.

All other fields of this structure are for internal use and should not be touched by user code.

Structure libraw_thumbnail_t: Description of Thumbnail

Structure libraw_thumbnail_t describes all parameters associated with the preview saved in the RAW file.

Data fields:

LibRaw_thumbnail_formats tformat;
Thumbnail data format. One of the values among enum LibRaw_thumbnail_formats .
ushort twidth, theight;
Dimensions of the preview image in pixels.
unsigned tlength;
Thumbnail length in bytes.
int tcolors;
Number of colors in the preview.
char *thumb;
Pointer to thumbmail, extracted from the data file.

Structure libraw_thumbnail_list_t: thumbnails present in the RAW file

libraw_thumbnail_list_t holds list of thumbnails (previews) present in RAW file.

Data fields:

int thumbcount;
Thumbnail count
libraw_thumbnail_item_t thumblist[LIBRAW_THUMBNAIL_MAXCOUNT];
Array of libraw_thumbnail_item_t, one for each thumbnail:
enum LibRaw_internal_thumbnail_formats tformat
Internal thumbnail format (this field stores thumbnail decoder needed for thumbnail extraction)
ushort twidth, theight
Thumbnail image size. Note: these fields may be zero (so, image size is unknown at parse phase)
ushort tflip
Thumbnail image rotation, it may differ from main image rotation. This field may be set to 0xffff, this means 'rotation is not known'
unsigned tlength;
Thumbnail on-disk data size
unsigned tmisc;
Bits per pixel and color count: (color << 5) | bits
INT64 toffset;
Thumbnail data offset in file

Note: even if no thumbnails were found in TIFF/CR3 structure, the thumbcount field will be initialized to 1 and thumblist[0] will be initialized to thumbnail data from the thumbnail data, so LibRaw::unpack_thumb_ex(0) will do the same as LibRaw::unpack_thumb().

Structure libraw_lensinfo_t: parsed lens data

The following parameters are extracted from Makernotes and EXIF, to help identify which lens was mounted on the camera. If the value is missing in Makernotes or EXIF, the parameter is set to zero with some exceptions noted below. In some cases the values for the fields like CameraFormat and CameraMount are set based on the camera model and/or camera ID.

libraw_makernotes_lens_t structure:

  • LensID (if not -1) and CamID (camera id, if non-zero) values are compatible with those used in exiftool, like |0x0010 CanonModelID| and |22 LensType| see http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html or 0x0207/CameraType and 0x0201/LensType (see http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Olympus.html )
  • Lens string, if not empty, contains the lens name present in Makernotes.
  • LensFormat and CameraFormat currently provide one of value from enum LibRaw_camera_formats;
  • In a similar manner, values for LensMount and CameraMount follow the enum LibRaw_camera_mounts;
  • In some cases, the Makernotes for MF cameras contain either an id for the body, or a string containing the name of the body. The name is copied to body field, while the id is converted to the appropriate body name and also copied to 'body' field. In other cases the 'body' field is empty.
  • FocalType is set based on Makernotes tag, if present. The values are:
    • -1 Undefined
    • 0 Unknown;
    • 1 Fixed focal length lens
    • 2 Zoom lens
  • LensFeatures_pre - lens name prefix and LensFeatures_suf - lens name suffix: (if not empty) some cameras record alphabet soup that characterizes the lens in separate Makernote tags (see, for example, 0xb02a LensSpec at http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Sony.html ), and for some lenses those acronyms can be derived from the 'Lens' field itself (see processCanonCameraInfo). Those can also help better lens identification.
  • MinFocal and MaxFocal , if non-zero, contain the minimum and maximum focal lengths for the lens mounted on the camera.
  • MaxAp4MinFocal, MaxAp4MaxFocal, MinAp4MinFocal, MinAp4MaxFocal - if non-zero, contain maximum aperture available at minimal focal length, maximum aperture available at maximum focal length, minimum aperture available at minimal focal length, minimum aperture available at maximum focal length, respectively.
  • MaxAp and MinAp, if non-zero, contain the maximum aperture for the lens (usually it is the maximum aperture for minimal focal length) and the minimum aperture across the focal length range. For zooms with variable maximum aperture this is usually the minimum aperture for the maximum focal length.
  • CurFocal, if non-zero, is current focal length - that is the focal length used to take the shot.
  • CurAp, if non-zero, is current aperture.
  • MaxAp4CurFocal and MinAp4CurFocal, if non-zero, contain the minimum and maximum apertures for the current focal length.
  • LensFStops - if non-zero, contains the number of aperture "clicks" or the number of f-stops, depending on the model of the camera.
  • TeleconverterID, AdapterID, AttachmentID, if non-zero, are the numbers extracted from Makernotes to identify lens accessories used to take the shot.
  • Teleconverter, Adapter, Attachment, if non-empty, are the strings containing the names of the accessories as they appear in Makernotes, or for some cameras, decoded from a numeric field in Makernotes.
  • FocalUnits - an auxiliary field, should not be needed most of the cases. See Canon.pm module in exiftool for more information on this value.
  • FocalLengthIn35mmFormat, if non-zero: for some reason certain Samsung cameras record this value in Makernotes instead of the EXIF proper. Also used for Sigma cameras.

libraw_nikonlens_t structure:

Contains additional parameters needed to identify the lens on a Nikon camera using a table - please see Nikon LensID Values at http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html

libraw_dnglens_t structure:

Contains minimum focal length, maximum focal length, maximum aperture available at minimal focal length, and maximum aperture available at maximum focal length, extracted from EXIF field of a DNG raw file.

libraw_lensinfo_t structure:

Contains all the structures described above, plus parameters extracted directly from EXIF fields:

  • MinFocal and MaxFocal , if non-zero, contain the minimum and maximum focal lengths for the lens mounted on the camera.
  • MaxAp4MinFocal, MaxAp4MaxFocal - if non-zero, contain maximum aperture available at minimal focal length and maximum aperture available at maximum focal length
  • LensMake, if not empty, contains a string with the lens manufacturer name.
  • Lens, if not empty, contains the lens name as recorded in EXIF
  • FocalLengthIn35mmFormat - if non-zero, same as FocalLengthIn35mmFilm in EXIF standard, tag 0xa405.
  • EXIF_MaxAp - if non-zero, contains the value derived from EXIF tag 0x9205.

Structure libraw_raw_unpack_params_t: RAW decoding options and flags

Structure libraw_raw_unpack_params_t contains fields/flags that affects RAWdata and metadata decoding

int options
Processing options used on unpack() phase for specific image formats, see below for possible values: LibRaw_processing_options
unsigned shot_select;
dcraw keys: -s
Selection of image number for processing (for formats that contain several RAW images in one file).
int specials
Special processing mode (e.g. omit YCC to RGB conversion), see below for possible values. LibRaw_rawspecial_t
int max_raw_memory_mb
Stop processing if raw buffer size grows larger than that value (in megabytes). Default is LIBRAW_MAX_ALLOC_MB_DEFAULT (2048Mb)
int sony_arw2_posterization_thr
If LIBRAW_PROCESSING_SONYARW2_DELTATOVALUE used for raw_processing_options, sets the level to suppress posterization display in shadows.
float coolscan_nef_gamma;
Gamma value for Coolscan NEF decoding (no way to get if from file, it should be set by calling application).
char p4shot_order[5];
Shot order for Pentax 4shot files. Default is "3102".

Structure libraw_output_params_t: management of dcraw-style postprocessing

Structure libraw_output_params_t (imgdata.params) is used for management of dcraw-compatible calls dcraw_process(), dcraw_ppm_tiff_writer(), and dcraw_thumb_writer(). Fields of this structure correspond to command line keys of dcraw.

Data fields:

unsigned greybox[4];
dcraw keys: -A x y w h
4 numbers corresponding to the coordinates (in pixels) of the rectangle that is used to calculate the white balance. X and Y are coordinates of the left-top rectangle corner; w and h are the rectangle's width and height, respectively.
unsigned cropbox[4];
dcraw keys: none
This field sets the image cropping rectangle. Cropbox[0] and cropbox[1] are the rectangle's top-left corner coordinates, remaining two values are width and height respectively. All coordinates are applied before any image rotation.
double aber[4];
dcraw keys: -C
Correction of chromatic aberrations; the only specified values are
aber[0], the red multiplier
aber[2], the blue multiplier. For some formats, it affects RAW data reading , since correction of aberrations changes the output size.
double gamm[6];
dcraw keys: -g power toe_slope
Sets user gamma-curve. Library user should set first two fields of gamm array:
gamm[0] - inverted gamma value)
gamm[1] - slope for linear part (so called toe slope). Set to zero for simple power curve.
Remaining 4 values are filled automatically.
By default settings for rec. BT.709 are used: power 2.222 (i.e. gamm[0]=1/2.222) and slope 4.5. For sRGB curve use gamm[0]=1/2.4 and gamm[1]=12.92, for linear curve set gamm[0]/gamm[1] to 1.0.
float user_mul[4];
dcraw keys: -r mul0 mul1 mul2 mul3
4 multipliers (r,g,b,g) of the user's white balance.
float bright;
dcraw keys: -b
Brightness (default 1.0).
float threshold;
dcraw keys: -n
Parameter for noise reduction through wavelet denoising.
int half_size;
dcraw keys: -h
Outputs the image in 50% size. For some formats, it affects RAW data reading .
int four_color_rgb;
dcraw keys: -f
Switches on separate interpolations for two green components.
int highlight;
dcraw keys: -H
0-9: Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild).
int use_auto_wb;
dcraw keys: -a
Use automatic white balance obtained after averaging over the entire image.
int use_camera_wb;
dcraw keys: -w
If possible, use the white balance from the camera.

If camera-recorded WB is not available, dcraw_process() will fallback to:

  • Auto-WB if bit LIBRAW_PROCESSING_CAMERAWB_FALLBACK_TO_DAYLIGHT is not set in params.raw_processing_options (or for the rare specific case: no valid WB index was parsed from CRW file)
  • Daylight-WB if abovementioned bit is not set.
int use_camera_matrix;
dcraw keys: +M/-M
  • 0: do not use embedded color profile
  • 1 (default): use embedded color profile (if present) for DNG files (always); for other files only if use_camera_wb is set;
  • 3: use embedded color data (if present) regardless of white balance setting.
int output_color;
dcraw keys: -o
[0-8] Output colorspace (raw, sRGB, Adobe, Wide, ProPhoto, XYZ, ACES, DCI-P3, Rec. 2020).
char* output_profile;
dcraw keys: -o filename
Path to output profile ICC file (used only if LibRaw compiled with LCMS support)
char* camera_profile;
dcraw keys: -p file
Path to input (camera) profile ICC file (or 'embed' for embedded profile). Used only if LCMS support compiled in.
char* bad_pixels;
dcraw keys: -P file
Path to file with bad pixels map (in dcraw format: "column row date-of-pixel-death-in-UNIX-format", one pixel per row).
char* dark_frame;
dcraw keys: -K file
Path to dark frame file (in 16-bit PGM format)
int output_bps;
dcraw keys: -4
8 bit (default)/16 bit (key -4).
int output_tiff;
dcraw keys: -T
0/1: output PPM/TIFF.
int output_flags;
dcraw keys: none
Bitfield that allows to set output file options:
  • LIBRAW_OUTPUT_FLAGS_PPMMETA - write additional metadata into PPM/PGM output files
int user_flip;
dcraw keys: -t
[0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW). Default -1, which means taking the corresponding value from RAW.
For some formats, affects RAW data reading , e.g., unpacking of thumbnails from Kodak cameras.
int user_qual;
dcraw keys: -q
0-10: interpolation quality:
  • 0 - linear interpolation
  • 1 - VNG interpolation
  • 2 - PPG interpolation
  • 3 - AHD interpolation
  • 4 - DCB interpolation
  • 11 - DHT interpolation
  • 12 - Modified AHD interpolation (by Anton Petrusevich)
int user_black;
dcraw keys: -k
User black level.
int user_cblack[4];
dcraw keys: none
Per-channel corrections to user_black.
int user_sat;
dcraw keys: -S
Saturation adjustment.
int med_passes;
dcraw keys: -m
Number of median filter passes.
int no_auto_bright;
dcraw keys: -W
Don't use automatic increase of brightness by histogram.
float auto_bright_thr;
dcraw keys: none
Portion of clipped pixels when auto brightness increase is used. Default value is 0.01 (1%) for dcraw compatibility. Recommended value for modern low-noise multimegapixel cameras depends on shooting style. Values in 0.001-0.00003 range looks reasonable.
float adjust_maximum_thr;
dcraw keys: none
This parameters controls auto-adjusting of maximum value based on channel_maximum[] data, calculated from real frame data. If calculated maximum is greater than adjust_maximum_thr*maximum, than maximum is set to calculated_maximum.
Default: 0.75. If you set this value above 0.99999, than default value will be used. If you set this value below 0.00001, than no maximum adjustment will be performed.
Adjusting maximum should not damage any picture (esp. if you use default value) and is very useful for correcting channel overflow problems (magenta clouds on landscape shots, green-blue highlights for indoor shots).
int use_fuji_rotate;
dcraw keys: -j
Default -1 (use), 0 - don't use rotation for cameras on a Fuji sensor.
int green_matching;
Turns on fixing of green channels disbalance. dcraw keys: none
Default: 0 (not use), 1 - turns on this postprocessing stage. green_matching requires additional memory for image data.
int dcb_iterations
dcraw keys: none
Number of DCB correction passes. Default is -1 (no correction). Useful only for DCB interpolation.
int dcb_enhance_fl
dcraw keys: none
nonzero: DCB interpolation with enhance interpolated colors.
int fbdd_noiserd
dcraw keys: none
Controls FBDD noise reduction before demosaic.
  • 0 - do not use FBDD noise reduction
  • 1 - light FBDD reduction
  • 2 (and more) - full FBDD reduction
int exp_correc; float exp_shift,exp_preser;
Exposure correction before demosaic.
  • exp_correc: positive value turns the feature on (default: off).
  • exp_shift: exposure shift in linear scale. Usable range from 0.25 (2-stop darken) to 8.0 (3-stop lighter). Default: 1.0 (no exposure shift).
  • exp_preser: preserve highlights when lighten the image. Usable range from 0.0 (no preservation) to 1.0 (full preservation). 0.0 is the default value.
int use_rawspeed;
Turns on using RawSpeed library for data unpacking (only if RawSpeed support compiled in).
int use_dng_sdk;
Turns on using Adobe DNG SDK (if compiled with it and dng host is set:
  • 0 - do not use
  • 1 - use for speciality formats (Float, Linear DNG, deflate compression, 8 bit)
  • 2 - use for all DNG files
int no_auto_scale;
Disables pixel values scaling (call to LibRaw::scale_colors()) in LibRaw::dcraw_process().
This is special use value because white balance is performed in scale_colors(), so skipping it will result in non-balanced image.
This setting is targeted to use with no_interpolation, or with own interpolation callback call.
int no_interpolation;
Disables call to demosaic code in LibRaw::dcraw_process()

Structure libraw_callbacks_t: user-settable callbacks

data_callback data_cb
Called on data error, settable via set_dataerror_handler. See C++ API for details.
progress_callback progress_cb
Called on process callback, settable via set_progress_handler. See C++ API for details.
exif_parser_callback exif_cb, params: (void *context, int tag, int type, int len, unsigned int ord, void *ifp)
Called by EXIF/TIFF IFD parsers on each processed tag.
Parameters:
  • context: user-specified context, set via set_exifparser_handler()
  • tag: 16-bit of TIFF/EXIF tag or'ed with
    • 0 - for EXIF parsing
    • 0x20000 - for Kodak makernotes parsing
    • 0x30000 - for Panasonic makernotes parsing
    • 0x40000 - for EXIF Interop IFD parsing
    • 0x50000 - for EXIF GPS IFD parsing
    • (ifdN + 1) << 20) - for TIFF ifdN
  • type: tag type (see TIFF/EXIF specs)
  • len: tag length
  • ord: byte order: 0x4949 for intel, 0x4d4d for motorola
  • ifp: pointer to LibRaw_abstract_datastream input stream, positioned to start of data. There is no need to restore data position in callback.
int pre_identify_cb(void *)
Called with this pointer as the only arg before calling to LibRaw::identify. If this callback return non-zero value, that means that identify() is not needed and all internal data fields are filled with values.
void post_identify_cb(void *)
Called after identify() from open_datastream(). May be used to tune internal variables after metadata parse.
dcraw_process() callbacks
These callbacks are called before/after dcraw_process phases, the only passed parameter is this pointer
  • pre_subtractblack_cb - called before black subtraction
  • pre_scalecolors_cb - called before scale_colors() call
  • pre_preinterpolate_cb - called before interpolaton (demosaic)
  • interpolate_bayer_cb - if set, called for bayer demosaic (regardless of params.user_qual value)
  • interpolate_xtrans_cb - if set, called for X-Trans demosaic
  • post_interpolate_cb - called after demosaic step. Note: if this callback is set, standard median_filter() is not called. So, if you need median filtering you should call it from callback function.
  • pre_converttorgb_cb - called after convert_to_rgb()
  • post_converttorgb_cb - called after convert_to_rgb(), so very last processing step.

Structure libraw_decoder_info_t: RAW decoder name and data format

This structure describes RAW format decoder name and data format:

const char *decoder_name
Decoder function name
unsigned decoder_flags
Decoder data format. See list of LibRaw_decoder_flags for details.

Structure libraw_processed_image_t - result set for dcraw_make_mem_image()/dcraw_make_mem_thumb() functions

Structure libraw_processed_image_t is produced by call of dcraw_make_mem_image()/dcraw_make_mem_thumb() and contains in-memory image of interpolated data or thumbnail.

Data fields:

LibRaw_image_formats type
This field records type of data, containing in remaining fields of structure.
  • LIBRAW_IMAGE_BITMAP - structure contains RGB bitmap. All metadata fields (see below) are valid and describes image data.
  • LIBRAW_IMAGE_JPEG - structure contain in-memory image of JPEG file. Only type, data_size and data fields are valid (and nonzero);
ushort height,width
Image size (in pixels). Valid only if type==LIBRAW_IMAGE_BITMAP.
ushort colors, bits
Number of colors components (1 or 3) and color depth in bits (8 or 16). These fields are valid only if type==LIBRAW_IMAGE_BITMAP.
ushort gamma_corrected
Is bitmap data gamma-corrected (always 1 for 8-bit data, may be 0 or 1 for 16-bit). Valid only if type==LIBRAW_IMAGE_BITMAP.
unsigned int data_size
Size of data field (in bytes). For bitmap image equal to (height*width*colors * (bits/8)). For JPEG image - exact JPEG size (i.e. extracted thnumbnail size + JPEG header + EXIF header).
unsigned char data[]
Data array itself. Should be interpreted as RGB triplets for bitmap type and as JPEG file for JPEG type.

Input abstraction layer

RAW data input (read) in LibRaw implemented by calling methods of object derived from LibRaw_abstract_datastream abstract class. Full list of methods is described in href="API-CXX.html#datastream">C++ API reference.

There is two ready to use implementations of datastream objects:

LibRaw user can create own datastream object derived from LibRaw_abstract_datastream . For example, such object may implement reading RAW data directly from camera (by remote interface). LibRaw can use these objects via LibRaw::open_datastream() interface.

Datastreams can be used either via LibRaw::open_datastream() call (in this case datastream object should be created an maintained by user) or via LibRaw::open_file() and LibRaw::open_buffer() shortcuts.

Only C++ API users may use object-oriented interface and implement own input interfaces. For C API users only built-on libraw_open_file()/libraw_open_buffer() shortcuts are available.

Data fields

Definition:

	class LibRaw_abstract_datastream {...protected: LibRaw_abstract_datastream *substream;}

Description: Objects derived from LibRaw_abstract_datastream always contains pointer to secondary data stream (substream). This substream initialized internally when needed (really used only for Sony RAW data) and used for temporary switch input stream to temporary memory buffer allocated internally in LibRaw.

Substream usage details described more precisely in own datastream objects creation guide .

Constants

enum LibRaw_errors: Error Codes

All functions returning integer numbers must return either errno or one of the following error codes (see also error code conventions ).

Fatal errors (return of such an error code implies that file processing has to be terminated, since the state of data structures is unknown).

LIBRAW_UNSUFFICIENT_MEMORY
Attempt to get memory from the system has failed.
All allocated resources will be freed, recycle() will be called, and the LibRaw object will be brought to the state "right after creation."
LIBRAW_DATA_ERROR
A fatal error emerged during data unpacking.
All allocated resources will be freed, recycle() will be called, and the LibRaw object will be brought to the state "right after creation."
LIBRAW_IO_ERROR
A fatal error emerged during file reading (premature end-of-file encountered or file is corrupt).
All allocated resources will be freed, recycle() will be called, and the LibRaw object will be brought to the state "right after creation."
LIBRAW_CANCELLED_BY_CALLBACK
Processing cancelled due to calling application demand (by returning nonzero code from progress callback ).
All allocated resources will be freed, recycle() will be called, and the LibRaw object will be brought to the state "right after creation."
LIBRAW_BAD_CROP
The incorrect cropping coordinates are set via params.cropbox[]: the left-top corner of cropping rectangle is outside the image. The processing will be cancelled, all allocated resources will be freed, LIBRAW_TOO_BIG
Raw data size exceeds data limit.

Non-Fatal Errors

LIBRAW_SUCCESS=0
No error; function terminated successfully.
LIBRAW_UNSPECIFIED_ERROR
An unknown error has been encountered. This code should never be generated.
LIBRAW_FILE_UNSUPPORTED
Unsupported file format (attempt to open a RAW file with a format unknown to the program).
LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE
Attempt to retrieve a RAW image with a number absent in the data file (only for formats supporting storage of several images in a file).
LIBRAW_OUT_OF_ORDER_CALL
API functions have been called in wrong order (e.g., unpack() before open_file() ) or the previous stage has ended with an error (e.g., unpack() is called after open_file() has returned an error).
LIBRAW_NO_THUMBNAIL
Returned upon an attempt to retrieve a thumbnail from a file containing no preview.
LIBRAW_UNSUPPORTED_THUMBNAIL
RAW file contains a preview of unsupported format.
LIBRAW_INPUT_CLOSED
Input stream is not available for reading.
LIBRAW_NOT_IMPLEMENTED
Decoder for specific RAW storage/compression format is not implemented.
LIBRAW_REQUEST_FOR_NONEXISTENT_THUMBNAIL
Attempt to retrieve a non-existent thumbnail by (invalid) index.

enum LibRaw_decoder_flags - RAW data format description

Depending of capabilities of given data format, the buffer with RAW data may have different layouts:

LIBRAW_DECODER_HASCURVE
This flag is set if decoder uses RAW tone curve and curve data may be modified before call to decoder (i.e. curve values are not read or calculated within decoder).
LIBRAW_DECODER_SONYARW2
This flag is set if file format is Sony ARW2.3, so sony_arw2_options is applicable.
LIBRAW_DECODER_TRYRAWSPEED
This flag is set if file format is (possibly) supported by RawSpeed library, so unpack() will try to use it.
LIBRAW_DECODER_FIXEDMAXC
Do not use automated maximum calculation for this data format.
LIBRAW_DECODER_OWNALLOC
Decoder allocates data, no need to pass allocated memory to decoder.
LIBRAW_DECODER_ADOBECOPYPIXEL
Internal flag, special to adobe DNG decoder.
LIBRAW_DECODER_LEGACY_WITH_MARGINS
Special flag uset for 4-channel (legacy) decoders with black/masked areas
LIBRAW_DECODER_3CHANNEL
3-component full-color data (not usual 4-component)

enum LibRaw_progress: Current State of LibRaw Object

LibRaw::imgdata.progress_flags contains a bit mask describing all stages of file processing that have already been performed.

File opening and RAW data extraction phase.

LIBRAW_PROGRESS_START=0
Object just created, no processing carried out.
LIBRAW_PROGRESS_OPEN
File to be processed has been opened.
LIBRAW_PROGRESS_IDENTIFY
Data identification performed, format recognized, metadata extracted.
LIBRAW_PROGRESS_SIZE_ADJUST
Data sizes adjusted (for files that require such adjustment, namely, certain files from Kodak cameras).
LIBRAW_PROGRESS_LOAD_RAW
RAW data loaded.

The following flags are set during usage of image processing that has been taken from dcraw.

LIBRAW_PROGRESS_RAW2_IMAGE
imgdata.image array allocated and filled with data.
LIBRAW_PROGRESS_REMOVE_ZEROES
Zero values removed for cameras that require such removal (Panasonic cameras).
LIBRAW_PROGRESS_BAD_PIXELS
Bad (dead) pixels removed.
LIBRAW_PROGRESS_DARK_FRAME
Dark frame subtracted from RAW data.
LIBRAW_PROGRESS_FOVEON_INTERPOLATE
Interpolation for cameras with a Foveon sensor performed.
LIBRAW_PROGRESS_SCALE_COLORS
White balance performed.
LIBRAW_PROGRESS_PRE_INTERPOLATE
Image size reduction (for the half_size mode) performed, as well as copying of 2nd green channel to the 1st one in points where the second channel is present and the first one is absent.
LIBRAW_PROGRESS_INTERPOLATE
Interpolation (debayer) performed.
LIBRAW_PROGRESS_MIX_GREEN
Averaging of green channels performed.
LIBRAW_PROGRESS_MEDIAN_FILTER
Median filtration performed.
LIBRAW_PROGRESS_HIGHLIGHTS
Work with highlights performed.
LIBRAW_PROGRESS_FUJI_ROTATE
For images from Fuji cameras, rotation performed (or adjust_sizes_info_only() called).
LIBRAW_PROGRESS_FLIP
Dimensions recalculated for images shot with a rotated camera (sizes.iwidth/sizes.iheight swapped).
LIBRAW_PROGRESS_CONVERT_RGB
Conversion into output RGB space performed.
LIBRAW_PROGRESS_STRETCH
Image dimensions changed for cameras with non-square pixels.
LIBRAW_PROGRESS_STAGE17 - LIBRAW_PROGRESS_STAGE27
Reserved for possible appearance of other processing stages.

The following flags are set during loading of thumbnails.

LIBRAW_PROGRESS_THUMB_LOAD Thumbnail data have been loaded (for Kodak cameras, the necessary conversions have also been made). LIBRAW_PROGRESS_TRESERVED1 - LIBRAW_PROGRESS_TRESERVED3 Reserved for possible future processing stages.

enum LibRaw_whitebalance_code - names for standard light sources

LIBRAW_WBI_lightsource_name, where name and value are standard EXIF light sources.

enum LibRaw_camera_mounts - codes for camera mounts

Constant name (e.g. LIBRAW_MOUNT_Leica_SL) speaks for itself

enum LibRaw_runtime_capabilities - libraw capabilities set at build

  • LIBRAW_CAPS_RAWSPEED - compiled with RawSpeed
  • LIBRAW_CAPS_DNGSDK - compiled with Adobe DNG SDK
  • LIBRAW_CAPS_GPRSDK - compiled w/ GoPro GPR SDK
  • LIBRAW_CAPS_UNICODEPATHS - compiled with Windows unicode (wchar_t*) filenames support

enum LibRaw_thumbnail_formats: Thumbnail Data Formats

Thumbnail data format is written in the imgdata.thumbnail.tformat data field.
Presently LibRaw knows about four thumbnail formats, among which two are unpacked:

LIBRAW_THUMBNAIL_UNKNOWN
Format unknown or thumbnail not yet read.
LIBRAW_THUMBNAIL_JPEG
The thumbnail buffer contains a JPEG file (read from the RAW file "as is," without any manipulations performed on it).
LIBRAW_THUMBNAIL_BITMAP
The thumbnail buffer contains the gamma-adjusted RGB bitmap (for Kodak cameras, the gamma correction is performed with allowance for maximum values and the white balance is set in accordance with the camera settings).
In this format, each pixel of the image is represented by a 8-bit RGB triplet.
LIBRAW_THUMBNAIL_BITMAP16
The thumbnail buffer contains the gamma-adjusted 16-bit RGB bitmap. To get this format instead of LIBRAW_THUMBNAIL_BITMAP you need to set LIBRAW_PROCESSING_USE_PPM16_THUMBS in processing options.
LIBRAW_THUMBNAIL_LAYER
Data format is presently recognized upon opening of RAW file but not supported: not unpacked into LibRaw::unpack_thumb.
LIBRAW_THUMBNAIL_ROLLEI
Data format is presently recognized upon opening of RAW file but not supported: not unpacked into LibRaw::unpack_thumb.
LIBRAW_THUMBNAIL_H265
The thumbnail buffer contains a H.265 data frame (read from RAW file as is, no manipulations performed on it).

Nonstandard Situations (Warnings) during RAW Data Processing

Some suspicious situations emerging during image processing are not fatal but may affect the result of data retrieval or postprocessing. Such states are indicated by setting a bit in the imgdata.process_warnings field.

LIBRAW_WARN_BAD_CAMERA_WB
Postprocessing must use white balance of the camera but this balance is not suitable for use.
LIBRAW_WARN_NO_METADATA
Only for cameras where the metadata are taken from an external JPEG file: metadata extraction has failed.
LIBRAW_WARN_NO_JPEGLIB
Only for P&S Kodak cameras: data in JPEG format. At the same time, open_file() will return LIBRAW_FILE_UNSUPPORTED.
LIBRAW_WARN_NO_EMBEDDED_PROFILE
(only if LCMS support compiled in). Caller set embedded input profile use, but no such profile exists in RAW.
LIBRAW_WARN_NO_INPUT_PROFILE
(only if LCMS support compiled in). Error when opening input profile ICC file.
LIBRAW_WARN_BAD_OUTPUT_PROFILE
(only if LCMS support compiled in). Error when opening output profile ICC file.
LIBRAW_WARN_NO_BADPIXELMAP
Error when opening bad pixels map file.
LIBRAW_WARN_BAD_DARKFRAME_FILE
Error when opening dark frame file.
LIBRAW_WARN_BAD_DARKFRAME_DIM
Dark frame file either differs in dimensions from RAW-file processed, or have wrong format. Dark frame should be in 16-bit PGM format (one can generate it using simple_dcraw -4 -D).
LIBRAW_WARN_RAWSPEED_PROBLEM
Problems detected in RawSpeed decompressor. The image data processed by LibRaw own decoder.
LIBRAW_WARN_RAWSPEED_UNSUPPORTED
This file not supported by RawSpeed (although compatible decoder exists).
LIBRAW_WARN_RAWSPEED_PROCESSED
Not warning, but information. The file was decoded by RawSpeed.
LIBRAW_WARN_FALLBACK_TO_AHD
Incorrect/unsupported user_qual was set, AHD demosaic used instead.
LIBRAW_WARN_PARSEFUJI_PROCESSED
Not really a warning, but flag that fuji parser was used.
LIBRAW_DNGSDK_PROCESSED
Not really a warning: image was decoded by DNG SDK
LIBRAW_DNG_IMAGES_REORDERED
DNG sub0images was reordered
LIBRAW_DNG_STAGE2_APPLIED
DNG Stage2 conversion was performed
LIBRAW_DNG_STAGE3_APPLIED
DNG Stage3 conversion was performed

enum LibRaw_image_formats - possible types of data, contains in libraw_processed_image_t structure

type field of libraw_processed_image_t structure may have one of these values:

LIBRAW_IMAGE_BITMAP
The structure contains RGB-bitmap, metadata described in other fields of libraw_processed_image_t.
LIBRAW_IMAGE_JPEG
libraw_processed_image_t structure contains JPEG image (in memory). Only data_size field is meaningful.

enum enum LibRaw_processing_options - bit that affects RAW data extraction

These flags could be OR'ed with imgdata.params.raw_processing_options:

Pentax 4-shot options:

  • LIBRAW_RAWOPTIONS_PENTAX_PS_ALLFRAMES - merge all frames for Pentax 4-shot files

Floating point DNG files:

  • LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT - convert FP data to 16-bit integer

Sony ARQ Files:

  • LIBRAW_RAWOPTIONS_ARQ_SKIP_CHANNEL_SWAP - do not perform Sony ARQ channel swap to RGBG channel format, but use RGGB original channel order

DNG processing flags:

  • LIBRAW_RAWOPTIONS_DONT_CHECK_DNG_ILLUMINANT - skip DNG illuminant check when parsing DNG color data (use for compatibility w/ older LibRaw versions).
  • LIBRAW_RAWOPTIONS_DNGSDK_ZEROCOPY - do not copy data extracted by Adobe DNG SDK into separate buffer, but use DNG SDK buffer as is.
  • LIBRAW_RAWOPTIONS_DNG_ADD_ENHANCED - if set, LibRaw will add Enhanced DNG frame (NewSubfileType == 16) to the list of available frames.
  • LIBRAW_RAWOPTIONS_DNG_ADD_PREVIEWS - if set, LibRaw will add previews (NewSubfileType == 1) to the frames list.
  • LIBRAW_RAWOPTIONS_DNG_PREFER_LARGEST_IMAGE- By default, DNG frames are not reordered and are available in same order as in DNG  (LibRaw traverses IFD/Sub-IFD trees in deep-first order).This bit will prioritize the largest image
  • LIBRAW_RAWOPTIONS_DNG_STAGE2 - request DNG Stage2 processing (by DNG SDK)
  • LIBRAW_RAWOPTIONS_DNG_STAGE3 - request DNG Stage3 processing
  • LIBRAW_RAWOPTIONS_DNG_ALLOWSIZECHANGE - by default, if image size parsed by DNG SDK does not match image dimensions parsed by LibRaw, processing will stop with LIBRAW_DATA_ERROR code. This flags allows size change in LibRaw::unpack() stage.
  • LIBRAW_RAWOPTIONS_DNG_DISABLEWBADJUST - by default, for DNG images with different per-channel maximums WB adjustment procedure is performed. This flag disables such adjustment.
Other flags
  • LIBRAW_RAWOPTIONS_NO_ROTATE_FOR_KODAK_THUMBNAILS - disable auto-rotation for Kodak PPM bitmaps
  • LIBRAW_RAWOPTIONS_USE_PPM16_THUMBS - enable 16-bit PPM thumbnails
  • LIBRAW_RAWOPTIONS_ZEROFILTERS_FOR_MONOCHROMETIFFS - by default, LibRaw assigns bayer pattern for Monochrome TIFF files (e.g. images from Kodak 760).This does not work as expected if input file is really monochrome (e.g. scan from Imacon X1 in monochrome mode).This flag will force monochrome mode for TIFF RAWs w/o bayer filter tags (so, it will break old Kodak processing). It is better to make it settable via user interaction.
  • LIBRAW_RAWOPTIONS_PROVIDE_NONSTANDARD_WB - If set and when applicable, color.cam_mul[] and color.WB_Coeffs/WBCT_Coeffs will contain WB settings for a non-standard workflow. Right now only Sony DSC-F828 is affected: camera-recorded white balance can't be directly applied to raw data because WB is for RGB, while raw data is RGBE.
  • LIBRAW_RAWOPTIONS_CAMERAWB_FALLBACK_TO_DAYLIGHT - if use_camera_wb is set, but no camera-recorded white balance present in metadata, then fallback to daylight WB (default: fallback to auto-balance).
  • LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_KNOWN_VENDORS - Some cameras (e.g.Ricoh) may record broken thumbnail in file:data offset plus data size is beyond filecontents. This flag enforces size+offset checks for files from known vendors (this will result into correct but smaller thumbnail selected).
  • LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_ALL_VENDORS - same is above, but check is performed regardless of vendor (Make tag).

enum LibRaw_rawspecial_t - special/non standard RAW extraction modes

These flags are applied to imgdata.rawparams:

Sony ARW2.3 processing options: (for more details see http://www.rawdigger.com/howtouse/sony-craw-arw2-posterization-detection)

  • LIBRAW_RAWSPECIAL_SONYARW2_BASEONLY - decode only base pixels, leave delta pixels as zero;
  • LIBRAW_RAWSPECIAL_SONYARW2_DELTAONLY - decode only delta pixels with base pixels zeroed;
  • LIBRAW_RAWSPECIAL_SONYARW2_DELTAZEROBASE - decode delta pixels, do not add base value;
  • LIBRAW_RAWSPECIAL_SONYARW2_DELTATOVALUE - show possible posterization areas;

Sigma Quattro decoding flags:

  • LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATERG - disable R/G channels interpolation
  • LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATEAF - disable data interpolation of low-sensitivity (AF or overexposure control) points on Quattro sensors.

Canon/Nikon small RAW (YCC) decoding flags (do not use both at same time):

  • LIBRAW_RAWSPECIAL_SRAW_NO_RGB - disable YCC to RGB conversion
  • LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE - disable missing color values interpolation
[back to Index] LibRaw-0.21.4/doc/API-notes.html000066400000000000000000000435121477673233700162000ustar00rootroot00000000000000

LibRaw: General Notes on API[back to Index]

LibRaw: General Notes on API

Contents

  1. LibRaw editions
  2. Error Code Conventions and Error Handling
  3. Nonstandard Situations That Are Not Errors
  4. Input Layer Abstraction
  5. Thread Safety
  6. The Use of C++
  7. Parameters of the LibRaw::imgdata.params Structure Affecting the Behavior of open_file/unpack/unpack_thumb
  8. Memory Usage
    1. Stack Usage
    2. Dynamic Memory Management
    3. Dynamic Memory Usage
      1. Memory Buffer for the RAW Image
      2. Memory for the Postprocessed Image
      3. Memory for the Decoded Thumbnail
      4. Memory for RAW Unpacking
      5. Memory for Postprocessing
      6. Memory for File Writing
      7. Unpacking into memory buffer
  9. Incompatibilities with dcraw
    1. Automatic maximum search/brightness adjustment
    2. Processing of Thumbnails from Kodak cameras

LibRaw Versions

Since version 0.9, there is only one LibRaw variants. Older versions have three separate editions (normal, -Lite and -Commercial versions).

Error Code Conventions and Error Handling

The following conventions concern the returned errors:

  1. All functions that can return an error code have integer type of return data.
  2. If there is no error, the return value is 0 (LIBRAW_SUCCESS).
  3. If an error has happened in a system call, the return value is errno (a positive number), which can be analyzed using strerror() or similar means.
  4. All LibRaw's own error codes are negative; each of these errors belongs to one of two types:
    Non-fatal errors
    Non-fatal errors do not forbid execution of other functions in the processing succession (e.g., unpack_thumb() can easily return the code corresponding to "preview is absent" but this does not prevent further call of unpack().
    Fatal errors
    In the case of fatal errors (memory shortage, input data error, data unpacking failure), the current stage of processing is terminated and all allocated resources are freed.
    If an attempt to continue processing is made, all subsequent API calls will return the LIBRAW_OUT_OF_ORDER_CALL error.
    At the same time, the LibRaw instance in which a fatal error has occurred can process the next RAW files in the usual way (by calling open_file() (or other input methods), then unpack(), etc.).
  5. The macro LIBRAW_FATAL_ERROR(error code) checks if an error is fatal or not.
  6. The error codes are listed and deciphered here.

Nonstandard Situations That Are Not Errors

If the program has encountered a nonstandard situation that does not prevent retrieval of some data from a file, it sends a signal by setting the corresponding bit in imgdata.process_warnings. The possible types of warnings are listed and deciphered here.

Input Layer Abstraction

LibRaw uses objects derived from LibRaw_abstract_datastream for data input. Semantics of these objects is similar to 'file with arbitrary seek' object: both read and seek operations are used.

Some RAW formats requires temporary switch to another data stream created on top on memory buffer for metadata read. Methods for doing so are implemented in base class LibRaw_abstract_datastream by internal data field substream. Look into source code of LibRaw_file_datastream class in libraw/libraw_datastream.h file for more details.
When implementing own datastream classes, you need to take substream into account and pass control to methods of this field if it is active (not NULL).

If datastream implementation knows name of input file, it should provide fname() call. This name will be used in error callbacks and in guessing name of JPEG file with metadata (for RAW files with external metadata).

For external metadata support input class should implement subfile_open()/subfile_close() methods. âîçâðàøàþò êîä îøèáêè.
Sample of these methods implementation may be found in LibRaw_file_datastream class (look into libraw/libraw_datastream.h file for details).

Thread safety

Thread safety is ensured if a LibRaw object is created and used within one thread. At the same time, the number of threads (each with its own LibRaw object) is not limited in any way (except by memory requirements).

If a LibRaw object is created in one execution thread and used in another, external synchronization is necessary.

There is two libraries under Unix environment (Linux/FreeBSD/MacOS): libraw_r.a (thread-safe) and libraw.a (single-threaded, slightly faster).

Thread-safe library version stores intermediate unpacker data into LibRaw class data. So, several copies of LibRaw, working in parallel, is possible.

Not thread-safe library uses global variable for intermediate data store which is faster but not reenterant. This non-thread-safe library still may be used in multi-threaded apps, but only if exactly one LibRaw class copy exists in program.

Windows version is similar to multi-threaded Unix one.

The Use of C++

Exception situations within LibRaw are handled using the C++ exception mechanism. All exceptions are caught inside the library functions and should not penetrate outside.

Memory is allocated/freed using functions malloc(calloc)/free rather than new/delete.

If C API is used, references to C++ calls new/delete still remain, and so linking with libstdc++(Unix)/....(Windows) is necessary.

Parameters of the LibRaw::imgdata.params Structure Affecting the Behavior of open_file/unpack/unpack_thumb

Most data fields of structure LibRaw::imgdata.params affect only data postprocessing, but there are some exceptions, which have been inherited by the current version of LibRaw from/ dcraw source texts (these dependences will be gradually removed).

imgdata.params.use_camera_matrix and imgdata.params.use_camera_wb
These fields affect loading of RAW data for cameras with a color matrix.
Attention! If parameter imgdata.params.use_camera_matrix is not set by the user, it is copied from imgdata.params.use_camera_wb at the stage of file opening.
imgdata.params.user_flip
If this parameter is greater than or equal to zero, assignment imgdata.sizes.flip = imgdata.params.user_flip is performed at the open_file() stage.
imgdata.params.shot_select
This parameter makes it possible to select the number of the extracted image for data formats in which storage of several RAW images in one data file is possible.
imgdata.params.half_size
Affects RAW data loading for Phase One and Sinar backs. Also, it this parameter is set then image bitmap will be reduced by half in each dimension. In later case, all 4 components of bitmap will be filled during data extraction phase.
imgdata.params.threshold, imgdata.params.aber
If these parameters used, then half-sized bitmap will be used for data unpacking. See above for details.
imgdata.params.use_camera_wb
Affects loading of white balance matrix for Leaf backs.

Memory Usage

Stack Usage

An instance of the LibRaw class has its own size about 800 Kb; if constructions like LibRaw imageProcessor; are used, this memory is stack-allocated.

Methods of class LibRaw (and C API calls) may allocate up to 130-140 Kb of data on the stack (to place auto variables) during their work.

Thus, the work of one LibRaw instance may require about 1MB of stack memory. This is not a problem for most contemporary architectures. However, when working in a multithreaded environment, one should not forget to allocate a sufficient amount of memory for the thread stack.

In the case of dynamic allocation (LibRaw *iProcessor = new LibRaw;), the requirements to stack memory will decrease by ~800 Kb, which is the size of a class instance). If C API is used, the LibRaw instance is allocated dynamically.

Dynamic Memory Management

LibRaw keeps record of all allocated dynamic memory blocks; in the case of an exceptional situation (fatal error), they are all freed. The code for keeping this record is fairly primitive and not designed to consider allocation of many blocks (in the normal situation, allocation takes place from 2 to 6 times during file processing); this fact should be taken into account by developers trying to add new methods to LibRaw.

Dynamic Memory Usage

LibRaw uses dynamic memory

  • for the decoded image;
  • for the decoded thumbnail;
  • for the postprocessed image;
  • for the ICC profile retrieved from the RAW file (if available);
  • for temporary data at the stage of RAW file unpacking;
  • for temporary data at the stage of postprocessing and result output;
  • for reading of the RAW source file (only under Win32).

Memory buffer for the RAW image

Decoded RAW data are stored:

  • one 16-bit value per pixel for "bayer" images. The masked pixels (black or dark or masked frame) are stored with image data.
  • Free or four 16-bit values for full-color images (Foveon, Linear DNG, Canon sRAW etc.).
  • one,three, or four 32-bit floating point values per pixel for floating-point data.

The buffer for RAW data is allocated by unpack() call and freed upon calling recycle().

Memory for the Postprocessed Image

On postprocessing stage each pixel contains four 16-bit values, one for each possible color channel (some sensors are actually 4-color).

The buffer for the decoded image is allocated upon calling raw2image() or dcraw_process()

The buffer freed upon calling recycle() or free_image() calls.

Memory for the Decoded Thumbnail

Memory for the thumbmail is allocated upon calling unpack_thumb() and freed upon calling recycle(). The size of the allocated buffer is precisely adjusted to the thumbnail size, i.e., up to several Mb.

Memory for RAW Unpacking

Memory for temporary buffer needed during RAW data unpacking may be allocated during the work of unpack() and freed before completion of this function. The sizes of the allocated buffers are small, up to tens of Kb.

Memory for Postprocessing

During image postprocessing (inherited from dcraw), memory for the histogram (128 Kb) is allocated. This memory is allocated upon calling dcraw_process() and freed upon calling recycle().

In addition, during the work of dcraw_process() and during the usage of some available possibilities, like

  • rotation of images from FUJI cameras;
  • correction of chromatic aberrations;
  • image size changes (including correction of non-square pixels);
  • highlight recovery;

a temporary buffer with the size equal to the size of the resultant image (6-8 bytes per pixel for various processing stages) will be allocated. As soon as the intermediate substage of processing is completed, the buffer with the previous copy of the image will be freed.
If postprocessing is not used, then temporary buffers are not allocated.

Memory for File Writing

Upon calling dcraw_ppm_tiff_writer(), memory for a single row of the output image is allocated. The allocated memory is freed before the end of this call.

Unpacking into memory buffer

Functions dcraw_make_mem_image() dcraw_make_mem_thumb() (and complementary calls in C-API) allocates memory for entire output datasets (full RGB bitmap and thumbnail, respectively).To free allocated memory use dcraw_clear_mem() function.

Incompatibilities with dcraw

Automatic maximum search/brightness adjustment

Many camera formats really use less data range, than possible by format nature (bit count). If data maximum estimated incorrectly (too low) this may resuls in colored highlights ('pink clouds') because of data cut at wrong level.

To prevent this, LibRaw uses real data maximum from current file if this maximum is larger than format maximum multiplied by imdata.params.adjust_maximum_thr value (default is 0.75).

To turn off this feature (and repeat dcraw.c pink clouds) set imdata.params.adjust_maximum_thr to 0.0

Processing of Thumbnails from Kodak cameras

In some Kodak cameras, the preview (thumbnail) is stored in the form of uncorrected image. During its extraction using dcraw -e, the white balance, color conversion, and other settings are the same as those used for extraction of the main RAW data (including defect removal and dark frame subtraction, which is erroneous, since the image size is different).
In LibRaw::unpack_thumb() calls, the white balance taken from the camera ("as shot") is used and no settings from imgdata.params are considered.

For all other cameras, thumbnails are extracted "as is," without any color conversions, both in dcraw and in LibRaw.

[back to Index]

LibRaw-0.21.4/doc/API-overview.html000066400000000000000000000053531477673233700167170ustar00rootroot00000000000000 Overview of LibRaw API (C++) [back to Index]

Overview of LibRaw API (C++)

General Remarks

  1. The entire processing is carried out by an instance of the LibRaw class, which is an image processor.
  2. One image processor can simultaneously process only one data source file, but consecutive processing of any number of files is possible.
  3. There may be several simultaneously working image processors in a software program (e.g., in different threads), although one should remember that each image processor may require much memory.
  4. Reading of source data from the RAW file requires virtually no customization (see API Notes for exceptions to this rule).
  5. All data extracted from the RAW file are accessible through data fields of the image processor (LibRaw class instance).
  6. Although LibRaw is not intended for RAW data postprocessing, the library includes calls that enable complete emulation of the dcraw utility.
  7. All customization for the processing is performed via data fields of the LibRaw class.

Brief Demonstration

The example below contains no error processing for the sake of brevity.

#include "libraw/libraw.h"
int process_image(char *file)
{
        // Let us create an image processor
        LibRaw iProcessor;

        // Open the file and read the metadata
        iProcessor.open_file(file);

        // The metadata are accessible through data fields of the class
        printf("Image size: %d x %d\n",iProcessor.imgdata.sizes.width,iProcessor.imgdata.sizes.height);

        // Let us unpack the image
        iProcessor.unpack();

        // Convert from imgdata.rawdata to imgdata.image:
        iProcessor.raw2image();

        // And let us print its dump; the data are accessible through data fields of the class
        for(i = 0;i lt; iProcessor.imgdata.sizes.iwidth *  iProcessor.imgdata.sizes.iheight; i++)
           printf("i=%d R=%d G=%d B=%d G2=%d\n",
                        i,
                        iProcessor.imgdata.image[i][0],
                        iProcessor.imgdata.image[i][1],
                        iProcessor.imgdata.image[i][2],
                        iProcessor.imgdata.image[i][3]
                );

        // Finally, let us free the image processor for work with the next image
        iProcessor.recycle();
}
[back to Index] LibRaw-0.21.4/doc/Install-LibRaw.html000066400000000000000000000135271477673233700172300ustar00rootroot00000000000000 LibRaw Compilation and Installation [back to Index]

LibRaw Compilation and Installation

LibRaw is distributed in the form of source codes. For further use, they should be compiled (and, if desired, placed into system folders with libraries and include-files).

Unix Systems (FreeBSD, Linux, Mac OS X)

To build the library, you will need a working C++ compiler (gcc 3+ and clang 2+ are OK) and the make utility.

Additional libraries (optional):

  • zlib (used to decode deflated DNGs)
  • libjasper (used to decode RED files)
  • libjpeg8 (used to decode lossy DNGs and several old Kodak cameras)

LibRaw has been tested on 32- and 64-bit Unix systems working on x86- (and AMD64-) compatible processors. Building and work on other architectures have not been tested.

Compilation of Library and Examples

Unpack the downloaded distribution package.

        tar xzvf LibRaw-X.YY.tar.gz

For GitHub downloads (clones), perform ./configure script generation via

        autoreconf --install

Go to LibRaw directory and run ./configure and make:

cd LibRaw-X.YY
./configure # with optional args
make
    

As a result, you will compile

  • Library libraw.a in the lib/ folder
  • Examples in the bin/ folder (source codes of examples are in the samples/ folder).

In the current version, only static libraries are built:

  • libraw.a: non-thread-safe version
  • libraw_r.a: thread-safe

Build parameters

./configure script have some non-standard parameters:

--enable-openmp
--disable-openmp
Enable/disable OpenMP support if compiler supports it. OpenMP is enabled by default.
--enable-lcms
--disable-lcms
Enable/disable LCMS color engine support. If enabled, ./configure will try to find lcms library. Both LCMS-1.x and LCMS-2.x are supported LCMS support is enabled by default
--enable-examples
--disable-examples
Enables/disables examples compilation and installation. Enabled by default

Installation and Usage

To install the library, run

    sudo make install
    

It will place the libraries in /usr/local/lib, the include-files in /usr/local/include (subfolder of libraw) and LibRaw samples to /usr/local/bin. You can override installation path by using ./configure script.
To use LibRaw, add the following parameters to the compiler call (when building your own projects):

  • Path to include-files: -I/usr/local/include
  • Path to libraries: -L/usr/local/lib
  • Library: -lraw (ordinary version) or -lraw_r (thread-safe version).

Windows: Building under Cygwin

Building and installation are completely similar to building and installation under Unix systems.

Windows: Native Building

Building under Windows has three steps:

  • Unpack the distribution package (if you have got no tar+gzip, take the LibRaw distribution package in the .ZIP format) and go to folder LibRaw-X.YYY.
  • Set the environment parameters so that the compiler/linker would find the libraries and include-files. For Visual C++, this is done by running vcvars32.bat.
  • Run
    nmake -f Makefile.msvc

You may need to edit Makefile.msvc to provide libjpeg/zlib/libjasper paths to INCLUDE/LIB.

If all paths are set correctly and the include-files/libraries have been found, then the following will be compiled:

  • Library libraw_static.lib in folder lib
  • Dynamic library bin/libraw.dll and linking library for it lib/libraw.lib
  • Examples in folder bin/.

Only the thread-safe library is built under Win32, but it can be used with non-threaded applications as well. All examples are linked with the dynamic library (DLL); if static linking is necessary, one should link applications with library libraw_static.lib and set the preprocessor option /DLIBRAW_NODLL during compilation.

Windows-version compiles without LCMS support for now.

During building of DLL, all public functions are exported; further, the exported subset may be reduced.

Unfortunately, paths to include/ libraries depend on the way Visual C (or other compiler) is installed; therefore, it is impossible to specify some standard paths in Makefile.msvc.

Windows Installation

No installation under Windows is supported. It is assumed that all DLLs will be supplied together with the software using them (and this software will perform the installation). Accordingly, in building of programs using LibRaw, the paths to libraries, DLLs, and include-files should be specified manually.

[back to Index] LibRaw-0.21.4/doc/Samples-LibRaw.html000066400000000000000000000251011477673233700172150ustar00rootroot00000000000000

LibRaw: Usage Examples[back to Index]

LibRaw: Usage Examples

Overview of Examples in the Distribution Package (samples/*)

The LibRaw package contains several examples illustrating the use of this library. Their source codes are located in the samples/ folder, and after library build they will be in the bin/ folder:

  • raw-identify The only LibRaw call it uses is open_file(); further code prints the values of the fields of the imgdata structure.
    raw-identify -v provides extensive dump of metadata/
    Command line key -u shows unpacking function name, while -u -f prints function name and masked are sizes.
    raw-identify -w will print white balance tables stored in RAW file.
  • simple_dcraw A simple "emulation" of dcraw reproducing the behavior of dcraw [-e] [-v] [-T].  A simplified version of this example is considered below.
    -B command-line switch turns on use of open_buffer() API call used via mmap() of input file (Unix only).
  • dcraw_half Demonstrates the use of C API. The example emulates the behavior of dcraw -h (no other control parameters can be specified in this example).
  • dcraw_emu Almost complete emulation of dcraw (except for keys -D -d -E -i -v -e, which are considered in other usage examples). Of most interest is processing of command line keys (copied from dcraw).

    This sample supports additional command-line parameters absent in original dcraw:

    -mmap
    Use open_buffer() interface. Buffer prepared by mmap() call. This option not supported under Win32.
    -meme
    Use open_buffer() interface. Buffer prepared by malloc()+read() calls.
    -c float-value
    This key sets params.adjust_maximum_thr parameter.
    Use -c 0 to completely disable automatic maximum calculation.
    Default value: 0.75
    -timing
    Turns on detailed timing print.
    -G
    Turns on "green_matching" mode to suppress color mazes on cameras with different green channels.
    -B x y w h
    Crops output to rectangle with width w, height h and x,y coordinates of left upper corner. All coordinates applied before any image rotation.
    -F
    Will use FILE I/O (bigfile_datastream) instead on standard LibRaw_file_datastream.
    -dcbi N
    Sets number of additional DCB-demosaic iterations (option valid only for -q 4, i.e. for DCB demosaic).
    -dcbe
    Turns on DCB color enhance mode (only for DCB demosaic, -q 4).
    -aexpo e p
    Turns on exposure correction. e is exposure shift in linear scale from 0.25 (darken 2 stops) to 8.0 (lighten 3 stops). p is highlights preservation amount from 0.0 (no preservation, full clipping) to 1.0 (full preservation, S-like curve in highlights).
    -apentax4shot
    Will merge 4 frames from Pentax 4-shot RAWs
    -apentax4shotorder abce
    Order of frames in pentax 4-shot files (default is 3102)
    -mmap
    Use mmap + memory IO instead of file IO (unix only)
    -disars
    Disable RawSpeed library (if compiled with this library)
    -doutputflags N
    set imgdata.params.output_flags to N
    -disinterp
    Do not run interpolation step
    -dsrawrgb1
    Disable YCbCr to RGB conversion for sRAW (Cb/Cr interpolation enabled)
    -dsrawrgb2
    Disable YCbCr to RGB conversion for sRAW (Cb/Cr interpolation disabled)
  • half_mt Emulation of dcraw -h. It "understands" the following keys: -a (automatic white balance over the entire image), -w (white balance of the camera), -T (output in the tiff format), and -J n (number of parallel threads launched for image processing).
    On multiprocessor/multicore computers, the speed gain is notable in the case of mass processing. On a Win32 machine, the example is assembled from the initial file half_mt_win32.c, since work with threads under Windows is fundamentally different and it it easier to copy simple source codes than write one complex code.
  • mem_image This sample uses dcraw_make_mem_image and dcraw_make_mem_thumb calls, than writes data in PPM format.
  • unprocessed_raw This sample extracts (mostly) unaltered RAW data including masked pixels data (on supported cameras). If black frame exists and black frame extraction is supported for given format, masked pixels data is added to resulting .TIFF file. Command line options: -q - be quiet, -A - autoscale data (integer multiplier), -g gamma-correction (gamma 2.2) for data (instead of precise linear one), -B turns on black level subtraction
  • 4channnels - splits RAW-file into four separate 16-bit grayscale TIFFs (per RAW channel).
    Command line switches:
    • -s N selects N-th image from RAW with multiple images
    • -g gamma correction (gamma 2.2)
    • -A values autoscale by auto-calculated integer factor
    • -B turn off black subtraction
    • -N no RAW curve
  • multirender_test - very simple example of multiple rendering on one file without reopen.
  • postprocessing_benchmark - will print timings of RAW processing steps

Example of docmode

Below we consider the samples/simple_dcraw.cpp example, which emulates the behavior of dcraw [-e][-v][-t]. To save space, let us assume that keys -t -v are always specified (to avoid comments on command line parsing) and there is always one parameter (name of file), which is the only one and always passed to the program.

int main(int ac, char *av[])
{
 int i, ret, verbose=0, output_thumbs=0;
 char outfn[1024],thumbfn[1024];
 // Creation of image processing object
 LibRaw RawProcessor;
 // The date in TIFF is written in the local format; let us specify the timezone for compatibility with dcraw
 putenv ((char*)"TZ=UTC");
// Let us define variables for convenient access to fields of RawProcessor
#define P1 RawProcessor.imgdata.idata
#define S RawProcessor.imgdata.sizes
#define C RawProcessor.imgdata.color
#define T RawProcessor.imgdata.thumbnail
#define P2 RawProcessor.imgdata.other
#define OUT RawProcessor.imgdata.params
 OUT.output_tiff = 1; // Let us output TIFF
 // Let us open the file
 if( (ret = RawProcessor.open_file(av[1])) != LIBRAW_SUCCESS)
 {
 fprintf(stderr,"Cannot open %s: %s\n",av[i],libraw_strerror(ret));
 // recycle() is needed only if we want to free the resources right now.
 // If we process files in a cycle, the next open_file()
 // will also call recycle(). If a fatal error has happened, it means that recycle()
 // has already been called (repeated call will not cause any harm either).
 RawProcessor.recycle();
 goto end;
 }
 // Let us unpack the image
 if( (ret = RawProcessor.unpack() ) != LIBRAW_SUCCESS)
 {
 fprintf(stderr,"Cannot unpack_thumb %s: %s\n",av[i],libraw_strerror(ret));
 if(LIBRAW_FATAL_ERROR(ret))
 goto end;
 // if there has been a non-fatal error, we will try to continue
 }
 // Let us unpack the thumbnail
 if( (ret = RawProcessor.unpack_thumb() ) != LIBRAW_SUCCESS)
 {
 // error processing is completely similar to the previous case
 fprintf(stderr,"Cannot unpack_thumb %s: %s\n",av[i],libraw_strerror(ret));
 if(LIBRAW_FATAL_ERROR(ret))
 goto end;
 }
 else // We have successfully unpacked the thumbnail, now let us write it to a file
 {
 snprintf(thumbfn,sizeof(thumbfn),"%s.%s",av[i],T.tformat == LIBRAW_THUMBNAIL_JPEG ? "thumb.jpg" : "thumb.ppm");
 if( LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_thumb_writer(thumbfn)))
 {
 fprintf(stderr,"Cannot write %s: %s\n",thumbfn,libraw_strerror(ret));
 // in the case of fatal error, we should terminate processing of the current file
 if(LIBRAW_FATAL_ERROR(ret))
 goto end;
 }
 }
 // Data unpacking
 ret = RawProcessor.dcraw_process();
 if(LIBRAW_SUCCESS != ret ) // error at the previous step
 {
 fprintf(stderr,"Cannot do postprocessing on %s: %s\n",av[i],libraw_strerror(ret));
 if(LIBRAW_FATAL_ERROR(ret))
 goto end;
 }
 else // Successful document processing
 {
 snprintf(outfn,sizeof(outfn),"%s.%s", av[i], "tiff");
 if( LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn)))
 fprintf(stderr,"Cannot write %s: error %d\n",outfn,ret);
 }
 // we don't evoke recycle() or call the destructor; C++ will do everything for us
 return 0;
end:
 // got here after an error
 return 1;
}

[back to Index]

LibRaw-0.21.4/doc/Why-LibRaw.html000066400000000000000000000161711477673233700163670ustar00rootroot00000000000000

Purpose and Objectives[back to Index]

LibRaw Project Goals and Objectives

Who May Be Interested in This Project

The proposed project and the software products generated within this project are intended for:

  • Developers of RAW converters, including current and new developments
  • Developers of applications that need access to decoded RAW data (for pre-processing, stitching, stacking, color profiling, etc.)
  • Those willing to write their own graphic interface for RAW file processing
  • Developers and enthusiasts creating their own primary and auxiliary data processing algorithms, including
    • Interpolation (demosaic),
    • Noise reduction
    • White balance
    • Correction of aberrations and distortions
    • RAW data analysis
    • Comparison of cameras and lenses
    • and so on...

Some History

The LibRaw project started in 2008. At that time dcraw was very popular as a method of accessing RAW data. It was hard to find a more or less popular camera that was not supported by this utility; while the implementation of RAW data extraction in dcraw was of a very high quality.

However, developers and enthusiasts were experiencing a number of difficulties when using dcraw. First, the author of dcraw refused to turn his product into a handy library. Besides, dcraw contains a number of questionable features that may hinder its use without modifications, as well as instances of distortions in the photographic sense of it. As a result, once every several months, with each new release of dcraw, virtually all developers, part of them listed on the dcraw Web site, were to check the differences, figure out the patches, and apply those patches to their dcraw-based code and libraries.

As for enthusiasts, the "entry cost" of verifying their own ideas and implementing their own algorithms in such an environment is often unreasonably high: they have to either use the dcraw command line, thus being forced to use the unavoidable early processing stages, or understand the source code and maintain their own library based on it.

Thus, the inconveniences of dcraw make the developers' community quite small and halt further evolution and improvement of RAW format converters.

Our project started with the idea to get a library based on dcraw, only better. Today we are well past that initial goal, not in the least because dcraw is not actively supported since 2015, and the latest release was published nearly 2 years ago, in May 2016. Since then several distinctly different RAW formats (introduced by Fujifilm, Nikon, Pentax, Samsung, Sigma, Sony) emerged, none of which is supported by dcraw. Additionally, we see it necessary to extract more metadata to help better interpretation of RAW data and to add flexibility to the RAW conversion process.

Goals and Objectives

We are maintaining LibRaw as a library providing access to decoded raw data and metadata useful for correct interpretation of the said data. Thus:

  1. To keep on adding RAW decoding for new and previously unsupported cameras
  2. To continue the development of a stable and consistent API suitable for other applications (RAW converters, data analyzers, panorama stitchers, etc.)
  3. To have RAW processing as separate independent parts (groups of API calls)
    • Reading, decoding, and unpacking of RAW data: this is the main functionality of LibRaw
    • Data conversions: interpolation, white balance, etc.: this part of LibRaw is frozen: we ported dcraw functionality, but expect that library users will create own postprocessing code.
    • File output of the processing results. This part is very primitive, only tiff and ppm output is supported.

The latter two groups of functions are maintained to provide some postprocessing/saving ability from scratch, without writing own code. We do not have any plans to extend/improve this code.

  1. To improve the procedures of RAW data retrieval and decoding.
  2. To supply other developers with a "framework" (freeware and open-source), e.g., for experimenting with their own methods of RAW data processing (interpolation, noise reduction, white balance, etc.; some directions of the possible efforts are listed above), so that they could create their own GUI programs and interfaces without developing the entire RAW converter.

LibRaw Release Schedule

  1. Production releases will be published at intervals of 1-1.5 years. Production releases will be maintained through bugfixes. New cameras will not be added to production releases, but only to snapshots and non-stable/beta releases. Patch (bugfix) releases of production releases should provide API/ABI consistency (so, version 0.21.5 should be binary compatible with 0.21.0).
  2. Snapshots are planned to be released every 2-3 quarters. Snapshots will include support for new cameras, stable and tested in our own applications. API calls and internal routines may be changed. No binary compatibility maintained, to upgrade to newer snapshot one need to recompile application that uses it.
  3. Non-stable/beta releases with new features, like initial support for some new RAW format that needs extensive testing by the community.  No exact schedule, to be published as needed.

How You Can Help/Participate

We welcome any help, however:

  1. If you are submitting any core functionality extensions/improvements, that is, something that has to do with the decoding of RAW and/or metadata, that would be highly valuable and we will maintain your submission on our own, if necessary; you don’t need to be committed.
  2. If your contribution adds to post-processing, please be committed to supporting and maintaining such a contribution. Our previous experience with such contributions has been less than positive, exactly because of the lack of maintenance on the part of the contributors. We are unable to maintain such contributions on our own, because our primary goal is to maintain RAW and metadata decoding.

[back to Index]

LibRaw-0.21.4/doc/index.html000066400000000000000000000041111477673233700155400ustar00rootroot00000000000000 LibRaw: better dcraw (library)

LibRaw: RAW image decoding/processing library

LibRaw is a library for reading RAW files from digital photo cameras (CRW/CR2, NEF, RAF, DNG, MOS, KDC, DCR, etc.; virtually all RAW formats are supported). It pays special attention to correct retrieval of data required for subsequent RAW conversion.

The library is intended for embedding in RAW converters, data analyzers, and other programs using RAW files as the initial data.

Contents

  1. Copyright
  2. Purpose and Objectives
  3. Overview of LibRaw API (C++)
  4. Compilation and Installation
  5. Data Structures, Error Codes, and Constants
  6. C++ API
  7. C API
  8. Notes on API (error code conventions, memory usage)
  9. Examples

Copyright

LibRaw library, Copyright (C) 2008-2021 LibRaw LLC (info@libraw.org)
The library includes source code from
dcraw.c, Dave Coffin's raw photo decoder
Copyright 1997-2016 by Dave Coffin, dcoffin a cybercom o net

LibRaw is distributed for free under two different licenses:

You may use one of these licensing modes and switch between them.

LibRaw-0.21.4/export-dist.sh000077500000000000000000000006161477673233700156250ustar00rootroot00000000000000#!/bin/sh DEST=$1 VERSION=$2 if test x$VERSION = x ; then VERSION=`./version.sh` echo VERSION set to $VERSION fi if test -d $DEST ; then echo Using $DEST/$VERSION else echo Usage: $0 destination-dir exit 1 fi cd .. for dir in LibRaw do cd $dir git pull origin cd .. done for dir in LibRaw do cd $dir git archive --prefix=$dir-$VERSION/ $VERSION | (cd $DEST; tar xvf - ) cd .. done LibRaw-0.21.4/internal/000077500000000000000000000000001477673233700146155ustar00rootroot00000000000000LibRaw-0.21.4/internal/dcraw_defs.h000066400000000000000000000040741477673233700170740ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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). */ #ifndef DCRAW_DEFS_H #define DCRAW_DEFS_H #include #define LIBRAW_LIBRARY_BUILD #define LIBRAW_IO_REDEFINED #include "libraw/libraw.h" #include "libraw/libraw_types.h" #include "internal/defines.h" #include "internal/var_defines.h" #define stmread(buf, maxlen, fp) stread(buf, MIN(maxlen, sizeof(buf)), fp) #define strbuflen(buf) strnlen(buf, sizeof(buf) - 1) #define makeIs(idx) (maker_index == idx) #define strnXcat(buf, string) \ strncat(buf, string, LIM(sizeof(buf) - strbuflen(buf) - 1, 0, sizeof(buf))) // DNG was written by: #define nonDNG 0 #define CameraDNG 1 #define AdobeDNG 2 // Makernote tag type: #define is_0x927c 0 /* most cameras */ #define is_0xc634 2 /* Adobe DNG, Sony SR2, Pentax */ // abbreviations #define ilm imgdata.lens.makernotes #define icWBC imgdata.color.WB_Coeffs #define icWBCCTC imgdata.color.WBCT_Coeffs #define imCanon imgdata.makernotes.canon #define imFuji imgdata.makernotes.fuji #define imHassy imgdata.makernotes.hasselblad #define imKodak imgdata.makernotes.kodak #define imNikon imgdata.makernotes.nikon #define imOly imgdata.makernotes.olympus #define imPana imgdata.makernotes.panasonic #define imPentax imgdata.makernotes.pentax #define imPhaseOne imgdata.makernotes.phaseone #define imRicoh imgdata.makernotes.ricoh #define imSamsung imgdata.makernotes.samsung #define imSony imgdata.makernotes.sony #define imCommon imgdata.makernotes.common #define ph1_bits(n) ph1_bithuff(n, 0) #define ph1_huff(h) ph1_bithuff(*h, h + 1) #define getbits(n) getbithuff(n, 0) #define gethuff(h) getbithuff(*h, h + 1) #endif LibRaw-0.21.4/internal/dcraw_fileio_defs.h000066400000000000000000000012531477673233700204170ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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). */ #ifndef DCRAW_FILEIO_DEFS_H #define DCRAW_FILEIO_DEFS_H #include #define LIBRAW_LIBRARY_BUILD #include "libraw/libraw.h" #include "internal/defines.h" #include "internal/var_defines.h" #endif LibRaw-0.21.4/internal/defines.h000066400000000000000000000140201477673233700164000ustar00rootroot00000000000000/* Copyright 2008-2021 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). This file is generated from Dave Coffin's dcraw.c dcraw.c -- Dave Coffin's raw photo decoder Copyright 1997-2010 by Dave Coffin, dcoffin a cybercom o net Look into dcraw homepage (probably http://cybercom.net/~dcoffin/dcraw/) for more information */ #ifndef LIBRAW_INT_DEFINES_H #define LIBRAW_INT_DEFINES_H #ifndef USE_JPEG #define NO_JPEG #endif #ifndef USE_JASPER #define NO_JASPER #endif #define DCRAW_VERSION "9.26" #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #define _USE_MATH_DEFINES #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __CYGWIN__ #include #endif #if defined LIBRAW_WIN32_CALLS #include #ifndef LIBRAW_NO_WINSOCK2 #include #pragma comment(lib, "ws2_32.lib") #endif #define snprintf _snprintf #define strcasecmp stricmp #define strncasecmp strnicmp #else #include #include #include typedef long long INT64; typedef unsigned long long UINT64; #endif #ifdef NODEPS #define NO_JASPER #define NO_JPEG #define NO_LCMS #endif #ifndef NO_JASPER #include /* Decode Red camera movies */ #endif #ifndef NO_JPEG #include /* Decode compressed Kodak DC120 photos */ #endif /* and Adobe Lossy DNGs */ #ifndef NO_LCMS #ifdef USE_LCMS #include /* Support color profiles */ #else #include /* Support color profiles */ #endif #endif #ifdef LOCALEDIR #include #define _(String) gettext(String) #else #define _(String) (String) #endif #ifdef LJPEG_DECODE #error Please compile dcraw.c by itself. #error Do not link it with ljpeg_decode. #endif #ifndef LONG_BIT #define LONG_BIT (8 * sizeof(long)) #endif #define FORC(cnt) for (c = 0; c < cnt; c++) #define FORC3 FORC(3) #define FORC4 FORC(4) #define FORCC for (c = 0; c < colors && c < 4; c++) #define SQR(x) ((x) * (x)) #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define LIM(x, min, max) MAX(min, MIN(x, max)) #define ULIM(x, y, z) ((y) < (z) ? LIM(x, y, z) : LIM(x, z, y)) #define CLIP(x) LIM((int)(x), 0, 65535) #define CLIP15(x) LIM((int)(x), 0, 32767) #define SWAP(a, b) \ { \ a = a + b; \ b = a - b; \ a = a - b; \ } #define my_swap(type, i, j) \ { \ type t = i; \ i = j; \ j = t; \ } #ifdef __GNUC__ inline #elif defined(_MSC_VER) __forceinline #else static #endif float fMAX(float a, float b) { return MAX(a, b); } /* In order to inline this calculation, I make the risky assumption that all filter patterns can be described by a repeating pattern of eight rows and two columns Do not use the FC or BAYER macros with the Leaf CatchLight, because its pattern is 16x16, not 2x8. Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2 PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4: 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 G M G M G M 0 C Y C Y C Y 0 Y C Y C Y C 0 G M G M G M 1 C Y C Y C Y 1 M G M G M G 1 M G M G M G 1 Y C Y C Y C 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M 4 C Y C Y C Y 4 Y C Y C Y C PowerShot A5 5 G M G M G M 5 G M G M G M 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y 7 M G M G M G 7 M G M G M G 0 1 2 3 4 5 0 C Y C Y C Y 1 G M G M G M 2 C Y C Y C Y 3 M G M G M G All RGB cameras use one of these Bayer grids: 0x16161616: 0x61616161: 0x49494949: 0x94949494: 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 B G B G B G 0 G R G R G R 0 G B G B G B 0 R G R G R G 1 G R G R G R 1 B G B G B G 1 R G R G R G 1 G B G B G B 2 B G B G B G 2 G R G R G R 2 G B G B G B 2 R G R G R G 3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B */ // _RGBG means R, G1, B, G2 sequence #define GRBG_2_RGBG(q) (q ^ (q >> 1) ^ 1) #define RGGB_2_RGBG(q) (q ^ (q >> 1)) #define BG2RG1_2_RGBG(q) (q ^ 2) #define G2BRG1_2_RGBG(q) (q ^ (q >> 1) ^ 3) #define GRGB_2_RGBG(q) (q ^ 1) #define RBGG_2_RGBG(q) ((q >> 1) | ((q & 1) << 1)) #define RAWINDEX(row, col) ((row)*raw_width + (col)) #define RAW(row, col) raw_image[(row)*raw_width + (col)] #define BAYER(row, col) \ image[((row) >> shrink) * iwidth + ((col) >> shrink)][FC(row, col)] #define BAYER2(row, col) \ image[((row) >> shrink) * iwidth + ((col) >> shrink)][fcol(row, col)] #define BAYERC(row, col, c) \ imgdata.image[((row) >> IO.shrink) * S.iwidth + ((col) >> IO.shrink)][c] #endif LibRaw-0.21.4/internal/dmp_include.h000066400000000000000000000013151477673233700172510ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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). */ #ifndef DMP_INCLUDE_H #define DMP_INCLUDE_H #define LIBRAW_LIBRARY_BUILD #define LIBRAW_IO_REDEFINED #include "libraw/libraw.h" #include "internal/defines.h" #define SRC_USES_SHRINK #define SRC_USES_BLACK #define SRC_USES_CURVE #endif LibRaw-0.21.4/internal/libraw_cameraids.h000066400000000000000000000361371477673233700202700ustar00rootroot00000000000000/* -*- C++ -*- * File: internal/libraw_cameraids.h * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Aug 17, 2020 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). */ #ifndef LIBRAW_CONST_H #define LIBRAW_CONST_H #define CanonID_EOS_M50 0x00000412ULL #define CanonID_EOS_M6_Mark_II 0x00000811ULL #define CanonID_EOS_M200 0x00000812ULL #define CanonID_EOS_D30 0x01140000ULL #define CanonID_EOS_D60 0x01668000ULL #define CanonID_EOS_M3 0x03740000ULL #define CanonID_EOS_M10 0x03840000ULL #define CanonID_EOS_M5 0x03940000ULL #define CanonID_EOS_M100 0x03980000ULL #define CanonID_EOS_M6 0x04070000ULL #define CanonID_EOS_1D (0x80000000ULL + 0x001ULL) #define CanonID_EOS_1Ds (0x80000000ULL + 0x167ULL) #define CanonID_EOS_10D (0x80000000ULL + 0x168ULL) #define CanonID_EOS_1D_Mark_III (0x80000000ULL + 0x169ULL) #define CanonID_EOS_300D (0x80000000ULL + 0x170ULL) #define CanonID_EOS_1D_Mark_II (0x80000000ULL + 0x174ULL) #define CanonID_EOS_20D (0x80000000ULL + 0x175ULL) #define CanonID_EOS_450D (0x80000000ULL + 0x176ULL) #define CanonID_EOS_1Ds_Mark_II (0x80000000ULL + 0x188ULL) #define CanonID_EOS_350D (0x80000000ULL + 0x189ULL) #define CanonID_EOS_40D (0x80000000ULL + 0x190ULL) #define CanonID_EOS_5D (0x80000000ULL + 0x213ULL) #define CanonID_EOS_1Ds_Mark_III (0x80000000ULL + 0x215ULL) #define CanonID_EOS_5D_Mark_II (0x80000000ULL + 0x218ULL) #define CanonID_EOS_1D_Mark_II_N (0x80000000ULL + 0x232ULL) #define CanonID_EOS_30D (0x80000000ULL + 0x234ULL) #define CanonID_EOS_400D (0x80000000ULL + 0x236ULL) #define CanonID_EOS_7D (0x80000000ULL + 0x250ULL) #define CanonID_EOS_500D (0x80000000ULL + 0x252ULL) #define CanonID_EOS_1000D (0x80000000ULL + 0x254ULL) #define CanonID_EOS_50D (0x80000000ULL + 0x261ULL) #define CanonID_EOS_1D_X (0x80000000ULL + 0x269ULL) #define CanonID_EOS_550D (0x80000000ULL + 0x270ULL) #define CanonID_EOS_1D_Mark_IV (0x80000000ULL + 0x281ULL) #define CanonID_EOS_5D_Mark_III (0x80000000ULL + 0x285ULL) #define CanonID_EOS_600D (0x80000000ULL + 0x286ULL) #define CanonID_EOS_60D (0x80000000ULL + 0x287ULL) #define CanonID_EOS_1100D (0x80000000ULL + 0x288ULL) #define CanonID_EOS_7D_Mark_II (0x80000000ULL + 0x289ULL) #define CanonID_EOS_650D (0x80000000ULL + 0x301ULL) #define CanonID_EOS_6D (0x80000000ULL + 0x302ULL) #define CanonID_EOS_1D_C (0x80000000ULL + 0x324ULL) #define CanonID_EOS_70D (0x80000000ULL + 0x325ULL) #define CanonID_EOS_700D (0x80000000ULL + 0x326ULL) #define CanonID_EOS_1200D (0x80000000ULL + 0x327ULL) #define CanonID_EOS_1D_X_Mark_II (0x80000000ULL + 0x328ULL) #define CanonID_EOS_M (0x80000000ULL + 0x331ULL) #define CanonID_EOS_100D (0x80000000ULL + 0x346ULL) #define CanonID_EOS_760D (0x80000000ULL + 0x347ULL) #define CanonID_EOS_5D_Mark_IV (0x80000000ULL + 0x349ULL) #define CanonID_EOS_80D (0x80000000ULL + 0x350ULL) #define CanonID_EOS_M2 (0x80000000ULL + 0x355ULL) #define CanonID_EOS_5DS (0x80000000ULL + 0x382ULL) #define CanonID_EOS_750D (0x80000000ULL + 0x393ULL) #define CanonID_EOS_5DS_R (0x80000000ULL + 0x401ULL) #define CanonID_EOS_1300D (0x80000000ULL + 0x404ULL) #define CanonID_EOS_800D (0x80000000ULL + 0x405ULL) #define CanonID_EOS_6D_Mark_II (0x80000000ULL + 0x406ULL) #define CanonID_EOS_77D (0x80000000ULL + 0x408ULL) #define CanonID_EOS_200D (0x80000000ULL + 0x417ULL) #define CanonID_EOS_R5 (0x80000000ULL + 0x421ULL) #define CanonID_EOS_3000D (0x80000000ULL + 0x422ULL) #define CanonID_EOS_R (0x80000000ULL + 0x424ULL) #define CanonID_EOS_1D_X_Mark_III (0x80000000ULL + 0x428ULL) #define CanonID_EOS_1500D (0x80000000ULL + 0x432ULL) #define CanonID_EOS_RP (0x80000000ULL + 0x433ULL) #define CanonID_EOS_850D (0x80000000ULL + 0x435ULL) #define CanonID_EOS_250D (0x80000000ULL + 0x436ULL) #define CanonID_EOS_90D (0x80000000ULL + 0x437ULL) #define CanonID_EOS_R3 (0x80000000ULL + 0x450ULL) #define CanonID_EOS_R6 (0x80000000ULL + 0x453ULL) #define CanonID_EOS_R7 (0x80000000ULL + 0x464ULL) #define CanonID_EOS_R10 (0x80000000ULL + 0x465ULL) #define CanonID_EOS_M50_Mark_II (0x80000000ULL + 0x468ULL) // CanonID_EOS_D2000C after Canon's TIFF2CR2 convertor: #define CanonID_EOS_D2000C (0x80000000ULL + 0x520ULL) // CanonID_EOS_D6000C id after Canon's TIFF2CR2 convertor: #define CanonID_EOS_D6000C (0x80000000ULL + 0x560ULL) #define OlyID_str2hex(str) ((unsigned long long)str[0]<<32 | str[1]<<24 | str[2]<<16 | str[3]<<8 | str[4]) #define OlyID_E_20 OlyID_str2hex("D4029") #define OlyID_E_1 OlyID_str2hex("D4040") #define OlyID_E_300 OlyID_str2hex("D4041") #define OlyID_SP_550UZ OlyID_str2hex("D4321") #define OlyID_SP_510UZ OlyID_str2hex("D4322") #define OlyID_SP_560UZ OlyID_str2hex("D4355") #define OlyID_SP_570UZ OlyID_str2hex("D4364") #define OlyID_SP_565UZ OlyID_str2hex("D4374") #define OlyID_XZ_1 OlyID_str2hex("D4401") #define OlyID_XZ_2 OlyID_str2hex("D4531") #define OlyID_XZ_10 OlyID_str2hex("D4546") #define OlyID_STYLUS_1 OlyID_str2hex("D4572") #define OlyID_SH_2 OlyID_str2hex("D4585") #define OlyID_TG_4 OlyID_str2hex("D4586") #define OlyID_TG_5 OlyID_str2hex("D4593") #define OlyID_TG_6 OlyID_str2hex("D4603") #define OlyID_E_10 OlyID_str2hex("D4842") #define OlyID_AIR_A01 OlyID_str2hex("K0055") #define OlyID_NORMA OlyID_str2hex("NORMA") #define OlyID_E_330 OlyID_str2hex("S0003") #define OlyID_E_500 OlyID_str2hex("S0004") #define OlyID_E_400 OlyID_str2hex("S0009") #define OlyID_E_510 OlyID_str2hex("S0010") #define OlyID_E_3 OlyID_str2hex("S0011") #define OlyID_E_410 OlyID_str2hex("S0013") #define OlyID_E_420 OlyID_str2hex("S0016") #define OlyID_E_30 OlyID_str2hex("S0017") #define OlyID_E_520 OlyID_str2hex("S0018") #define OlyID_E_P1 OlyID_str2hex("S0019") #define OlyID_E_620 OlyID_str2hex("S0023") #define OlyID_E_P2 OlyID_str2hex("S0026") #define OlyID_E_PL1 OlyID_str2hex("S0027") #define OlyID_E_450 OlyID_str2hex("S0029") #define OlyID_E_600 OlyID_str2hex("S0030") #define OlyID_E_P3 OlyID_str2hex("S0032") #define OlyID_E_5 OlyID_str2hex("S0033") #define OlyID_E_PL2 OlyID_str2hex("S0034") #define OlyID_E_M5 OlyID_str2hex("S0036") #define OlyID_E_PL3 OlyID_str2hex("S0038") #define OlyID_E_PM1 OlyID_str2hex("S0039") #define OlyID_E_PL1s OlyID_str2hex("S0040") #define OlyID_E_PL5 OlyID_str2hex("S0042") #define OlyID_E_PM2 OlyID_str2hex("S0043") #define OlyID_E_P5 OlyID_str2hex("S0044") #define OlyID_E_PL6 OlyID_str2hex("S0045") #define OlyID_E_PL7 OlyID_str2hex("S0046") #define OlyID_E_M1 OlyID_str2hex("S0047") #define OlyID_E_M10 OlyID_str2hex("S0051") #define OlyID_E_M5_Mark_II OlyID_str2hex("S0052") #define OlyID_E_M10_Mark_II OlyID_str2hex("S0059") #define OlyID_PEN_F OlyID_str2hex("S0061") #define OlyID_E_PL8 OlyID_str2hex("S0065") #define OlyID_E_M1_Mark_II OlyID_str2hex("S0067") #define OlyID_E_M10_Mark_III OlyID_str2hex("S0068") #define OlyID_E_PL9 OlyID_str2hex("S0076") #define OlyID_E_M1X OlyID_str2hex("S0080") #define OlyID_E_PL10 OlyID_str2hex("S0085") #define OlyID_E_M10_Mark_IV OlyID_str2hex("S0088") #define OlyID_E_M5_Mark_III OlyID_str2hex("S0089") #define OlyID_E_M1_Mark_III OlyID_str2hex("S0092") #define OlyID_E_P7 OlyID_str2hex("S0093") #define OlyID_OM_1 OlyID_str2hex("S0095") #define OlyID_C_3030Z OlyID_str2hex("SX351") #define OlyID_C_5050Z OlyID_str2hex("SX558") #define OlyID_C_350Z OlyID_str2hex("SX751") #define OlyID_C_740UZ OlyID_str2hex("SX754") #define OlyID_C_5060WZ OlyID_str2hex("SX756") #define OlyID_C_8080WZ OlyID_str2hex("SX757") #define OlyID_C_770UZ OlyID_str2hex("SX772") #define OlyID_C_7070WZ OlyID_str2hex("SX851") #define OlyID_C_7000Z OlyID_str2hex("SX852") #define OlyID_SP_500UZ OlyID_str2hex("SX853") #define OlyID_SP_310 OlyID_str2hex("SX854") #define OlyID_SP_350 OlyID_str2hex("SX855") #define OlyID_SP_320 OlyID_str2hex("SX873") #define PentaxID_Optio_S 0x1296cULL #define PentaxID_Optio_S_V101 0x12971ULL #define PentaxID_staristD 0x12994ULL #define PentaxID_Optio_33WR 0x129c6ULL #define PentaxID_Optio_S4 0x129d5ULL #define PentaxID_Optio_750Z 0x12a66ULL #define PentaxID_staristDS 0x12aa2ULL #define PentaxID_staristDL 0x12b1aULL #define PentaxID_staristDS2 0x12b60ULL #define PentaxID_GX_1S 0x12b62ULL #define PentaxID_staristDL2 0x12b7eULL #define PentaxID_GX_1L 0x12b80ULL #define PentaxID_K100D 0x12b9cULL #define PentaxID_K110D 0x12b9dULL #define PentaxID_K100D_Super 0x12ba2ULL #define PentaxID_K10D 0x12c1eULL #define PentaxID_GX10 0x12c20ULL #define PentaxID_K20D 0x12cd2ULL #define PentaxID_GX20 0x12cd4ULL #define PentaxID_K200D 0x12cfaULL #define PentaxID_K2000 0x12d72ULL #define PentaxID_K_m 0x12d73ULL #define PentaxID_K_7 0x12db8ULL #define PentaxID_K_x 0x12dfeULL #define PentaxID_645D 0x12e08ULL #define PentaxID_K_r 0x12e6cULL #define PentaxID_K_5 0x12e76ULL #define PentaxID_Q 0x12ee4ULL #define PentaxID_K_01 0x12ef8ULL #define PentaxID_K_30 0x12f52ULL #define PentaxID_Q10 0x12f66ULL #define PentaxID_K_5_II 0x12f70ULL #define PentaxID_K_5_II_s 0x12f71ULL #define PentaxID_Q7 0x12f7aULL #define PentaxID_MX_1 0x12f84ULL #define PentaxID_K_50 0x12fb6ULL #define PentaxID_K_3 0x12fc0ULL #define PentaxID_K_500 0x12fcaULL #define PentaxID_645Z 0x13010ULL #define PentaxID_K_S1 0x1301aULL #define PentaxID_K_S2 0x13024ULL #define PentaxID_Q_S1 0x1302eULL #define PentaxID_K_1 0x13092ULL #define PentaxID_K_3_II 0x1309cULL #define PentaxID_GR_III 0x1320eULL #define PentaxID_K_70 0x13222ULL #define PentaxID_KP 0x1322cULL #define PentaxID_K_1_Mark_II 0x13240ULL #define PentaxID_K_3_III 0x13254ULL #define PentaxID_GR_IIIx 0x1329aULL #define SonyID_DSC_R1 0x002ULL #define SonyID_DSLR_A100 0x100ULL #define SonyID_DSLR_A900 0x101ULL #define SonyID_DSLR_A700 0x102ULL #define SonyID_DSLR_A200 0x103ULL #define SonyID_DSLR_A350 0x104ULL #define SonyID_DSLR_A300 0x105ULL #define SonyID_DSLR_A900_APSC 0x106ULL #define SonyID_DSLR_A380 0x107ULL #define SonyID_DSLR_A330 0x108ULL #define SonyID_DSLR_A230 0x109ULL #define SonyID_DSLR_A290 0x10aULL #define SonyID_DSLR_A850 0x10dULL #define SonyID_DSLR_A850_APSC 0x10eULL #define SonyID_DSLR_A550 0x111ULL #define SonyID_DSLR_A500 0x112ULL #define SonyID_DSLR_A450 0x113ULL #define SonyID_NEX_5 0x116ULL #define SonyID_NEX_3 0x117ULL #define SonyID_SLT_A33 0x118ULL #define SonyID_SLT_A55 0x119ULL #define SonyID_DSLR_A560 0x11aULL #define SonyID_DSLR_A580 0x11bULL #define SonyID_NEX_C3 0x11cULL #define SonyID_SLT_A35 0x11dULL #define SonyID_SLT_A65 0x11eULL #define SonyID_SLT_A77 0x11fULL #define SonyID_NEX_5N 0x120ULL #define SonyID_NEX_7 0x121ULL #define SonyID_NEX_VG20 0x122ULL #define SonyID_SLT_A37 0x123ULL #define SonyID_SLT_A57 0x124ULL #define SonyID_NEX_F3 0x125ULL #define SonyID_SLT_A99 0x126ULL #define SonyID_NEX_6 0x127ULL #define SonyID_NEX_5R 0x128ULL #define SonyID_DSC_RX100 0x129ULL #define SonyID_DSC_RX1 0x12aULL #define SonyID_NEX_VG900 0x12bULL #define SonyID_NEX_VG30 0x12cULL #define SonyID_ILCE_3000 0x12eULL #define SonyID_SLT_A58 0x12fULL #define SonyID_NEX_3N 0x131ULL #define SonyID_ILCE_7 0x132ULL #define SonyID_NEX_5T 0x133ULL #define SonyID_DSC_RX100M2 0x134ULL #define SonyID_DSC_RX10 0x135ULL #define SonyID_DSC_RX1R 0x136ULL #define SonyID_ILCE_7R 0x137ULL #define SonyID_ILCE_6000 0x138ULL #define SonyID_ILCE_5000 0x139ULL #define SonyID_DSC_RX100M3 0x13dULL #define SonyID_ILCE_7S 0x13eULL #define SonyID_ILCA_77M2 0x13fULL #define SonyID_ILCE_5100 0x153ULL #define SonyID_ILCE_7M2 0x154ULL #define SonyID_DSC_RX100M4 0x155ULL #define SonyID_DSC_RX10M2 0x156ULL #define SonyID_DSC_RX1RM2 0x158ULL #define SonyID_ILCE_QX1 0x15aULL #define SonyID_ILCE_7RM2 0x15bULL #define SonyID_ILCE_7SM2 0x15eULL #define SonyID_ILCA_68 0x161ULL #define SonyID_ILCA_99M2 0x162ULL #define SonyID_DSC_RX10M3 0x163ULL #define SonyID_DSC_RX100M5 0x164ULL #define SonyID_ILCE_6300 0x165ULL #define SonyID_ILCE_9 0x166ULL #define SonyID_ILCE_6500 0x168ULL #define SonyID_ILCE_7RM3 0x16aULL #define SonyID_ILCE_7M3 0x16bULL #define SonyID_DSC_RX0 0x16cULL #define SonyID_DSC_RX10M4 0x16dULL #define SonyID_DSC_RX100M6 0x16eULL #define SonyID_DSC_HX99 0x16fULL #define SonyID_DSC_RX100M5A 0x171ULL #define SonyID_ILCE_6400 0x173ULL #define SonyID_DSC_RX0M2 0x174ULL #define SonyID_DSC_RX100M7 0x176ULL #define SonyID_ILCE_7RM4 0x177ULL #define SonyID_ILCE_9M2 0x178ULL #define SonyID_ILCE_6600 0x17aULL #define SonyID_ILCE_6100 0x17bULL #define SonyID_ZV_1 0x17cULL #define SonyID_ILCE_7C 0x17dULL #define SonyID_ZV_E10 0x17eULL #define SonyID_ILCE_7SM3 0x17fULL #define SonyID_ILCE_1 0x180ULL #define SonyID_ILME_FX3 0x181ULL #define SonyID_ILCE_7RM3A 0x182ULL #define SonyID_ILCE_7RM4A 0x183ULL #define SonyID_ILCE_7M4 0x184ULL #endif LibRaw-0.21.4/internal/libraw_cxx_defs.h000066400000000000000000000124011477673233700201270ustar00rootroot00000000000000/* -*- C++ -*- * File: internal/libraw_cxx_defs.h * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Aug 17, 2020 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). */ #ifndef _LIBRAW_CXX_DEFS_H #define _LIBRAW_CXX_DEFS_H #include #include #include #include #include #include #include #define LIBRAW_LIBRARY_BUILD #include "libraw/libraw.h" #include "internal/defines.h" #ifdef USE_ZLIB #include #endif #ifndef LIBRAW_WIN32_CALLS #include #else #ifndef LIBRAW_NO_WINSOCK2 #include #endif #include #endif #ifdef USE_RAWSPEED #include #include #include #include #include #include extern const char *_rawspeed_data_xml[]; extern const int RAWSPEED_DATA_COUNT; class CameraMetaDataLR : public RawSpeed::CameraMetaData { public: CameraMetaDataLR() : CameraMetaData() {} CameraMetaDataLR(char *filename) : RawSpeed::CameraMetaData(filename) {} CameraMetaDataLR(char *data, int sz); }; CameraMetaDataLR *make_camera_metadata(); #endif #ifdef USE_DNGSDK #include "dng_host.h" #include "dng_negative.h" #include "dng_simple_image.h" #include "dng_info.h" #endif #define P1 imgdata.idata #define S imgdata.sizes #define O imgdata.params #define C imgdata.color #define T imgdata.thumbnail #define MN imgdata.makernotes #define IO libraw_internal_data.internal_output_params #define ID libraw_internal_data.internal_data #define makeIs(idx) (imgdata.idata.maker_index == idx) #define mnCamID imgdata.lens.makernotes.CamID #define EXCEPTION_HANDLER(e) \ do \ { \ switch (e) \ { \ case LIBRAW_EXCEPTION_MEMPOOL: \ recycle(); \ return LIBRAW_MEMPOOL_OVERFLOW; \ case LIBRAW_EXCEPTION_ALLOC: \ recycle(); \ return LIBRAW_UNSUFFICIENT_MEMORY; \ case LIBRAW_EXCEPTION_TOOBIG: \ recycle(); \ return LIBRAW_TOO_BIG; \ case LIBRAW_EXCEPTION_DECODE_RAW: \ case LIBRAW_EXCEPTION_DECODE_JPEG: \ recycle(); \ return LIBRAW_DATA_ERROR; \ case LIBRAW_EXCEPTION_DECODE_JPEG2000: \ recycle(); \ return LIBRAW_DATA_ERROR; \ case LIBRAW_EXCEPTION_IO_EOF: \ case LIBRAW_EXCEPTION_IO_CORRUPT: \ recycle(); \ return LIBRAW_IO_ERROR; \ case LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK: \ recycle(); \ return LIBRAW_CANCELLED_BY_CALLBACK; \ case LIBRAW_EXCEPTION_BAD_CROP: \ recycle(); \ return LIBRAW_BAD_CROP; \ case LIBRAW_EXCEPTION_UNSUPPORTED_FORMAT: \ recycle(); \ return LIBRAW_FILE_UNSUPPORTED; \ default: \ return LIBRAW_UNSPECIFIED_ERROR; \ } \ } while (0) // copy-n-paste from image pipe #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define LIM(x, min, max) MAX(min, MIN(x, max)) #ifndef CLIP #define CLIP(x) LIM(x, 0, 65535) #endif #define THUMB_READ_BEYOND 16384 #define ZERO(a) memset(&a, 0, sizeof(a)) #endif LibRaw-0.21.4/internal/libraw_internal_funcs.h000066400000000000000000000421701477673233700213440ustar00rootroot00000000000000/* -*- C++ -*- * File: libraw_internal_funcs.h * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Mar 14, 2008 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). */ #ifndef _LIBRAW_INTERNAL_FUNCS_H #define _LIBRAW_INTERNAL_FUNCS_H #ifndef LIBRAW_LIBRARY_BUILD #error "This file should be used only for libraw library build" #else /* inline functions */ static int stread(char *buf, size_t len, LibRaw_abstract_datastream *fp); static int getwords(char *line, char *words[], int maxwords, int maxlen); static void remove_trailing_spaces(char *string, size_t len); static void remove_caseSubstr(char *string, char *remove); static void removeExcessiveSpaces(char *string); static void trimSpaces(char *s); /* static tables/variables */ static libraw_static_table_t tagtype_dataunit_bytes; static libraw_static_table_t Canon_wbi2std; static libraw_static_table_t Canon_KeyIsZero_Len2048_linenums_2_StdWBi; static libraw_static_table_t Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi; static libraw_static_table_t Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi; static libraw_static_table_t Canon_D30_linenums_2_StdWBi; static libraw_static_table_t Canon_G9_linenums_2_StdWBi; static libraw_static_table_t Fuji_wb_list1; static libraw_static_table_t FujiCCT_K; static libraw_static_table_t Fuji_wb_list2; static libraw_static_table_t Pentax_wb_list1; static libraw_static_table_t Pentax_wb_list2; static libraw_static_table_t Oly_wb_list1; static libraw_static_table_t Oly_wb_list2; static libraw_static_table_t Sony_SRF_wb_list; static libraw_static_table_t Sony_SR2_wb_list; static libraw_static_table_t Sony_SR2_wb_list1; /* */ int find_ifd_by_offset(int ); void libraw_swab(void *arr, size_t len); ushort sget2 (uchar *s); ushort sget2Rev(uchar *s); libraw_area_t get_CanonArea(); int parseCR3(INT64 oAtomList, INT64 szAtomList, short &nesting, char *AtomNameStack, short& nTrack, short &TrackType); void selectCRXTrack(); void parseCR3_Free(); int parseCR3_CTMD(short trackNum); int selectCRXFrame(short trackNum, unsigned frameIndex); void setCanonBodyFeatures (unsigned long long id); void processCanonCameraInfo (unsigned long long id, uchar *CameraInfo, unsigned maxlen, unsigned type, unsigned dng_writer); static float _CanonConvertAperture(ushort in); void Canon_CameraSettings(unsigned len); void Canon_WBpresets (int skip1, int skip2); void Canon_WBCTpresets (short WBCTversion); void parseCanonMakernotes (unsigned tag, unsigned type, unsigned len, unsigned dng_writer); void processNikonLensData (uchar *LensData, unsigned len); void Nikon_NRW_WBtag (int wb, int skip); void parseNikonMakernote (int base, int uptag, unsigned dng_writer); void parseEpsonMakernote (int base, int uptag, unsigned dng_writer); void parseSigmaMakernote (int base, int uptag, unsigned dng_writer); void setOlympusBodyFeatures (unsigned long long id); void getOlympus_CameraType2 (); void getOlympus_SensorTemperature (unsigned len); void parseOlympus_Equipment (unsigned tag, unsigned type, unsigned len, unsigned dng_writer); void parseOlympus_CameraSettings (int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer); void parseOlympus_ImageProcessing (unsigned tag, unsigned type, unsigned len, unsigned dng_writer); void parseOlympus_RawInfo (unsigned tag, unsigned type, unsigned len, unsigned dng_writer); void parseOlympusMakernotes (int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer); void setPhaseOneFeatures (unsigned long long id); void setPentaxBodyFeatures (unsigned long long id); void PentaxISO (ushort c); void PentaxLensInfo (unsigned long long id, unsigned len); void parsePentaxMakernotes(int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer); void parseRicohMakernotes(int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer); void parseSamsungMakernotes(int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer); #ifdef LIBRAW_OLD_VIDEO_SUPPORT void fixupArri(); #endif void setSonyBodyFeatures (unsigned long long id); void parseSonyLensType2 (uchar a, uchar b); void parseSonyLensFeatures (uchar a, uchar b); void process_Sony_0x0116 (uchar * buf, ushort, unsigned long long id); void process_Sony_0x2010 (uchar * buf, ushort); void process_Sony_0x9050 (uchar * buf, ushort, unsigned long long id); void process_Sony_0x9400 (uchar * buf, ushort, unsigned long long id); void process_Sony_0x9402 (uchar * buf, ushort); void process_Sony_0x9403 (uchar * buf, ushort); void process_Sony_0x9406 (uchar * buf, ushort); void process_Sony_0x940c (uchar * buf, ushort); void process_Sony_0x940e (uchar * buf, ushort, unsigned long long id); void parseSonyMakernotes (int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer, uchar *&table_buf_0x0116, ushort &table_buf_0x0116_len, uchar *&table_buf_0x2010, ushort &table_buf_0x2010_len, uchar *&table_buf_0x9050, ushort &table_buf_0x9050_len, uchar *&table_buf_0x9400, ushort &table_buf_0x9400_len, uchar *&table_buf_0x9402, ushort &table_buf_0x9402_len, uchar *&table_buf_0x9403, ushort &table_buf_0x9403_len, uchar *&table_buf_0x9406, ushort &table_buf_0x9406_len, uchar *&table_buf_0x940c, ushort &table_buf_0x940c_len, uchar *&table_buf_0x940e, ushort &table_buf_0x940e_len); void parseSonySR2 (uchar *cbuf_SR2, unsigned SR2SubIFDOffset, unsigned SR2SubIFDLength, unsigned dng_writer); void parseSonySRF (unsigned len); void parseFujiMakernotes (unsigned tag, unsigned type, unsigned len, unsigned dng_writer); const char* HassyRawFormat_idx2HR(unsigned idx); void process_Hassy_Lens (int LensMount); void parseHassyModel (); void setLeicaBodyFeatures(int LeicaMakernoteSignature); void parseLeicaLensID(); int parseLeicaLensName(unsigned len); int parseLeicaInternalBodySerial(unsigned len); void parseLeicaMakernote(int base, int uptag, unsigned MakernoteTagType); void parseAdobePanoMakernote (); void parseAdobeRAFMakernote (); void GetNormalizedModel (); void SetStandardIlluminants (unsigned, const char* ); ushort get2(); unsigned sget4 (uchar *s); unsigned getint(int type); float int_to_float (int i); double getreal (int type); double sgetreal(int type, uchar *s); void read_shorts (ushort *pixel, unsigned count); /* Canon P&S cameras */ void canon_600_fixed_wb (int temp); int canon_600_color (int ratio[2], int mar); void canon_600_auto_wb(); void canon_600_coeff(); void canon_600_load_raw(); void canon_600_correct(); int canon_s2is(); void parse_ciff (int offset, int length, int); void ciff_block_1030(); // LJPEG decoder unsigned getbithuff (int nbits, ushort *huff); ushort* make_decoder_ref (const uchar **source); ushort* make_decoder (const uchar *source); int ljpeg_start (struct jhead *jh, int info_only); void ljpeg_end(struct jhead *jh); int ljpeg_diff (ushort *huff); ushort * ljpeg_row (int jrow, struct jhead *jh); ushort * ljpeg_row_unrolled (int jrow, struct jhead *jh); void ljpeg_idct (struct jhead *jh); unsigned ph1_bithuff (int nbits, ushort *huff); // Canon DSLRs void crw_init_tables (unsigned table, ushort *huff[2]); int canon_has_lowbits(); void canon_load_raw(); void lossless_jpeg_load_raw(); void canon_sraw_load_raw(); // Adobe DNG void adobe_copy_pixel (unsigned int row, unsigned int col, ushort **rp); void lossless_dng_load_raw(); void deflate_dng_load_raw(); void packed_dng_load_raw(); void packed_tiled_dng_load_raw(); void uncompressed_fp_dng_load_raw(); void lossy_dng_load_raw(); //void adobe_dng_load_raw_nc(); // Pentax void pentax_load_raw(); void pentax_4shot_load_raw(); void pentax_tree(); // Nikon (and Minolta Z2) void nikon_load_raw(); void nikon_he_load_raw_placeholder(); void nikon_read_curve(); void nikon_load_striped_packed_raw(); void nikon_load_padded_packed_raw(); void nikon_load_sraw(); void nikon_yuv_load_raw(); void nikon_coolscan_load_raw(); int nikon_e995(); int nikon_e2100(); void nikon_3700(); int minolta_z2(); // void nikon_e2100_load_raw(); // Fuji // void fuji_load_raw(); int guess_RAFDataGeneration (uchar *RAFData_start); void parse_fuji (int offset); void parse_fuji_thumbnail(int offset); #ifdef LIBRAW_OLD_VIDEO_SUPPORT // RedCine void parse_redcine(); void redcine_load_raw(); #endif // Rollei void rollei_load_raw(); void parse_rollei(); // Contax void parse_kyocera (); // MF backs //int bayer (unsigned row, unsigned col); int p1raw(unsigned,unsigned); void phase_one_flat_field (int is_float, int nc); int p1rawc(unsigned row, unsigned col, unsigned& count); void phase_one_fix_col_pixel_avg(unsigned row, unsigned col); void phase_one_fix_pixel_grad(unsigned row, unsigned col); void phase_one_load_raw(); unsigned ph1_bits (int nbits); void phase_one_load_raw_c(); void phase_one_load_raw_s(); void hasselblad_load_raw(); void leaf_hdr_load_raw(); void sinar_4shot_load_raw(); void imacon_full_load_raw(); void hasselblad_full_load_raw(); void packed_load_raw(); float find_green(int,int,int,int); void unpacked_load_raw(); void unpacked_load_raw_FujiDBP(); void unpacked_load_raw_reversed(); void unpacked_load_raw_fuji_f700s20(); void parse_sinar_ia(); void parse_phase_one (int base); // Misc P&S cameras void parse_broadcom(); void broadcom_load_raw(); void nokia_load_raw(); void android_loose_load_raw(); void android_tight_load_raw(); #ifdef LIBRAW_OLD_VIDEO_SUPPORT void canon_rmf_load_raw(); #endif unsigned pana_data (int nb, unsigned *bytes); void panasonic_load_raw(); // void panasonic_16x10_load_raw(); void olympus_load_raw(); // void olympus_cseries_load_raw(); void minolta_rd175_load_raw(); void quicktake_100_load_raw(); const int* make_decoder_int (const int *source, int level); int radc_token (int tree); void kodak_radc_load_raw(); void kodak_jpeg_load_raw(); void kodak_dc120_load_raw(); void eight_bit_load_raw(); void smal_decode_segment (unsigned seg[2][2], int holes); void smal_v6_load_raw(); int median4 (int *p); void fill_holes (int holes); void smal_v9_load_raw(); void parse_riff(int maxdepth); void parse_cine(); void parse_smal (int offset, int fsize); int parse_jpeg (int offset); // Kodak void kodak_262_load_raw(); int kodak_65000_decode (short *out, int bsize); void kodak_65000_load_raw(); void kodak_rgb_load_raw(); void kodak_ycbcr_load_raw(); // void kodak_yrgb_load_raw(); void kodak_c330_load_raw(); void kodak_c603_load_raw(); void kodak_rgb_load_thumb(); void kodak_ycbcr_load_thumb(); void vc5_dng_load_raw_placeholder(); // It's a Sony (and K&M) void sony_decrypt (unsigned *data, int len, int start, int key); void sony_load_raw(); void sony_arw_load_raw(); void sony_arw2_load_raw(); void sony_arq_load_raw(); void sony_ljpeg_load_raw(); void samsung_load_raw(); void samsung2_load_raw(); void samsung3_load_raw(); void parse_minolta (int base); #ifdef USE_X3FTOOLS // Foveon/Sigma // We always have x3f code compiled in! void parse_x3f(); void x3f_load_raw(); void x3f_dpq_interpolate_rg(); void x3f_dpq_interpolate_af(int xstep, int ystep, int scale); // 1x1 af pixels void x3f_dpq_interpolate_af_sd(int xstart,int ystart, int xend, int yend, int xstep, int ystep, int scale); // sd Quattro interpolation #else void parse_x3f() {} void x3f_load_raw(){} #endif #ifdef USE_6BY9RPI void rpi_load_raw8(); void rpi_load_raw12(); void rpi_load_raw14(); void rpi_load_raw16(); void parse_raspberrypi(); #endif // CAM/RGB void pseudoinverse (double (*in)[3], double (*out)[3], int size); void simple_coeff (int index); // Openp char** malloc_omp_buffers(int buffer_count, size_t buffer_size); void free_omp_buffers(char** buffers, int buffer_count); // Tiff/Exif parsers void tiff_get (unsigned base,unsigned *tag, unsigned *type, unsigned *len, unsigned *save); short tiff_sget(unsigned save, uchar *buf, unsigned buf_len, INT64 *tag_offset, unsigned *tag_id, unsigned *tag_type, INT64 *tag_dataoffset, unsigned *tag_datalen, int *tag_dataunit_len); void parse_thumb_note (int base, unsigned toff, unsigned tlen); void parse_makernote (int base, int uptag); void parse_makernote_0xc634(int base, int uptag, unsigned dng_writer); void parse_exif (int base); void parse_exif_interop(int base); void linear_table(unsigned len); void Kodak_DCR_WBtags(int wb, unsigned type, int wbi); void Kodak_KDC_WBtags(int wb, int wbi); short KodakIllumMatrix (unsigned type, float *romm_camIllum); void parse_kodak_ifd (int base); int parse_tiff_ifd (int base); int parse_tiff (int base); void apply_tiff(void); void parse_gps (int base); void parse_gps_libraw(int base); void aRGB_coeff(double aRGB_cam[3][3]); void romm_coeff(float romm_cam[3][3]); void parse_mos (INT64 offset); void parse_qt (int end); void get_timestamp (int reversed); // The identify short guess_byte_order (int words); void identify_process_dng_fields(); void identify_finetune_pentax(); void identify_finetune_by_filesize(int); void identify_finetune_dcr(char head[64],int,int); // Tiff writer void tiff_set(struct tiff_hdr *th, ushort *ntag,ushort tag, ushort type, int count, int val); void tiff_head (struct tiff_hdr *th, int full); // split AHD code void ahd_interpolate_green_h_and_v(int top, int left, ushort (*out_rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3]); void ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[LIBRAW_AHD_TILE][3], short (*out_lab)[LIBRAW_AHD_TILE][3]); void ahd_interpolate_r_and_b_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], short (*out_lab)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3]); void ahd_interpolate_build_homogeneity_map(int top, int left, short (*lab)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], char (*out_homogeneity_map)[LIBRAW_AHD_TILE][2]); void ahd_interpolate_combine_homogeneous_pixels(int top, int left, ushort (*rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], char (*homogeneity_map)[LIBRAW_AHD_TILE][2]); void init_fuji_compr(struct fuji_compressed_params* info); void init_fuji_block(struct fuji_compressed_block* info, const struct fuji_compressed_params *params, INT64 raw_offset, unsigned dsize); void copy_line_to_xtrans(struct fuji_compressed_block* info, int cur_line, int cur_block, int cur_block_width); void copy_line_to_bayer(struct fuji_compressed_block* info, int cur_line, int cur_block, int cur_block_width); void xtrans_decode_block(struct fuji_compressed_block* info, const struct fuji_compressed_params *params, int cur_line); void fuji_bayer_decode_block(struct fuji_compressed_block* info, const struct fuji_compressed_params *params, int cur_line); void fuji_compressed_load_raw(); void fuji_14bit_load_raw(); void parse_fuji_compressed_header(); void crxLoadRaw(); int crxParseImageHeader(uchar *cmp1TagData, int nTrack, int size); void panasonicC6_load_raw(); void panasonicC7_load_raw(); void nikon_14bit_load_raw(); // DCB void dcb_pp(); void dcb_copy_to_buffer(float (*image2)[3]); void dcb_restore_from_buffer(float (*image2)[3]); void dcb_color(); void dcb_color_full(); void dcb_map(); void dcb_correction(); void dcb_correction2(); void dcb_refinement(); void rgb_to_lch(double (*image3)[3]); void lch_to_rgb(double (*image3)[3]); void fbdd_correction(); void fbdd_correction2(double (*image3)[3]); void fbdd_green(); void dcb_ver(float (*image3)[3]); void dcb_hor(float (*image2)[3]); void dcb_color2(float (*image2)[3]); void dcb_color3(float (*image3)[3]); void dcb_decide(float (*image2)[3], float (*image3)[3]); void dcb_nyquist(); #endif #endif LibRaw-0.21.4/internal/var_defines.h000066400000000000000000000240671477673233700172640ustar00rootroot00000000000000/* -*- C++ -*- * File: var_defines.h * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8, 2008 * * LibRaw redefinitions of dcraw internal variables 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). */ #ifndef VAR_DEFINES_H #define VAR_DEFINES_H // imgdata.idata #define make (imgdata.idata.make) #define model (imgdata.idata.model) #define software (imgdata.idata.software) #define is_raw (imgdata.idata.raw_count) #define dng_version (imgdata.idata.dng_version) #define is_foveon (imgdata.idata.is_foveon) #define colors (imgdata.idata.colors) #define cdesc (imgdata.idata.cdesc) #define filters (imgdata.idata.filters) #define xtrans (imgdata.idata.xtrans) #define xtrans_abs (imgdata.idata.xtrans_abs) #define xmpdata (imgdata.idata.xmpdata) #define xmplen (imgdata.idata.xmplen) //imgdata image #define image (imgdata.image) #define raw_image (imgdata.rawdata.raw_image) #define color_image (imgdata.rawdata.color_image) #define normalized_make (imgdata.idata.normalized_make) #define normalized_model (imgdata.idata.normalized_model) #define maker_index (imgdata.idata.maker_index) // imgdata.sizes #define raw_height (imgdata.sizes.raw_height) #define raw_width (imgdata.sizes.raw_width) #define raw_pitch (imgdata.sizes.raw_pitch) #define height (imgdata.sizes.height) #define width (imgdata.sizes.width) #define top_margin (imgdata.sizes.top_margin) #define left_margin (imgdata.sizes.left_margin) #define bottom_margin (imgdata.sizes.bottom_margin) #define right_margin (imgdata.sizes.right_margin) #define iheight (imgdata.sizes.iheight) #define iwidth (imgdata.sizes.iwidth) #define pixel_aspect (imgdata.sizes.pixel_aspect) #define flip (imgdata.sizes.flip) #define mask (imgdata.sizes.mask) #define raw_stride (libraw_internal_data.unpacker_data.raw_stride) //imgdata.color #define white (imgdata.color.white) #define cam_mul (imgdata.color.cam_mul) #define pre_mul (imgdata.color.pre_mul) #define cmatrix (imgdata.color.cmatrix) #define rgb_cam (imgdata.color.rgb_cam) #ifndef SRC_USES_CURVE #define curve (imgdata.color.curve) #endif #ifndef SRC_USES_BLACK #define black (imgdata.color.black) #define cblack (imgdata.color.cblack) #endif #define maximum (imgdata.color.maximum) #define channel_maximum (imgdata.color.channel_maximum) #define profile_length (imgdata.color.profile_length) #define color_flags (imgdata.color.color_flags) #define ph1 (imgdata.color.phase_one_data) #define flash_used (imgdata.color.flash_used) #define canon_ev (imgdata.color.canon_ev) #define model2 (imgdata.color.model2) //imgdata.thumbnail #define thumb_width (imgdata.thumbnail.twidth) #define thumb_height (imgdata.thumbnail.theight) #define thumb_length (imgdata.thumbnail.tlength) //imgdata.others #define iso_speed (imgdata.other.iso_speed) #define shutter (imgdata.other.shutter) #define aperture (imgdata.other.aperture) #define focal_len (imgdata.other.focal_len) #define timestamp (imgdata.other.timestamp) #define shot_order (imgdata.other.shot_order) #define gpsdata (imgdata.other.gpsdata) #define desc (imgdata.other.desc) #define artist (imgdata.other.artist) #define FujiCropMode (imgdata.makernotes.fuji.CropMode) //imgdata.output #define greybox (imgdata.params.greybox) #define cropbox (imgdata.params.cropbox) #define aber (imgdata.params.aber) #define gamm (imgdata.params.gamm) #define user_mul (imgdata.params.user_mul) #define shot_select (imgdata.rawparams.shot_select) #define bright (imgdata.params.bright) #define threshold (imgdata.params.threshold) #define half_size (imgdata.params.half_size) #define four_color_rgb (imgdata.params.four_color_rgb) #define highlight (imgdata.params.highlight) #define use_auto_wb (imgdata.params.use_auto_wb) #define use_camera_wb (imgdata.params.use_camera_wb) #define use_camera_matrix (imgdata.params.use_camera_matrix) #define output_color (imgdata.params.output_color) #define output_bps (imgdata.params.output_bps) #define gamma_16bit (imgdata.params.gamma_16bit) #define output_tiff (imgdata.params.output_tiff) #define med_passes (imgdata.params.med_passes) #define no_auto_bright (imgdata.params.no_auto_bright) #define auto_bright_thr (imgdata.params.auto_bright_thr) #define use_fuji_rotate (imgdata.params.use_fuji_rotate) #define filtering_mode (imgdata.params.filtering_mode) // DCB #define dcb_iterations (imgdata.params.iterations) #define dcb_enhance_fl (imgdata.params.dcb_enhance) #define fbdd_noiserd (imgdata.params.fbdd_noiserd) //libraw_internal_data.internal_data #define meta_data (libraw_internal_data.internal_data.meta_data) #define ifp libraw_internal_data.internal_data.input #define ifname ((char*)libraw_internal_data.internal_data.input->fname()) #define ofp libraw_internal_data.internal_data.output #define profile_offset (libraw_internal_data.internal_data.profile_offset) #define thumb_offset (libraw_internal_data.internal_data.toffset) #define pana_black (libraw_internal_data.internal_data.pana_black) //libraw_internal_data.internal_output_params #define mix_green (libraw_internal_data.internal_output_params.mix_green) #define raw_color (libraw_internal_data.internal_output_params.raw_color) #define use_gamma (libraw_internal_data.internal_output_params.use_gamma) #define zero_is_bad (libraw_internal_data.internal_output_params.zero_is_bad) #ifndef SRC_USES_SHRINK #define shrink (libraw_internal_data.internal_output_params.shrink) #endif #define fuji_width (libraw_internal_data.internal_output_params.fuji_width) #define thumb_format (libraw_internal_data.unpacker_data.thumb_format) //libraw_internal_data.output_data #define histogram (libraw_internal_data.output_data.histogram) #define oprof (libraw_internal_data.output_data.oprof) //libraw_internal_data.identify_data #define exif_cfa (libraw_internal_data.identify_data.olympus_exif_cfa) #define unique_id (libraw_internal_data.identify_data.unique_id) #define OlyID (libraw_internal_data.identify_data.OlyID) #define tiff_nifds (libraw_internal_data.identify_data.tiff_nifds) #define tiff_flip (libraw_internal_data.identify_data.tiff_flip) #define metadata_blocks (libraw_internal_data.identify_data.metadata_blocks) //libraw_internal_data.unpacker_data #define order (libraw_internal_data.unpacker_data.order) #define data_error (libraw_internal_data.unpacker_data.data_error) #define cr2_slice (libraw_internal_data.unpacker_data.cr2_slice) #define sraw_mul (libraw_internal_data.unpacker_data.sraw_mul) #define kodak_cbpp (libraw_internal_data.unpacker_data.kodak_cbpp) #define strip_offset (libraw_internal_data.unpacker_data.strip_offset) #define data_offset (libraw_internal_data.unpacker_data.data_offset) #define data_size (libraw_internal_data.unpacker_data.data_size) #define meta_offset (libraw_internal_data.unpacker_data.meta_offset) #define meta_length (libraw_internal_data.unpacker_data.meta_length) #define thumb_misc (libraw_internal_data.unpacker_data.thumb_misc) #define fuji_layout (libraw_internal_data.unpacker_data.fuji_layout) #define tiff_samples (libraw_internal_data.unpacker_data.tiff_samples) #define tiff_bps (libraw_internal_data.unpacker_data.tiff_bps) #define tiff_compress (libraw_internal_data.unpacker_data.tiff_compress) #define tiff_sampleformat (libraw_internal_data.unpacker_data.tiff_sampleformat) #define zero_after_ff (libraw_internal_data.unpacker_data.zero_after_ff) #define tile_width (libraw_internal_data.unpacker_data.tile_width) #define tile_length (libraw_internal_data.unpacker_data.tile_length) #define load_flags (libraw_internal_data.unpacker_data.load_flags) #define pana_encoding (libraw_internal_data.unpacker_data.pana_encoding) #define pana_bpp (libraw_internal_data.unpacker_data.pana_bpp) #define CM_found (libraw_internal_data.unpacker_data.CM_found) #define is_NikonTransfer (libraw_internal_data.unpacker_data.is_NikonTransfer) #define is_Olympus (libraw_internal_data.unpacker_data.is_Olympus) #define OlympusDNG_SubDirOffsetValid (libraw_internal_data.unpacker_data.OlympusDNG_SubDirOffsetValid) #define is_Sony (libraw_internal_data.unpacker_data.is_Sony) #define is_PentaxRicohMakernotes (libraw_internal_data.unpacker_data.is_PentaxRicohMakernotes) #define is_pana_raw (libraw_internal_data.unpacker_data.is_pana_raw) #ifdef LIBRAW_IO_REDEFINED #define fread(ptr,size,n,stream) stream->read(ptr,size,n) #define fseek(stream,o,w) stream->seek(o,w) #define fseeko(stream,o,w) stream->seek(o,w) #define ftell(stream) stream->tell() #define ftello(stream) stream->tell() #define feof(stream) stream->eof() #ifdef getc #undef getc #endif #define getc(stream) stream->get_char() #define fgetc(stream) stream->get_char() #define fgetcb(stream) stream->get_char_buf() #define fgets(str,n,stream) stream->gets(str,n) #define fscanf(stream,fmt,ptr) stream->scanf_one(fmt,ptr) #endif #endif LibRaw-0.21.4/internal/x3f_tools.h000066400000000000000000000350431477673233700167130ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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). */ /* Library for accessing X3F Files ---------------------------------------------------------------- BSD-style License ---------------------------------------------------------------- * Copyright (c) 2010, Roland Karlsson (roland@proxel.se) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the organization nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY ROLAND KARLSSON ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL ROLAND KARLSSON BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef X3F_TOOLS_H #define X3F_TOOLS_H #include #include #include #include #include #include "../libraw/libraw_datastream.h" /* From X3F_IO.H */ #define SIZE_UNIQUE_IDENTIFIER 16 #define SIZE_WHITE_BALANCE 32 #define SIZE_COLOR_MODE 32 #define NUM_EXT_DATA_2_1 32 #define NUM_EXT_DATA_3_0 64 #define NUM_EXT_DATA NUM_EXT_DATA_3_0 #define X3F_VERSION(MAJ, MIN) (uint32_t)(((MAJ) << 16) + MIN) #define X3F_VERSION_2_0 X3F_VERSION(2, 0) #define X3F_VERSION_2_1 X3F_VERSION(2, 1) #define X3F_VERSION_2_2 X3F_VERSION(2, 2) #define X3F_VERSION_2_3 X3F_VERSION(2, 3) #define X3F_VERSION_3_0 X3F_VERSION(3, 0) #define X3F_VERSION_4_0 X3F_VERSION(4, 0) /* Main file identifier */ #define X3F_FOVb (uint32_t)(0x62564f46) /* Directory identifier */ #define X3F_SECd (uint32_t)(0x64434553) /* Property section identifiers */ #define X3F_PROP (uint32_t)(0x504f5250) #define X3F_SECp (uint32_t)(0x70434553) /* Image section identifiers */ #define X3F_IMAG (uint32_t)(0x46414d49) #define X3F_IMA2 (uint32_t)(0x32414d49) #define X3F_SECi (uint32_t)(0x69434553) /* CAMF section identifiers */ #define X3F_CAMF (uint32_t)(0x464d4143) #define X3F_SECc (uint32_t)(0x63434553) /* CAMF entry identifiers */ #define X3F_CMbP (uint32_t)(0x50624d43) #define X3F_CMbT (uint32_t)(0x54624d43) #define X3F_CMbM (uint32_t)(0x4d624d43) #define X3F_CMb (uint32_t)(0x00624d43) /* SDQ section identifiers ? - TODO */ #define X3F_SPPA (uint32_t)(0x41505053) #define X3F_SECs (uint32_t)(0x73434553) #define X3F_IMAGE_THUMB_PLAIN (uint32_t)(0x00020003) #define X3F_IMAGE_THUMB_HUFFMAN (uint32_t)(0x0002000b) #define X3F_IMAGE_THUMB_JPEG (uint32_t)(0x00020012) #define X3F_IMAGE_THUMB_SDQ (uint32_t)(0x00020019) /* SDQ ? - TODO */ #define X3F_IMAGE_RAW_HUFFMAN_X530 (uint32_t)(0x00030005) #define X3F_IMAGE_RAW_HUFFMAN_10BIT (uint32_t)(0x00030006) #define X3F_IMAGE_RAW_TRUE (uint32_t)(0x0003001e) #define X3F_IMAGE_RAW_MERRILL (uint32_t)(0x0001001e) #define X3F_IMAGE_RAW_QUATTRO (uint32_t)(0x00010023) #define X3F_IMAGE_RAW_SDQ (uint32_t)(0x00010025) #define X3F_IMAGE_RAW_SDQH (uint32_t)(0x00010027) #define X3F_IMAGE_RAW_SDQH2 (uint32_t)(0x00010029) #define X3F_IMAGE_HEADER_SIZE 28 #define X3F_CAMF_HEADER_SIZE 28 #define X3F_PROPERTY_LIST_HEADER_SIZE 24 typedef uint16_t utf16_t; typedef int bool_t; typedef enum x3f_extended_types_e { X3F_EXT_TYPE_NONE = 0, X3F_EXT_TYPE_EXPOSURE_ADJUST = 1, X3F_EXT_TYPE_CONTRAST_ADJUST = 2, X3F_EXT_TYPE_SHADOW_ADJUST = 3, X3F_EXT_TYPE_HIGHLIGHT_ADJUST = 4, X3F_EXT_TYPE_SATURATION_ADJUST = 5, X3F_EXT_TYPE_SHARPNESS_ADJUST = 6, X3F_EXT_TYPE_RED_ADJUST = 7, X3F_EXT_TYPE_GREEN_ADJUST = 8, X3F_EXT_TYPE_BLUE_ADJUST = 9, X3F_EXT_TYPE_FILL_LIGHT_ADJUST = 10 } x3f_extended_types_t; typedef struct x3f_property_s { /* Read from file */ uint32_t name_offset; uint32_t value_offset; /* Computed */ utf16_t *name; /* 0x0000 terminated UTF 16 */ utf16_t *value; /* 0x0000 terminated UTF 16 */ } x3f_property_t; typedef struct x3f_property_table_s { uint32_t size; x3f_property_t *element; } x3f_property_table_t; typedef struct x3f_property_list_s { /* 2.0 Fields */ uint32_t num_properties; uint32_t character_format; uint32_t reserved; uint32_t total_length; x3f_property_table_t property_table; void *data; uint32_t data_size; } x3f_property_list_t; typedef struct x3f_table8_s { uint32_t size; uint8_t *element; } x3f_table8_t; typedef struct x3f_table16_s { uint32_t size; uint16_t *element; } x3f_table16_t; typedef struct x3f_table32_s { uint32_t size; uint32_t *element; } x3f_table32_t; typedef struct { uint8_t *data; /* Pointer to actual image data */ void *buf; /* Pointer to allocated buffer for free() */ uint32_t rows; uint32_t columns; uint32_t channels; uint32_t row_stride; } x3f_area8_t; typedef struct { uint16_t *data; /* Pointer to actual image data */ void *buf; /* Pointer to allocated buffer for free() */ uint32_t rows; uint32_t columns; uint32_t channels; uint32_t row_stride; } x3f_area16_t; #define UNDEFINED_LEAF 0xffffffff typedef struct x3f_huffnode_s { struct x3f_huffnode_s *branch[2]; uint32_t leaf; } x3f_huffnode_t; typedef struct x3f_hufftree_s { uint32_t free_node_index; /* Free node index in huffman tree array */ uint32_t total_node_index; x3f_huffnode_t *nodes; /* Coding tree */ } x3f_hufftree_t; typedef struct x3f_true_huffman_element_s { uint8_t code_size; uint8_t code; } x3f_true_huffman_element_t; typedef struct x3f_true_huffman_s { uint32_t size; x3f_true_huffman_element_t *element; } x3f_true_huffman_t; /* 0=bottom, 1=middle, 2=top */ #define TRUE_PLANES 3 typedef struct x3f_true_s { uint16_t seed[TRUE_PLANES]; /* Always 512,512,512 */ uint16_t unknown; /* Always 0 */ x3f_true_huffman_t table; /* Huffman table - zero terminated. size is the number of leaves plus 1.*/ x3f_table32_t plane_size; /* Size of the 3 planes */ uint8_t *plane_address[TRUE_PLANES]; /* computed offset to the planes */ x3f_hufftree_t tree; /* Coding tree */ x3f_area16_t x3rgb16; /* 3x16 bit X3-RGB data */ } x3f_true_t; typedef struct x3f_quattro_s { struct { uint16_t columns; uint16_t rows; } plane[TRUE_PLANES]; uint32_t unknown; bool_t quattro_layout; x3f_area16_t top16; /* Container for the bigger top layer */ } x3f_quattro_t; typedef struct x3f_huffman_s { x3f_table16_t mapping; /* Value Mapping = X3F lossy compression */ x3f_table32_t table; /* Coding Table */ x3f_hufftree_t tree; /* Coding tree */ x3f_table32_t row_offsets; /* Row offsets */ x3f_area8_t rgb8; /* 3x8 bit RGB data */ x3f_area16_t x3rgb16; /* 3x16 bit X3-RGB data */ } x3f_huffman_t; typedef struct x3f_image_data_s { /* 2.0 Fields */ /* ------------------------------------------------------------------ */ /* Known combinations of type and format are: 1-6, 2-3, 2-11, 2-18, 3-6 */ uint32_t type; /* 1 = RAW X3 (SD1) 2 = thumbnail or maybe just RGB 3 = RAW X3 */ uint32_t format; /* 3 = 3x8 bit pixmap 6 = 3x10 bit huffman with map table 11 = 3x8 bit huffman 18 = JPEG */ uint32_t type_format; /* type<<16 + format */ /* ------------------------------------------------------------------ */ uint32_t columns; /* width / row size in pixels */ uint32_t rows; /* height */ uint32_t row_stride; /* row size in bytes */ /* NULL if not used */ x3f_huffman_t *huffman; /* Huffman help data */ x3f_true_t *tru; /* TRUE help data */ x3f_quattro_t *quattro; /* Quattro help data */ void *data; /* Take from file if NULL. Otherwise, this is the actual data bytes in the file. */ uint32_t data_size; } x3f_image_data_t; typedef struct camf_dim_entry_s { uint32_t size; uint32_t name_offset; uint32_t n; /* 0,1,2,3... */ char *name; } camf_dim_entry_t; typedef enum { M_FLOAT, M_INT, M_UINT } matrix_type_t; typedef struct camf_entry_s { /* pointer into decoded data */ void *entry; /* entry header */ uint32_t id; uint32_t version; uint32_t entry_size; uint32_t name_offset; uint32_t value_offset; /* computed values */ char *name_address; void *value_address; uint32_t name_size; uint32_t value_size; /* extracted values for explicit CAMF entry types*/ uint32_t text_size; char *text; uint32_t property_num; char **property_name; uint8_t **property_value; uint32_t matrix_dim; camf_dim_entry_t *matrix_dim_entry; /* Offset, pointer and size and type of raw data */ uint32_t matrix_type; uint32_t matrix_data_off; void *matrix_data; uint32_t matrix_element_size; /* Pointer and type of copied data */ matrix_type_t matrix_decoded_type; void *matrix_decoded; /* Help data to try to estimate element size */ uint32_t matrix_elements; uint32_t matrix_used_space; double matrix_estimated_element_size; } camf_entry_t; typedef struct camf_entry_table_s { uint32_t size; camf_entry_t *element; } camf_entry_table_t; typedef struct x3f_camf_typeN_s { uint32_t val0; uint32_t val1; uint32_t val2; uint32_t val3; } x3f_camf_typeN_t; typedef struct x3f_camf_type2_s { uint32_t reserved; uint32_t infotype; uint32_t infotype_version; uint32_t crypt_key; } x3f_camf_type2_t; typedef struct x3f_camf_type4_s { uint32_t decoded_data_size; uint32_t decode_bias; uint32_t block_size; uint32_t block_count; } x3f_camf_type4_t; typedef struct x3f_camf_type5_s { uint32_t decoded_data_size; uint32_t decode_bias; uint32_t unknown2; uint32_t unknown3; } x3f_camf_type5_t; typedef struct x3f_camf_s { /* Header info */ uint32_t type; union { x3f_camf_typeN_t tN; x3f_camf_type2_t t2; x3f_camf_type4_t t4; x3f_camf_type5_t t5; }; /* The encrypted raw data */ void *data; uint32_t data_size; /* Help data for type 4 Huffman compression */ x3f_true_huffman_t table; x3f_hufftree_t tree; uint8_t *decoding_start; uint32_t decoding_size; /* The decrypted data */ void *decoded_data; uint32_t decoded_data_size; /* Pointers into the decrypted data */ camf_entry_table_t entry_table; } x3f_camf_t; typedef struct x3f_directory_entry_header_s { uint32_t identifier; /* Should be ´SECp´, "SECi", ... */ uint32_t version; /* 0x00020001 is version 2.1 */ union { x3f_property_list_t property_list; x3f_image_data_t image_data; x3f_camf_t camf; } data_subsection; } x3f_directory_entry_header_t; typedef struct x3f_directory_entry_s { struct { uint32_t offset; uint32_t size; } input, output; uint32_t type; x3f_directory_entry_header_t header; } x3f_directory_entry_t; typedef struct x3f_directory_section_s { uint32_t identifier; /* Should be ´SECd´ */ uint32_t version; /* 0x00020001 is version 2.1 */ /* 2.0 Fields */ uint32_t num_directory_entries; x3f_directory_entry_t *directory_entry; } x3f_directory_section_t; typedef struct x3f_header_s { /* 2.0 Fields */ uint32_t identifier; /* Should be ´FOVb´ */ uint32_t version; /* 0x00020001 means 2.1 */ uint8_t unique_identifier[SIZE_UNIQUE_IDENTIFIER]; uint32_t mark_bits; uint32_t columns; /* Columns and rows ... */ uint32_t rows; /* ... before rotation */ uint32_t rotation; /* 0, 90, 180, 270 */ char white_balance[SIZE_WHITE_BALANCE]; /* Introduced in 2.1 */ char color_mode[SIZE_COLOR_MODE]; /* Introduced in 2.3 */ /* Introduced in 2.1 and extended from 32 to 64 in 3.0 */ uint8_t extended_types[NUM_EXT_DATA]; /* x3f_extended_types_t */ float extended_data[NUM_EXT_DATA]; /* 32 bits, but do type differ? */ } x3f_header_t; typedef struct x3f_info_s { char *error; struct { LibRaw_abstract_datastream *file; /* Use if more data is needed */ } input, output; } x3f_info_t; typedef struct x3f_s { x3f_info_t info; x3f_header_t header; x3f_directory_section_t directory_section; } x3f_t; typedef enum x3f_return_e { X3F_OK = 0, X3F_ARGUMENT_ERROR = 1, X3F_INFILE_ERROR = 2, X3F_OUTFILE_ERROR = 3, X3F_INTERNAL_ERROR = 4 } x3f_return_t; x3f_return_t x3f_delete(x3f_t *x3f); /* Hacky external flags */ /* --------------------------------------------------------------------- */ extern int legacy_offset; extern bool_t auto_legacy_offset; /* --------------------------------------------------------------------- */ /* Huffman Decode Macros */ /* --------------------------------------------------------------------- */ #define HUF_TREE_MAX_LENGTH 27 #define HUF_TREE_MAX_NODES(_leaves) ((HUF_TREE_MAX_LENGTH + 1) * (_leaves)) #define HUF_TREE_GET_LENGTH(_v) (((_v) >> 27) & 0x1f) #define HUF_TREE_GET_CODE(_v) ((_v)&0x07ffffff) x3f_t *x3f_new_from_file(LibRaw_abstract_datastream *infile); x3f_return_t x3f_delete(x3f_t *x3f); x3f_directory_entry_t *x3f_get_raw(x3f_t *x3f); x3f_directory_entry_t *x3f_get_thumb_plain(x3f_t *x3f); x3f_return_t x3f_load_data(x3f_t *x3f, x3f_directory_entry_t *DE); x3f_directory_entry_t *x3f_get_thumb_huffman(x3f_t *x3f); x3f_directory_entry_t *x3f_get_thumb_jpeg(x3f_t *x3f); x3f_directory_entry_t *x3f_get_camf(x3f_t *x3f); x3f_directory_entry_t *x3f_get_prop(x3f_t *x3f); /* extern */ int64_t x3f_load_data_size(x3f_t *x3f, x3f_directory_entry_t *DE); #endif LibRaw-0.21.4/lib/000077500000000000000000000000001477673233700135475ustar00rootroot00000000000000LibRaw-0.21.4/lib/Makefile000066400000000000000000000000521477673233700152040ustar00rootroot00000000000000all: @(cd ..; make library) @echo Done LibRaw-0.21.4/libraw.pc.in000066400000000000000000000005211477673233700152100ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libraw Description: Raw image decoder library (non-thread-safe) Requires: @PACKAGE_REQUIRES@ Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lraw -lstdc++@PC_OPENMP@ Libs.private: @PACKAGE_LIBS_PRIVATE@ Cflags: -I${includedir}/libraw -I${includedir} LibRaw-0.21.4/libraw/000077500000000000000000000000001477673233700142615ustar00rootroot00000000000000LibRaw-0.21.4/libraw/libraw.h000066400000000000000000000434401477673233700157170ustar00rootroot00000000000000/* -*- C++ -*- * File: libraw.h * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8, 2008 * * LibRaw C++ interface * 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). */ #ifndef _LIBRAW_CLASS_H #define _LIBRAW_CLASS_H #ifdef __linux__ #define _FILE_OFFSET_BITS 64 #endif // Enable use old cinema cameras if USE_OLD_VIDEOCAMS defined #ifdef USE_OLD_VIDEOCAMS #define LIBRAW_OLD_VIDEO_SUPPORT #endif #ifndef LIBRAW_USE_DEPRECATED_IOSTREAMS_DATASTREAM #define LIBRAW_NO_IOSTREAMS_DATASTREAM #endif #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM /* maximum file size to use LibRaw_file_datastream (fully buffered) I/O */ #define LIBRAW_USE_STREAMS_DATASTREAM_MAXSIZE (250 * 1024L * 1024L) #endif #include #include #include #include #include /* better WIN32 defines */ /* better WIN32 defines */ #if defined(WIN32) || defined(_WIN32) /* Win32 API */ # ifndef LIBRAW_WIN32_CALLS # define LIBRAW_WIN32_CALLS # endif /* DLLs: Microsoft or Intel compiler */ # if defined(_MSC_VER) || defined(__INTEL_COMPILER) # ifndef LIBRAW_WIN32_DLLDEFS # define LIBRAW_WIN32_DLLDEFS # endif #endif /* wchar_t* API for std::filebuf */ # if (defined(_MSC_VER) && (_MSC_VER > 1310)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 910)) # ifndef LIBRAW_WIN32_UNICODEPATHS # define LIBRAW_WIN32_UNICODEPATHS # endif # elif _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T # ifndef LIBRAW_WIN32_UNICODEPATHS # define LIBRAW_WIN32_UNICODEPATHS # endif # elif defined(_LIBCPP_HAS_OPEN_WITH_WCHAR) # ifndef LIBRAW_WIN32_UNICODEPATHS # define LIBRAW_WIN32_UNICODEPATHS # endif # endif #endif #include "libraw_datastream.h" #include "libraw_types.h" #include "libraw_const.h" #include "libraw_internal.h" #include "libraw_alloc.h" #ifdef __cplusplus extern "C" { #endif DllDef const char *libraw_strerror(int errorcode); DllDef const char *libraw_strprogress(enum LibRaw_progress); /* LibRaw C API */ DllDef libraw_data_t *libraw_init(unsigned int flags); DllDef int libraw_open_file(libraw_data_t *, const char *); #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM DllDef int libraw_open_file_ex(libraw_data_t *, const char *, INT64 max_buff_sz); #endif #if defined(_WIN32) || defined(WIN32) DllDef int libraw_open_wfile(libraw_data_t *, const wchar_t *); #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM DllDef int libraw_open_wfile_ex(libraw_data_t *, const wchar_t *, INT64 max_buff_sz); #endif #endif DllDef int libraw_open_buffer(libraw_data_t *, const void *buffer, size_t size); DllDef int libraw_open_bayer(libraw_data_t *lr, unsigned char *data, unsigned datalen, ushort _raw_width, ushort _raw_height, ushort _left_margin, ushort _top_margin, ushort _right_margin, ushort _bottom_margin, unsigned char procflags, unsigned char bayer_battern, unsigned unused_bits, unsigned otherflags, unsigned black_level); DllDef int libraw_unpack(libraw_data_t *); DllDef int libraw_unpack_thumb(libraw_data_t *); DllDef int libraw_unpack_thumb_ex(libraw_data_t *,int); DllDef void libraw_recycle_datastream(libraw_data_t *); DllDef void libraw_recycle(libraw_data_t *); DllDef void libraw_close(libraw_data_t *); DllDef void libraw_subtract_black(libraw_data_t *); DllDef int libraw_raw2image(libraw_data_t *); DllDef void libraw_free_image(libraw_data_t *); /* version helpers */ DllDef const char *libraw_version(); DllDef int libraw_versionNumber(); /* Camera list */ DllDef const char **libraw_cameraList(); DllDef int libraw_cameraCount(); /* helpers */ DllDef void libraw_set_exifparser_handler(libraw_data_t *, exif_parser_callback cb, void *datap); DllDef void libraw_set_dataerror_handler(libraw_data_t *, data_callback func, void *datap); DllDef void libraw_set_progress_handler(libraw_data_t *, progress_callback cb, void *datap); DllDef const char *libraw_unpack_function_name(libraw_data_t *lr); DllDef int libraw_get_decoder_info(libraw_data_t *lr, libraw_decoder_info_t *d); DllDef int libraw_COLOR(libraw_data_t *, int row, int col); DllDef unsigned libraw_capabilities(); /* DCRAW compatibility */ DllDef int libraw_adjust_sizes_info_only(libraw_data_t *); DllDef int libraw_dcraw_ppm_tiff_writer(libraw_data_t *lr, const char *filename); DllDef int libraw_dcraw_thumb_writer(libraw_data_t *lr, const char *fname); DllDef int libraw_dcraw_process(libraw_data_t *lr); DllDef libraw_processed_image_t * libraw_dcraw_make_mem_image(libraw_data_t *lr, int *errc); DllDef libraw_processed_image_t * libraw_dcraw_make_mem_thumb(libraw_data_t *lr, int *errc); DllDef void libraw_dcraw_clear_mem(libraw_processed_image_t *); /* getters/setters used by 3DLut Creator */ DllDef void libraw_set_demosaic(libraw_data_t *lr, int value); DllDef void libraw_set_output_color(libraw_data_t *lr, int value); DllDef void libraw_set_adjust_maximum_thr(libraw_data_t *lr, float value); DllDef void libraw_set_user_mul(libraw_data_t *lr, int index, float val); DllDef void libraw_set_output_bps(libraw_data_t *lr, int value); DllDef void libraw_set_gamma(libraw_data_t *lr, int index, float value); DllDef void libraw_set_no_auto_bright(libraw_data_t *lr, int value); DllDef void libraw_set_bright(libraw_data_t *lr, float value); DllDef void libraw_set_highlight(libraw_data_t *lr, int value); DllDef void libraw_set_fbdd_noiserd(libraw_data_t *lr, int value); DllDef int libraw_get_raw_height(libraw_data_t *lr); DllDef int libraw_get_raw_width(libraw_data_t *lr); DllDef int libraw_get_iheight(libraw_data_t *lr); DllDef int libraw_get_iwidth(libraw_data_t *lr); DllDef float libraw_get_cam_mul(libraw_data_t *lr, int index); DllDef float libraw_get_pre_mul(libraw_data_t *lr, int index); DllDef float libraw_get_rgb_cam(libraw_data_t *lr, int index1, int index2); DllDef int libraw_get_color_maximum(libraw_data_t *lr); DllDef void libraw_set_output_tif(libraw_data_t *lr, int value); DllDef libraw_iparams_t *libraw_get_iparams(libraw_data_t *lr); DllDef libraw_lensinfo_t *libraw_get_lensinfo(libraw_data_t *lr); DllDef libraw_imgother_t *libraw_get_imgother(libraw_data_t *lr); #ifdef __cplusplus } #endif #ifdef __cplusplus class DllDef LibRaw { public: libraw_data_t imgdata; LibRaw(unsigned int flags = LIBRAW_OPTIONS_NONE); libraw_output_params_t *output_params_ptr() { return &imgdata.params; } #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM int open_file(const char *fname, INT64 max_buffered_sz = LIBRAW_USE_STREAMS_DATASTREAM_MAXSIZE); #if defined(_WIN32) || defined(WIN32) int open_file(const wchar_t *fname, INT64 max_buffered_sz = LIBRAW_USE_STREAMS_DATASTREAM_MAXSIZE); #endif #else int open_file(const char *fname); #if defined(_WIN32) || defined(WIN32) int open_file(const wchar_t *fname); #endif #endif int open_buffer(const void *buffer, size_t size); virtual int open_datastream(LibRaw_abstract_datastream *); virtual int open_bayer(const unsigned char *data, unsigned datalen, ushort _raw_width, ushort _raw_height, ushort _left_margin, ushort _top_margin, ushort _right_margin, ushort _bottom_margin, unsigned char procflags, unsigned char bayer_pattern, unsigned unused_bits, unsigned otherflags, unsigned black_level); int error_count() { return libraw_internal_data.unpacker_data.data_error; } void recycle_datastream(); int unpack(void); int unpack_thumb(void); int unpack_thumb_ex(int); int thumbOK(INT64 maxsz = -1); int adjust_sizes_info_only(void); int subtract_black(); int subtract_black_internal(); int raw2image(); int raw2image_ex(int do_subtract_black); void raw2image_start(); void free_image(); int adjust_maximum(); int adjust_to_raw_inset_crop(unsigned mask, float maxcrop = 0.55f); void set_exifparser_handler(exif_parser_callback cb, void *data) { callbacks.exifparser_data = data; callbacks.exif_cb = cb; } void set_dataerror_handler(data_callback func, void *data) { callbacks.datacb_data = data; callbacks.data_cb = func; } void set_progress_handler(progress_callback pcb, void *data) { callbacks.progresscb_data = data; callbacks.progress_cb = pcb; } static const char* cameramakeridx2maker(unsigned maker); int setMakeFromIndex(unsigned index); void convertFloatToInt(float dmin = 4096.f, float dmax = 32767.f, float dtarget = 16383.f); /* helpers */ static unsigned capabilities(); static const char *version(); static int versionNumber(); static const char **cameraList(); static int cameraCount(); static const char *strprogress(enum LibRaw_progress); static const char *strerror(int p); /* dcraw emulation */ int dcraw_ppm_tiff_writer(const char *filename); int dcraw_thumb_writer(const char *fname); int dcraw_process(void); /* information calls */ int is_fuji_rotated() { return libraw_internal_data.internal_output_params.fuji_width; } int is_sraw(); int sraw_midpoint(); int is_nikon_sraw(); int is_coolscan_nef(); int is_jpeg_thumb(); int is_floating_point(); int have_fpdata(); /* memory writers */ virtual libraw_processed_image_t *dcraw_make_mem_image(int *errcode = NULL); virtual libraw_processed_image_t *dcraw_make_mem_thumb(int *errcode = NULL); static void dcraw_clear_mem(libraw_processed_image_t *); /* Additional calls for make_mem_image */ void get_mem_image_format(int *width, int *height, int *colors, int *bps) const; int copy_mem_image(void *scan0, int stride, int bgr); /* free all internal data structures */ void recycle(); virtual ~LibRaw(void); int COLOR(int row, int col) { if (!imgdata.idata.filters) return 6; /* Special value 0+1+2+3 */ if (imgdata.idata.filters < 1000) return fcol(row, col); return libraw_internal_data.internal_output_params.fuji_width ? FCF(row, col) : FC(row, col); } int FC(int row, int col) { return (imgdata.idata.filters >> (((row << 1 & 14) | (col & 1)) << 1) & 3); } int fcol(int row, int col); const char *unpack_function_name(); virtual int get_decoder_info(libraw_decoder_info_t *d_info); libraw_internal_data_t *get_internal_data_pointer() { return &libraw_internal_data; } static float powf_lim(float a, float b, float limup) { return (b > limup || b < -limup) ? 0.f : powf(a, b); } static float libraw_powf64l(float a, float b) { return powf_lim(a, b, 64.f); } static unsigned sgetn(int n, uchar *s) { unsigned result = 0; while (n-- > 0) result = (result << 8) | (*s++); return result; } /* Phase one correction/subtractBL calls */ /* Returns libraw error code */ int phase_one_subtract_black(ushort *src, ushort *dest); int phase_one_correct(); int set_rawspeed_camerafile(char *filename); virtual void setCancelFlag(); virtual void clearCancelFlag(); virtual int adobe_coeff(unsigned, const char *, int internal_only = 0); void set_dng_host(void *); protected: static void *memmem(char *haystack, size_t haystacklen, char *needle, size_t needlelen); static char *strcasestr(char *h, const char *n); static size_t strnlen(const char *s, size_t n); #ifdef LIBRAW_NO_IOSTREAMS_DATASTREAM int libraw_openfile_tail(LibRaw_abstract_datastream *stream); #endif int is_curve_linear(); void checkCancel(); void cam_xyz_coeff(float _rgb_cam[3][4], double cam_xyz[4][3]); void phase_one_allocate_tempbuffer(); void phase_one_free_tempbuffer(); virtual int is_phaseone_compressed(); virtual int is_canon_600(); /* Hotspots */ virtual void copy_fuji_uncropped(unsigned short cblack[4], unsigned short *dmaxp); virtual void copy_bayer(unsigned short cblack[4], unsigned short *dmaxp); virtual void fuji_rotate(); virtual void convert_to_rgb_loop(float out_cam[3][4]); virtual void lin_interpolate_loop(int *code, int size); virtual void scale_colors_loop(float scale_mul[4]); /* Fujifilm compressed decoder public interface (to make parallel decoder) */ virtual void fuji_decode_loop(struct fuji_compressed_params *common_info, int count, INT64 *offsets, unsigned *sizes, uchar *q_bases); void fuji_decode_strip(struct fuji_compressed_params *info_common, int cur_block, INT64 raw_offset, unsigned size, uchar *q_bases); /* CR3 decoder public interface to make parallel decoder */ virtual void crxLoadDecodeLoop(void *, int); int crxDecodePlane(void *, uint32_t planeNumber); virtual void crxLoadFinalizeLoopE3(void *, int); void crxConvertPlaneLineDf(void *, int); int FCF(int row, int col) { int rr, cc; if (libraw_internal_data.unpacker_data.fuji_layout) { rr = libraw_internal_data.internal_output_params.fuji_width - 1 - col + (row >> 1); cc = col + ((row + 1) >> 1); } else { rr = libraw_internal_data.internal_output_params.fuji_width - 1 + row - (col >> 1); cc = row + ((col + 1) >> 1); } return FC(rr, cc); } void adjust_bl(); void *malloc(size_t t); void *calloc(size_t n, size_t t); void *realloc(void *p, size_t s); void free(void *p); void derror(); LibRaw_TLS *tls; libraw_internal_data_t libraw_internal_data; decode first_decode[2048], *second_decode, *free_decode; tiff_ifd_t tiff_ifd[LIBRAW_IFD_MAXCOUNT]; libraw_memmgr memmgr; libraw_callbacks_t callbacks; //void (LibRaw::*write_thumb)(); void (LibRaw::*write_fun)(); void (LibRaw::*load_raw)(); //void (LibRaw::*thumb_load_raw)(); void (LibRaw::*pentax_component_load_raw)(); void kodak_thumb_loader(); void write_thumb_ppm_tiff(FILE *); #ifdef USE_X3FTOOLS void x3f_thumb_loader(); INT64 x3f_thumb_size(); #endif int own_filtering_supported() { return 0; } void identify(); void initdata(); unsigned parse_custom_cameras(unsigned limit, libraw_custom_camera_t table[], char **list); void write_ppm_tiff(); void convert_to_rgb(); void remove_zeroes(); void crop_masked_pixels(); #ifndef NO_LCMS void apply_profile(const char *, const char *); #endif void pre_interpolate(); void border_interpolate(int border); void lin_interpolate(); void vng_interpolate(); void ppg_interpolate(); void cielab(ushort rgb[3], short lab[3]); void xtrans_interpolate(int); void ahd_interpolate(); void dht_interpolate(); void aahd_interpolate(); void dcb(int iterations, int dcb_enhance); void fbdd(int noiserd); void exp_bef(float expos, float preser); void bad_pixels(const char *); void subtract(const char *); void hat_transform(float *temp, float *base, int st, int size, int sc); void wavelet_denoise(); void scale_colors(); void median_filter(); void blend_highlights(); void recover_highlights(); void green_matching(); void stretch(); void jpeg_thumb_writer(FILE *tfp, char *thumb, int thumb_length); #if 0 void jpeg_thumb(); void ppm_thumb(); void ppm16_thumb(); void layer_thumb(); void rollei_thumb(); #endif void kodak_thumb_load_raw(); unsigned get4(); int flip_index(int row, int col); void gamma_curve(double pwr, double ts, int mode, int imax); void cubic_spline(const int *x_, const int *y_, const int len); /* RawSpeed data */ void *_rawspeed_camerameta; void *_rawspeed_decoder; void *_rawspeed3_handle; void fix_after_rawspeed(int bl); int try_rawspeed(); /* returns LIBRAW_SUCCESS on success */ /* Fast cancel flag */ long _exitflag; /* DNG SDK data */ void *dnghost; void *dngnegative; void *dngimage; int valid_for_dngsdk(); int try_dngsdk(); /* X3F data */ void *_x3f_data; /* keep it even if USE_X3FTOOLS is not defined to do not change sizeof(LibRaw)*/ int raw_was_read() { return imgdata.rawdata.raw_image || imgdata.rawdata.color4_image || imgdata.rawdata.color3_image || imgdata.rawdata.float_image || imgdata.rawdata.float3_image || imgdata.rawdata.float4_image; } #ifdef LIBRAW_LIBRARY_BUILD #include "internal/libraw_internal_funcs.h" #endif }; #ifdef LIBRAW_LIBRARY_BUILD ushort libraw_sget2_static(short _order, uchar *s); unsigned libraw_sget4_static(short _order, uchar *s); int libraw_tagtype_dataunit_bytes(int tagtype); double libraw_sgetreal_static(short _order, int type, uchar *s); float libraw_int_to_float (int i); #endif #ifdef LIBRAW_LIBRARY_BUILD #define RUN_CALLBACK(stage, iter, expect) \ if (callbacks.progress_cb) \ { \ int rr = (*callbacks.progress_cb)(callbacks.progresscb_data, stage, iter, \ expect); \ if (rr != 0) \ throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; \ } #endif #endif /* __cplusplus */ #endif /* _LIBRAW_CLASS_H */ LibRaw-0.21.4/libraw/libraw_alloc.h000066400000000000000000000060731477673233700170720ustar00rootroot00000000000000/* -*- C++ -*- * File: libraw_alloc.h * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Mar 22, 2008 * * LibRaw C++ interface * 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). */ #ifndef __LIBRAW_ALLOC_H #define __LIBRAW_ALLOC_H #include #include #include "libraw_const.h" #ifdef __cplusplus #define LIBRAW_MSIZE 512 class DllDef libraw_memmgr { public: libraw_memmgr(unsigned ee) : extra_bytes(ee) { size_t alloc_sz = LIBRAW_MSIZE * sizeof(void *); mems = (void **)::malloc(alloc_sz); memset(mems, 0, alloc_sz); } ~libraw_memmgr() { cleanup(); ::free(mems); } void *malloc(size_t sz) { #ifdef LIBRAW_USE_CALLOC_INSTEAD_OF_MALLOC void *ptr = ::calloc(sz + extra_bytes, 1); #else void *ptr = ::malloc(sz + extra_bytes); #endif mem_ptr(ptr); return ptr; } void *calloc(size_t n, size_t sz) { void *ptr = ::calloc(n + (extra_bytes + sz - 1) / (sz ? sz : 1), sz); mem_ptr(ptr); return ptr; } void *realloc(void *ptr, size_t newsz) { void *ret = ::realloc(ptr, newsz + extra_bytes); forget_ptr(ptr); mem_ptr(ret); return ret; } void free(void *ptr) { forget_ptr(ptr); ::free(ptr); } void cleanup(void) { for (int i = 0; i < LIBRAW_MSIZE; i++) if (mems[i]) { ::free(mems[i]); mems[i] = NULL; } } private: void **mems; unsigned extra_bytes; void mem_ptr(void *ptr) { #if defined(LIBRAW_USE_OPENMP) bool ok = false; /* do not return from critical section */ #endif #if defined(LIBRAW_USE_OPENMP) #pragma omp critical { #endif if (ptr) { for (int i = 0; i < LIBRAW_MSIZE - 1; i++) if (!mems[i]) { mems[i] = ptr; #if defined(LIBRAW_USE_OPENMP) ok = true; break; #else return; #endif } #ifdef LIBRAW_MEMPOOL_CHECK #if !defined(LIBRAW_USE_OPENMP) /* remember ptr in last mems item to be free'ed at cleanup */ if (!mems[LIBRAW_MSIZE - 1]) mems[LIBRAW_MSIZE - 1] = ptr; throw LIBRAW_EXCEPTION_MEMPOOL; #endif #endif } #if defined(LIBRAW_USE_OPENMP) } if(!ok) { if (!mems[LIBRAW_MSIZE - 1]) mems[LIBRAW_MSIZE - 1] = ptr; throw LIBRAW_EXCEPTION_MEMPOOL; } #endif } void forget_ptr(void *ptr) { #if defined(LIBRAW_USE_OPENMP) #pragma omp critical { #endif if (ptr) for (int i = 0; i < LIBRAW_MSIZE; i++) if (mems[i] == ptr) { mems[i] = NULL; break; } #if defined(LIBRAW_USE_OPENMP) } #endif } }; #endif /* C++ */ #endif LibRaw-0.21.4/libraw/libraw_const.h000066400000000000000000000605231477673233700171260ustar00rootroot00000000000000/* -*- C++ -*- * File: libraw_const.h * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8 , 2008 * LibRaw error codes 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). */ #ifndef _LIBRAW_ERRORS_H #define _LIBRAW_ERRORS_H #define LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD 0.75f #define LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD 0.01f /* limit allocation size, default is 2Gb */ #ifndef LIBRAW_MAX_ALLOC_MB_DEFAULT #define LIBRAW_MAX_ALLOC_MB_DEFAULT 2048L #endif #ifndef LIBRAW_MAX_PROFILE_SIZE_MB #define LIBRAW_MAX_PROFILE_SIZE_MB 256LL #endif #ifndef LIBRAW_MAX_NONDNG_RAW_FILE_SIZE #define LIBRAW_MAX_NONDNG_RAW_FILE_SIZE 2147483647ULL #endif #ifndef LIBRAW_MAX_DNG_RAW_FILE_SIZE #ifdef USE_DNGSDK #define LIBRAW_MAX_DNG_RAW_FILE_SIZE 4294967295ULL #else #define LIBRAW_MAX_DNG_RAW_FILE_SIZE 2147483647ULL #endif #endif /* limit thumbnail size, default is 512Mb*/ #ifndef LIBRAW_MAX_THUMBNAIL_MB #define LIBRAW_MAX_THUMBNAIL_MB 512L #endif /* Check if enough file space exists before tag read */ #ifndef LIBRAW_NO_IOSPACE_CHECK #define LIBRAW_IOSPACE_CHECK #endif #ifndef LIBRAW_NO_CR3_MEMPOOL #define LIBRAW_CR3_MEMPOOL #endif /* LibRaw uses own memory pool management, with LIBRAW_MSIZE (512) entries. It is enough for parsing/decoding non-damaged files, but may overflow on specially crafted files (eg. with many string values like XMP blocks. LIBRAW_MEMPOOL_CHECK define will result in error on pool overflow */ #ifndef LIBRAW_NO_MEMPOOL_CHECK #define LIBRAW_MEMPOOL_CHECK #endif #define LIBRAW_MAX_METADATA_BLOCKS 1024 #define LIBRAW_CBLACK_SIZE 4104 #define LIBRAW_IFD_MAXCOUNT 10 #define LIBRAW_THUMBNAIL_MAXCOUNT 8 #define LIBRAW_CRXTRACKS_MAXCOUNT 16 #define LIBRAW_AFDATA_MAXCOUNT 4 #define LIBRAW_AHD_TILE 512 #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM enum LibRaw_open_flags { LIBRAW_OPEN_BIGFILE=1, LIBRAW_OPEN_FILE= 1<<1 }; #endif enum LibRaw_openbayer_patterns { LIBRAW_OPENBAYER_RGGB = 0x94, LIBRAW_OPENBAYER_BGGR = 0x16, LIBRAW_OPENBAYER_GRBG = 0x61, LIBRAW_OPENBAYER_GBRG = 0x49 }; enum LibRaw_dngfields_marks { LIBRAW_DNGFM_FORWARDMATRIX = 1, LIBRAW_DNGFM_ILLUMINANT = 1 << 1, LIBRAW_DNGFM_COLORMATRIX = 1 << 2, LIBRAW_DNGFM_CALIBRATION = 1 << 3, LIBRAW_DNGFM_ANALOGBALANCE = 1 << 4, LIBRAW_DNGFM_BLACK = 1 << 5, LIBRAW_DNGFM_WHITE = 1 << 6, LIBRAW_DNGFM_OPCODE2 = 1 << 7, LIBRAW_DNGFM_LINTABLE = 1 << 8, LIBRAW_DNGFM_CROPORIGIN = 1 << 9, LIBRAW_DNGFM_CROPSIZE = 1 << 10, LIBRAW_DNGFM_PREVIEWCS = 1 << 11, LIBRAW_DNGFM_ASSHOTNEUTRAL = 1 << 12, LIBRAW_DNGFM_BASELINEEXPOSURE = 1 << 13, LIBRAW_DNGFM_LINEARRESPONSELIMIT = 1 << 14, LIBRAW_DNGFM_USERCROP = 1 << 15, LIBRAW_DNGFM_OPCODE1 = 1 << 16, LIBRAW_DNGFM_OPCODE3 = 1 << 17, }; enum LibRaw_As_Shot_WB_Applied_codes { LIBRAW_ASWB_APPLIED = 1, LIBRAW_ASWB_CANON = 2, LIBRAW_ASWB_NIKON = 4, LIBRAW_ASWB_NIKON_SRAW = 8, LIBRAW_ASWB_PENTAX = 16 }; #define tagtypeIs(typex) (type == typex) enum LibRaw_ExifTagTypes { LIBRAW_EXIFTAG_TYPE_UNKNOWN = 0, LIBRAW_EXIFTAG_TYPE_BYTE = 1, LIBRAW_EXIFTAG_TYPE_ASCII = 2, LIBRAW_EXIFTAG_TYPE_SHORT = 3, LIBRAW_EXIFTAG_TYPE_LONG = 4, LIBRAW_EXIFTAG_TYPE_RATIONAL = 5, LIBRAW_EXIFTAG_TYPE_SBYTE = 6, LIBRAW_EXIFTAG_TYPE_UNDEFINED = 7, LIBRAW_EXIFTAG_TYPE_SSHORT = 8, LIBRAW_EXIFTAG_TYPE_SLONG = 9, LIBRAW_EXIFTAG_TYPE_SRATIONAL = 10, LIBRAW_EXIFTAG_TYPE_FLOAT = 11, LIBRAW_EXIFTAG_TYPE_DOUBLE = 12, LIBRAW_EXIFTAG_TYPE_IFD = 13, LIBRAW_EXIFTAG_TYPE_UNICODE = 14, LIBRAW_EXIFTAG_TYPE_COMPLEX = 15, LIBRAW_EXIFTAG_TYPE_LONG8 = 16, LIBRAW_EXIFTAG_TYPE_SLONG8 = 17, LIBRAW_EXIFTAG_TYPE_IFD8 = 18 }; #define LIBRAW_EXIFTOOLTAGTYPE_int8u LIBRAW_EXIFTAG_TYPE_BYTE #define LIBRAW_EXIFTOOLTAGTYPE_string LIBRAW_EXIFTAG_TYPE_ASCII #define LIBRAW_EXIFTOOLTAGTYPE_int16u LIBRAW_EXIFTAG_TYPE_SHORT #define LIBRAW_EXIFTOOLTAGTYPE_int32u LIBRAW_EXIFTAG_TYPE_LONG #define LIBRAW_EXIFTOOLTAGTYPE_rational64u LIBRAW_EXIFTAG_TYPE_RATIONAL #define LIBRAW_EXIFTOOLTAGTYPE_int8s LIBRAW_EXIFTAG_TYPE_SBYTE #define LIBRAW_EXIFTOOLTAGTYPE_undef LIBRAW_EXIFTAG_TYPE_UNDEFINED #define LIBRAW_EXIFTOOLTAGTYPE_binary LIBRAW_EXIFTAG_TYPE_UNDEFINED #define LIBRAW_EXIFTOOLTAGTYPE_int16s LIBRAW_EXIFTAG_TYPE_SSHORT #define LIBRAW_EXIFTOOLTAGTYPE_int32s LIBRAW_EXIFTAG_TYPE_SLONG #define LIBRAW_EXIFTOOLTAGTYPE_rational64s LIBRAW_EXIFTAG_TYPE_SRATIONAL #define LIBRAW_EXIFTOOLTAGTYPE_float LIBRAW_EXIFTAG_TYPE_FLOAT #define LIBRAW_EXIFTOOLTAGTYPE_double LIBRAW_EXIFTAG_TYPE_DOUBLE #define LIBRAW_EXIFTOOLTAGTYPE_ifd LIBRAW_EXIFTAG_TYPE_IFD #define LIBRAW_EXIFTOOLTAGTYPE_unicode LIBRAW_EXIFTAG_TYPE_UNICODE #define LIBRAW_EXIFTOOLTAGTYPE_complex LIBRAW_EXIFTAG_TYPE_COMPLEX #define LIBRAW_EXIFTOOLTAGTYPE_int64u LIBRAW_EXIFTAG_TYPE_LONG8 #define LIBRAW_EXIFTOOLTAGTYPE_int64s LIBRAW_EXIFTAG_TYPE_SLONG8 #define LIBRAW_EXIFTOOLTAGTYPE_ifd64 LIBRAW_EXIFTAG_TYPE_IFD8 #define LIBRAW_LENS_NOT_SET 0xffffffffffffffffULL enum LibRaw_whitebalance_code { // clang-format off /* EXIF light sources 12 = FL-D; Daylight fluorescent (D 5700K – 7100K) (F1,F5) 13 = FL-N; Day white fluorescent (N 4600K – 5400K) (F7,F8) 14 = FL-W; Cool white fluorescent (W 3900K – 4500K) (F2,F6, office, store, warehouse) 15 = FL-WW; White fluorescent (WW 3200K – 3700K) (F3, residential) 16 = FL-L; Soft/Warm white fluorescent (L 2600K - 3250K) (F4, kitchen, bath) */ //clang-format on LIBRAW_WBI_Unknown = 0, LIBRAW_WBI_Daylight = 1, LIBRAW_WBI_Fluorescent = 2, LIBRAW_WBI_Tungsten = 3, LIBRAW_WBI_Flash = 4, LIBRAW_WBI_FineWeather = 9, LIBRAW_WBI_Cloudy = 10, LIBRAW_WBI_Shade = 11, LIBRAW_WBI_FL_D = 12, LIBRAW_WBI_FL_N = 13, LIBRAW_WBI_FL_W = 14, LIBRAW_WBI_FL_WW = 15, LIBRAW_WBI_FL_L = 16, LIBRAW_WBI_Ill_A = 17, LIBRAW_WBI_Ill_B = 18, LIBRAW_WBI_Ill_C = 19, LIBRAW_WBI_D55 = 20, LIBRAW_WBI_D65 = 21, LIBRAW_WBI_D75 = 22, LIBRAW_WBI_D50 = 23, LIBRAW_WBI_StudioTungsten = 24, LIBRAW_WBI_Sunset = 64, LIBRAW_WBI_Underwater = 65, LIBRAW_WBI_FluorescentHigh = 66, LIBRAW_WBI_HT_Mercury = 67, LIBRAW_WBI_AsShot = 81, LIBRAW_WBI_Auto = 82, LIBRAW_WBI_Custom = 83, LIBRAW_WBI_Auto1 = 85, LIBRAW_WBI_Auto2 = 86, LIBRAW_WBI_Auto3 = 87, LIBRAW_WBI_Auto4 = 88, LIBRAW_WBI_Custom1 = 90, LIBRAW_WBI_Custom2 = 91, LIBRAW_WBI_Custom3 = 92, LIBRAW_WBI_Custom4 = 93, LIBRAW_WBI_Custom5 = 94, LIBRAW_WBI_Custom6 = 95, LIBRAW_WBI_PC_Set1 = 96, LIBRAW_WBI_PC_Set2 = 97, LIBRAW_WBI_PC_Set3 = 98, LIBRAW_WBI_PC_Set4 = 99, LIBRAW_WBI_PC_Set5 = 100, LIBRAW_WBI_Measured = 110, LIBRAW_WBI_BW = 120, LIBRAW_WBI_Kelvin = 254, LIBRAW_WBI_Other = 255, LIBRAW_WBI_None = 0xffff }; enum LibRaw_MultiExposure_related { LIBRAW_ME_NONE = 0, LIBRAW_ME_SIMPLE = 1, LIBRAW_ME_OVERLAY = 2, LIBRAW_ME_HDR = 3 }; enum LibRaw_dng_processing { LIBRAW_DNG_NONE = 0, LIBRAW_DNG_FLOAT = 1, LIBRAW_DNG_LINEAR = 2, LIBRAW_DNG_DEFLATE = 4, LIBRAW_DNG_XTRANS = 8, LIBRAW_DNG_OTHER = 16, LIBRAW_DNG_8BIT = 32, /*LIBRAW_DNG_LARGERANGE=64,*/ /* more than 16 bit integer */ LIBRAW_DNG_ALL = LIBRAW_DNG_FLOAT | LIBRAW_DNG_LINEAR | LIBRAW_DNG_DEFLATE | LIBRAW_DNG_XTRANS | LIBRAW_DNG_8BIT | LIBRAW_DNG_OTHER /* |LIBRAW_DNG_LARGERANGE */, LIBRAW_DNG_DEFAULT = LIBRAW_DNG_FLOAT | LIBRAW_DNG_LINEAR | LIBRAW_DNG_DEFLATE | LIBRAW_DNG_8BIT }; enum LibRaw_output_flags { LIBRAW_OUTPUT_FLAGS_NONE = 0, LIBRAW_OUTPUT_FLAGS_PPMMETA = 1 }; enum LibRaw_runtime_capabilities { LIBRAW_CAPS_RAWSPEED = 1, LIBRAW_CAPS_DNGSDK = 1<<1, LIBRAW_CAPS_GPRSDK = 1<<2, LIBRAW_CAPS_UNICODEPATHS = 1<<3, LIBRAW_CAPS_X3FTOOLS = 1<<4, LIBRAW_CAPS_RPI6BY9 = 1<<5, LIBRAW_CAPS_ZLIB = 1<<6, LIBRAW_CAPS_JPEG = 1<<7, LIBRAW_CAPS_RAWSPEED3 = 1<<8, LIBRAW_CAPS_RAWSPEED_BITS = 1<<9, }; enum LibRaw_colorspace { LIBRAW_COLORSPACE_NotFound = 0, LIBRAW_COLORSPACE_sRGB, LIBRAW_COLORSPACE_AdobeRGB, LIBRAW_COLORSPACE_WideGamutRGB, LIBRAW_COLORSPACE_ProPhotoRGB, LIBRAW_COLORSPACE_ICC, LIBRAW_COLORSPACE_Uncalibrated, // Tag 0x0001 InteropIndex containing "R03" + LIBRAW_COLORSPACE_Uncalibrated = Adobe RGB LIBRAW_COLORSPACE_CameraLinearUniWB, LIBRAW_COLORSPACE_CameraLinear, LIBRAW_COLORSPACE_CameraGammaUniWB, LIBRAW_COLORSPACE_CameraGamma, LIBRAW_COLORSPACE_MonochromeLinear, LIBRAW_COLORSPACE_MonochromeGamma, LIBRAW_COLORSPACE_Unknown = 255 }; enum LibRaw_cameramaker_index { LIBRAW_CAMERAMAKER_Unknown = 0, LIBRAW_CAMERAMAKER_Agfa, LIBRAW_CAMERAMAKER_Alcatel, LIBRAW_CAMERAMAKER_Apple, LIBRAW_CAMERAMAKER_Aptina, LIBRAW_CAMERAMAKER_AVT, LIBRAW_CAMERAMAKER_Baumer, LIBRAW_CAMERAMAKER_Broadcom, LIBRAW_CAMERAMAKER_Canon, LIBRAW_CAMERAMAKER_Casio, LIBRAW_CAMERAMAKER_CINE, LIBRAW_CAMERAMAKER_Clauss, LIBRAW_CAMERAMAKER_Contax, LIBRAW_CAMERAMAKER_Creative, LIBRAW_CAMERAMAKER_DJI, LIBRAW_CAMERAMAKER_DXO, LIBRAW_CAMERAMAKER_Epson, LIBRAW_CAMERAMAKER_Foculus, LIBRAW_CAMERAMAKER_Fujifilm, LIBRAW_CAMERAMAKER_Generic, LIBRAW_CAMERAMAKER_Gione, LIBRAW_CAMERAMAKER_GITUP, LIBRAW_CAMERAMAKER_Google, LIBRAW_CAMERAMAKER_GoPro, LIBRAW_CAMERAMAKER_Hasselblad, LIBRAW_CAMERAMAKER_HTC, LIBRAW_CAMERAMAKER_I_Mobile, LIBRAW_CAMERAMAKER_Imacon, LIBRAW_CAMERAMAKER_JK_Imaging, LIBRAW_CAMERAMAKER_Kodak, LIBRAW_CAMERAMAKER_Konica, LIBRAW_CAMERAMAKER_Leaf, LIBRAW_CAMERAMAKER_Leica, LIBRAW_CAMERAMAKER_Lenovo, LIBRAW_CAMERAMAKER_LG, LIBRAW_CAMERAMAKER_Logitech, LIBRAW_CAMERAMAKER_Mamiya, LIBRAW_CAMERAMAKER_Matrix, LIBRAW_CAMERAMAKER_Meizu, LIBRAW_CAMERAMAKER_Micron, LIBRAW_CAMERAMAKER_Minolta, LIBRAW_CAMERAMAKER_Motorola, LIBRAW_CAMERAMAKER_NGM, LIBRAW_CAMERAMAKER_Nikon, LIBRAW_CAMERAMAKER_Nokia, LIBRAW_CAMERAMAKER_Olympus, LIBRAW_CAMERAMAKER_OmniVison, LIBRAW_CAMERAMAKER_Panasonic, LIBRAW_CAMERAMAKER_Parrot, LIBRAW_CAMERAMAKER_Pentax, LIBRAW_CAMERAMAKER_PhaseOne, LIBRAW_CAMERAMAKER_PhotoControl, LIBRAW_CAMERAMAKER_Photron, LIBRAW_CAMERAMAKER_Pixelink, LIBRAW_CAMERAMAKER_Polaroid, LIBRAW_CAMERAMAKER_RED, LIBRAW_CAMERAMAKER_Ricoh, LIBRAW_CAMERAMAKER_Rollei, LIBRAW_CAMERAMAKER_RoverShot, LIBRAW_CAMERAMAKER_Samsung, LIBRAW_CAMERAMAKER_Sigma, LIBRAW_CAMERAMAKER_Sinar, LIBRAW_CAMERAMAKER_SMaL, LIBRAW_CAMERAMAKER_Sony, LIBRAW_CAMERAMAKER_ST_Micro, LIBRAW_CAMERAMAKER_THL, LIBRAW_CAMERAMAKER_VLUU, LIBRAW_CAMERAMAKER_Xiaomi, LIBRAW_CAMERAMAKER_XIAOYI, LIBRAW_CAMERAMAKER_YI, LIBRAW_CAMERAMAKER_Yuneec, LIBRAW_CAMERAMAKER_Zeiss, LIBRAW_CAMERAMAKER_OnePlus, LIBRAW_CAMERAMAKER_ISG, LIBRAW_CAMERAMAKER_VIVO, LIBRAW_CAMERAMAKER_HMD_Global, LIBRAW_CAMERAMAKER_HUAWEI, LIBRAW_CAMERAMAKER_RaspberryPi, LIBRAW_CAMERAMAKER_OmDigital, // Insert additional indexes here LIBRAW_CAMERAMAKER_TheLastOne }; enum LibRaw_camera_mounts { LIBRAW_MOUNT_Unknown = 0, LIBRAW_MOUNT_Alpa, LIBRAW_MOUNT_C, /* C-mount */ LIBRAW_MOUNT_Canon_EF_M, LIBRAW_MOUNT_Canon_EF_S, LIBRAW_MOUNT_Canon_EF, LIBRAW_MOUNT_Canon_RF, LIBRAW_MOUNT_Contax_N, LIBRAW_MOUNT_Contax645, LIBRAW_MOUNT_FT, /* original 4/3 */ LIBRAW_MOUNT_mFT, /* micro 4/3 */ LIBRAW_MOUNT_Fuji_GF, /* Fujifilm GFX cameras, G mount */ LIBRAW_MOUNT_Fuji_GX, /* Fujifilm GX680 */ LIBRAW_MOUNT_Fuji_X, LIBRAW_MOUNT_Hasselblad_H, /* Hasselblad Hn cameras, HC & HCD lenses */ LIBRAW_MOUNT_Hasselblad_V, LIBRAW_MOUNT_Hasselblad_XCD, /* Hasselblad Xn cameras, XCD lenses */ LIBRAW_MOUNT_Leica_M, /* Leica rangefinder bayonet */ LIBRAW_MOUNT_Leica_R, /* Leica SLRs, 'R' for reflex */ LIBRAW_MOUNT_Leica_S, /* LIBRAW_FORMAT_LeicaS 'MF' */ LIBRAW_MOUNT_Leica_SL, /* lens, mounts on 'L' throat, FF */ LIBRAW_MOUNT_Leica_TL, /* lens, mounts on 'L' throat, APS-C */ LIBRAW_MOUNT_LPS_L, /* Leica/Panasonic/Sigma camera mount, takes L, SL and TL lenses */ LIBRAW_MOUNT_Mamiya67, /* Mamiya RB67, RZ67 */ LIBRAW_MOUNT_Mamiya645, LIBRAW_MOUNT_Minolta_A, LIBRAW_MOUNT_Nikon_CX, /* used in 'Nikon 1' series */ LIBRAW_MOUNT_Nikon_F, LIBRAW_MOUNT_Nikon_Z, LIBRAW_MOUNT_PhaseOne_iXM_MV, LIBRAW_MOUNT_PhaseOne_iXM_RS, LIBRAW_MOUNT_PhaseOne_iXM, LIBRAW_MOUNT_Pentax_645, LIBRAW_MOUNT_Pentax_K, LIBRAW_MOUNT_Pentax_Q, LIBRAW_MOUNT_RicohModule, LIBRAW_MOUNT_Rollei_bayonet, /* Rollei Hy-6: Leaf AFi, Sinar Hy6- models */ LIBRAW_MOUNT_Samsung_NX_M, LIBRAW_MOUNT_Samsung_NX, LIBRAW_MOUNT_Sigma_X3F, LIBRAW_MOUNT_Sony_E, LIBRAW_MOUNT_LF, LIBRAW_MOUNT_DigitalBack, LIBRAW_MOUNT_FixedLens, LIBRAW_MOUNT_IL_UM, /* Interchangeable lens, mount unknown */ LIBRAW_MOUNT_TheLastOne }; enum LibRaw_camera_formats { LIBRAW_FORMAT_Unknown = 0, LIBRAW_FORMAT_APSC, LIBRAW_FORMAT_FF, LIBRAW_FORMAT_MF, LIBRAW_FORMAT_APSH, LIBRAW_FORMAT_1INCH, LIBRAW_FORMAT_1div2p3INCH, /* 1/2.3" */ LIBRAW_FORMAT_1div1p7INCH, /* 1/1.7" */ LIBRAW_FORMAT_FT, /* sensor size in FT & mFT cameras */ LIBRAW_FORMAT_CROP645, /* 44x33mm */ LIBRAW_FORMAT_LeicaS, /* 'MF' Leicas */ LIBRAW_FORMAT_645, LIBRAW_FORMAT_66, LIBRAW_FORMAT_69, LIBRAW_FORMAT_LF, LIBRAW_FORMAT_Leica_DMR, LIBRAW_FORMAT_67, LIBRAW_FORMAT_SigmaAPSC, /* DP1, DP2, SD15, SD14, SD10, SD9 */ LIBRAW_FORMAT_SigmaMerrill, /* SD1, 'SD1 Merrill', 'DP1 Merrill', 'DP2 Merrill' */ LIBRAW_FORMAT_SigmaAPSH, /* 'sd Quattro H' */ LIBRAW_FORMAT_3648, /* DALSA FTF4052C (Mamiya ZD) */ LIBRAW_FORMAT_68, /* Fujifilm GX680 */ LIBRAW_FORMAT_TheLastOne }; enum LibRawImageAspects { LIBRAW_IMAGE_ASPECT_UNKNOWN = 0, LIBRAW_IMAGE_ASPECT_OTHER = 1, LIBRAW_IMAGE_ASPECT_MINIMAL_REAL_ASPECT_VALUE = 99, /* 1:10*/ LIBRAW_IMAGE_ASPECT_MAXIMAL_REAL_ASPECT_VALUE = 10000, /* 10: 1*/ // Value: width / height * 1000 LIBRAW_IMAGE_ASPECT_3to2 = (1000 * 3)/2, LIBRAW_IMAGE_ASPECT_1to1 = 1000, LIBRAW_IMAGE_ASPECT_4to3 = (1000 * 4)/ 3, LIBRAW_IMAGE_ASPECT_16to9 = (1000 * 16) / 9, //LIBRAW_IMAGE_ASPECT_6to6, // what is the difference with 1:1 ? LIBRAW_IMAGE_ASPECT_5to4 = (1000 * 5) / 4, LIBRAW_IMAGE_ASPECT_7to6 = (1000 * 7) / 6, LIBRAW_IMAGE_ASPECT_6to5 = (1000 * 6) / 5, LIBRAW_IMAGE_ASPECT_7to5 = (1000 * 7) / 5 }; enum LibRaw_lens_focal_types { LIBRAW_FT_UNDEFINED = 0, LIBRAW_FT_PRIME_LENS = 1, LIBRAW_FT_ZOOM_LENS = 2, LIBRAW_FT_ZOOM_LENS_CONSTANT_APERTURE = 3, LIBRAW_FT_ZOOM_LENS_VARIABLE_APERTURE = 4 }; enum LibRaw_Canon_RecordModes { LIBRAW_Canon_RecordMode_UNDEFINED = 0, LIBRAW_Canon_RecordMode_JPEG, LIBRAW_Canon_RecordMode_CRW_THM, LIBRAW_Canon_RecordMode_AVI_THM, LIBRAW_Canon_RecordMode_TIF, LIBRAW_Canon_RecordMode_TIF_JPEG, LIBRAW_Canon_RecordMode_CR2, LIBRAW_Canon_RecordMode_CR2_JPEG, LIBRAW_Canon_RecordMode_UNKNOWN, LIBRAW_Canon_RecordMode_MOV, LIBRAW_Canon_RecordMode_MP4, LIBRAW_Canon_RecordMode_CRM, LIBRAW_Canon_RecordMode_CR3, LIBRAW_Canon_RecordMode_CR3_JPEG, LIBRAW_Canon_RecordMode_HEIF, LIBRAW_Canon_RecordMode_CR3_HEIF, LIBRAW_Canon_RecordMode_TheLastOne }; enum LibRaw_minolta_storagemethods { LIBRAW_MINOLTA_UNPACKED = 0x52, LIBRAW_MINOLTA_PACKED = 0x59 }; enum LibRaw_minolta_bayerpatterns { LIBRAW_MINOLTA_RGGB = 0x01, LIBRAW_MINOLTA_G2BRG1 = 0x04 }; enum LibRaw_sony_cameratypes { LIBRAW_SONY_DSC = 1, LIBRAW_SONY_DSLR = 2, LIBRAW_SONY_NEX = 3, LIBRAW_SONY_SLT = 4, LIBRAW_SONY_ILCE = 5, LIBRAW_SONY_ILCA = 6, LIBRAW_SONY_CameraType_UNKNOWN = 0xffff }; enum LibRaw_Sony_0x2010_Type { LIBRAW_SONY_Tag2010None = 0, LIBRAW_SONY_Tag2010a, LIBRAW_SONY_Tag2010b, LIBRAW_SONY_Tag2010c, LIBRAW_SONY_Tag2010d, LIBRAW_SONY_Tag2010e, LIBRAW_SONY_Tag2010f, LIBRAW_SONY_Tag2010g, LIBRAW_SONY_Tag2010h, LIBRAW_SONY_Tag2010i }; enum LibRaw_Sony_0x9050_Type { LIBRAW_SONY_Tag9050None = 0, LIBRAW_SONY_Tag9050a, LIBRAW_SONY_Tag9050b, LIBRAW_SONY_Tag9050c }; enum LIBRAW_SONY_FOCUSMODEmodes { LIBRAW_SONY_FOCUSMODE_MF = 0, LIBRAW_SONY_FOCUSMODE_AF_S = 2, LIBRAW_SONY_FOCUSMODE_AF_C = 3, LIBRAW_SONY_FOCUSMODE_AF_A = 4, LIBRAW_SONY_FOCUSMODE_DMF = 6, LIBRAW_SONY_FOCUSMODE_AF_D = 7, LIBRAW_SONY_FOCUSMODE_AF = 101, LIBRAW_SONY_FOCUSMODE_PERMANENT_AF = 104, LIBRAW_SONY_FOCUSMODE_SEMI_MF = 105, LIBRAW_SONY_FOCUSMODE_UNKNOWN = -1 }; enum LibRaw_KodakSensors { LIBRAW_Kodak_UnknownSensor = 0, LIBRAW_Kodak_M1 = 1, LIBRAW_Kodak_M15 = 2, LIBRAW_Kodak_M16 = 3, LIBRAW_Kodak_M17 = 4, LIBRAW_Kodak_M2 = 5, LIBRAW_Kodak_M23 = 6, LIBRAW_Kodak_M24 = 7, LIBRAW_Kodak_M3 = 8, LIBRAW_Kodak_M5 = 9, LIBRAW_Kodak_M6 = 10, LIBRAW_Kodak_C14 = 11, LIBRAW_Kodak_X14 = 12, LIBRAW_Kodak_M11 = 13 }; enum LibRaw_HasselbladFormatCodes { LIBRAW_HF_Unknown = 0, LIBRAW_HF_3FR, LIBRAW_HF_FFF, LIBRAW_HF_Imacon, LIBRAW_HF_HasselbladDNG, LIBRAW_HF_AdobeDNG, LIBRAW_HF_AdobeDNG_fromPhocusDNG }; enum LibRaw_rawspecial_t { LIBRAW_RAWSPECIAL_SONYARW2_NONE = 0, LIBRAW_RAWSPECIAL_SONYARW2_BASEONLY = 1, LIBRAW_RAWSPECIAL_SONYARW2_DELTAONLY = 1 << 1, LIBRAW_RAWSPECIAL_SONYARW2_DELTAZEROBASE = 1 << 2, LIBRAW_RAWSPECIAL_SONYARW2_DELTATOVALUE = 1 << 3, LIBRAW_RAWSPECIAL_SONYARW2_ALLFLAGS = LIBRAW_RAWSPECIAL_SONYARW2_BASEONLY + LIBRAW_RAWSPECIAL_SONYARW2_DELTAONLY + LIBRAW_RAWSPECIAL_SONYARW2_DELTAZEROBASE + LIBRAW_RAWSPECIAL_SONYARW2_DELTATOVALUE, LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATERG = 1<<4, LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATEAF = 1 << 5, LIBRAW_RAWSPECIAL_SRAW_NO_RGB = 1 << 6, LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE = 1 << 7 }; enum LibRaw_rawspeed_bits_t { LIBRAW_RAWSPEEDV1_USE = 1, LIBRAW_RAWSPEEDV1_FAILONUNKNOWN = 1 << 1, LIBRAW_RAWSPEEDV1_IGNOREERRORS = 1 << 2, /* bits 3-7 are reserved*/ LIBRAW_RAWSPEEDV3_USE = 1 << 8, LIBRAW_RAWSPEEDV3_FAILONUNKNOWN = 1 << 9, LIBRAW_RAWSPEEDV3_IGNOREERRORS = 1 << 10, }; enum LibRaw_processing_options { LIBRAW_RAWOPTIONS_PENTAX_PS_ALLFRAMES = 1, LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT = 1 << 1, LIBRAW_RAWOPTIONS_ARQ_SKIP_CHANNEL_SWAP = 1 << 2, LIBRAW_RAWOPTIONS_NO_ROTATE_FOR_KODAK_THUMBNAILS = 1 << 3, // LIBRAW_RAWOPTIONS_USE_DNG_DEFAULT_CROP = 1 << 4, LIBRAW_RAWOPTIONS_USE_PPM16_THUMBS = 1 << 5, LIBRAW_RAWOPTIONS_DONT_CHECK_DNG_ILLUMINANT = 1 << 6, LIBRAW_RAWOPTIONS_DNGSDK_ZEROCOPY = 1 << 7, LIBRAW_RAWOPTIONS_ZEROFILTERS_FOR_MONOCHROMETIFFS = 1 << 8, LIBRAW_RAWOPTIONS_DNG_ADD_ENHANCED = 1 << 9, LIBRAW_RAWOPTIONS_DNG_ADD_PREVIEWS = 1 << 10, LIBRAW_RAWOPTIONS_DNG_PREFER_LARGEST_IMAGE = 1 << 11, LIBRAW_RAWOPTIONS_DNG_STAGE2 = 1 << 12, LIBRAW_RAWOPTIONS_DNG_STAGE3 = 1 << 13, LIBRAW_RAWOPTIONS_DNG_ALLOWSIZECHANGE = 1 << 14, LIBRAW_RAWOPTIONS_DNG_DISABLEWBADJUST = 1 << 15, LIBRAW_RAWOPTIONS_PROVIDE_NONSTANDARD_WB = 1 << 16, LIBRAW_RAWOPTIONS_CAMERAWB_FALLBACK_TO_DAYLIGHT = 1 << 17, LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_KNOWN_VENDORS = 1 << 18, LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_ALL_VENDORS = 1 << 19, LIBRAW_RAWOPTIONS_DNG_STAGE2_IFPRESENT = 1 << 20, LIBRAW_RAWOPTIONS_DNG_STAGE3_IFPRESENT = 1 << 21, LIBRAW_RAWOPTIONS_DNG_ADD_MASKS = 1 << 22, LIBRAW_RAWOPTIONS_CANON_IGNORE_MAKERNOTES_ROTATION = 1 << 23 }; enum LibRaw_decoder_flags { LIBRAW_DECODER_HASCURVE = 1 << 4, LIBRAW_DECODER_SONYARW2 = 1 << 5, LIBRAW_DECODER_TRYRAWSPEED = 1 << 6, LIBRAW_DECODER_OWNALLOC = 1 << 7, LIBRAW_DECODER_FIXEDMAXC = 1 << 8, LIBRAW_DECODER_ADOBECOPYPIXEL = 1 << 9, LIBRAW_DECODER_LEGACY_WITH_MARGINS = 1 << 10, LIBRAW_DECODER_3CHANNEL = 1 << 11, LIBRAW_DECODER_SINAR4SHOT = 1 << 11, LIBRAW_DECODER_FLATDATA = 1 << 12, LIBRAW_DECODER_FLAT_BG2_SWAPPED = 1<<13, LIBRAW_DECODER_UNSUPPORTED_FORMAT = 1 << 14, LIBRAW_DECODER_NOTSET = 1 << 15, LIBRAW_DECODER_TRYRAWSPEED3 = 1 << 16 }; #define LIBRAW_XTRANS 9 enum LibRaw_constructor_flags { LIBRAW_OPTIONS_NONE = 0, LIBRAW_OPTIONS_NO_DATAERR_CALLBACK = 1 << 1, /* Compatibility w/ years old typo */ LIBRAW_OPIONS_NO_DATAERR_CALLBACK = LIBRAW_OPTIONS_NO_DATAERR_CALLBACK }; enum LibRaw_warnings { LIBRAW_WARN_NONE = 0, LIBRAW_WARN_BAD_CAMERA_WB = 1 << 2, LIBRAW_WARN_NO_METADATA = 1 << 3, LIBRAW_WARN_NO_JPEGLIB = 1 << 4, LIBRAW_WARN_NO_EMBEDDED_PROFILE = 1 << 5, LIBRAW_WARN_NO_INPUT_PROFILE = 1 << 6, LIBRAW_WARN_BAD_OUTPUT_PROFILE = 1 << 7, LIBRAW_WARN_NO_BADPIXELMAP = 1 << 8, LIBRAW_WARN_BAD_DARKFRAME_FILE = 1 << 9, LIBRAW_WARN_BAD_DARKFRAME_DIM = 1 << 10, #ifdef LIBRAW_OLD_VIDEO_SUPPORT LIBRAW_WARN_NO_JASPER = 1 << 11, #endif LIBRAW_WARN_RAWSPEED_PROBLEM = 1 << 12, LIBRAW_WARN_RAWSPEED_UNSUPPORTED = 1 << 13, LIBRAW_WARN_RAWSPEED_PROCESSED = 1 << 14, LIBRAW_WARN_FALLBACK_TO_AHD = 1 << 15, LIBRAW_WARN_PARSEFUJI_PROCESSED = 1 << 16, LIBRAW_WARN_DNGSDK_PROCESSED = 1 << 17, LIBRAW_WARN_DNG_IMAGES_REORDERED = 1 << 18, LIBRAW_WARN_DNG_STAGE2_APPLIED = 1 << 19, LIBRAW_WARN_DNG_STAGE3_APPLIED = 1 << 20, LIBRAW_WARN_RAWSPEED3_PROBLEM = 1 << 21, LIBRAW_WARN_RAWSPEED3_UNSUPPORTED = 1 << 22, LIBRAW_WARN_RAWSPEED3_PROCESSED = 1 << 23, LIBRAW_WARN_RAWSPEED3_NOTLISTED = 1 << 24 }; enum LibRaw_exceptions { LIBRAW_EXCEPTION_NONE = 0, LIBRAW_EXCEPTION_ALLOC = 1, LIBRAW_EXCEPTION_DECODE_RAW = 2, LIBRAW_EXCEPTION_DECODE_JPEG = 3, LIBRAW_EXCEPTION_IO_EOF = 4, LIBRAW_EXCEPTION_IO_CORRUPT = 5, LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK = 6, LIBRAW_EXCEPTION_BAD_CROP = 7, LIBRAW_EXCEPTION_IO_BADFILE = 8, LIBRAW_EXCEPTION_DECODE_JPEG2000 = 9, LIBRAW_EXCEPTION_TOOBIG = 10, LIBRAW_EXCEPTION_MEMPOOL = 11, LIBRAW_EXCEPTION_UNSUPPORTED_FORMAT = 12 }; enum LibRaw_progress { LIBRAW_PROGRESS_START = 0, LIBRAW_PROGRESS_OPEN = 1, LIBRAW_PROGRESS_IDENTIFY = 1 << 1, LIBRAW_PROGRESS_SIZE_ADJUST = 1 << 2, LIBRAW_PROGRESS_LOAD_RAW = 1 << 3, LIBRAW_PROGRESS_RAW2_IMAGE = 1 << 4, LIBRAW_PROGRESS_REMOVE_ZEROES = 1 << 5, LIBRAW_PROGRESS_BAD_PIXELS = 1 << 6, LIBRAW_PROGRESS_DARK_FRAME = 1 << 7, LIBRAW_PROGRESS_FOVEON_INTERPOLATE = 1 << 8, LIBRAW_PROGRESS_SCALE_COLORS = 1 << 9, LIBRAW_PROGRESS_PRE_INTERPOLATE = 1 << 10, LIBRAW_PROGRESS_INTERPOLATE = 1 << 11, LIBRAW_PROGRESS_MIX_GREEN = 1 << 12, LIBRAW_PROGRESS_MEDIAN_FILTER = 1 << 13, LIBRAW_PROGRESS_HIGHLIGHTS = 1 << 14, LIBRAW_PROGRESS_FUJI_ROTATE = 1 << 15, LIBRAW_PROGRESS_FLIP = 1 << 16, LIBRAW_PROGRESS_APPLY_PROFILE = 1 << 17, LIBRAW_PROGRESS_CONVERT_RGB = 1 << 18, LIBRAW_PROGRESS_STRETCH = 1 << 19, /* reserved */ LIBRAW_PROGRESS_STAGE20 = 1 << 20, LIBRAW_PROGRESS_STAGE21 = 1 << 21, LIBRAW_PROGRESS_STAGE22 = 1 << 22, LIBRAW_PROGRESS_STAGE23 = 1 << 23, LIBRAW_PROGRESS_STAGE24 = 1 << 24, LIBRAW_PROGRESS_STAGE25 = 1 << 25, LIBRAW_PROGRESS_STAGE26 = 1 << 26, LIBRAW_PROGRESS_STAGE27 = 1 << 27, LIBRAW_PROGRESS_THUMB_LOAD = 1 << 28, LIBRAW_PROGRESS_TRESERVED1 = 1 << 29, LIBRAW_PROGRESS_TRESERVED2 = 1 << 30 }; #define LIBRAW_PROGRESS_THUMB_MASK 0x0fffffff enum LibRaw_errors { LIBRAW_SUCCESS = 0, LIBRAW_UNSPECIFIED_ERROR = -1, LIBRAW_FILE_UNSUPPORTED = -2, LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE = -3, LIBRAW_OUT_OF_ORDER_CALL = -4, LIBRAW_NO_THUMBNAIL = -5, LIBRAW_UNSUPPORTED_THUMBNAIL = -6, LIBRAW_INPUT_CLOSED = -7, LIBRAW_NOT_IMPLEMENTED = -8, LIBRAW_REQUEST_FOR_NONEXISTENT_THUMBNAIL = -9, LIBRAW_UNSUFFICIENT_MEMORY = -100007, LIBRAW_DATA_ERROR = -100008, LIBRAW_IO_ERROR = -100009, LIBRAW_CANCELLED_BY_CALLBACK = -100010, LIBRAW_BAD_CROP = -100011, LIBRAW_TOO_BIG = -100012, LIBRAW_MEMPOOL_OVERFLOW = -100013 }; #define LIBRAW_FATAL_ERROR(ec) ((ec) < -100000) enum LibRaw_internal_thumbnail_formats { LIBRAW_INTERNAL_THUMBNAIL_UNKNOWN = 0, LIBRAW_INTERNAL_THUMBNAIL_KODAK_THUMB = 1, LIBRAW_INTERNAL_THUMBNAIL_KODAK_YCBCR = 2, LIBRAW_INTERNAL_THUMBNAIL_KODAK_RGB = 3, LIBRAW_INTERNAL_THUMBNAIL_JPEG = 4, LIBRAW_INTERNAL_THUMBNAIL_LAYER, LIBRAW_INTERNAL_THUMBNAIL_ROLLEI, LIBRAW_INTERNAL_THUMBNAIL_PPM, LIBRAW_INTERNAL_THUMBNAIL_PPM16, LIBRAW_INTERNAL_THUMBNAIL_X3F, }; enum LibRaw_thumbnail_formats { LIBRAW_THUMBNAIL_UNKNOWN = 0, LIBRAW_THUMBNAIL_JPEG = 1, LIBRAW_THUMBNAIL_BITMAP = 2, LIBRAW_THUMBNAIL_BITMAP16 = 3, LIBRAW_THUMBNAIL_LAYER = 4, LIBRAW_THUMBNAIL_ROLLEI = 5, LIBRAW_THUMBNAIL_H265 = 6 }; enum LibRaw_image_formats { LIBRAW_IMAGE_JPEG = 1, LIBRAW_IMAGE_BITMAP = 2 }; #endif LibRaw-0.21.4/libraw/libraw_datastream.h000066400000000000000000000251201477673233700201170ustar00rootroot00000000000000/* -*- C -*- * File: libraw_datastream.h * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sun Jan 18 13:07:35 2009 * * LibRaw Data stream interface 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). */ #ifndef __LIBRAW_DATASTREAM_H #define __LIBRAW_DATASTREAM_H #include #include #include #include #ifndef __cplusplus #else /* __cplusplus */ #if defined _WIN32 #ifndef LIBRAW_NO_WINSOCK2 #include #endif #endif /* No unique_ptr on Apple ?? */ #if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) || \ (defined(_MSC_VER) && _MSVC_LANG >= 201103L) /* OK - use unique_ptr unless LIBRAW_USE_AUTOPTR defined externally*/ #else /* Force to use auto_ptr */ #ifndef LIBRAW_USE_AUTOPTR #define LIBRAW_USE_AUTOPTR #endif #endif #include "libraw_const.h" #include "libraw_types.h" #include #include #include #if defined(_WIN32) && (_MSC_VER) >= 1500 #define WIN32SECURECALLS #endif #ifdef USE_DNGSDK #if defined LIBRAW_WIN32_CALLS #define qWinOS 1 #define qMacOS 0 #elif defined(__APPLE__) #define qWinOS 0 #define qMacOS 1 #else /* define OS types for DNG here */ #endif #define qDNGXMPDocOps 0 #define qDNGUseLibJPEG 1 #define qDNGXMPFiles 0 #define qDNGExperimental 1 #define qDNGThreadSafe 1 #include "dng_stream.h" #endif /* DNGSDK */ #define IOERROR() \ do \ { \ throw LIBRAW_EXCEPTION_IO_EOF; \ } while (0) class LibRaw_buffer_datastream; class LibRaw_bit_buffer; class DllDef LibRaw_abstract_datastream { public: LibRaw_abstract_datastream() { }; virtual ~LibRaw_abstract_datastream(void) { } virtual int valid() = 0; virtual int read(void *, size_t, size_t) = 0; virtual int seek(INT64, int) = 0; virtual INT64 tell() = 0; virtual INT64 size() = 0; virtual int get_char() = 0; virtual char *gets(char *, int) = 0; virtual int scanf_one(const char *, void *) = 0; virtual int eof() = 0; #ifdef LIBRAW_OLD_VIDEO_SUPPORT virtual void *make_jas_stream() = 0; #endif virtual int jpeg_src(void *); virtual void buffering_off() {} /* reimplement in subclass to use parallel access in xtrans_load_raw() if * OpenMP is not used */ virtual int lock() { return 1; } /* success */ virtual void unlock() {} virtual const char *fname() { return NULL; }; #ifdef LIBRAW_WIN32_UNICODEPATHS virtual const wchar_t *wfname() { return NULL; }; #endif }; #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM #ifdef LIBRAW_WIN32_DLLDEFS #ifdef LIBRAW_USE_AUTOPTR template class DllDef std::auto_ptr; #else template class DllDef std::unique_ptr; #endif #endif class DllDef LibRaw_file_datastream : public LibRaw_abstract_datastream { protected: #ifdef LIBRAW_USE_AUTOPTR std::auto_ptr f; /* will close() automatically through dtor */ #else std::unique_ptr f; #endif std::string filename; INT64 _fsize; #ifdef LIBRAW_WIN32_UNICODEPATHS std::wstring wfilename; #endif FILE *jas_file; public: virtual ~LibRaw_file_datastream(); LibRaw_file_datastream(const char *fname); #ifdef LIBRAW_WIN32_UNICODEPATHS LibRaw_file_datastream(const wchar_t *fname); #endif #ifdef LIBRAW_OLD_VIDEO_SUPPORT virtual void *make_jas_stream(); #endif virtual int valid(); virtual int read(void *ptr, size_t size, size_t nmemb); virtual int eof(); virtual int seek(INT64 o, int whence); virtual INT64 tell(); virtual INT64 size() { return _fsize; } virtual int get_char() {return f->sbumpc();} virtual char *gets(char *str, int sz); virtual int scanf_one(const char *fmt, void *val); virtual const char *fname(); #ifdef LIBRAW_WIN32_UNICODEPATHS virtual const wchar_t *wfname(); #endif }; #endif #if defined (LIBRAW_NO_IOSTREAMS_DATASTREAM) && defined (LIBRAW_WIN32_CALLS) struct DllDef LibRaw_bufio_params { static int bufsize; static void set_bufsize(int bs); }; class buffer_t : public std::vector { public: INT64 _bstart, _bend; buffer_t() : std::vector(LibRaw_bufio_params::bufsize), _bstart(0), _bend(0) {} int charOReof(INT64 _fpos) { if (_bstart < 0LL || _bend < 0LL || _bend < _bstart || _fpos < 0LL) return -1; if ((_bend - _bstart) > (INT64)size()) return -1; if (_fpos >= _bstart && _fpos < _bend) return data()[_fpos - _bstart]; return -1; } bool contains(INT64 _fpos, INT64& contains) { if (_bstart < 0LL || _bend < 0LL || _bend < _bstart || _fpos < 0LL) { contains = 0; return false; } if ((_bend - _bstart) > (INT64)size()) { contains = 0; return false; } if (_fpos >= _bstart && _fpos < _bend) { contains = _bend - _fpos; return true; } contains = 0; return false; } }; class DllDef LibRaw_bigfile_buffered_datastream : public LibRaw_abstract_datastream { public: LibRaw_bigfile_buffered_datastream(const char *fname); #ifdef LIBRAW_WIN32_UNICODEPATHS LibRaw_bigfile_buffered_datastream(const wchar_t *fname); #endif virtual ~LibRaw_bigfile_buffered_datastream(); virtual int valid(); #ifdef LIBRAW_OLD_VIDEO_SUPPORT virtual void *make_jas_stream(); #endif virtual void buffering_off() { buffered = 0; } virtual int read(void *ptr, size_t size, size_t nmemb); virtual int eof(); virtual int seek(INT64 o, int whence); virtual INT64 tell(); virtual INT64 size() { return _fsize; } virtual char *gets(char *str, int sz); virtual int scanf_one(const char *fmt, void *val); virtual const char *fname(); #ifdef LIBRAW_WIN32_UNICODEPATHS virtual const wchar_t *wfname(); #endif virtual int get_char() { int r = iobuffers[0].charOReof(_fpos); if (r >= 0) { _fpos++; return r; } unsigned char c; r = read(&c, 1, 1); return r > 0 ? c : r; } protected: INT64 readAt(void *ptr, size_t size, INT64 off); bool fillBufferAt(int buf, INT64 off); int selectStringBuffer(INT64 len, INT64& contains); HANDLE fhandle; INT64 _fsize; INT64 _fpos; /* current file position; current buffer start position */ #ifdef LIBRAW_WIN32_UNICODEPATHS std::wstring wfilename; #endif std::string filename; buffer_t iobuffers[2]; int buffered; }; #endif class DllDef LibRaw_buffer_datastream : public LibRaw_abstract_datastream { public: LibRaw_buffer_datastream(const void *buffer, size_t bsize); virtual ~LibRaw_buffer_datastream(); virtual int valid(); #ifdef LIBRAW_OLD_VIDEO_SUPPORT virtual void *make_jas_stream(); #endif virtual int jpeg_src(void *jpegdata); virtual int read(void *ptr, size_t sz, size_t nmemb); virtual int eof(); virtual int seek(INT64 o, int whence); virtual INT64 tell(); virtual INT64 size() { return streamsize; } virtual char *gets(char *s, int sz); virtual int scanf_one(const char *fmt, void *val); virtual int get_char() { if (streampos >= streamsize) return -1; return buf[streampos++]; } private: unsigned char *buf; size_t streampos, streamsize; }; class DllDef LibRaw_bigfile_datastream : public LibRaw_abstract_datastream { public: LibRaw_bigfile_datastream(const char *fname); #ifdef LIBRAW_WIN32_UNICODEPATHS LibRaw_bigfile_datastream(const wchar_t *fname); #endif virtual ~LibRaw_bigfile_datastream(); virtual int valid(); #ifdef LIBRAW_OLD_VIDEO_SUPPORT virtual void *make_jas_stream(); #endif virtual int read(void *ptr, size_t size, size_t nmemb); virtual int eof(); virtual int seek(INT64 o, int whence); virtual INT64 tell(); virtual INT64 size() { return _fsize; } virtual char *gets(char *str, int sz); virtual int scanf_one(const char *fmt, void *val); virtual const char *fname(); #ifdef LIBRAW_WIN32_UNICODEPATHS virtual const wchar_t *wfname(); #endif virtual int get_char() { #ifndef LIBRAW_WIN32_CALLS return getc_unlocked(f); #else return fgetc(f); #endif } protected: FILE *f; std::string filename; INT64 _fsize; #ifdef LIBRAW_WIN32_UNICODEPATHS std::wstring wfilename; #endif }; #ifdef LIBRAW_WIN32_CALLS class DllDef LibRaw_windows_datastream : public LibRaw_buffer_datastream { public: /* ctor: high level constructor opens a file by name */ LibRaw_windows_datastream(const TCHAR *sFile); /* ctor: construct with a file handle - caller is responsible for closing the * file handle */ LibRaw_windows_datastream(HANDLE hFile); /* dtor: unmap and close the mapping handle */ virtual ~LibRaw_windows_datastream(); virtual INT64 size() { return cbView_; } protected: void Open(HANDLE hFile); inline void reconstruct_base() { /* this subterfuge is to overcome the private-ness of * LibRaw_buffer_datastream */ (LibRaw_buffer_datastream &)*this = LibRaw_buffer_datastream(pView_, (size_t)cbView_); } HANDLE hMap_; /* handle of the file mapping */ void *pView_; /* pointer to the mapped memory */ __int64 cbView_; /* size of the mapping in bytes */ }; #endif #ifdef USE_DNGSDK class libraw_dng_stream : public dng_stream { public: libraw_dng_stream(LibRaw_abstract_datastream *p) : dng_stream((dng_abort_sniffer *)NULL, kBigBufferSize, 0), parent_stream(p) { if (parent_stream) { parent_stream->buffering_off(); off = parent_stream->tell(); parent_stream->seek(0UL, SEEK_SET); /* seek to start */ } } ~libraw_dng_stream() { if (parent_stream) parent_stream->seek(off, SEEK_SET); } virtual uint64 DoGetLength() { if (parent_stream) return parent_stream->size(); return 0; } virtual void DoRead(void *data, uint32 count, uint64 offset) { if (parent_stream) { parent_stream->seek(offset, SEEK_SET); parent_stream->read(data, 1, count); } } private: libraw_dng_stream(const libraw_dng_stream &stream); libraw_dng_stream &operator=(const libraw_dng_stream &stream); LibRaw_abstract_datastream *parent_stream; INT64 off; }; #endif #endif /* cplusplus */ #endif LibRaw-0.21.4/libraw/libraw_internal.h000066400000000000000000000247361477673233700176220ustar00rootroot00000000000000/* -*- C++ -*- * File: libraw_internal.h * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8 , 2008 * * LibRaw internal data structures (not visible outside) 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). */ #ifndef _LIBRAW_INTERNAL_TYPES_H #define _LIBRAW_INTERNAL_TYPES_H #include #ifdef __cplusplus #include "libraw_datastream.h" #include "libraw_types.h" class LibRaw_TLS { public: struct { unsigned bitbuf; int vbits, reset; } getbits; struct { UINT64 bitbuf; int vbits; } ph1_bits; struct { unsigned pad[128], p; } sony_decrypt; struct { uchar buf[0x4002]; int vpos, padding; } pana_data; uchar jpeg_buffer[4096]; struct { float cbrt[0x10000], xyz_cam[3][4]; } ahd_data; void init() { getbits.bitbuf = 0; getbits.vbits = getbits.reset = 0; ph1_bits.bitbuf = 0; ph1_bits.vbits = 0; pana_data.vpos = 0; ahd_data.cbrt[0] = -2.0f; } }; class LibRaw_constants { public: static const float d65_white[3]; static const double xyz_rgb[3][3]; static const double xyzd50_srgb[3][3]; static const double rgb_rgb[3][3]; static const double adobe_rgb[3][3]; static const double wide_rgb[3][3]; static const double prophoto_rgb[3][3]; static const double aces_rgb[3][3]; static const double dcip3d65_rgb[3][3]; static const double rec2020_rgb[3][3]; }; #endif /* __cplusplus */ typedef struct { #ifndef __cplusplus struct #endif LibRaw_abstract_datastream *input; FILE *output; int input_internal; char *meta_data; INT64 profile_offset; INT64 toffset; unsigned pana_black[4]; } internal_data_t; #define LIBRAW_HISTOGRAM_SIZE 0x2000 typedef struct { int (*histogram)[LIBRAW_HISTOGRAM_SIZE]; unsigned *oprof; } output_data_t; typedef struct { unsigned olympus_exif_cfa; unsigned long long unique_id; unsigned long long OlyID; unsigned tiff_nifds; int tiff_flip; int metadata_blocks; } identify_data_t; typedef struct { uint32_t first; uint32_t count; uint32_t id; } crx_sample_to_chunk_t; // contents of tag CMP1 for relevant track in CR3 file typedef struct { int32_t version; int32_t f_width; int32_t f_height; int32_t tileWidth; int32_t tileHeight; int32_t nBits; int32_t nPlanes; int32_t cfaLayout; int32_t encType; int32_t imageLevels; int32_t hasTileCols; int32_t hasTileRows; int32_t mdatHdrSize; int32_t medianBits; // Not from header, but from datastream uint32_t MediaSize; INT64 MediaOffset; uint32_t MediaType; /* 1 -> /C/RAW, 2-> JPEG, 3-> CTMD metadata*/ crx_sample_to_chunk_t * stsc_data; /* samples to chunk */ uint32_t stsc_count; uint32_t sample_count; uint32_t sample_size; /* zero if not fixed sample size */ int32_t *sample_sizes; uint32_t chunk_count; INT64 *chunk_offsets; } crx_data_header_t; typedef struct { short order; ushort sraw_mul[4], cr2_slice[3]; unsigned kodak_cbpp; INT64 strip_offset, data_offset; INT64 meta_offset; INT64 exif_offset, exif_subdir_offset, ifd0_offset; unsigned data_size; unsigned meta_length; unsigned cr3_exif_length, cr3_ifd0_length; unsigned thumb_misc; enum LibRaw_internal_thumbnail_formats thumb_format; unsigned fuji_layout; unsigned tiff_samples; unsigned tiff_bps; unsigned tiff_compress; unsigned tiff_sampleformat; unsigned zero_after_ff; unsigned tile_width, tile_length, load_flags; unsigned data_error; int hasselblad_parser_flag; long long posRAFData; unsigned lenRAFData; int fuji_total_lines, fuji_total_blocks, fuji_block_width, fuji_bits, fuji_raw_type, fuji_lossless; int pana_encoding, pana_bpp; crx_data_header_t crx_header[LIBRAW_CRXTRACKS_MAXCOUNT]; int crx_track_selected; int crx_track_count; short CR3_CTMDtag; short CR3_Version; int CM_found; unsigned is_NikonTransfer; unsigned is_Olympus; int OlympusDNG_SubDirOffsetValid; unsigned is_Sony; unsigned is_pana_raw; unsigned is_PentaxRicohMakernotes; /* =1 for Ricoh software by Pentax, Camera DNG */ unsigned dng_frames[LIBRAW_IFD_MAXCOUNT*2]; /* bits: 0-7: shot_select, 8-15: IFD#, 16-31: low 16 bit of newsubfile type */ unsigned short raw_stride; } unpacker_data_t; typedef struct { internal_data_t internal_data; libraw_internal_output_params_t internal_output_params; output_data_t output_data; identify_data_t identify_data; unpacker_data_t unpacker_data; } libraw_internal_data_t; struct decode { struct decode *branch[2]; int leaf; }; struct tiff_ifd_t { int t_width, t_height, bps, comp, phint, offset, t_flip, samples, bytes, extrasamples; int t_tile_width, t_tile_length, sample_format, predictor; int rows_per_strip; int *strip_offsets, strip_offsets_count; int *strip_byte_counts, strip_byte_counts_count; unsigned t_filters; int t_vwidth, t_vheight, t_lm,t_tm; int t_fuji_width; float t_shutter; /* Per-IFD DNG fields */ INT64 opcode2_offset; INT64 lineartable_offset; int lineartable_len; libraw_dng_color_t dng_color[2]; libraw_dng_levels_t dng_levels; int newsubfiletype; }; struct jhead { int algo, bits, high, wide, clrs, sraw, psv, restart, vpred[6]; ushort quant[64], idct[64], *huff[20], *free[20], *row; }; struct libraw_tiff_tag { ushort tag, type; int count; union { char c[4]; short s[2]; int i; } val; }; struct tiff_hdr { ushort t_order, magic; int ifd; ushort pad, ntag; struct libraw_tiff_tag tag[23]; int nextifd; ushort pad2, nexif; struct libraw_tiff_tag exif[4]; ushort pad3, ngps; struct libraw_tiff_tag gpst[10]; short bps[4]; int rat[10]; unsigned gps[26]; char t_desc[512], t_make[64], t_model[64], soft[32], date[20], t_artist[64]; }; #ifdef DEBUG_STAGE_CHECKS #define CHECK_ORDER_HIGH(expected_stage) \ do \ { \ if ((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) >= \ expected_stage) \ { \ fprintf(stderr, "CHECK_HIGH: check %d >= %d\n", \ imgdata.progress_flags &LIBRAW_PROGRESS_THUMB_MASK, \ expected_stage); \ return LIBRAW_OUT_OF_ORDER_CALL; \ } \ } while (0) #define CHECK_ORDER_LOW(expected_stage) \ do \ { \ printf("Checking LOW %d/%d : %d\n", imgdata.progress_flags, \ expected_stage, imgdata.progress_flags < expected_stage); \ if ((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) < \ expected_stage) \ { \ printf("failed!\n"); \ return LIBRAW_OUT_OF_ORDER_CALL; \ } \ } while (0) #define CHECK_ORDER_BIT(expected_stage) \ do \ { \ if (imgdata.progress_flags & expected_stage) \ return LIBRAW_OUT_OF_ORDER_CALL; \ } while (0) #define SET_PROC_FLAG(stage) \ do \ { \ imgdata.progress_flags |= stage; \ fprintf(stderr, "SET_FLAG: %d\n", stage); \ } while (0) #else #define CHECK_ORDER_HIGH(expected_stage) \ do \ { \ if ((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) >= \ expected_stage) \ { \ return LIBRAW_OUT_OF_ORDER_CALL; \ } \ } while (0) #define CHECK_ORDER_LOW(expected_stage) \ do \ { \ if ((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) < \ expected_stage) \ return LIBRAW_OUT_OF_ORDER_CALL; \ } while (0) #define CHECK_ORDER_BIT(expected_stage) \ do \ { \ if (imgdata.progress_flags & expected_stage) \ return LIBRAW_OUT_OF_ORDER_CALL; \ } while (0) #define SET_PROC_FLAG(stage) \ do \ { \ imgdata.progress_flags |= stage; \ } while (0) #endif #endif LibRaw-0.21.4/libraw/libraw_types.h000066400000000000000000001005661477673233700171460ustar00rootroot00000000000000/* -*- C++ -*- * File: libraw_types.h * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8 , 2008 * * LibRaw C data structures * 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). */ #ifndef _LIBRAW_TYPES_H #define _LIBRAW_TYPES_H #include #ifndef _WIN32 #include #endif #include #if defined(_WIN32) #if defined(_MSC_VER) && (_MSC_VER <= 1500) typedef signed __int8 int8_t; typedef unsigned __int8 uint8_t; typedef signed __int16 int16_t; typedef unsigned __int16 uint16_t; typedef signed __int32 int32_t; typedef unsigned __int32 uint32_t; typedef signed __int64 int64_t; typedef unsigned __int64 uint64_t; #else /* WIN32, but not old MSVC */ #include #endif /* _WIN32 */ #include #else #include #endif #if defined(_OPENMP) #if defined(LIBRAW_FORCE_OPENMP) #define LIBRAW_USE_OPENMP #else #if defined(_WIN32) #if defined(_MSC_VER) && \ (_MSC_VER >= 1600 || (_MSC_VER == 1500 && _MSC_FULL_VER >= 150030729)) /* VS2010+ : OpenMP works OK, VS2008: have tested by cgilles */ #define LIBRAW_USE_OPENMP #elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 910) /* Have not tested on 9.x and 10.x, but Intel documentation claims OpenMP 2.5 * support in 9.1 */ #define LIBRAW_USE_OPENMP #else #undef LIBRAW_USE_OPENMP #endif /* Not Win32 */ #elif (defined(__APPLE__) || defined(__MACOSX__)) && defined(_REENTRANT) /* Latest XCode works with OpenMP, need to recheck here */ #undef LIBRAW_USE_OPENMP #else #define LIBRAW_USE_OPENMP #endif #endif #endif #ifdef LIBRAW_USE_OPENMP #include #endif #ifdef __cplusplus extern "C" { #endif #if defined(USE_LCMS) #include #elif defined(USE_LCMS2) #include #else #define NO_LCMS #endif #include "libraw_const.h" #include "libraw_version.h" #ifdef _WIN32 typedef __int64 INT64; typedef unsigned __int64 UINT64; #else typedef long long INT64; typedef unsigned long long UINT64; #endif typedef unsigned char uchar; typedef unsigned short ushort; #ifdef LIBRAW_WIN32_DLLDEFS #ifdef LIBRAW_NODLL #define DllDef #else #ifdef LIBRAW_BUILDLIB #define DllDef __declspec(dllexport) #else #define DllDef __declspec(dllimport) #endif #endif #else #define DllDef #endif typedef struct { const char *decoder_name; unsigned decoder_flags; } libraw_decoder_info_t; typedef struct { unsigned mix_green; unsigned raw_color; unsigned zero_is_bad; ushort shrink; ushort fuji_width; } libraw_internal_output_params_t; typedef void (*memory_callback)(void *data, const char *file, const char *where); typedef void (*exif_parser_callback)(void *context, int tag, int type, int len, unsigned int ord, void *ifp, INT64 base); typedef void (*data_callback)(void *data, const char *file, const int offset); DllDef void default_data_callback(void *data, const char *file, const int offset); typedef int (*progress_callback)(void *data, enum LibRaw_progress stage, int iteration, int expected); typedef int (*pre_identify_callback)(void *ctx); typedef void (*post_identify_callback)(void *ctx); typedef void (*process_step_callback)(void *ctx); typedef struct { data_callback data_cb; void *datacb_data; progress_callback progress_cb; void *progresscb_data; exif_parser_callback exif_cb; void *exifparser_data; pre_identify_callback pre_identify_cb; post_identify_callback post_identify_cb; process_step_callback pre_subtractblack_cb, pre_scalecolors_cb, pre_preinterpolate_cb, pre_interpolate_cb, interpolate_bayer_cb, interpolate_xtrans_cb, post_interpolate_cb, pre_converttorgb_cb, post_converttorgb_cb; } libraw_callbacks_t; typedef struct { enum LibRaw_image_formats type; ushort height, width, colors, bits; unsigned int data_size; unsigned char data[1]; } libraw_processed_image_t; typedef struct { char guard[4]; char make[64]; char model[64]; char software[64]; char normalized_make[64]; char normalized_model[64]; unsigned maker_index; unsigned raw_count; unsigned dng_version; unsigned is_foveon; int colors; unsigned filters; char xtrans[6][6]; char xtrans_abs[6][6]; char cdesc[5]; unsigned xmplen; char *xmpdata; } libraw_iparams_t; typedef struct { ushort cleft, ctop, cwidth, cheight; } libraw_raw_inset_crop_t; typedef struct { ushort raw_height, raw_width, height, width, top_margin, left_margin; ushort iheight, iwidth; unsigned raw_pitch; double pixel_aspect; int flip; int mask[8][4]; ushort raw_aspect; libraw_raw_inset_crop_t raw_inset_crops[2]; } libraw_image_sizes_t; typedef struct { short t,l,b,r; // top, left, bottom, right pixel coordinates, (0,0) is top left pixel; } libraw_area_t; struct ph1_t { int format, key_off, tag_21a; int t_black, split_col, black_col, split_row, black_row; float tag_210; }; typedef struct { unsigned parsedfields; ushort illuminant; float calibration[4][4]; float colormatrix[4][3]; float forwardmatrix[3][4]; } libraw_dng_color_t; typedef struct { unsigned parsedfields; unsigned dng_cblack[LIBRAW_CBLACK_SIZE]; unsigned dng_black; float dng_fcblack[LIBRAW_CBLACK_SIZE]; float dng_fblack; unsigned dng_whitelevel[4]; ushort default_crop[4]; /* Origin and size */ float user_crop[4]; // top-left-bottom-right relative to default_crop unsigned preview_colorspace; float analogbalance[4]; float asshotneutral[4]; float baseline_exposure; float LinearResponseLimit; } libraw_dng_levels_t; typedef struct { float romm_cam[9]; } libraw_P1_color_t; typedef struct { int ColorDataVer; int ColorDataSubVer; int SpecularWhiteLevel; int NormalWhiteLevel; int ChannelBlackLevel[4]; int AverageBlackLevel; /* multishot */ unsigned int multishot[4]; /* metering */ short MeteringMode; short SpotMeteringMode; uchar FlashMeteringMode; short FlashExposureLock; short ExposureMode; short AESetting; /* stabilization */ short ImageStabilization; /* flash */ short FlashMode; short FlashActivity; short FlashBits; short ManualFlashOutput; short FlashOutput; short FlashGuideNumber; /* drive */ short ContinuousDrive; /* sensor */ short SensorWidth; short SensorHeight; int AFMicroAdjMode; float AFMicroAdjValue; short MakernotesFlip; short RecordMode; short SRAWQuality; unsigned wbi; short RF_lensID; int AutoLightingOptimizer; int HighlightTonePriority; /* -1 = n/a 1 = Economy 2 = Normal 3 = Fine 4 = RAW 5 = Superfine 7 = CRAW 130 = Normal Movie, CRM LightRaw 131 = CRM StandardRaw */ short Quality; /* data compression curve 0 = OFF 1 = CLogV1 2 = CLogV2? 3 = CLogV3 */ int CanonLog; libraw_area_t DefaultCropAbsolute; libraw_area_t RecommendedImageArea; // contains the image in proper aspect ratio? libraw_area_t LeftOpticalBlack; // use this, when present, to estimate black levels? libraw_area_t UpperOpticalBlack; libraw_area_t ActiveArea; short ISOgain[2]; // AutoISO & BaseISO per ExifTool } libraw_canon_makernotes_t; typedef struct { int BaseISO; double Gain; char Sensor[8]; char SensorUnit[64]; // SU char HostBody[64]; // HB int SensorCode; int SensorSubCode; int CoatingCode; int uncropped; /* CaptureSequenceInitiator is based on the content of the 'model' tag - values like 'Pinhole', 'Flash Sync', '500 Mech.' etc in .3FR 'model' tag come from MAIN MENU > SETTINGS > Camera; - otherwise 'model' contains: 1. if CF/CFV/CFH, SU enclosure, can be with SU type if '-' is present 2. else if '-' is present, HB + SU type; 3. HB; */ char CaptureSequenceInitiator[32]; /* SensorUnitConnector, makernotes 0x0015 tag: - in .3FR - SU side - in .FFF - HB side */ char SensorUnitConnector[64]; int format; // 3FR, FFF, Imacon (H3D-39 and maybe others), Hasselblad/Phocus DNG, Adobe DNG int nIFD_CM[2]; // number of IFD containing CM int RecommendedCrop[2]; /* mnColorMatrix is in makernotes tag 0x002a; not present in .3FR files and Imacon/H3D-39 .FFF files; when present in .FFF and Phocus .DNG files, it is a copy of CM1 from .3FR; available samples contain all '1's in the first 3 elements */ double mnColorMatrix[4][3]; } libraw_hasselblad_makernotes_t; typedef struct { float ExpoMidPointShift; ushort DynamicRange; ushort FilmMode; ushort DynamicRangeSetting; ushort DevelopmentDynamicRange; ushort AutoDynamicRange; ushort DRangePriority; ushort DRangePriorityAuto; ushort DRangePriorityFixed; /* tag 0x9200, converted to BrightnessCompensation F700, S3Pro, S5Pro, S20Pro, S200EXR E550, E900, F810, S5600, S6500fd, S9000, S9500, S100FS */ float BrightnessCompensation; /* in EV, if =4, raw data * 2^4 */ ushort FocusMode; ushort AFMode; ushort FocusPixel[2]; ushort PrioritySettings; unsigned FocusSettings; unsigned AF_C_Settings; ushort FocusWarning; ushort ImageStabilization[3]; ushort FlashMode; ushort WB_Preset; /* ShutterType: 0 - mechanical 1 = electronic 2 = electronic, long shutter speed 3 = electronic, front curtain */ ushort ShutterType; ushort ExrMode; ushort Macro; unsigned Rating; /* CropMode: 1 - FF on GFX, 2 - sports finder (mechanical shutter), 4 - 1.25x crop (electronic shutter, continuous high) */ ushort CropMode; char SerialSignature[0x0c + 1]; char SensorID[4 + 1]; char RAFVersion[4 + 1]; int RAFDataGeneration; // 0 (none), 1..4, 4096 ushort RAFDataVersion; int isTSNERDTS; /* DriveMode: 0 - single frame 1 - continuous low 2 - continuous high */ short DriveMode; /* tag 0x4000 BlackLevel: S9100, S9000, S7000, S6000fd, S5200, S5100, S5000, S5Pro, S3Pro, S2Pro, S20Pro, S200EXR, S100FS, F810, F700, E900, E550, DBP, and aliases for all of the above */ ushort BlackLevel[9]; unsigned RAFData_ImageSizeTable[32]; int AutoBracketing; int SequenceNumber; int SeriesLength; float PixelShiftOffset[2]; int ImageCount; } libraw_fuji_info_t; typedef struct { ushort cleft, ctop, cwidth, cheight; } libraw_sensor_highspeed_crop_t; typedef struct { double ExposureBracketValue; ushort ActiveDLighting; ushort ShootingMode; /* stabilization */ uchar ImageStabilization[7]; uchar VibrationReduction; uchar VRMode; /* flash */ char FlashSetting[13]; char FlashType[20]; uchar FlashExposureCompensation[4]; uchar ExternalFlashExposureComp[4]; uchar FlashExposureBracketValue[4]; uchar FlashMode; signed char FlashExposureCompensation2; signed char FlashExposureCompensation3; signed char FlashExposureCompensation4; uchar FlashSource; uchar FlashFirmware[2]; uchar ExternalFlashFlags; uchar FlashControlCommanderMode; uchar FlashOutputAndCompensation; uchar FlashFocalLength; uchar FlashGNDistance; uchar FlashGroupControlMode[4]; uchar FlashGroupOutputAndCompensation[4]; uchar FlashColorFilter; /* NEF compression, comments follow those for ExifTool tag 0x0093: 1: Lossy (type 1) 2: Uncompressed 3: Lossless 4: Lossy (type 2) 5: Striped packed 12-bit 6: Uncompressed (14-bit reduced to 12-bit) 7: Unpacked 12-bit 8: Small raw 9: Packed 12-bit 10: Packed 14-bit 13: High Efficiency (HE) 14: High Efficiency* (HE*) */ ushort NEFCompression; int ExposureMode; int ExposureProgram; int nMEshots; int MEgainOn; double ME_WB[4]; uchar AFFineTune; uchar AFFineTuneIndex; int8_t AFFineTuneAdj; unsigned LensDataVersion; unsigned FlashInfoVersion; unsigned ColorBalanceVersion; uchar key; ushort NEFBitDepth[4]; ushort HighSpeedCropFormat; /* 1 -> 1.3x; 2 -> DX; 3 -> 5:4; 4 -> 3:2; 6 -> 16:9; 11 -> FX uncropped; 12 -> DX uncropped; 17 -> 1:1 */ libraw_sensor_highspeed_crop_t SensorHighSpeedCrop; ushort SensorWidth; ushort SensorHeight; ushort Active_D_Lighting; unsigned ShotInfoVersion; short MakernotesFlip; double RollAngle; // positive is clockwise, CW double PitchAngle; // positive is upwords double YawAngle; // positive is to the right } libraw_nikon_makernotes_t; typedef struct { char CameraType2[6]; ushort ValidBits; int SensorCalibration[2]; ushort DriveMode[5]; ushort ColorSpace; ushort FocusMode[2]; ushort AutoFocus; ushort AFPoint; unsigned AFAreas[64]; double AFPointSelected[5]; ushort AFResult; uchar AFFineTune; short AFFineTuneAdj[3]; unsigned SpecialMode[3]; ushort ZoomStepCount; ushort FocusStepCount; ushort FocusStepInfinity; ushort FocusStepNear; double FocusDistance; ushort AspectFrame[4]; // left, top, width, height unsigned StackedImage[2]; uchar isLiveND; unsigned LiveNDfactor; ushort Panorama_mode; ushort Panorama_frameNum; } libraw_olympus_makernotes_t; typedef struct { /* Compression: 34826 (Panasonic RAW 2): LEICA DIGILUX 2; 34828 (Panasonic RAW 3): LEICA D-LUX 3; LEICA V-LUX 1; Panasonic DMC-LX1; Panasonic DMC-LX2; Panasonic DMC-FZ30; Panasonic DMC-FZ50; 34830 (not in exiftool): LEICA DIGILUX 3; Panasonic DMC-L1; 34316 (Panasonic RAW 1): others (LEICA, Panasonic, YUNEEC); */ ushort Compression; ushort BlackLevelDim; float BlackLevel[8]; unsigned Multishot; /* 0 is Off, 65536 is Pixel Shift */ float gamma; int HighISOMultiplier[3]; /* 0->R, 1->G, 2->B */ short FocusStepNear; short FocusStepCount; unsigned ZoomPosition; unsigned LensManufacturer; } libraw_panasonic_makernotes_t; typedef struct { uchar DriveMode[4]; ushort FocusMode[2]; ushort AFPointSelected[2]; ushort AFPointSelected_Area; int AFPointsInFocus_version; unsigned AFPointsInFocus; ushort FocusPosition; short AFAdjustment; uchar AFPointMode; uchar MultiExposure; /* last bit is not "1" if ME is not used */ ushort Quality; /* 4 is raw, 7 is raw w/ pixel shift, 8 is raw w/ dynamic pixel shift */ } libraw_pentax_makernotes_t; typedef struct { ushort AFStatus; unsigned AFAreaXPosition[2]; unsigned AFAreaYPosition[2]; ushort AFAreaMode; unsigned SensorWidth; unsigned SensorHeight; unsigned CroppedImageWidth; unsigned CroppedImageHeight; ushort WideAdapter; ushort CropMode; ushort NDFilter; ushort AutoBracketing; ushort MacroMode; ushort FlashMode; double FlashExposureComp; double ManualFlashOutput; } libraw_ricoh_makernotes_t; typedef struct { unsigned ImageSizeFull[4]; unsigned ImageSizeCrop[4]; int ColorSpace[2]; unsigned key[11]; double DigitalGain; /* PostAEGain, digital stretch */ int DeviceType; char LensFirmware[32]; } libraw_samsung_makernotes_t; typedef struct { ushort BlackLevelTop; ushort BlackLevelBottom; short offset_left, offset_top; /* KDC files, negative values or zeros */ ushort clipBlack, clipWhite; /* valid for P712, P850, P880 */ float romm_camDaylight[3][3]; float romm_camTungsten[3][3]; float romm_camFluorescent[3][3]; float romm_camFlash[3][3]; float romm_camCustom[3][3]; float romm_camAuto[3][3]; ushort val018percent, val100percent, val170percent; short MakerNoteKodak8a; float ISOCalibrationGain; float AnalogISO; } libraw_kodak_makernotes_t; typedef struct { char Software[64]; // tag 0x0203 char SystemType[64]; // tag 0x0204 char FirmwareString[256]; // tag 0x0301 char SystemModel[64]; } libraw_p1_makernotes_t; typedef struct { /* afdata: 0x0010 CameraInfo 0x2020 AFPointsUsed 0x2022 FocalPlaneAFPointsUsed 0x202a Tag202a 0x940e AFInfo */ ushort CameraType; // init in 0xffff uchar Sony0x9400_version; /* 0 if not found/deciphered, 0xa, 0xb, 0xc following exiftool convention */ uchar Sony0x9400_ReleaseMode2; unsigned Sony0x9400_SequenceImageNumber; uchar Sony0x9400_SequenceLength1; unsigned Sony0x9400_SequenceFileNumber; uchar Sony0x9400_SequenceLength2; uint8_t AFAreaModeSetting; // init in 0xff; + uint16_t AFAreaMode; // init in 0xffff; + ushort FlexibleSpotPosition[2]; // init in (0xffff, 0xffff) uint8_t AFPointSelected; // init in 0xff uint8_t AFPointSelected_0x201e; // init in 0xff short nAFPointsUsed; uint8_t AFPointsUsed[10]; uint8_t AFTracking; // init in 0xff uint8_t AFType; ushort FocusLocation[4]; ushort FocusPosition; // init in 0xffff int8_t AFMicroAdjValue; // init in 0x7f int8_t AFMicroAdjOn; // init in -1 uchar AFMicroAdjRegisteredLenses; // init in 0xff ushort VariableLowPassFilter; unsigned LongExposureNoiseReduction; // init in 0xffffffff ushort HighISONoiseReduction; // init in 0xffff ushort HDR[2]; ushort group2010; ushort group9050; ushort real_iso_offset; // init in 0xffff ushort MeteringMode_offset; ushort ExposureProgram_offset; ushort ReleaseMode2_offset; unsigned MinoltaCamID; // init in 0xffffffff float firmware; ushort ImageCount3_offset; // init in 0xffff unsigned ImageCount3; unsigned ElectronicFrontCurtainShutter; // init in 0xffffffff ushort MeteringMode2; char SonyDateTime[20]; unsigned ShotNumberSincePowerUp; ushort PixelShiftGroupPrefix; unsigned PixelShiftGroupID; char nShotsInPixelShiftGroup; char numInPixelShiftGroup; /* '0' if ARQ, first shot in the group has '1' here */ ushort prd_ImageHeight, prd_ImageWidth; ushort prd_Total_bps; ushort prd_Active_bps; ushort prd_StorageMethod; /* 82 -> Padded; 89 -> Linear */ ushort prd_BayerPattern; /* 0 -> not valid; 1 -> RGGB; 4 -> GBRG */ ushort SonyRawFileType; /* init in 0xffff valid for ARW 2.0 and up (FileFormat >= 3000) takes precedence over RAWFileType and Quality: 0 for uncompressed 14-bit raw 1 for uncompressed 12-bit raw 2 for compressed raw (lossy) 3 for lossless compressed raw 4 for lossless compressed raw v.2 (ILCE-1) */ ushort RAWFileType; /* init in 0xffff takes precedence over Quality 0 for compressed raw, 1 for uncompressed; 2 lossless compressed raw v.2 */ ushort RawSizeType; /* init in 0xffff 1 - large, 2 - small, 3 - medium */ unsigned Quality; /* init in 0xffffffff 0 or 6 for raw, 7 or 8 for compressed raw */ ushort FileFormat; /* 1000 SR2 2000 ARW 1.0 3000 ARW 2.0 3100 ARW 2.1 3200 ARW 2.2 3300 ARW 2.3 3310 ARW 2.3.1 3320 ARW 2.3.2 3330 ARW 2.3.3 3350 ARW 2.3.5 4000 ARW 4.0 */ char MetaVersion [16]; } libraw_sony_info_t; typedef struct { ushort curve[0x10000]; unsigned cblack[LIBRAW_CBLACK_SIZE]; unsigned black; unsigned data_maximum; unsigned maximum; // Canon (SpecularWhiteLevel) // Kodak (14N, 14nx, SLR/c/n, DCS720X, DCS760C, DCS760M, ProBack, ProBack645, P712, P880, P850) // Olympus, except: // C5050Z, C5060WZ, C7070WZ, C8080WZ // SP350, SP500UZ, SP510UZ, SP565UZ // E-10, E-20 // E-300, E-330, E-400, E-410, E-420, E-450, E-500, E-510, E-520 // E-1, E-3 // XZ-1 // Panasonic // Pentax // Sony // and aliases of the above // DNG long linear_max[4]; float fmaximum; float fnorm; ushort white[8][8]; float cam_mul[4]; float pre_mul[4]; float cmatrix[3][4]; float ccm[3][4]; float rgb_cam[3][4]; float cam_xyz[4][3]; struct ph1_t phase_one_data; float flash_used; float canon_ev; char model2[64]; char UniqueCameraModel[64]; char LocalizedCameraModel[64]; char ImageUniqueID[64]; char RawDataUniqueID[17]; char OriginalRawFileName[64]; void *profile; unsigned profile_length; unsigned black_stat[8]; libraw_dng_color_t dng_color[2]; libraw_dng_levels_t dng_levels; int WB_Coeffs[256][4]; /* R, G1, B, G2 coeffs */ float WBCT_Coeffs[64][5]; /* CCT, than R, G1, B, G2 coeffs */ int as_shot_wb_applied; libraw_P1_color_t P1_color[2]; unsigned raw_bps; /* for Phase One: raw format; For other cameras: bits per pixel (copy of tiff_bps in most cases) */ /* Phase One raw format values, makernotes tag 0x010e: 0 Name unknown 1 "RAW 1" 2 "RAW 2" 3 "IIQ L" (IIQ L14) 4 Never seen 5 "IIQ S" 6 "IIQ Sv2" (S14 / S14+) 7 Never seen 8 "IIQ L16" (IIQ L16EX / IIQ L16) */ int ExifColorSpace; } libraw_colordata_t; typedef struct { enum LibRaw_thumbnail_formats tformat; ushort twidth, theight; unsigned tlength; int tcolors; char *thumb; } libraw_thumbnail_t; typedef struct { enum LibRaw_internal_thumbnail_formats tformat; ushort twidth, theight, tflip; unsigned tlength; unsigned tmisc; INT64 toffset; }libraw_thumbnail_item_t; typedef struct { int thumbcount; libraw_thumbnail_item_t thumblist[LIBRAW_THUMBNAIL_MAXCOUNT]; } libraw_thumbnail_list_t; typedef struct { float latitude[3]; /* Deg,min,sec */ float longitude[3]; /* Deg,min,sec */ float gpstimestamp[3]; /* Deg,min,sec */ float altitude; char altref, latref, longref, gpsstatus; char gpsparsed; } libraw_gps_info_t; typedef struct { float iso_speed; float shutter; float aperture; float focal_len; time_t timestamp; unsigned shot_order; unsigned gpsdata[32]; libraw_gps_info_t parsed_gps; char desc[512], artist[64]; float analogbalance[4]; } libraw_imgother_t; typedef struct { unsigned AFInfoData_tag; short AFInfoData_order; unsigned AFInfoData_version; unsigned AFInfoData_length; uchar *AFInfoData; } libraw_afinfo_item_t; typedef struct { float FlashEC; float FlashGN; float CameraTemperature; float SensorTemperature; float SensorTemperature2; float LensTemperature; float AmbientTemperature; float BatteryTemperature; float exifAmbientTemperature; float exifHumidity; float exifPressure; float exifWaterDepth; float exifAcceleration; float exifCameraElevationAngle; float real_ISO; float exifExposureIndex; ushort ColorSpace; char firmware[128]; float ExposureCalibrationShift; libraw_afinfo_item_t afdata[LIBRAW_AFDATA_MAXCOUNT]; int afcount; } libraw_metadata_common_t; typedef struct { unsigned greybox[4]; /* -A x1 y1 x2 y2 */ unsigned cropbox[4]; /* -B x1 y1 x2 y2 */ double aber[4]; /* -C */ double gamm[6]; /* -g */ float user_mul[4]; /* -r mul0 mul1 mul2 mul3 */ float bright; /* -b */ float threshold; /* -n */ int half_size; /* -h */ int four_color_rgb; /* -f */ int highlight; /* -H */ int use_auto_wb; /* -a */ int use_camera_wb; /* -w */ int use_camera_matrix; /* +M/-M */ int output_color; /* -o */ char *output_profile; /* -o */ char *camera_profile; /* -p */ char *bad_pixels; /* -P */ char *dark_frame; /* -K */ int output_bps; /* -4 */ int output_tiff; /* -T */ int output_flags; int user_flip; /* -t */ int user_qual; /* -q */ int user_black; /* -k */ int user_cblack[4]; int user_sat; /* -S */ int med_passes; /* -m */ float auto_bright_thr; float adjust_maximum_thr; int no_auto_bright; /* -W */ int use_fuji_rotate; /* -j */ int green_matching; /* DCB parameters */ int dcb_iterations; int dcb_enhance_fl; int fbdd_noiserd; int exp_correc; float exp_shift; float exp_preser; /* Disable Auto-scale */ int no_auto_scale; /* Disable intepolation */ int no_interpolation; } libraw_output_params_t; typedef struct { /* Raw speed */ int use_rawspeed; /* DNG SDK */ int use_dngsdk; unsigned options; unsigned shot_select; /* -s */ unsigned specials; unsigned max_raw_memory_mb; int sony_arw2_posterization_thr; /* Nikon Coolscan */ float coolscan_nef_gamma; char p4shot_order[5]; /* Custom camera list */ char **custom_camera_strings; }libraw_raw_unpack_params_t; typedef struct { /* really allocated bitmap */ void *raw_alloc; /* alias to single_channel variant */ ushort *raw_image; /* alias to 4-channel variant */ ushort (*color4_image)[4]; /* alias to 3-color variand decoded by RawSpeed */ ushort (*color3_image)[3]; /* float bayer */ float *float_image; /* float 3-component */ float (*float3_image)[3]; /* float 4-component */ float (*float4_image)[4]; /* Phase One black level data; */ short (*ph1_cblack)[2]; short (*ph1_rblack)[2]; /* save color and sizes here, too.... */ libraw_iparams_t iparams; libraw_image_sizes_t sizes; libraw_internal_output_params_t ioparams; libraw_colordata_t color; } libraw_rawdata_t; typedef struct { unsigned long long LensID; char Lens[128]; ushort LensFormat; /* to characterize the image circle the lens covers */ ushort LensMount; /* 'male', lens itself */ unsigned long long CamID; ushort CameraFormat; /* some of the sensor formats */ ushort CameraMount; /* 'female', body throat */ char body[64]; short FocalType; /* -1/0 is unknown; 1 is fixed focal; 2 is zoom */ char LensFeatures_pre[16], LensFeatures_suf[16]; float MinFocal, MaxFocal; float MaxAp4MinFocal, MaxAp4MaxFocal, MinAp4MinFocal, MinAp4MaxFocal; float MaxAp, MinAp; float CurFocal, CurAp; float MaxAp4CurFocal, MinAp4CurFocal; float MinFocusDistance; float FocusRangeIndex; float LensFStops; unsigned long long TeleconverterID; char Teleconverter[128]; unsigned long long AdapterID; char Adapter[128]; unsigned long long AttachmentID; char Attachment[128]; ushort FocalUnits; float FocalLengthIn35mmFormat; } libraw_makernotes_lens_t; typedef struct { float EffectiveMaxAp; uchar LensIDNumber, LensFStops, MCUVersion, LensType; } libraw_nikonlens_t; typedef struct { float MinFocal, MaxFocal, MaxAp4MinFocal, MaxAp4MaxFocal; } libraw_dnglens_t; typedef struct { float MinFocal, MaxFocal, MaxAp4MinFocal, MaxAp4MaxFocal, EXIF_MaxAp; char LensMake[128], Lens[128], LensSerial[128], InternalLensSerial[128]; ushort FocalLengthIn35mmFormat; libraw_nikonlens_t nikon; libraw_dnglens_t dng; libraw_makernotes_lens_t makernotes; } libraw_lensinfo_t; typedef struct { libraw_canon_makernotes_t canon; libraw_nikon_makernotes_t nikon; libraw_hasselblad_makernotes_t hasselblad; libraw_fuji_info_t fuji; libraw_olympus_makernotes_t olympus; libraw_sony_info_t sony; libraw_kodak_makernotes_t kodak; libraw_panasonic_makernotes_t panasonic; libraw_pentax_makernotes_t pentax; libraw_p1_makernotes_t phaseone; libraw_ricoh_makernotes_t ricoh; libraw_samsung_makernotes_t samsung; libraw_metadata_common_t common; } libraw_makernotes_t; typedef struct { short DriveMode; short FocusMode; short MeteringMode; short AFPoint; short ExposureMode; short ExposureProgram; short ImageStabilization; char BodySerial[64]; char InternalBodySerial[64]; /* this may be PCB or sensor serial, depends on make/model */ } libraw_shootinginfo_t; typedef struct { unsigned fsize; ushort rw, rh; uchar lm, tm, rm, bm; ushort lf; uchar cf, max, flags; char t_make[10], t_model[20]; ushort offset; } libraw_custom_camera_t; typedef struct { ushort (*image)[4]; libraw_image_sizes_t sizes; libraw_iparams_t idata; libraw_lensinfo_t lens; libraw_makernotes_t makernotes; libraw_shootinginfo_t shootinginfo; libraw_output_params_t params; libraw_raw_unpack_params_t rawparams; unsigned int progress_flags; unsigned int process_warnings; libraw_colordata_t color; libraw_imgother_t other; libraw_thumbnail_t thumbnail; libraw_thumbnail_list_t thumbs_list; libraw_rawdata_t rawdata; void *parent_class; } libraw_data_t; struct fuji_q_table { int8_t *q_table; /* quantization table */ int raw_bits; int total_values; int max_grad; // sdp val int q_grad_mult; // quant_gradient multiplier int q_base; }; struct fuji_compressed_params { struct fuji_q_table qt[4]; void *buf; int max_bits; int min_value; int max_value; // q_point[4] ushort line_width; }; #ifdef __cplusplus } #endif #if defined (LIBRAW_LIBRARY_BUILD) && defined(__cplusplus) class libraw_static_table_t { public: libraw_static_table_t(const int *a, const unsigned s): data(a),_size(s) {} libraw_static_table_t(): data(0),_size(0){} libraw_static_table_t(const libraw_static_table_t& s) : data(s.data), _size(s._size) {} unsigned size() const { return _size; } libraw_static_table_t& operator = (const libraw_static_table_t& s) { _size = s._size; data = s.data; return *this; } int operator [] (unsigned idx) const { if (idx < _size) return data[idx]; if(_size>0 && data) return data[0]; return 0; } private: const int *data; unsigned _size; }; #endif /* Byte order */ #if defined(__POWERPC__) #define LibRawBigEndian 1 #elif defined(__INTEL__) #define LibRawBigEndian 0 #elif defined(_M_IX86) || defined(__i386__) #define LibRawBigEndian 0 #elif defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) #define LibRawBigEndian 0 #elif defined(__LITTLE_ENDIAN__) #define LibRawBigEndian 0 #elif defined(__BIG_ENDIAN__) #define LibRawBigEndian 1 #elif defined(_ARM_) #define LibRawBigEndian 0 #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define LibRawBigEndian 0 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #define LibRawBigEndian 1 #else #ifndef qXCodeRez #error Unable to figure out byte order. #endif #endif #endif LibRaw-0.21.4/libraw/libraw_version.h000066400000000000000000000046431477673233700174660ustar00rootroot00000000000000/* -*- C++ -*- * File: libraw_version.h * Copyright 2008-2025 LibRaw LLC (info@libraw.org) * Created: Mon Sept 8, 2008 * * LibRaw C++ interface * 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 the file LICENSE.LGPL provided in LibRaw distribution archive for details). 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 (See the file LICENSE.CDDL provided in LibRaw distribution archive for details). */ #ifndef __VERSION_H #define __VERSION_H #define LIBRAW_MAJOR_VERSION 0 #define LIBRAW_MINOR_VERSION 21 #define LIBRAW_PATCH_VERSION 4 #define LIBRAW_VERSION_TAIL Release #define LIBRAW_SHLIB_CURRENT 23 #define LIBRAW_SHLIB_REVISION 0 #define LIBRAW_SHLIB_AGE 0 #define _LIBRAW_VERSION_MAKE(a, b, c, d) #a "." #b "." #c "-" #d #define LIBRAW_VERSION_MAKE(a, b, c, d) _LIBRAW_VERSION_MAKE(a, b, c, d) #define LIBRAW_VERSION_STR \ LIBRAW_VERSION_MAKE(LIBRAW_MAJOR_VERSION, LIBRAW_MINOR_VERSION, \ LIBRAW_PATCH_VERSION, LIBRAW_VERSION_TAIL) #define LIBRAW_MAKE_VERSION(major, minor, patch) \ (((major) << 16) | ((minor) << 8) | (patch)) #define LIBRAW_VERSION \ LIBRAW_MAKE_VERSION(LIBRAW_MAJOR_VERSION, LIBRAW_MINOR_VERSION, \ LIBRAW_PATCH_VERSION) #define LIBRAW_CHECK_VERSION(major, minor, patch) \ (LibRaw::versionNumber() >= LIBRAW_MAKE_VERSION(major, minor, patch)) #define LIBRAW_RUNTIME_CHECK_VERSION_EXACT() \ ((LibRaw::versionNumber() & 0xffff00) == \ LIBRAW_MAKE_VERSION(LIBRAW_MAJOR_VERSION, LIBRAW_MINOR_VERSION, 0)) #define LIBRAW_RUNTIME_CHECK_VERSION_NOTLESS() \ ((LibRaw::versionNumber() & 0xffff00) >= \ LIBRAW_MAKE_VERSION(LIBRAW_MAJOR_VERSION, LIBRAW_MINOR_VERSION, 0)) #define LIBRAW_COMPILE_CHECK_VERSION(major, minor) \ (LIBRAW_MAKE_VERSION(major, minor, 0) == (LIBRAW_VERSION & 0xffff00)) #define LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(major, minor) \ (LIBRAW_MAKE_VERSION(major, minor, 0) <= (LIBRAW_VERSION & 0xffff00)) #endif LibRaw-0.21.4/libraw_r.pc.in000066400000000000000000000005171477673233700155360ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libraw Description: Raw image decoder library (thread-safe) Requires: @PACKAGE_REQUIRES@ Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lraw_r -lstdc++@PC_OPENMP@ Libs.private: @PACKAGE_LIBS_PRIVATE@ Cflags: -I${includedir}/libraw -I${includedir} LibRaw-0.21.4/m4/000077500000000000000000000000001477673233700133215ustar00rootroot00000000000000LibRaw-0.21.4/m4/ax_openmp.m4000066400000000000000000000102741477673233700155550ustar00rootroot00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_openmp.html # =========================================================================== # # SYNOPSIS # # AX_OPENMP([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro tries to find out how to compile programs that use OpenMP a # standard API and set of compiler directives for parallel programming # (see http://www-unix.mcs/) # # On success, it sets the OPENMP_CFLAGS/OPENMP_CXXFLAGS/OPENMP_F77FLAGS # output variable to the flag (e.g. -omp) used both to compile *and* link # OpenMP programs in the current language. # # NOTE: You are assumed to not only compile your program with these flags, # but also link it with them as well. # # If you want to compile everything with OpenMP, you should set: # # CFLAGS="$CFLAGS $OPENMP_CFLAGS" # #OR# CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" # #OR# FFLAGS="$FFLAGS $OPENMP_FFLAGS" # # (depending on the selected language). # # The user can override the default choice by setting the corresponding # environment variable (e.g. OPENMP_CFLAGS). # # ACTION-IF-FOUND is a list of shell commands to run if an OpenMP flag is # found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it is # not found. If ACTION-IF-FOUND is not specified, the default action will # define HAVE_OPENMP. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 8 AC_DEFUN([AX_OPENMP], [ AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX AC_CACHE_CHECK([for OpenMP flag of _AC_LANG compiler], ax_cv_[]_AC_LANG_ABBREV[]_openmp, [save[]_AC_LANG_PREFIX[]FLAGS=$[]_AC_LANG_PREFIX[]FLAGS ax_cv_[]_AC_LANG_ABBREV[]_openmp=unknown # Flags to try: -fopenmp (gcc), -openmp (icc), -mp (SGI & PGI), # -xopenmp (Sun), -omp (Tru64), -qsmp=omp (AIX), none ax_openmp_flags="-fopenmp -openmp -mp -xopenmp -omp -qsmp=omp none" if test "x$OPENMP_[]_AC_LANG_PREFIX[]FLAGS" != x; then ax_openmp_flags="$OPENMP_[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flags" fi for ax_openmp_flag in $ax_openmp_flags; do case $ax_openmp_flag in none) []_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[] ;; *) []_AC_LANG_PREFIX[]FLAGS="$save[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flag" ;; esac AC_TRY_LINK_FUNC(omp_set_num_threads, [ax_cv_[]_AC_LANG_ABBREV[]_openmp=$ax_openmp_flag; break]) done []_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[]FLAGS ]) if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" = "xunknown"; then m4_default([$2],:) else if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" != "xnone"; then OPENMP_[]_AC_LANG_PREFIX[]FLAGS=$ax_cv_[]_AC_LANG_ABBREV[]_openmp fi m4_default([$1], [AC_DEFINE(HAVE_OPENMP,1,[Define if OpenMP is enabled])]) fi ])dnl AX_OPENMP LibRaw-0.21.4/mkdist.sh000077500000000000000000000006141477673233700146340ustar00rootroot00000000000000#!/bin/sh if [ -d CVS ] ; then echo 'Use mkdist script in cvs export-ed dirs' else if [ -f Makefile.devel ] ; then autoreconf --install mkdir dcraw cd dcraw wget https://www.dechifro.org/dcraw/dcraw.c cd .. rm -f clist2c.pl clist2html.pl rm -f Makefile.devel rm mkdist.sh export-dist.sh else echo 'Wrong directory or mkdist.sh already executed' fi fi LibRaw-0.21.4/object/000077500000000000000000000000001477673233700142475ustar00rootroot00000000000000LibRaw-0.21.4/object/.keep_me000066400000000000000000000000001477673233700156430ustar00rootroot00000000000000LibRaw-0.21.4/rsxml2c.sh000077500000000000000000000002341477673233700147310ustar00rootroot00000000000000#!/bin/sh echo "const char *_rawspeed_data_xml[]={" cat $1 | tr -d '\015' | sed -e 's/\\/\\\\/g;s/"/\\"/g;s/ /\\t/g;s/^/"/;s/$/\\n",/' echo "0" echo "};" LibRaw-0.21.4/samples/000077500000000000000000000000001477673233700144455ustar00rootroot00000000000000LibRaw-0.21.4/samples/4channels.cpp000066400000000000000000000113571477673233700170370ustar00rootroot00000000000000/* -*- C++ -*- * File: 4channels.cpp * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Mon Feb 09, 2009 * * LibRaw sample * Generates 4 TIFF file from RAW data, one file per channel * 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 #include #include #include "libraw/libraw.h" #ifndef LIBRAW_WIN32_CALLS #include #else #include #endif #ifdef LIBRAW_WIN32_CALLS #define snprintf _snprintf #endif int main(int ac, char *av[]) { int i, ret; int autoscale = 0, black_subtraction = 1, use_gamma = 0; char outfn[1024]; LibRaw RawProcessor; if (ac < 2) { usage: printf("4channels - LibRaw %s sample. %d cameras supported\n" "Usage: %s [-s N] [-g] [-A] [-B] [-N] raw-files....\n" "\t-s N - select Nth image in file (default=0)\n" "\t-g - use gamma correction with gamma 2.2 (not precise,use for " "visual inspection only)\n" "\t-A - autoscaling (by integer factor)\n" "\t-B - no black subtraction\n", LibRaw::version(), LibRaw::cameraCount(), av[0]); return 0; } #define P1 RawProcessor.imgdata.idata #define S RawProcessor.imgdata.sizes #define C RawProcessor.imgdata.color #define T RawProcessor.imgdata.thumbnail #define P2 RawProcessor.imgdata.other #define OUT RawProcessor.imgdata.params #define OUTR RawProcessor.imgdata.rawparams OUT.output_bps = 16; OUT.output_tiff = 1; OUT.user_flip = 0; OUT.no_auto_bright = 1; OUT.half_size = 1; for (i = 1; i < ac; i++) { if (av[i][0] == '-') { if (av[i][1] == 's' && av[i][2] == 0) { i++; OUTR.shot_select = av[i] ? atoi(av[i]) : 0; } else if (av[i][1] == 'g' && av[i][2] == 0) use_gamma = 1; else if (av[i][1] == 'A' && av[i][2] == 0) autoscale = 1; else if (av[i][1] == 'B' && av[i][2] == 0) { black_subtraction = 0; } else goto usage; continue; } if (!use_gamma) OUT.gamm[0] = OUT.gamm[1] = 1; int c; printf("Processing file %s\n", av[i]); if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot open %s: %s\n", av[i], libraw_strerror(ret)); continue; // no recycle b/c open file will recycle itself } if (P1.is_foveon) { printf("Cannot process Foveon image %s\n", av[i]); continue; } if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret)); continue; } RawProcessor.raw2image(); if (black_subtraction) { RawProcessor.subtract_black(); } if (autoscale) { unsigned max = 0, scale = 1; for (int j = 0; j < S.iheight * S.iwidth; j++) for (int c = 0; c < 4; c++) if (max < RawProcessor.imgdata.image[j][c]) max = RawProcessor.imgdata.image[j][c]; if (max > 0 && max < 1 << 15) { scale = (1 << 16) / max; printf("Scaling with multiplier=%d (max=%d)\n", scale, max); for (int j = 0; j < S.iheight * S.iwidth; j++) for (c = 0; c < 4; c++) RawProcessor.imgdata.image[j][c] *= scale; } printf("Black level (scaled)=%d\n", C.black * scale); } else printf("Black level (unscaled)=%d\n", C.black); // hack to make dcraw tiff writer happy int isrgb = (P1.colors == 4 ? 0 : 1); P1.colors = 1; S.width = S.iwidth; S.height = S.iheight; for (int layer = 0; layer < 4; layer++) { if (layer > 0) { for (int rc = 0; rc < S.iheight * S.iwidth; rc++) RawProcessor.imgdata.image[rc][0] = RawProcessor.imgdata.image[rc][layer]; } char lname[8]; if (isrgb) { snprintf(lname, 7, "%c", ((char *)("RGBG"))[layer]); if (layer == 3) strcat(lname, "2"); } else snprintf(lname, 7, "%c", ((char *)("GCMY"))[layer]); if (OUTR.shot_select) snprintf(outfn, sizeof(outfn), "%s-%d.%s.tiff", av[i], OUTR.shot_select, lname); else snprintf(outfn, sizeof(outfn), "%s.%s.tiff", av[i], lname); printf("Writing file %s\n", outfn); if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn))) fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret)); } } return 0; } LibRaw-0.21.4/samples/Makefile000066400000000000000000000000411477673233700161000ustar00rootroot00000000000000all: (cd ..; make all_samples) LibRaw-0.21.4/samples/dcraw_emu.cpp000066400000000000000000000466721477673233700171360ustar00rootroot00000000000000/* -*- C++ -*- * File: dcraw_emu.cpp * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sun Mar 23, 2008 * * LibRaw simple C++ API sample: almost complete dcraw emulator * 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). */ #ifdef _MSC_VER // suppress sprintf-related warning. sprintf() is permitted in sample code #define _CRT_SECURE_NO_WARNINGS #endif #include #include #include #include #include #include "libraw/libraw.h" #ifndef LIBRAW_WIN32_CALLS #include #include #include #else #include #endif #include #include #ifdef LIBRAW_WIN32_CALLS #define snprintf _snprintf #include #else #define O_BINARY 0 #endif #ifdef USE_DNGSDK #include "dng_host.h" #include "dng_negative.h" #include "dng_simple_image.h" #include "dng_info.h" #endif void usage(const char *prog) { printf("dcraw_emu: almost complete dcraw emulator\n"); printf("Usage: %s [OPTION]... [FILE]...\n", prog); printf("-c float-num Set adjust maximum threshold (default 0.75)\n" "-v Verbose: print progress messages (repeated -v will add " "verbosity)\n" "-w Use camera white balance, if possible\n" "-a Average the whole image for white balance\n" "-A Average a grey box for white balance\n" "-r Set custom white balance\n" "+M/-M Use/don't use an embedded color matrix\n" "-C Correct chromatic aberration\n" "-P Fix the dead pixels listed in this file\n" "-K Subtract dark frame (16-bit raw PGM)\n" "-k Set the darkness level\n" "-S Set the saturation level\n" "-R Set raw processing options to num\n" "-n Set threshold for wavelet denoising\n" "-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)\n" "-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)\n" "-o [0-8] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ,ACES,\n" " DCI-P3,Rec2020)\n" #ifndef NO_LCMS "-o file Output ICC profile\n" "-p file Camera input profile (use \'embed\' for embedded profile)\n" #endif "-j Don't stretch or rotate raw pixels\n" "-W Don't automatically brighten the image\n" "-b Adjust brightness (default = 1.0)\n" "-q N Set the interpolation quality:\n" " 0 - linear, 1 - VNG, 2 - PPG, 3 - AHD, 4 - DCB\n" " 11 - DHT, 12 - AAHD\n" "-h Half-size color image (twice as fast as \"-q 0\")\n" "-f Interpolate RGGB as four colors\n" "-m Apply a 3x3 median filter to R-G and B-G\n" "-s [0..N-1] Select one raw image from input file\n" "-4 Linear 16-bit, same as \"-6 -W -g 1 1\n" "-6 Write 16-bit output\n" "-g pow ts Set gamma curve to gamma pow and toe slope ts (default = " "2.222 4.5)\n" "-T Write TIFF instead of PPM\n" "-G Use green_matching() filter\n" "-B use cropbox\n" "-F Use FILE I/O instead of streambuf API\n" "-Z Output filename generation rules\n" " .suf => append .suf to input name, keeping existing suffix " "too\n" " suf => replace input filename last extension\n" " - => output to stdout\n" " filename.suf => output to filename.suf\n" "-timing Detailed timing report\n" "-fbdd N 0 - disable FBDD noise reduction (default), 1 - light " "FBDD, 2 - full\n" "-dcbi N Number of extra DCD iterations (default - 0)\n" "-dcbe DCB color enhance\n" "-aexpo exposure correction\n" "-apentax4shot enables merge of 4-shot pentax files\n" "-apentax4shotorder 3102 sets pentax 4-shot alignment order\n" #ifdef USE_RAWSPEED_BITS "-arsbits V Set use_rawspeed to V\n" #endif "-mmap Use memory mmaped buffer instead of plain FILE I/O\n" "-mem Use memory buffer instead of FILE I/O\n" "-disars Do not use RawSpeed library\n" "-disinterp Do not run interpolation step\n" "-dsrawrgb1 Disable YCbCr to RGB conversion for sRAW (Cb/Cr " "interpolation enabled)\n" "-dsrawrgb2 Disable YCbCr to RGB conversion for sRAW (Cb/Cr " "interpolation disabled)\n" #ifdef USE_DNGSDK "-dngsdk Use Adobe DNG SDK for DNG decode\n" "-dngflags N set DNG decoding options to value N\n" #endif "-doutputflags N set params.output_flags to N\n" ); exit(1); } static int verbosity = 0; int cnt = 0; int my_progress_callback(void *d, enum LibRaw_progress p, int iteration, int expected) { char *passed = (char *)(d ? d : "default string"); // data passed to callback // at set_callback stage if (verbosity > 2) // verbosity set by repeat -v switches { printf("CB: %s pass %d of %d (data passed=%s)\n", libraw_strprogress(p), iteration, expected, passed); } else if (iteration == 0) // 1st iteration of each step printf("Starting %s (expecting %d iterations)\n", libraw_strprogress(p), expected); else if (iteration == expected - 1) printf("%s finished\n", libraw_strprogress(p)); /// if(++cnt>10) return 1; // emulate user termination on 10-th callback /// call return 0; // always return 0 to continue processing } // timer #ifndef LIBRAW_WIN32_CALLS static struct timeval start, end; void timerstart(void) { gettimeofday(&start, NULL); } void timerprint(const char *msg, const char *filename) { gettimeofday(&end, NULL); float msec = (end.tv_sec - start.tv_sec) * 1000.0f + (end.tv_usec - start.tv_usec) / 1000.0f; printf("Timing: %s/%s: %6.3f msec\n", filename, msg, msec); } #else LARGE_INTEGER start; void timerstart(void) { QueryPerformanceCounter(&start); } void timerprint(const char *msg, const char *filename) { LARGE_INTEGER unit, end; QueryPerformanceCounter(&end); QueryPerformanceFrequency(&unit); float msec = (float)(end.QuadPart - start.QuadPart); msec /= (float)unit.QuadPart / 1000.0f; printf("Timing: %s/%s: %6.3f msec\n", filename, msg, msec); } #endif struct file_mapping { void *map; INT64 fsize; #ifdef LIBRAW_WIN32_CALLS HANDLE fd, fd_map; file_mapping() : map(0), fsize(0), fd(INVALID_HANDLE_VALUE), fd_map(INVALID_HANDLE_VALUE){} #else int fd; file_mapping() : map(0), fsize(0), fd(-1){} #endif }; void create_mapping(struct file_mapping& data, const std::string& fn) { #ifdef LIBRAW_WIN32_CALLS std::wstring fpath(fn.begin(), fn.end()); if ((data.fd = CreateFileW(fpath.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE) return; LARGE_INTEGER fs; if (!GetFileSizeEx(data.fd, &fs)) return; data.fsize = fs.QuadPart; if ((data.fd_map = ::CreateFileMapping(data.fd, 0, PAGE_READONLY, fs.HighPart, fs.LowPart, 0)) == INVALID_HANDLE_VALUE) return; data.map = MapViewOfFile(data.fd_map, FILE_MAP_READ, 0, 0, data.fsize); #else struct stat stt; if ((data.fd = open(fn.c_str(), O_RDONLY)) < 0) return; if (fstat(data.fd, &stt) != 0) return; data.fsize = stt.st_size; data.map = mmap(0, data.fsize, PROT_READ | PROT_WRITE, MAP_PRIVATE, data.fd, 0); return; #endif } void close_mapping(struct file_mapping& data) { #ifdef LIBRAW_WIN32_CALLS if (data.map) UnmapViewOfFile(data.map); if (data.fd_map != INVALID_HANDLE_VALUE) CloseHandle(data.fd_map); if (data.fd != INVALID_HANDLE_VALUE) CloseHandle(data.fd); data.map = 0; data.fsize = 0; data.fd = data.fd_map = INVALID_HANDLE_VALUE; #else if (data.map) munmap(data.map, data.fsize); if (data.fd >= 0) close(data.fd); data.map = 0; data.fsize = 0; data.fd = -1; #endif } int main(int argc, char *argv[]) { if (argc == 1) usage(argv[0]); LibRaw RawProcessor; int i, arg, c, ret; char opm, opt, *cp, *sp; int use_timing = 0, use_mem = 0, use_mmap = 0; char *outext = NULL; #ifdef USE_DNGSDK dng_host *dnghost = NULL; #endif struct file_mapping mapping; void *iobuffer = 0; #ifdef OUT #undef OUT #endif #define OUT RawProcessor.imgdata.params #define OUTR RawProcessor.imgdata.rawparams argv[argc] = (char *)""; for (arg = 1; (((opm = argv[arg][0]) - 2) | 2) == '+';) { char *optstr = argv[arg]; opt = argv[arg++][1]; if ((cp = strchr(sp = (char *)"cnbrkStqmHABCgU", opt)) != 0) for (i = 0; i < "111411111144221"[cp - sp] - '0'; i++) if (!isdigit(argv[arg + i][0]) && !optstr[2]) { fprintf(stderr, "Non-numeric argument to \"-%c\"\n", opt); return 1; } if (!strchr("ftdeam", opt) && argv[arg - 1][2]) { fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]); continue; } switch (opt) { case 'v': verbosity++; break; case 'G': OUT.green_matching = 1; break; case 'c': OUT.adjust_maximum_thr = (float)atof(argv[arg++]); break; case 'U': OUT.auto_bright_thr = (float)atof(argv[arg++]); break; case 'n': OUT.threshold = (float)atof(argv[arg++]); break; case 'b': OUT.bright = (float)atof(argv[arg++]); break; case 'P': OUT.bad_pixels = argv[arg++]; break; case 'K': OUT.dark_frame = argv[arg++]; break; case 'r': for (c = 0; c < 4; c++) OUT.user_mul[c] = (float)atof(argv[arg++]); break; case 'C': OUT.aber[0] = 1 / atof(argv[arg++]); OUT.aber[2] = 1 / atof(argv[arg++]); break; case 'g': OUT.gamm[0] = 1 / atof(argv[arg++]); OUT.gamm[1] = atof(argv[arg++]); break; case 'k': OUT.user_black = atoi(argv[arg++]); break; case 'S': OUT.user_sat = atoi(argv[arg++]); break; case 'R': OUTR.options = atoi(argv[arg++]); break; case 't': if (!strcmp(optstr, "-timing")) use_timing = 1; else if (!argv[arg - 1][2]) OUT.user_flip = atoi(argv[arg++]); else fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]); break; case 'q': OUT.user_qual = atoi(argv[arg++]); break; case 'm': if (!strcmp(optstr, "-mmap")) use_mmap = 1; else if (!strcmp(optstr, "-mem")) use_mem = 1; else { if (!argv[arg - 1][2]) OUT.med_passes = atoi(argv[arg++]); else fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]); } break; case 'H': OUT.highlight = atoi(argv[arg++]); break; case 's': OUTR.shot_select = abs(atoi(argv[arg++])); break; case 'o': if (isdigit(argv[arg][0]) && !isdigit(argv[arg][1])) OUT.output_color = atoi(argv[arg++]); #ifndef NO_LCMS else OUT.output_profile = argv[arg++]; break; case 'p': OUT.camera_profile = argv[arg++]; #endif break; case 'h': OUT.half_size = 1; break; case 'f': if (!strcmp(optstr, "-fbdd")) OUT.fbdd_noiserd = atoi(argv[arg++]); else { if (!argv[arg - 1][2]) OUT.four_color_rgb = 1; else fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]); } break; case 'A': for (c = 0; c < 4; c++) OUT.greybox[c] = atoi(argv[arg++]); break; case 'B': for (c = 0; c < 4; c++) OUT.cropbox[c] = atoi(argv[arg++]); break; case 'a': if (!strcmp(optstr, "-aexpo")) { OUT.exp_correc = 1; OUT.exp_shift = (float)atof(argv[arg++]); OUT.exp_preser = (float)atof(argv[arg++]); } #ifdef USE_RAWSPEED_BITS else if (!strcmp(optstr, "-arsbits")) { OUTR.use_rawspeed = atoi(argv[arg++]); } #endif else if (!strcmp(optstr, "-apentax4shot")) { OUTR.options |= LIBRAW_RAWOPTIONS_PENTAX_PS_ALLFRAMES; } else if (!strcmp(optstr, "-apentax4shotorder")) { strncpy(OUTR.p4shot_order, argv[arg++], 5); } else if (!argv[arg - 1][2]) OUT.use_auto_wb = 1; else fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]); break; case 'w': OUT.use_camera_wb = 1; break; case 'M': OUT.use_camera_matrix = (opm == '+')?3:0; break; case 'j': OUT.use_fuji_rotate = 0; break; case 'W': OUT.no_auto_bright = 1; break; case 'T': OUT.output_tiff = 1; break; case '4': OUT.gamm[0] = OUT.gamm[1] = OUT.no_auto_bright = 1; /* no break here! */ case '6': OUT.output_bps = 16; break; case 'Z': outext = strdup(argv[arg++]); break; case 'd': if (!strcmp(optstr, "-dcbi")) OUT.dcb_iterations = atoi(argv[arg++]); else if (!strcmp(optstr, "-doutputflags")) OUT.output_flags = atoi(argv[arg++]); else if (!strcmp(optstr, "-disars")) OUTR.use_rawspeed = 0; else if (!strcmp(optstr, "-disinterp")) OUT.no_interpolation = 1; else if (!strcmp(optstr, "-dcbe")) OUT.dcb_enhance_fl = 1; else if (!strcmp(optstr, "-dsrawrgb1")) { OUTR.specials |= LIBRAW_RAWSPECIAL_SRAW_NO_RGB; OUTR.specials &= ~LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE; } else if (!strcmp(optstr, "-dsrawrgb2")) { OUTR.specials &= ~LIBRAW_RAWSPECIAL_SRAW_NO_RGB; OUTR.specials |= LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE; } #ifdef USE_DNGSDK else if (!strcmp(optstr, "-dngsdk")) { dnghost = new dng_host; RawProcessor.set_dng_host(dnghost); } else if (!strcmp(optstr, "-dngflags")) { OUTR.use_dngsdk = atoi(argv[arg++]); } #endif else fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]); break; default: fprintf(stderr, "Unknown option \"-%c\".\n", opt); break; } } #ifndef LIBRAW_WIN32_CALLS putenv((char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field #else _putenv( (char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field #endif #define P1 RawProcessor.imgdata.idata #define S RawProcessor.imgdata.sizes #define C RawProcessor.imgdata.color #define T RawProcessor.imgdata.thumbnail #define P2 RawProcessor.imgdata.other if (outext && !strcmp(outext, "-")) use_timing = verbosity = 0; if (verbosity > 1) RawProcessor.set_progress_handler(my_progress_callback, (void *)"Sample data passed"); #ifdef LIBRAW_USE_OPENMP if (verbosity) printf("Using %d threads\n", omp_get_max_threads()); #endif int done = 0; int total = argc - arg; for (; arg < argc; arg++) { char outfn[1024]; if (verbosity) printf("Processing file %s\n", argv[arg]); timerstart(); if (use_mmap) { create_mapping(mapping, argv[arg]); if (!mapping.map) { fprintf(stderr, "Cannot map %s\n", argv[arg]); close_mapping(mapping); continue; } if ((ret = RawProcessor.open_buffer(mapping.map,mapping.fsize) != LIBRAW_SUCCESS)) { fprintf(stderr, "Cannot open_buffer %s: %s\n", argv[arg], libraw_strerror(ret)); close_mapping(mapping); continue; // no recycle b/c open file will recycle itself } } else if (use_mem) { int file = open(argv[arg], O_RDONLY | O_BINARY); struct stat st; if (file < 0) { fprintf(stderr, "Cannot open %s: %s\n", argv[arg], strerror(errno)); continue; } if (fstat(file, &st)) { fprintf(stderr, "Cannot stat %s: %s\n", argv[arg], strerror(errno)); close(file); continue; } if (!(iobuffer = malloc(st.st_size))) { fprintf(stderr, "Cannot allocate %d kbytes for memory buffer\n", (int)(st.st_size / 1024)); close(file); continue; } int rd; if (st.st_size != (rd = read(file, iobuffer, st.st_size))) { fprintf(stderr, "Cannot read %d bytes instead of %d to memory buffer\n", (int)rd, (int)st.st_size); close(file); free(iobuffer); continue; } close(file); if ((ret = RawProcessor.open_buffer(iobuffer, st.st_size)) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot open_buffer %s: %s\n", argv[arg], libraw_strerror(ret)); free(iobuffer); continue; // no recycle b/c open file will recycle itself } } else { ret = RawProcessor.open_file(argv[arg]); if (ret != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot open %s: %s\n", argv[arg], libraw_strerror(ret)); continue; // no recycle b/c open_file will recycle itself } } if (use_timing) timerprint("LibRaw::open_file()", argv[arg]); timerstart(); if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot unpack %s: %s\n", argv[arg], libraw_strerror(ret)); continue; } if (use_timing) timerprint("LibRaw::unpack()", argv[arg]); timerstart(); if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_process())) { fprintf(stderr, "Cannot do postprocessing on %s: %s\n", argv[arg], libraw_strerror(ret)); if (LIBRAW_FATAL_ERROR(ret)) continue; } if (use_timing) timerprint("LibRaw::dcraw_process()", argv[arg]); if (!outext) snprintf(outfn, sizeof(outfn), "%s.%s", argv[arg], OUT.output_tiff ? "tiff" : (P1.colors > 1 ? "ppm" : "pgm")); else if (!strcmp(outext, "-")) snprintf(outfn, sizeof(outfn), "-"); else { if (*outext == '.') // append snprintf(outfn, sizeof(outfn), "%s%s", argv[arg], outext); else if (strchr(outext, '.') && *outext != '.') // dot is not 1st char strncpy(outfn, outext, sizeof(outfn)); else { strncpy(outfn, argv[arg], sizeof(outfn)); if (strlen(outfn) > 0) { char *lastchar = outfn + strlen(outfn); // points to term 0 while (--lastchar > outfn) { if (*lastchar == '/' || *lastchar == '\\') break; if (*lastchar == '.') { *lastchar = 0; break; }; } } strncat(outfn, ".", sizeof(outfn) - strlen(outfn) - 1); strncat(outfn, outext, sizeof(outfn) - strlen(outfn) - 1); } } if (verbosity) { printf("Writing file %s\n", outfn); } if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn))) fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret)); else done++; RawProcessor.recycle(); // just for show this call if (use_mmap && mapping.map) close_mapping(mapping); else if (use_mem && iobuffer) { free(iobuffer); iobuffer = 0; } } #ifdef USE_DNGSDK if (dnghost) delete dnghost; #endif if (total == 0) return 1; if (done < total) return 2; return 0; } LibRaw-0.21.4/samples/dcraw_half.c000066400000000000000000000044751477673233700167150ustar00rootroot00000000000000/* -*- C++ -*- * File: dcraw_half.c * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8 , 2008 * * LibRaw C API sample: emulates "dcraw -h" * 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 #include #include #include #include "libraw/libraw.h" #define HANDLE_FATAL_ERROR(ret) \ if (ret) \ { \ fprintf(stderr, "%s: libraw %s\n", av[i], libraw_strerror(ret)); \ if (LIBRAW_FATAL_ERROR(ret)) \ exit(1); \ } #define HANDLE_ALL_ERRORS(ret) \ if (ret) \ { \ fprintf(stderr, "%s: libraw %s\n", av[i], libraw_strerror(ret)); \ continue; \ } int main(int ac, char *av[]) { int i; libraw_data_t *iprc = libraw_init(0); if (!iprc) { fprintf(stderr, "Cannot create libraw handle\n"); exit(1); } iprc->params.half_size = 1; /* dcraw -h */ for (i = 1; i < ac; i++) { char outfn[1024]; int ret = libraw_open_file(iprc, av[i]); HANDLE_ALL_ERRORS(ret); printf("Processing %s (%s %s)\n", av[i], iprc->idata.make, iprc->idata.model); ret = libraw_unpack(iprc); HANDLE_ALL_ERRORS(ret); ret = libraw_dcraw_process(iprc); HANDLE_ALL_ERRORS(ret); strcpy(outfn, av[i]); strcat(outfn, ".ppm"); printf("Writing to %s\n", outfn); ret = libraw_dcraw_ppm_tiff_writer(iprc, outfn); HANDLE_FATAL_ERROR(ret); } libraw_close(iprc); return 0; } LibRaw-0.21.4/samples/half_mt.c000066400000000000000000000107151477673233700162270ustar00rootroot00000000000000/* -*- C++ -*- * File: halt_mt.c * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8, 2008 * * LibRaw C API mutithreaded sample: emulates call to "dcraw -h [-w] [-a] [-v]" * 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 #include #include #include #include #include "libraw/libraw.h" #define HANDLE_ERRORS(ret) \ do \ { \ if (ret) \ { \ fprintf(stderr, "%s: %s\n", fn, libraw_strerror(ret)); \ if (LIBRAW_FATAL_ERROR(ret)) \ { \ libraw_close(iprc); \ return NULL; \ } \ } \ } while (0) int verbose = 0, use_camera_wb = 0, use_auto_wb = 0, tiff_mode = 0; pthread_mutex_t qm; char **queue = NULL; size_t qsize = 0, qptr = 0; char *get_next_file() { char *ret; if (!queue) return NULL; if (qptr >= qsize) return NULL; pthread_mutex_lock(&qm); ret = queue[qptr++]; pthread_mutex_unlock(&qm); return ret; } void *process_files(void *q) { int ret; int count = 0; char outfn[1024], *fn; libraw_data_t *iprc = libraw_init(0); if (!iprc) { fprintf(stderr, "Cannot create libraw handle\n"); return NULL; } while ((fn = get_next_file())) { iprc->params.half_size = 1; /* dcraw -h */ iprc->params.use_camera_wb = use_camera_wb; iprc->params.use_auto_wb = use_auto_wb; iprc->params.output_tiff = tiff_mode; ret = libraw_open_file(iprc, fn); if (verbose) fprintf(stderr, "%s: %s/%s\n", fn, iprc->idata.make, iprc->idata.model); HANDLE_ERRORS(ret); ret = libraw_unpack(iprc); HANDLE_ERRORS(ret); ret = libraw_dcraw_process(iprc); HANDLE_ERRORS(ret); snprintf(outfn, 1023, "%s.%s", fn, tiff_mode ? "tiff" : "ppm"); if (verbose) fprintf(stderr, "Writing file %s\n", outfn); ret = libraw_dcraw_ppm_tiff_writer(iprc, outfn); HANDLE_ERRORS(ret); count++; } libraw_close(iprc); return NULL; } void usage(const char *p) { printf("%s: Multi-threaded LibRaw sample app. Emulates dcraw -h [-w] [-a]\n", p); printf("Options:\n" "-J n - set parallel job count (default 2)\n" "-v - verbose\n" "-w - use camera white balance\n" "-a - average image for white balance\n"); exit(1); } int show_files(void *q) { char *p; int cnt = 0; while ((p = get_next_file())) { printf("%s\n", p); cnt++; } return cnt; } int main(int ac, char *av[]) { int i, max_threads = 2; pthread_t *threads; if (ac < 2) usage(av[0]); queue = calloc(ac - 1, sizeof(queue[0])); for (i = 1; i < ac; i++) { if (av[i][0] == '-') { if (av[i][1] == 'w') use_camera_wb = 1; if (av[i][1] == 'a') use_auto_wb = 1; if (av[i][1] == 'v') verbose = 1; if (av[i][1] == 'T') tiff_mode = 1; if (av[i][1] == 'J') { max_threads = atoi(av[++i]); if (max_threads < 1) { fprintf(stderr, "Job count should be at least 1\n"); exit(1); } } } else queue[qsize++] = av[i]; } pthread_mutex_init(&qm, NULL); threads = calloc(max_threads, sizeof(threads[0])); for (i = 0; i < max_threads; i++) pthread_create(&threads[i], NULL, process_files, NULL); for (i = 0; i < max_threads; i++) { int *iptr; if (threads[i]) { pthread_join(threads[i], (void *)&iptr); } } return 0; } LibRaw-0.21.4/samples/half_mt_win32.c000066400000000000000000000126731477673233700172560ustar00rootroot00000000000000/* -*- C++ -*- * File: halt_mt_win32.c * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8, 2008 * * LibRaw C API mutithreaded sample: emulates call to "dcraw -h [-w] [-a] [-v]" * Win32 version 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 #include #include #include #include #include "libraw/libraw.h" #ifdef LIBRAW_WIN32_CALLS #define snprintf _snprintf #endif #define HANDLE_ERRORS(ret) \ do \ { \ if (ret) \ { \ fprintf(stderr, "%s: %s\n", fn, libraw_strerror(ret)); \ if (LIBRAW_FATAL_ERROR(ret)) \ { \ libraw_close(iprc); \ return -1; \ } \ } \ } while (0) // global settings int verbose = 0, use_camera_wb = 0, use_auto_wb = 0, tiff_mode = 0; // global file queue HANDLE qmutex; char **queue = NULL; size_t qsize = 0, qptr = 0; char *get_next_file() { char *ret; DWORD dwWaitResult; if (!queue) return NULL; if (qptr >= qsize) return NULL; dwWaitResult = WaitForSingleObject(qmutex, // handle to mutex INFINITE); // no time-out interval switch (dwWaitResult) { // The thread got ownership of the mutex case WAIT_OBJECT_0: ret = queue[qptr++]; ReleaseMutex(qmutex); break; case WAIT_ABANDONED: return NULL; // cannot obtain the lock }; return ret; } // thread routine int process_files(void *q) { int ret; int count = 0; char outfn[1024], *fn; libraw_data_t *iprc = libraw_init(0); if (!iprc) { fprintf(stderr, "Cannot create libraw handle\n"); return -1; } while ((fn = get_next_file())) { iprc->params.half_size = 1; /* dcraw -h */ iprc->params.use_camera_wb = use_camera_wb; iprc->params.use_auto_wb = use_auto_wb; iprc->params.output_tiff = tiff_mode; ret = libraw_open_file(iprc, fn); if (verbose) fprintf(stderr, "%s: %s/%s\n", fn, iprc->idata.make, iprc->idata.model); HANDLE_ERRORS(ret); ret = libraw_unpack(iprc); HANDLE_ERRORS(ret); ret = libraw_dcraw_process(iprc); HANDLE_ERRORS(ret); snprintf(outfn, 1023, "%s.%s", fn, tiff_mode ? "tif" : "ppm"); if (verbose) fprintf(stderr, "Writing file %s\n", outfn); ret = libraw_dcraw_ppm_tiff_writer(iprc, outfn); HANDLE_ERRORS(ret); count++; } libraw_close(iprc); printf("Processed %d files\n", count); return 0; } void usage(const char *p) { printf("Options:\n" "-J n - set parallel job count (default 2)\n" "-v - verbose\n" "-w - use camera white balance\n" "-T - output TIFF instead of PPM\n" "-a - average image for white balance\n"); exit(1); } int show_files(void *q) { char *p; int cnt = 0; while (p = get_next_file()) { printf("%s\n", p); cnt++; } return cnt; } int main(int ac, char *av[]) { int i, max_threads = 2; HANDLE *threads; DWORD ThreadID; if (ac < 2) usage(av[0]); queue = calloc(ac - 1, sizeof(queue[0])); for (i = 1; i < ac; i++) { if (av[i][0] == '-') { if (av[i][1] == 'w') use_camera_wb = 1; if (av[i][1] == 'a') use_auto_wb = 1; if (av[i][1] == 'v') verbose = 1; if (av[i][1] == 'T') tiff_mode = 1; if (av[i][1] == 'J') { max_threads = atoi(av[++i]); if (max_threads < 1) { fprintf(stderr, "Job count should be at least 1\n"); exit(1); } } } else queue[qsize++] = av[i]; } qmutex = CreateMutex(NULL, FALSE, NULL); threads = calloc(max_threads, sizeof(threads[0])); for (i = 0; i < max_threads; i++) { if (NULL == (threads[i] = CreateThread(NULL, // default security attributes 0, // default stack size (LPTHREAD_START_ROUTINE)process_files, NULL, // no thread function arguments 0, // default creation flags &ThreadID) // receive thread identifier )) { printf("CreateThread error: %d\n", GetLastError()); return 1; } } WaitForMultipleObjects(max_threads, threads, TRUE, INFINITE); // Close thread and mutex handles for (i = 0; i < max_threads; i++) CloseHandle(threads[i]); CloseHandle(qmutex); return 0; } LibRaw-0.21.4/samples/mem_image_sample.cpp000066400000000000000000000176721477673233700204470ustar00rootroot00000000000000/* -*- C++ -*- * File: mem_image.cpp * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * * LibRaw mem_image/mem_thumb API test. Results should be same (bitwise) to dcraw [-4] [-6] [-e] * Testing note: for ppm-thumbnails you should use dcraw -w -e for thumbnail extraction 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 #include #include #include "libraw/libraw.h" #ifdef USE_JPEG #include "jpeglib.h" #endif #ifdef LIBRAW_WIN32_CALLS #define snprintf _snprintf #include #pragma comment(lib, "ws2_32.lib") #else #include #endif #ifdef USE_JPEG void write_jpeg(libraw_processed_image_t *img, const char *basename, int quality) { char fn[1024]; if(img->colors != 1 && img->colors != 3) { printf("Only BW and 3-color images supported for JPEG output\n"); return; } snprintf(fn, 1024, "%s.jpg", basename); FILE *f = fopen(fn, "wb"); if (!f) return; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ int row_stride; /* physical row width in image buffer */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, f); cinfo.image_width = img->width; /* image width and height, in pixels */ cinfo.image_height = img->height; cinfo.input_components = img->colors; /* # of color components per pixel */ cinfo.in_color_space = img->colors==3?JCS_RGB:JCS_GRAYSCALE; /* colorspace of input image */ jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); jpeg_start_compress(&cinfo, TRUE); row_stride = img->width * img->colors; /* JSAMPLEs per row in image_buffer */ while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = &img->data[cinfo.next_scanline * row_stride]; (void)jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); fclose(f); jpeg_destroy_compress(&cinfo); } #endif // no error reporting, only params check void write_ppm(libraw_processed_image_t *img, const char *basename) { if (!img) return; // type SHOULD be LIBRAW_IMAGE_BITMAP, but we'll check if (img->type != LIBRAW_IMAGE_BITMAP) return; if (img->colors != 3 && img->colors != 1) { printf("Only monochrome and 3-color images supported for PPM output\n"); return; } char fn[1024]; snprintf(fn, 1024, "%s.p%cm", basename, img->colors==1?'g':'p'); FILE *f = fopen(fn, "wb"); if (!f) return; fprintf(f, "P%d\n%d %d\n%d\n", img->colors/2 + 5, img->width, img->height, (1 << img->bits) - 1); /* NOTE: data in img->data is not converted to network byte order. So, we should swap values on some architectures for dcraw compatibility (unfortunately, xv cannot display 16-bit PPMs with network byte order data */ #define SWAP(a, b) \ { \ a ^= b; \ a ^= (b ^= a); \ } if (img->bits == 16 && htons(0x55aa) != 0x55aa) for (unsigned i = 0; i < img->data_size-1; i += 2) SWAP(img->data[i], img->data[i + 1]); #undef SWAP fwrite(img->data, img->data_size, 1, f); fclose(f); } void write_thumb(libraw_processed_image_t *img, const char *basename) { if (!img) return; if (img->type == LIBRAW_IMAGE_BITMAP) { char fnt[1024]; snprintf(fnt, 1024, "%s.thumb", basename); write_ppm(img, fnt); } else if (img->type == LIBRAW_IMAGE_JPEG) { char fn[1024]; snprintf(fn, 1024, "%s.thumb.jpg", basename); FILE *f = fopen(fn, "wb"); if (!f) return; fwrite(img->data, img->data_size, 1, f); fclose(f); } } int main(int ac, char *av[]) { int i, ret, output_thumbs = 0; #ifdef USE_JPEG int output_jpeg = 0, jpgqual = 90; #endif // don't use fixed size buffers in real apps! LibRaw RawProcessor; if (ac < 2) { printf("mem_image - LibRaw sample, to illustrate work for memory buffers.\n" "Emulates dcraw [-4] [-1] [-e] [-h]\n" #ifdef USE_JPEG "Usage: %s [-D] [-j[nn]] [-T] [-v] [-e] raw-files....\n" #else "Usage: %s [-D] [-T] [-v] [-e] raw-files....\n" #endif "\t-6 - output 16-bit PPM\n" "\t-4 - linear 16-bit data\n" "\t-e - extract thumbnails (same as dcraw -e in separate run)\n" #ifdef USE_JPEG "\t-j[qual] - output JPEG with qual quality (e.g. -j90)\n" #endif "\t-h - use half_size\n", av[0]); return 0; } putenv((char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field #define P1 RawProcessor.imgdata.idata #define S RawProcessor.imgdata.sizes #define C RawProcessor.imgdata.color #define T RawProcessor.imgdata.thumbnail #define P2 RawProcessor.imgdata.other #define OUT RawProcessor.imgdata.params for (i = 1; i < ac; i++) { if (av[i][0] == '-') { if (av[i][1] == '6' && av[i][2] == 0) OUT.output_bps = 16; if (av[i][1] == '4' && av[i][2] == 0) { OUT.output_bps = 16; OUT.gamm[0] = OUT.gamm[1] = OUT.no_auto_bright = 1; } if (av[i][1] == 'e' && av[i][2] == 0) output_thumbs++; if (av[i][1] == 'h' && av[i][2] == 0) OUT.half_size = 1; #ifdef USE_JPEG if (av[i][1] == 'j') { output_jpeg = 1; if(av[i][2] != 0) jpgqual = atoi(av[i]+2); } #endif continue; } #ifdef USE_JPEG if(output_jpeg && OUT.output_bps>8) { printf("JPEG is limited to 8 bit\n"); OUT.output_bps = 8; } #endif printf("Processing %s\n", av[i]); if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot open %s: %s\n", av[i], libraw_strerror(ret)); continue; // no recycle b/c open file will recycle itself } if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret)); continue; } // we should call dcraw_process before thumbnail extraction because for // some cameras (i.e. Kodak ones) white balance for thumbnail should be set // from main image settings ret = RawProcessor.dcraw_process(); if (LIBRAW_SUCCESS != ret) { fprintf(stderr, "Cannot do postprocessing on %s: %s\n", av[i], libraw_strerror(ret)); if (LIBRAW_FATAL_ERROR(ret)) continue; } libraw_processed_image_t *image = RawProcessor.dcraw_make_mem_image(&ret); if (image) { #ifdef USE_JPEG if(output_jpeg) write_jpeg(image, av[i], jpgqual); else #endif write_ppm(image, av[i]); LibRaw::dcraw_clear_mem(image); } else fprintf(stderr, "Cannot unpack %s to memory buffer: %s\n", av[i], libraw_strerror(ret)); if (output_thumbs) { if ((ret = RawProcessor.unpack_thumb()) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot unpack_thumb %s: %s\n", av[i], libraw_strerror(ret)); if (LIBRAW_FATAL_ERROR(ret)) continue; // skip to next file } else { libraw_processed_image_t *thumb = RawProcessor.dcraw_make_mem_thumb(&ret); if (thumb) { write_thumb(thumb, av[i]); LibRaw::dcraw_clear_mem(thumb); } else fprintf(stderr, "Cannot unpack thumbnail of %s to memory buffer: %s\n", av[i], libraw_strerror(ret)); } } RawProcessor.recycle(); // just for show this call } return 0; } LibRaw-0.21.4/samples/multirender_test.cpp000066400000000000000000000063301477673233700205440ustar00rootroot00000000000000/* -*- C++ -*- * File: multirender_test.cpp * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Jul 10, 2011 * * LibRaw simple C++ API: creates 8 different renderings from 1 source file. The 1st and 4th one should be identical 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 #include #include #include "libraw/libraw.h" #ifndef LIBRAW_WIN32_CALLS #include #include #include #include #endif #ifdef LIBRAW_WIN32_CALLS #define snprintf _snprintf #endif int process_once(LibRaw &RawProcessor, int half_mode, int camera_wb, int auto_wb, int suffix, int user_flip, char *fname) { char outfn[1024]; RawProcessor.imgdata.params.half_size = half_mode; RawProcessor.imgdata.params.use_camera_wb = camera_wb; RawProcessor.imgdata.params.use_auto_wb = auto_wb; RawProcessor.imgdata.params.user_flip = user_flip; int ret = RawProcessor.dcraw_process(); if (LIBRAW_SUCCESS != ret) { fprintf(stderr, "Cannot do postprocessing on %s: %s\n", fname, libraw_strerror(ret)); return ret; } snprintf(outfn, sizeof(outfn), "%s.%d.%s", fname, suffix, (RawProcessor.imgdata.idata.colors > 1 ? "ppm" : "pgm")); printf("Writing file %s\n", outfn); if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn))) fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret)); return ret; } int main(int ac, char *av[]) { int i, ret; LibRaw RawProcessor; if (ac < 2) { printf("multirender_test - LibRaw %s sample. Performs 4 different " "renderings of one file\n" " %d cameras supported\n" "Usage: %s raw-files....\n", LibRaw::version(), LibRaw::cameraCount(), av[0]); return 0; } for (i = 1; i < ac; i++) { printf("Processing file %s\n", av[i]); if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot open_file %s: %s\n", av[i], libraw_strerror(ret)); continue; // no recycle b/c open file will recycle itself } if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret)); continue; } process_once(RawProcessor, 0, 0, 0, 1, -1, av[i]); // default flip process_once(RawProcessor, 1, 0, 1, 2, -1, av[i]); process_once(RawProcessor, 1, 1, 0, 3, -1, av[i]); // default flip process_once(RawProcessor, 1, 1, 0, 4, 1, av[i]); // flip 1 process_once(RawProcessor, 1, 1, 0, 5, 3, av[i]); // flip 3 process_once(RawProcessor, 1, 1, 0, 6, 1, av[i]); // 1 again same as 4 process_once(RawProcessor, 1, 1, 0, 7, -1, av[i]); // default again, same as 3 process_once(RawProcessor, 0, 0, 0, 8, -1, av[i]); // same as 1 RawProcessor.recycle(); // just for show this call } return 0; } LibRaw-0.21.4/samples/openbayer_sample.cpp000066400000000000000000000034141477673233700205000ustar00rootroot00000000000000/* -*- C++ -*- * File: openvayer_sample.cpp * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Feb 11, 2020 * * LibRaw simple C++ API: opens bayer data (Kodak KAI-0340 sensor) from buffer, dump as 8-bit tiff 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 #include #include #include "libraw/libraw.h" #ifndef LIBRAW_WIN32_CALLS #include #include #include #include #endif int main(int ac, char *av[]) { if (ac != 2) return 1; FILE *in = fopen(av[1], "rb"); fseek(in, 0, SEEK_END); unsigned fsz = ftell(in); unsigned char *buffer = (unsigned char *)malloc(fsz); if (!buffer) return 2; fseek(in, 0, SEEK_SET); unsigned readb = fread(buffer, 1, fsz, in); if (readb != fsz) return 3; LibRaw rp; rp.imgdata.params.output_tiff = 1; int ret = rp.open_bayer(buffer, fsz, 640, 480, 0, 0, 0, 0, 0, LIBRAW_OPENBAYER_RGGB, 0, 0, 1400); if (ret != LIBRAW_SUCCESS) return 4; if ((ret = rp.unpack()) != LIBRAW_SUCCESS) printf("Unpack error: %d\n", ret); if ((ret = rp.dcraw_process()) != LIBRAW_SUCCESS) printf("Processing error: %d\n", ret); char outfn[256]; sprintf(outfn, "%s.tif", av[1]); if (LIBRAW_SUCCESS != (ret = rp.dcraw_ppm_tiff_writer(outfn))) printf("Cannot write %s: %s\n", outfn, libraw_strerror(ret)); else printf("Created %s\n", outfn); } LibRaw-0.21.4/samples/postprocessing_benchmark.cpp000066400000000000000000000145331477673233700222530ustar00rootroot00000000000000/* -*- C++ -*- * File: postprocessing_benchmark.cpp * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Jul 13, 2011 * * LibRaw simple C++ API: creates 8 different renderings from 1 source file. The 1st and 4th one should be identical 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 #include #include #include "libraw/libraw.h" #ifndef LIBRAW_WIN32_CALLS #include #include #include #else #include #endif #include "libraw/libraw.h" void timerstart(void); float timerend(void); int main(int argc, char *argv[]) { int i, ret, rep = 1; LibRaw RawProcessor; #ifdef OUT #undef OUT #endif #define OUT RawProcessor.imgdata.params #define OUTR RawProcessor.imgdata.rawparams #define S RawProcessor.imgdata.sizes if (argc < 2) { printf( "postprocessing benchmark: LibRaw %s sample, %d cameras supported\n" "Measures postprocessing speed with different options\n" "Usage: %s [-a] [-H N] [-q N] [-h] [-m N] [-n N] [-s N] [-B x y w h] " "[-R N]\n" "-a average image for white balance\n" "-H Highlight mode (0=clip, 1=unclip, 2=blend, " "3+=rebuild)\n" "-q Set the interpolation quality\n" "-h Half-size color image\n" "-m Apply a num-passes 3x3 median filter to R-G and B-G\n" "-n Set threshold for wavelet denoising\n" "-s Select one raw image from input file\n" "-B Crop output image\n" "-R Number of repetitions\n" "-c Do not use rawspeed\n", LibRaw::version(), LibRaw::cameraCount(), argv[0]); return 0; } char opm, opt, *cp, *sp; int arg, c; int shrink = 0; argv[argc] = (char *)""; for (arg = 1; (((opm = argv[arg][0]) - 2) | 2) == '+';) { char *optstr = argv[arg]; opt = argv[arg++][1]; if ((cp = strchr(sp = (char *)"HqmnsBR", opt)) != 0) for (i = 0; i < "1111141"[cp - sp] - '0'; i++) if (!isdigit(argv[arg + i][0]) && !optstr[2]) { fprintf(stderr, "Non-numeric argument to \"-%c\"\n", opt); return 1; } switch (opt) { case 'a': OUT.use_auto_wb = 1; break; case 'H': OUT.highlight = atoi(argv[arg++]); break; case 'q': OUT.user_qual = atoi(argv[arg++]); break; case 'h': OUT.half_size = 1; OUT.four_color_rgb = 1; shrink = 1; break; case 'm': OUT.med_passes = atoi(argv[arg++]); break; case 'n': OUT.threshold = (float)atof(argv[arg++]); break; case 's': OUTR.shot_select = abs(atoi(argv[arg++])); break; case 'B': for (c = 0; c < 4; c++) OUT.cropbox[c] = atoi(argv[arg++]); break; case 'R': rep = abs(atoi(argv[arg++])); if (rep < 1) rep = 1; break; case 'c': RawProcessor.imgdata.rawparams.use_rawspeed = 0; break; default: fprintf(stderr, "Unknown option \"-%c\".\n", opt); return 1; } } for (; arg < argc; arg++) { printf("Processing file %s\n", argv[arg]); timerstart(); if ((ret = RawProcessor.open_file(argv[arg])) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot open_file %s: %s\n", argv[arg], libraw_strerror(ret)); continue; // no recycle b/c open file will recycle itself } if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot unpack %s: %s\n", argv[arg], libraw_strerror(ret)); continue; } float qsec = timerend(); printf("\n%.1f msec for unpack\n", qsec); float mpix, rmpix; timerstart(); for (c = 0; c < rep; c++) { if ((ret = RawProcessor.dcraw_process()) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot postprocess %s: %s\n", argv[arg], libraw_strerror(ret)); break; } libraw_processed_image_t *p = RawProcessor.dcraw_make_mem_image(); if (p) RawProcessor.dcraw_clear_mem(p); RawProcessor.free_image(); } float msec = timerend() / (float)rep; if ((ret = RawProcessor.adjust_sizes_info_only()) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot adjust sizes for %s: %s\n", argv[arg], libraw_strerror(ret)); break; } rmpix = (S.iwidth * S.iheight) / 1000000.0f; if (c == rep) // no failure { unsigned int crop[4]; for (int i = 0; i < 4; i++) crop[i] = (OUT.cropbox[i]) >> shrink; if (crop[0] + crop[2] > S.iwidth) crop[2] = S.iwidth - crop[0]; if (crop[1] + crop[3] > S.iheight) crop[3] = S.iheight - crop[1]; mpix = float(crop[2] * crop[3]) / 1000000.0f; float mpixsec = mpix * 1000.0f / msec; printf("Performance: %.2f Mpix/sec\n" "File: %s, Frame: %d %.1f total Mpix, %.1f msec\n" "Params: WB=%s Highlight=%d Qual=%d HalfSize=%s Median=%d " "Wavelet=%.0f\n" "Crop: %u-%u:%ux%u, active Mpix: %.2f, %.1f frames/sec\n", mpixsec, argv[arg], OUTR.shot_select, rmpix, msec, OUT.use_auto_wb ? "auto" : "default", OUT.highlight, OUT.user_qual, OUT.half_size ? "YES" : "No", OUT.med_passes, OUT.threshold, crop[0], crop[1], crop[2], crop[3], mpix, 1000.0f / msec); } } return 0; } #ifndef LIBRAW_WIN32_CALLS static struct timeval start, end; void timerstart(void) { gettimeofday(&start, NULL); } float timerend(void) { gettimeofday(&end, NULL); float msec = (end.tv_sec - start.tv_sec) * 1000.0f + (end.tv_usec - start.tv_usec) / 1000.0f; return msec; } #else LARGE_INTEGER start; void timerstart(void) { QueryPerformanceCounter(&start); } float timerend() { LARGE_INTEGER unit, end; QueryPerformanceCounter(&end); QueryPerformanceFrequency(&unit); float msec = (float)(end.QuadPart - start.QuadPart); msec /= (float)unit.QuadPart / 1000.0f; return msec; } #endif LibRaw-0.21.4/samples/raw-identify.cpp000066400000000000000000000644261477673233700175670ustar00rootroot00000000000000/* -*- C++ -*- * File: identify.cpp * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8, 2008 * * LibRaw C++ demo: emulates dcraw -i [-v] * 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 #include #include #include #include #include #include "libraw/libraw.h" #ifdef LIBRAW_WIN32_CALLS #define snprintf _snprintf #define strcasecmp stricmp #define strncasecmp strnicmp #endif #ifndef LIBRAW_WIN32_CALLS #include #include #include #include #include #ifndef MAX_PATH #ifdef PATH_MAX #define MAX_PATH PATH_MAX #else #define MAX_PATH 4096 #endif #endif #endif #ifdef _MSC_VER #if _MSC_VER < 1800 /* below MSVC 2013 */ float roundf(float f) { return floorf(f + 0.5); } #endif #endif #define P1 MyCoolRawProcessor.imgdata.idata #define P2 MyCoolRawProcessor.imgdata.other #define P3 MyCoolRawProcessor.imgdata.makernotes.common #define mnLens MyCoolRawProcessor.imgdata.lens.makernotes #define exifLens MyCoolRawProcessor.imgdata.lens #define ShootingInfo MyCoolRawProcessor.imgdata.shootinginfo #define S MyCoolRawProcessor.imgdata.sizes #define O MyCoolRawProcessor.imgdata.params #define C MyCoolRawProcessor.imgdata.color #define T MyCoolRawProcessor.imgdata.thumbnail void print_verbose(FILE *, LibRaw &MyCoolRawProcessor, std::string &fn); void print_wbfun(FILE *, LibRaw &MyCoolRawProcessor, std::string &fn); void print_szfun(FILE *, LibRaw &MyCoolRawProcessor, std::string &fn); void print_unpackfun(FILE *, LibRaw &MyCoolRawProcessor, int print_frame, std::string &fn); /* table of fluorescents: 12 = FL-D; Daylight fluorescent (D 5700K – 7100K) (F1,F5) 13 = FL-N; Day white fluorescent (N 4600K – 5400K) (F7,F8) 14 = FL-W; Cool white fluorescent (W 3900K – 4500K) (F2,F6, office, store,warehouse) 15 = FL-WW; White fluorescent (WW 3200K – 3700K) (F3, residential) 16 = FL-L; Soft/Warm white fluorescent (L 2600K - 3250K) (F4, kitchen, bath) */ static const struct { const int NumId; const char *StrId; const char *hrStrId; // human-readable const int aux_setting; } WBToStr[] = { {LIBRAW_WBI_Unknown, "WBI_Unknown", "Unknown", 0}, {LIBRAW_WBI_Daylight, "WBI_Daylight", "Daylight", 0}, {LIBRAW_WBI_Fluorescent, "WBI_Fluorescent", "Fluorescent", 0}, {LIBRAW_WBI_Tungsten, "WBI_Tungsten", "Tungsten (Incandescent)", 0}, {LIBRAW_WBI_Flash, "WBI_Flash", "Flash", 0}, {LIBRAW_WBI_FineWeather, "WBI_FineWeather", "Fine Weather", 0}, {LIBRAW_WBI_Cloudy, "WBI_Cloudy", "Cloudy", 0}, {LIBRAW_WBI_Shade, "WBI_Shade", "Shade", 0}, {LIBRAW_WBI_FL_D, "WBI_FL_D", "Daylight Fluorescent", 0}, {LIBRAW_WBI_FL_N, "WBI_FL_N", "Day White Fluorescent", 0}, {LIBRAW_WBI_FL_W, "WBI_FL_W", "Cool White Fluorescent", 0}, {LIBRAW_WBI_FL_WW, "WBI_FL_WW", "White Fluorescent", 0}, {LIBRAW_WBI_FL_L, "WBI_FL_L", "Warm White Fluorescent", 0}, {LIBRAW_WBI_Ill_A, "WBI_Ill_A", "Illuminant A", 0}, {LIBRAW_WBI_Ill_B, "WBI_Ill_B", "Illuminant B", 0}, {LIBRAW_WBI_Ill_C, "WBI_Ill_C", "Illuminant C", 0}, {LIBRAW_WBI_D55, "WBI_D55", "D55", 0}, {LIBRAW_WBI_D65, "WBI_D65", "D65", 0}, {LIBRAW_WBI_D75, "WBI_D75", "D75", 0}, {LIBRAW_WBI_D50, "WBI_D50", "D50", 0}, {LIBRAW_WBI_StudioTungsten, "WBI_StudioTungsten", "ISO Studio Tungsten", 0}, {LIBRAW_WBI_BW, "WBI_BW", "BW", 0}, {LIBRAW_WBI_Other, "WBI_Other", "Other", 0}, {LIBRAW_WBI_Sunset, "WBI_Sunset", "Sunset", 1}, {LIBRAW_WBI_Underwater, "WBI_Underwater", "Underwater", 1}, {LIBRAW_WBI_FluorescentHigh, "WBI_FluorescentHigh", "Fluorescent High", 1}, {LIBRAW_WBI_HT_Mercury, "WBI_HT_Mercury", "HT Mercury", 1}, {LIBRAW_WBI_AsShot, "WBI_AsShot", "As Shot", 1}, {LIBRAW_WBI_Measured, "WBI_Measured", "Camera Measured", 1}, {LIBRAW_WBI_Auto, "WBI_Auto", "Camera Auto", 1}, {LIBRAW_WBI_Auto1, "WBI_Auto1", "Camera Auto 1", 1}, {LIBRAW_WBI_Auto2, "WBI_Auto2", "Camera Auto 2", 1}, {LIBRAW_WBI_Auto3, "WBI_Auto3", "Camera Auto 3", 1}, {LIBRAW_WBI_Auto4, "WBI_Auto4", "Camera Auto 4", 1}, {LIBRAW_WBI_Custom, "WBI_Custom", "Custom", 1}, {LIBRAW_WBI_Custom1, "WBI_Custom1", "Custom 1", 1}, {LIBRAW_WBI_Custom2, "WBI_Custom2", "Custom 2", 1}, {LIBRAW_WBI_Custom3, "WBI_Custom3", "Custom 3", 1}, {LIBRAW_WBI_Custom4, "WBI_Custom4", "Custom 4", 1}, {LIBRAW_WBI_Custom5, "WBI_Custom5", "Custom 5", 1}, {LIBRAW_WBI_Custom6, "WBI_Custom6", "Custom 6", 1}, {LIBRAW_WBI_PC_Set1, "WBI_PC_Set1", "PC Set 1", 1}, {LIBRAW_WBI_PC_Set2, "WBI_PC_Set2", "PC Set 2", 1}, {LIBRAW_WBI_PC_Set3, "WBI_PC_Set3", "PC Set 3", 1}, {LIBRAW_WBI_PC_Set4, "WBI_PC_Set4", "PC Set 4", 1}, {LIBRAW_WBI_PC_Set5, "WBI_PC_Set5", "PC Set 5", 1}, {LIBRAW_WBI_Kelvin, "WBI_Kelvin", "Kelvin", 1}, }; const char *WB_idx2str(unsigned WBi) { for (int i = 0; i < int(sizeof WBToStr / sizeof *WBToStr); i++) if (WBToStr[i].NumId == (int)WBi) return WBToStr[i].StrId; return 0; } const char *WB_idx2hrstr(unsigned WBi) { for (int i = 0; i < int(sizeof WBToStr / sizeof *WBToStr); i++) if (WBToStr[i].NumId == (int)WBi) return WBToStr[i].hrStrId; return 0; } double _log2(double a) { if(a > 0.00000000001) return log(a)/log(2.0); return -1000; } void trimSpaces(char *s) { char *p = s; if (!strncasecmp(p, "NO=", 3)) p = p + 3; /* fix for Nikon D70, D70s */ int l = strlen(p); if (!l) return; while (isspace(p[l - 1])) p[--l] = 0; /* trim trailing spaces */ while (*p && isspace(*p)) ++p, --l; /* trim leading spaces */ memmove(s, p, l + 1); } void print_usage(const char *pname) { printf("Usage: %s [options] inputfiles\n", pname); printf("Options:\n" "\t-v\tverbose output\n" "\t-w\tprint white balance\n" "\t-u\tprint unpack function\n" "\t-f\tprint frame size (only w/ -u)\n" "\t-s\tprint output image size\n" "\t-h\tforce half-size mode (only for -s)\n" "\t-M\tdisable use of raw-embedded color data\n" "\t+M\tforce use of raw-embedded color data\n" "\t-L filename\tread input files list from filename\n" "\t-o filename\toutput to filename\n"); } int main(int ac, char *av[]) { int ret; int verbose = 0, print_sz = 0, print_unpack = 0, print_frame = 0, print_wb = 0; LibRaw MyCoolRawProcessor; char *filelistfile = NULL; char *outputfilename = NULL; FILE *outfile = stdout; std::vector filelist; filelist.reserve(ac - 1); for (int i = 1; i < ac; i++) { if (av[i][0] == '-') { if (!strcmp(av[i], "-v")) verbose++; if (!strcmp(av[i], "-w")) print_wb++; if (!strcmp(av[i], "-u")) print_unpack++; if (!strcmp(av[i], "-s")) print_sz++; if (!strcmp(av[i], "-h")) O.half_size = 1; if (!strcmp(av[i], "-f")) print_frame++; if (!strcmp(av[i], "-M")) MyCoolRawProcessor.imgdata.params.use_camera_matrix = 0; if (!strcmp(av[i], "-L") && i < ac - 1) { filelistfile = av[i + 1]; i++; } if (!strcmp(av[i], "-o") && i < ac - 1) { outputfilename = av[i + 1]; i++; } continue; } else if (!strcmp(av[i], "+M")) { MyCoolRawProcessor.imgdata.params.use_camera_matrix = 3; continue; } filelist.push_back(av[i]); } if (filelistfile) { char *p; char path[MAX_PATH + 1]; FILE *f = fopen(filelistfile, "r"); if (f) { while (fgets(path, MAX_PATH, f)) { if ((p = strchr(path, '\n'))) *p = 0; if ((p = strchr(path, '\r'))) *p = 0; filelist.push_back(path); } fclose(f); } } if (filelist.size() < 1) { print_usage(av[0]); return 1; } if (outputfilename) outfile = fopen(outputfilename, "wt"); for (int i = 0; i < (int)filelist.size(); i++) { if ((ret = MyCoolRawProcessor.open_file(filelist[i].c_str())) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot decode %s: %s\n", filelist[i].c_str(), libraw_strerror(ret)); continue; // no recycle, open_file will recycle } if (print_sz) print_szfun(outfile, MyCoolRawProcessor, filelist[i]); else if (verbose) print_verbose(outfile, MyCoolRawProcessor, filelist[i]); else if (print_unpack) print_unpackfun(outfile, MyCoolRawProcessor, print_frame, filelist[i]); else if (print_wb) print_wbfun(outfile, MyCoolRawProcessor, filelist[i]); else fprintf(outfile, "%s is a %s %s image.\n", filelist[i].c_str(), P1.make, P1.model); MyCoolRawProcessor.recycle(); } // endfor return 0; } #define PRINTMATRIX3x4(of, mat, clrs) \ do \ { \ for (int r = 0; r < 3; r++) \ if (clrs == 4) \ fprintf(of, "%6.4f\t%6.4f\t%6.4f\t%6.4f\n", mat[r][0], mat[r][1], mat[r][2], mat[r][3]); \ else \ fprintf(of, "%6.4f\t%6.4f\t%6.4f\n", mat[r][0], mat[r][1], mat[r][2]); \ } while (0) #define PRINTMATRIX4x3(of, mat, clrs) \ do \ { \ for (int r = 0; r < clrs && r < 4; r++) \ fprintf(of, "%6.4f\t%6.4f\t%6.4f\n", mat[r][0], mat[r][1], mat[r][2]); \ } while (0) void print_verbose(FILE *outfile, LibRaw &MyCoolRawProcessor, std::string &fn) { int WBi; float denom; int ret; if ((ret = MyCoolRawProcessor.adjust_sizes_info_only())) { fprintf(outfile, "Cannot decode %s: %s\n", fn.c_str(), libraw_strerror(ret)); return; // no recycle, open_file will recycle } fprintf(outfile, "\nFilename: %s\n", fn.c_str()); if (C.OriginalRawFileName[0]) fprintf(outfile, "OriginalRawFileName: =%s=\n", C.OriginalRawFileName); fprintf(outfile, "Timestamp: %s", ctime(&(P2.timestamp))); fprintf(outfile, "Camera: %s %s ID: 0x%llx\n", P1.make, P1.model, mnLens.CamID); fprintf(outfile, "Normalized Make/Model: =%s/%s= ", P1.normalized_make, P1.normalized_model); fprintf(outfile, "CamMaker ID: %d\n", P1.maker_index); { int i = 0; char sep[] = ", "; if (C.UniqueCameraModel[0]) { i++; fprintf(outfile, "UniqueCameraModel: =%s=", C.UniqueCameraModel); } if (C.LocalizedCameraModel[0]) { if (i) { fprintf(outfile, "%s", sep); i++; } fprintf(outfile, "LocalizedCameraModel: =%s=", C.LocalizedCameraModel); } if (i) { fprintf(outfile, "\n"); i = 0; } if (C.ImageUniqueID[0]) { if (i) fprintf(outfile, "%s", sep); i++; fprintf(outfile, "ImageUniqueID: =%s=", C.ImageUniqueID); } if (C.RawDataUniqueID[0]) { if (i) fprintf(outfile, "%s", sep); i++; fprintf(outfile, "RawDataUniqueID: =%s=", C.RawDataUniqueID); } if (i) fprintf(outfile, "\n"); } if (ShootingInfo.BodySerial[0] && strcmp(ShootingInfo.BodySerial, "0")) { trimSpaces(ShootingInfo.BodySerial); fprintf(outfile, "Body#: %s", ShootingInfo.BodySerial); } else if (C.model2[0] && (!strncasecmp(P1.normalized_make, "Kodak", 5))) { trimSpaces(C.model2); fprintf(outfile, "Body#: %s", C.model2); } if (ShootingInfo.InternalBodySerial[0]) { trimSpaces(ShootingInfo.InternalBodySerial); fprintf(outfile, " BodyAssy#: %s", ShootingInfo.InternalBodySerial); } if (exifLens.LensSerial[0]) { trimSpaces(exifLens.LensSerial); fprintf(outfile, " Lens#: %s", exifLens.LensSerial); } if (exifLens.InternalLensSerial[0]) { trimSpaces(exifLens.InternalLensSerial); fprintf(outfile, " LensAssy#: %s", exifLens.InternalLensSerial); } if (P2.artist[0]) fprintf(outfile, " Owner: %s\n", P2.artist); if (P1.dng_version) { fprintf(outfile, " DNG Version: "); for (int i = 24; i >= 0; i -= 8) fprintf(outfile, "%d%c", P1.dng_version >> i & 255, i ? '.' : '\n'); } fprintf(outfile, "\nEXIF:\n"); fprintf(outfile, "\tMinFocal: %0.1f mm\n", exifLens.MinFocal); fprintf(outfile, "\tMaxFocal: %0.1f mm\n", exifLens.MaxFocal); fprintf(outfile, "\tMaxAp @MinFocal: f/%0.1f\n", exifLens.MaxAp4MinFocal); fprintf(outfile, "\tMaxAp @MaxFocal: f/%0.1f\n", exifLens.MaxAp4MaxFocal); fprintf(outfile, "\tCurFocal: %0.1f mm\n", P2.focal_len); fprintf(outfile, "\tMaxAperture @CurFocal: f/%0.1f\n", exifLens.EXIF_MaxAp); fprintf(outfile, "\tFocalLengthIn35mmFormat: %d mm\n", exifLens.FocalLengthIn35mmFormat); fprintf(outfile, "\tLensMake: %s\n", exifLens.LensMake); fprintf(outfile, "\tLens: %s\n", exifLens.Lens); fprintf(outfile, "\n"); fprintf(outfile, "\nMakernotes:\n"); fprintf(outfile, "\tDriveMode: %d\n", ShootingInfo.DriveMode); fprintf(outfile, "\tFocusMode: %d\n", ShootingInfo.FocusMode); fprintf(outfile, "\tMeteringMode: %d\n", ShootingInfo.MeteringMode); fprintf(outfile, "\tAFPoint: %d\n", ShootingInfo.AFPoint); fprintf(outfile, "\tExposureMode: %d\n", ShootingInfo.ExposureMode); fprintf(outfile, "\tExposureProgram: %d\n", ShootingInfo.ExposureProgram); fprintf(outfile, "\tImageStabilization: %d\n", ShootingInfo.ImageStabilization); fprintf(outfile, "\tLens: %s\n", mnLens.Lens); fprintf(outfile, "\tLensFormat: %d, ", mnLens.LensFormat); fprintf(outfile, "\tLensMount: %d, ", mnLens.LensMount); fprintf(outfile, "\tFocalType: %d, ", mnLens.FocalType); switch (mnLens.FocalType) { case LIBRAW_FT_UNDEFINED: fprintf(outfile, "Undefined\n"); break; case LIBRAW_FT_PRIME_LENS: fprintf(outfile, "Prime lens\n"); break; case LIBRAW_FT_ZOOM_LENS: fprintf(outfile, "Zoom lens\n"); break; default: fprintf(outfile, "Unknown\n"); break; } fprintf(outfile, "\tLensFeatures_pre: %s\n", mnLens.LensFeatures_pre); fprintf(outfile, "\tLensFeatures_suf: %s\n", mnLens.LensFeatures_suf); fprintf(outfile, "\tMinFocal: %0.1f mm\n", mnLens.MinFocal); fprintf(outfile, "\tMaxFocal: %0.1f mm\n", mnLens.MaxFocal); fprintf(outfile, "\tMaxAp @MinFocal: f/%0.1f\n", mnLens.MaxAp4MinFocal); fprintf(outfile, "\tMaxAp @MaxFocal: f/%0.1f\n", mnLens.MaxAp4MaxFocal); fprintf(outfile, "\tMinAp @MinFocal: f/%0.1f\n", mnLens.MinAp4MinFocal); fprintf(outfile, "\tMinAp @MaxFocal: f/%0.1f\n", mnLens.MinAp4MaxFocal); fprintf(outfile, "\tMaxAp: f/%0.1f\n", mnLens.MaxAp); fprintf(outfile, "\tMinAp: f/%0.1f\n", mnLens.MinAp); fprintf(outfile, "\tCurFocal: %0.1f mm\n", mnLens.CurFocal); fprintf(outfile, "\tCurAp: f/%0.1f\n", mnLens.CurAp); fprintf(outfile, "\tMaxAp @CurFocal: f/%0.1f\n", mnLens.MaxAp4CurFocal); fprintf(outfile, "\tMinAp @CurFocal: f/%0.1f\n", mnLens.MinAp4CurFocal); if (exifLens.makernotes.FocalLengthIn35mmFormat > 1.0f) fprintf(outfile, "\tFocalLengthIn35mmFormat: %0.1f mm\n", exifLens.makernotes.FocalLengthIn35mmFormat); if (exifLens.nikon.EffectiveMaxAp > 0.1f) fprintf(outfile, "\tEffectiveMaxAp: f/%0.1f\n", exifLens.nikon.EffectiveMaxAp); if (exifLens.makernotes.LensFStops > 0.1f) fprintf(outfile, "\tLensFStops @CurFocal: %0.2f\n", exifLens.makernotes.LensFStops); fprintf(outfile, "\tTeleconverterID: %lld\n", mnLens.TeleconverterID); fprintf(outfile, "\tTeleconverter: %s\n", mnLens.Teleconverter); fprintf(outfile, "\tAdapterID: %lld\n", mnLens.AdapterID); fprintf(outfile, "\tAdapter: %s\n", mnLens.Adapter); fprintf(outfile, "\tAttachmentID: %lld\n", mnLens.AttachmentID); fprintf(outfile, "\tAttachment: %s\n", mnLens.Attachment); fprintf(outfile, "\n"); fprintf(outfile, "ISO speed: %d\n", (int)P2.iso_speed); if (P3.real_ISO > 0.1f) fprintf(outfile, "real ISO speed: %d\n", (int)P3.real_ISO); fprintf(outfile, "Shutter: "); if (P2.shutter > 0 && P2.shutter < 1) P2.shutter = fprintf(outfile, "1/%0.1f\n", 1.0f / P2.shutter); else if (P2.shutter >= 1) fprintf(outfile, "%0.1f sec\n", P2.shutter); else /* negative*/ fprintf(outfile, " negative value\n"); fprintf(outfile, "Aperture: f/%0.1f\n", P2.aperture); fprintf(outfile, "Focal length: %0.1f mm\n", P2.focal_len); if (P3.exifAmbientTemperature > -273.15f) fprintf(outfile, "Ambient temperature (exif data): %6.2f° C\n", P3.exifAmbientTemperature); if (P3.CameraTemperature > -273.15f) fprintf(outfile, "Camera temperature: %6.2f° C\n", P3.CameraTemperature); if (P3.SensorTemperature > -273.15f) fprintf(outfile, "Sensor temperature: %6.2f° C\n", P3.SensorTemperature); if (P3.SensorTemperature2 > -273.15f) fprintf(outfile, "Sensor temperature2: %6.2f° C\n", P3.SensorTemperature2); if (P3.LensTemperature > -273.15f) fprintf(outfile, "Lens temperature: %6.2f° C\n", P3.LensTemperature); if (P3.AmbientTemperature > -273.15f) fprintf(outfile, "Ambient temperature: %6.2f° C\n", P3.AmbientTemperature); if (P3.BatteryTemperature > -273.15f) fprintf(outfile, "Battery temperature: %6.2f° C\n", P3.BatteryTemperature); if (P3.FlashGN > 1.0f) fprintf(outfile, "Flash Guide Number: %6.2f\n", P3.FlashGN); fprintf(outfile, "Flash exposure compensation: %0.2f EV\n", P3.FlashEC); if (C.profile) fprintf(outfile, "Embedded ICC profile: yes, %d bytes\n", C.profile_length); else fprintf(outfile, "Embedded ICC profile: no\n"); if (C.dng_levels.baseline_exposure > -999.f) fprintf(outfile, "Baseline exposure: %04.3f\n", C.dng_levels.baseline_exposure); fprintf(outfile, "Number of raw images: %d\n", P1.raw_count); if (S.pixel_aspect != 1) fprintf(outfile, "Pixel Aspect Ratio: %0.6f\n", S.pixel_aspect); if (T.tlength) fprintf(outfile, "Thumb size: %4d x %d\n", T.twidth, T.theight); fprintf(outfile, "Full size: %4d x %d\n", S.raw_width, S.raw_height); if (S.raw_inset_crops[0].cwidth) { fprintf(outfile, "Raw inset, width x height: %4d x %d ", S.raw_inset_crops[0].cwidth, S.raw_inset_crops[0].cheight); if (S.raw_inset_crops[0].cleft != 0xffff) fprintf(outfile, "left: %d ", S.raw_inset_crops[0].cleft); if (S.raw_inset_crops[0].ctop != 0xffff) fprintf(outfile, "top: %d", S.raw_inset_crops[0].ctop); fprintf(outfile, "\n"); } fprintf(outfile, "Image size: %4d x %d\n", S.width, S.height); fprintf(outfile, "Output size: %4d x %d\n", S.iwidth, S.iheight); fprintf(outfile, "Image flip: %d\n", S.flip); fprintf(outfile, "Raw colors: %d", P1.colors); if (P1.filters) { fprintf(outfile, "\nFilter pattern: "); if (!P1.cdesc[3]) P1.cdesc[3] = 'G'; for (int i = 0; i < 16; i++) putchar(P1.cdesc[MyCoolRawProcessor.fcol(i >> 1, i & 1)]); } if (C.black) { fprintf(outfile, "\nblack: %d", C.black); } if (C.cblack[0] != 0) { fprintf(outfile, "\ncblack[0 .. 3]:"); for (int c = 0; c < 4; c++) fprintf(outfile, " %d", C.cblack[c]); } if ((C.cblack[4] * C.cblack[5]) > 0) { fprintf(outfile, "\nBlackLevelRepeatDim: %d x %d\n", C.cblack[4], C.cblack[5]); int n = C.cblack[4] * C.cblack[5]; fprintf(outfile, "cblack[6 .. %d]:", 6 + n - 1); for (int c = 6; c < 6 + n; c++) fprintf(outfile, " %d", C.cblack[c]); } if (C.linear_max[0] != 0) { fprintf(outfile, "\nHighlight linearity limits:"); for (int c = 0; c < 4; c++) fprintf(outfile, " %ld", C.linear_max[c]); } if (P1.colors > 1) { fprintf(outfile, "\nMakernotes WB data: coeffs EVs"); if ((C.cam_mul[0] > 0) && (C.cam_mul[1] > 0)) { fprintf(outfile, "\n %-23s %g %g %g %g %5.2f %5.2f %5.2f %5.2f", "As shot", C.cam_mul[0], C.cam_mul[1], C.cam_mul[2], C.cam_mul[3], roundf(_log2(C.cam_mul[0] / C.cam_mul[1]) * 100.0f) / 100.0f, 0.0f, roundf(_log2(C.cam_mul[2] / C.cam_mul[1]) * 100.0f) / 100.0f, C.cam_mul[3] ? roundf(_log2(C.cam_mul[3] / C.cam_mul[1]) * 100.0f) / 100.0f : 0.0f); } for (int cnt = 0; cnt < int(sizeof WBToStr / sizeof *WBToStr); cnt++) { WBi = WBToStr[cnt].NumId; if ((C.WB_Coeffs[WBi][0] > 0) && (C.WB_Coeffs[WBi][1] > 0)) { denom = (float)C.WB_Coeffs[WBi][1]; fprintf(outfile, "\n %-23s %4d %4d %4d %4d %5.2f %5.2f %5.2f %5.2f", WBToStr[cnt].hrStrId, C.WB_Coeffs[WBi][0], C.WB_Coeffs[WBi][1], C.WB_Coeffs[WBi][2], C.WB_Coeffs[WBi][3], roundf(_log2((float)C.WB_Coeffs[WBi][0] / denom) * 100.0f) / 100.0f, 0.0f, roundf(_log2((float)C.WB_Coeffs[WBi][2] / denom) * 100.0f) / 100.0f, C.WB_Coeffs[3] ? roundf(_log2((float)C.WB_Coeffs[WBi][3] / denom) * 100.0f) / 100.0f : 0.0f); } } if (C.rgb_cam[0][0] > 0.0001) { fprintf(outfile, "\n\nCamera2RGB matrix (mode: %d):\n", MyCoolRawProcessor.imgdata.params.use_camera_matrix); PRINTMATRIX3x4(outfile, C.rgb_cam, P1.colors); } fprintf(outfile, "\nXYZ->CamRGB matrix:\n"); PRINTMATRIX4x3(outfile, C.cam_xyz, P1.colors); for (int cnt = 0; cnt < 2; cnt++) { if (fabsf(C.P1_color[cnt].romm_cam[0]) > 0) { fprintf(outfile, "\nPhaseOne Matrix %d:\n", cnt + 1); for (int i = 0; i < 3; i++) fprintf(outfile, "%6.4f\t%6.4f\t%6.4f\n", C.P1_color[cnt].romm_cam[i * 3], C.P1_color[cnt].romm_cam[i * 3 + 1], C.P1_color[cnt].romm_cam[i * 3 + 2]); } } if (fabsf(C.cmatrix[0][0]) > 0) { fprintf(outfile, "\ncamRGB -> sRGB Matrix:\n"); PRINTMATRIX3x4(outfile, C.cmatrix, P1.colors); } if (fabsf(C.ccm[0][0]) > 0) { fprintf(outfile, "\nColor Correction Matrix:\n"); PRINTMATRIX3x4(outfile, C.ccm, P1.colors); } for (int cnt = 0; cnt < 2; cnt++) { if (C.dng_color[cnt].illuminant != LIBRAW_WBI_None) { if (C.dng_color[cnt].illuminant <= LIBRAW_WBI_StudioTungsten) { fprintf(outfile, "\nDNG Illuminant %d: %s", cnt + 1, WB_idx2hrstr(C.dng_color[cnt].illuminant)); } else if (C.dng_color[cnt].illuminant == LIBRAW_WBI_Other) { fprintf(outfile, "\nDNG Illuminant %d: Other", cnt + 1); } else { fprintf(outfile, "\nDNG Illuminant %d is out of EXIF LightSources range " "[0:24, 255]: %d", cnt + 1, C.dng_color[cnt].illuminant); } } } for (int n = 0; n < 2; n++) { if (fabsf(C.dng_color[n].colormatrix[0][0]) > 0) { fprintf(outfile, "\nDNG color matrix %d:\n", n + 1); PRINTMATRIX4x3(outfile, C.dng_color[n].colormatrix, P1.colors); } } for (int n = 0; n < 2; n++) { if (fabsf(C.dng_color[n].calibration[0][0]) > 0) { fprintf(outfile, "\nDNG calibration matrix %d:\n", n + 1); for (int i = 0; i < P1.colors && i < 4; i++) { for (int j = 0; j < P1.colors && j < 4; j++) fprintf(outfile, "%6.4f\t", C.dng_color[n].calibration[j][i]); fprintf(outfile, "\n"); } } } for (int n = 0; n < 2; n++) { if (fabsf(C.dng_color[n].forwardmatrix[0][0]) > 0) { fprintf(outfile, "\nDNG forward matrix %d:\n", n + 1); PRINTMATRIX3x4(outfile, C.dng_color[n].forwardmatrix, P1.colors); } } fprintf(outfile, "\nDerived D65 multipliers:"); for (int c = 0; c < P1.colors; c++) fprintf(outfile, " %f", C.pre_mul[c]); fprintf(outfile, "\n"); } } void print_wbfun(FILE *outfile, LibRaw &MyCoolRawProcessor, std::string &fn) { int WBi; float denom; fprintf(outfile, "// %s %s\n", P1.make, P1.model); for (int cnt = 0; cnt < int(sizeof WBToStr / sizeof *WBToStr); cnt++) { WBi = WBToStr[cnt].NumId; if (C.WB_Coeffs[WBi][0] && C.WB_Coeffs[WBi][1] && !WBToStr[cnt].aux_setting) { denom = (float)C.WB_Coeffs[WBi][1]; fprintf(outfile, "{\"%s\", \"%s\", %s, {%6.5ff, 1.0f, %6.5ff, ", P1.normalized_make, P1.normalized_model, WBToStr[cnt].StrId, C.WB_Coeffs[WBi][0] / denom, C.WB_Coeffs[WBi][2] / denom); if (C.WB_Coeffs[WBi][1] == C.WB_Coeffs[WBi][3]) fprintf(outfile, "1.0f}},\n"); else fprintf(outfile, "%6.5ff}},\n", C.WB_Coeffs[WBi][3] / denom); } } for (int cnt = 0; cnt < 64; cnt++) if (C.WBCT_Coeffs[cnt][0]) { fprintf(outfile, "{\"%s\", \"%s\", %d, {%6.5ff, 1.0f, %6.5ff, ", P1.normalized_make, P1.normalized_model, (int)C.WBCT_Coeffs[cnt][0], C.WBCT_Coeffs[cnt][1] / C.WBCT_Coeffs[cnt][2], C.WBCT_Coeffs[cnt][3] / C.WBCT_Coeffs[cnt][2]); if (C.WBCT_Coeffs[cnt][2] == C.WBCT_Coeffs[cnt][4]) fprintf(outfile, "1.0f}},\n"); else fprintf(outfile, "%6.5ff}},\n", C.WBCT_Coeffs[cnt][4] / C.WBCT_Coeffs[cnt][2]); } else break; fprintf(outfile, "\n"); } void print_szfun(FILE *outfile, LibRaw &MyCoolRawProcessor, std::string &fn) { fprintf(outfile, "%s\t%s\t%s\t%d\t%d\n", fn.c_str(), P1.make, P1.model, S.width, S.height); } void print_unpackfun(FILE *outfile, LibRaw &MyCoolRawProcessor, int print_frame, std::string &fn) { char frame[48] = ""; if (print_frame) { ushort right_margin = S.raw_width - S.width - S.left_margin; ushort bottom_margin = S.raw_height - S.height - S.top_margin; snprintf(frame, 48, "F=%dx%dx%dx%d RS=%dx%d", S.left_margin, S.top_margin, right_margin, bottom_margin, S.raw_width, S.raw_height); } fprintf(outfile, "%s\t%s\t%s\t%s/%s\n", fn.c_str(), MyCoolRawProcessor.unpack_function_name(), frame, P1.make, P1.model); } LibRaw-0.21.4/samples/rawtextdump.cpp000066400000000000000000000101411477673233700175320ustar00rootroot00000000000000/* -*- C++ -*- * File: raw2text.cpp * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sun Sept 01, 2020 * * LibRaw sample * Dumps (small) selection of RAW data to text file * 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 #include #include #ifndef WIN32 #include #else #include #endif #include "libraw/libraw.h" void usage(const char *av) { printf( "Dump (small) selection of RAW file as tab-separated text file\n" "Usage: %s inputfile COL ROW [CHANNEL] [width] [height]\n" " COL - start column\n" " ROW - start row\n" " CHANNEL - raw channel to dump, default is 0 (red for rggb)\n" " width - area width to dump, default is 16\n" " height - area height to dump, default is 4\n" , av); } unsigned subtract_bl(unsigned int val, int bl) { return val > (unsigned)bl ? val - (unsigned)bl : 0; } class LibRaw_bl : public LibRaw { public: void adjust_blacklevel() { LibRaw::adjust_bl(); } }; int main(int ac, char *av[]) { if (ac < 4) { usage(av[0]); exit(1); } int colstart = atoi(av[2]); int rowstart = atoi(av[3]); int channel = 0; if (ac > 4) channel = atoi(av[4]); int width = 16; if (ac > 5) width = atoi(av[5]); int height = 4; if (ac > 6) height = atoi(av[6]); if (width <1 || height<1) { usage(av[0]); exit(1); } LibRaw_bl lr; if (lr.open_file(av[1]) != LIBRAW_SUCCESS) { fprintf(stderr, "Unable to open file %s\n", av[1]); exit(1); } if ((lr.imgdata.idata.colors == 1 && channel>0) || (channel >3)) { fprintf(stderr, "Incorrect CHANNEL specified: %d\n", channel); exit(1); } if (lr.unpack() != LIBRAW_SUCCESS) { fprintf(stderr, "Unable to unpack raw data from %s\n", av[1]); exit(1); } lr.adjust_blacklevel(); printf("%s\t%d-%d-%dx%d\tchannel: %d\n", av[1], colstart, rowstart, width, height, channel); printf("%6s", "R\\C"); for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++) printf("%6u", col); printf("\n"); if (lr.imgdata.rawdata.raw_image) { for (int row = rowstart; row < rowstart + height && row < lr.imgdata.sizes.raw_height; row++) { unsigned rcolors[48]; if (lr.imgdata.idata.colors > 1) for (int c = 0; c < 48; c++) rcolors[c] = lr.COLOR(row, c); else memset(rcolors, 0, sizeof(rcolors)); unsigned short *rowdata = &lr.imgdata.rawdata.raw_image[row * lr.imgdata.sizes.raw_pitch / 2]; printf("%6u", row); for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++) if (rcolors[col % 48] == (unsigned)channel) printf("%6u", subtract_bl(rowdata[col],lr.imgdata.color.cblack[channel])); else printf(" -"); printf("\n"); } } else if (lr.imgdata.rawdata.color4_image && channel < 4) { for (int row = rowstart; row < rowstart + height && row < lr.imgdata.sizes.raw_height; row++) { unsigned short(*rowdata)[4] = &lr.imgdata.rawdata.color4_image[row * lr.imgdata.sizes.raw_pitch / 8]; printf("%6u", row); for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++) printf("%6u", subtract_bl(rowdata[col][channel],lr.imgdata.color.cblack[channel])); printf("\n"); } } else if (lr.imgdata.rawdata.color3_image && channel < 3) { for (int row = rowstart; row < rowstart + height && row < lr.imgdata.sizes.raw_height; row++) { unsigned short(*rowdata)[3] = &lr.imgdata.rawdata.color3_image[row * lr.imgdata.sizes.raw_pitch / 6]; printf("%6u", row); for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++) printf("%6u", subtract_bl(rowdata[col][channel],lr.imgdata.color.cblack[channel])); printf("\n"); } } else printf("Unsupported file data (e.g. floating point format), or incorrect channel specified\n"); } LibRaw-0.21.4/samples/simple_dcraw.cpp000066400000000000000000000160541477673233700176300ustar00rootroot00000000000000/* -*- C++ -*- * File: simple_dcraw.cpp * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8, 2008 * * LibRaw simple C++ API: emulates call to "dcraw [-D] [-T] [-v] [-e] [-4]" 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 #include #include #include "libraw/libraw.h" #ifndef LIBRAW_WIN32_CALLS #include #include #include #include #endif #ifdef LIBRAW_WIN32_CALLS #define snprintf _snprintf #endif int my_progress_callback(void *unused_data, enum LibRaw_progress state, int iter, int expected) { if (iter == 0) printf("CB: state=%x, expected %d iterations\n", state, expected); return 0; } char *customCameras[] = { (char *)"43704960,4080,5356, 0, 0, 0, 0,0,148,0,0, Dalsa, FTF4052C Full,0", (char *)"42837504,4008,5344, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 3:4", (char *)"32128128,4008,4008, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 1:1", (char *)"24096096,4008,3006, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 4:3", (char *)"18068064,4008,2254, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 16:9", (char *)"67686894,5049,6703, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C Full", (char *)"66573312,4992,6668, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 3:4", (char *)"49840128,4992,4992, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 1:1", (char *)"37400064,4992,3746, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 4:3", (char *)"28035072,4992,2808, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 16:9", NULL}; int main(int ac, char *av[]) { int i, ret, verbose = 0, output_thumbs = 0, output_all_thumbs = 0; // don't use fixed size buffers in real apps! char outfn[1024], thumbfn[1024]; LibRaw* RawProcessor = new LibRaw; RawProcessor->imgdata.rawparams.custom_camera_strings = customCameras; if (ac < 2) { printf("simple_dcraw - LibRaw %s sample. Emulates dcraw [-D] [-T] [-v] " "[-e] [-E]\n" " %d cameras supported\n" "Usage: %s [-D] [-T] [-v] [-e] raw-files....\n" "\t-4 - 16-bit mode\n" "\t-L - list supported cameras and exit\n" "\t-v - verbose output\n" "\t-T - output TIFF files instead of .pgm/ppm\n" "\t-e - extract thumbnails (same as dcraw -e in separate run)\n" "\t-E - extract all thumbnails\n", LibRaw::version(), LibRaw::cameraCount(), av[0]); delete RawProcessor; return 0; } putenv((char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field #define P1 RawProcessor->imgdata.idata #define S RawProcessor->imgdata.sizes #define C RawProcessor->imgdata.color #define T RawProcessor->imgdata.thumbnail #define P2 RawProcessor->imgdata.other #define OUT RawProcessor->imgdata.params for (i = 1; i < ac; i++) { if (av[i][0] == '-') { if (av[i][1] == 'T' && av[i][2] == 0) OUT.output_tiff = 1; if (av[i][1] == 'v' && av[i][2] == 0) verbose++; if (av[i][1] == 'e' && av[i][2] == 0) output_thumbs++; if (av[i][1] == 'E' && av[i][2] == 0) { output_thumbs++; output_all_thumbs++; } if (av[i][1] == '4' && av[i][2] == 0) OUT.output_bps = 16; if (av[i][1] == 'C' && av[i][2] == 0) RawProcessor->set_progress_handler(my_progress_callback, NULL); if (av[i][1] == 'L' && av[i][2] == 0) { const char **clist = LibRaw::cameraList(); const char **cc = clist; while (*cc) { printf("%s\n", *cc); cc++; } delete RawProcessor; exit(0); } continue; } if (verbose) printf("Processing file %s\n", av[i]); if ((ret = RawProcessor->open_file(av[i])) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot open_file %s: %s\n", av[i], libraw_strerror(ret)); continue; // no recycle b/c open file will recycle itself } if (!output_thumbs) // No unpack for thumb extraction if ((ret = RawProcessor->unpack()) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret)); continue; } // thumbnail unpacking and output in the middle of main // image processing - for test purposes! if(output_all_thumbs) { if (verbose) printf("Extracting %d thumbnails\n", RawProcessor->imgdata.thumbs_list.thumbcount); for (int t = 0; t < RawProcessor->imgdata.thumbs_list.thumbcount; t++) { if ((ret = RawProcessor->unpack_thumb_ex(t)) != LIBRAW_SUCCESS) fprintf(stderr, "Cannot unpack_thumb #%d from %s: %s\n", t, av[i], libraw_strerror(ret)); if (LIBRAW_FATAL_ERROR(ret)) break; // skip to next file snprintf(thumbfn, sizeof(thumbfn), "%s.thumb.%d.%s", av[i], t, T.tformat == LIBRAW_THUMBNAIL_JPEG ? "jpg" : "ppm"); if (verbose) printf("Writing thumbnail file %s\n", thumbfn); if (LIBRAW_SUCCESS != (ret = RawProcessor->dcraw_thumb_writer(thumbfn))) { fprintf(stderr, "Cannot write %s: %s\n", thumbfn, libraw_strerror(ret)); if (LIBRAW_FATAL_ERROR(ret)) break; } } continue; } else if (output_thumbs) { if ((ret = RawProcessor->unpack_thumb()) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot unpack_thumb %s: %s\n", av[i], libraw_strerror(ret)); if (LIBRAW_FATAL_ERROR(ret)) continue; // skip to next file } else { snprintf(thumbfn, sizeof(thumbfn), "%s.%s", av[i], T.tformat == LIBRAW_THUMBNAIL_JPEG ? "thumb.jpg" : (T.tcolors == 1? "thumb.pgm" : "thumb.ppm")); if (verbose) printf("Writing thumbnail file %s\n", thumbfn); if (LIBRAW_SUCCESS != (ret = RawProcessor->dcraw_thumb_writer(thumbfn))) { fprintf(stderr, "Cannot write %s: %s\n", thumbfn, libraw_strerror(ret)); if (LIBRAW_FATAL_ERROR(ret)) continue; } } continue; } ret = RawProcessor->dcraw_process(); if (LIBRAW_SUCCESS != ret) { fprintf(stderr, "Cannot do postprocessing on %s: %s\n", av[i], libraw_strerror(ret)); if (LIBRAW_FATAL_ERROR(ret)) continue; } snprintf(outfn, sizeof(outfn), "%s.%s", av[i], OUT.output_tiff ? "tiff" : (P1.colors > 1 ? "ppm" : "pgm")); if (verbose) printf("Writing file %s\n", outfn); if (LIBRAW_SUCCESS != (ret = RawProcessor->dcraw_ppm_tiff_writer(outfn))) fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret)); RawProcessor->recycle(); // just for show this call } delete RawProcessor; return 0; } LibRaw-0.21.4/samples/unprocessed_raw.cpp000066400000000000000000000220751477673233700203620ustar00rootroot00000000000000/* -*- C++ -*- * File: unprocessed_raw.cpp * Copyright 2009-2021 LibRaw LLC (info@libraw.org) * Created: Fri Jan 02, 2009 * * LibRaw sample * Generates unprocessed raw image: with masked pixels and without black subtraction * 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 #include #include #include #include "libraw/libraw.h" #ifndef LIBRAW_WIN32_CALLS #include #else #include #include #endif #ifdef LIBRAW_WIN32_CALLS #define snprintf _snprintf #endif #if !(LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(0, 14)) #error This code is for LibRaw 0.14+ only #endif void gamma_curve(unsigned short curve[]); void write_ppm(unsigned width, unsigned height, unsigned short *bitmap, const char *basename); void write_tiff(int width, int height, unsigned short *bitmap, const char *basename); int main(int ac, char *av[]) { int i, ret; int verbose = 1, autoscale = 0, use_gamma = 0, out_tiff = 0; char outfn[1024]; LibRaw RawProcessor; if (ac < 2) { usage: printf("unprocessed_raw - LibRaw %s sample. %d cameras supported\n" "Usage: %s [-q] [-A] [-g] [-s N] raw-files....\n" "\t-q - be quiet\n" "\t-s N - select Nth image in file (default=0)\n" "\t-g - use gamma correction with gamma 2.2 (not precise,use for " "visual inspection only)\n" "\t-A - autoscaling (by integer factor)\n" "\t-T - write tiff instead of pgm\n", LibRaw::version(), LibRaw::cameraCount(), av[0]); return 0; } #define S RawProcessor.imgdata.sizes #define OUT RawProcessor.imgdata.params #define OUTR RawProcessor.imgdata.rawparams for (i = 1; i < ac; i++) { if (av[i][0] == '-') { if (av[i][1] == 'q' && av[i][2] == 0) verbose = 0; else if (av[i][1] == 'A' && av[i][2] == 0) autoscale = 1; else if (av[i][1] == 'g' && av[i][2] == 0) use_gamma = 1; else if (av[i][1] == 'T' && av[i][2] == 0) out_tiff = 1; else if (av[i][1] == 's' && av[i][2] == 0) { i++; OUTR.shot_select = av[i] ? atoi(av[i]) : 0; } else goto usage; continue; } if (verbose) printf("Processing file %s\n", av[i]); if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot open %s: %s\n", av[i], libraw_strerror(ret)); continue; // no recycle b/c open file will recycle itself } if (verbose) { printf("Image size: %dx%d\nRaw size: %dx%d\n", S.width, S.height, S.raw_width, S.raw_height); printf("Margins: top=%d, left=%d\n", S.top_margin, S.left_margin); } if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS) { fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret)); continue; } if (verbose) printf("Unpacked....\n"); if (!(RawProcessor.imgdata.idata.filters || RawProcessor.imgdata.idata.colors == 1)) { printf("Only Bayer-pattern RAW files supported, sorry....\n"); continue; } if (autoscale) { unsigned max = 0, scale; for (int j = 0; j < S.raw_height * S.raw_width; j++) if (max < RawProcessor.imgdata.rawdata.raw_image[j]) max = RawProcessor.imgdata.rawdata.raw_image[j]; if (max > 0 && max < 1 << 15) { scale = (1 << 16) / max; if (verbose) printf("Scaling with multiplier=%d (max=%d)\n", scale, max); for (int j = 0; j < S.raw_height * S.raw_width; j++) RawProcessor.imgdata.rawdata.raw_image[j] *= scale; } } if (use_gamma) { unsigned short curve[0x10000]; gamma_curve(curve); for (int j = 0; j < S.raw_height * S.raw_width; j++) RawProcessor.imgdata.rawdata.raw_image[j] = curve[RawProcessor.imgdata.rawdata.raw_image[j]]; if (verbose) printf("Gamma-corrected....\n"); } if (OUTR.shot_select) snprintf(outfn, sizeof(outfn), "%s-%d.%s", av[i], OUTR.shot_select, out_tiff ? "tiff" : "pgm"); else snprintf(outfn, sizeof(outfn), "%s.%s", av[i], out_tiff ? "tiff" : "pgm"); if (out_tiff) write_tiff(S.raw_width, S.raw_height, RawProcessor.imgdata.rawdata.raw_image, outfn); else write_ppm(S.raw_width, S.raw_height, RawProcessor.imgdata.rawdata.raw_image, outfn); if (verbose) printf("Stored to file %s\n", outfn); } return 0; } void write_ppm(unsigned width, unsigned height, unsigned short *bitmap, const char *fname) { if (!bitmap) return; FILE *f = fopen(fname, "wb"); if (!f) return; int bits = 16; fprintf(f, "P5\n%d %d\n%d\n", width, height, (1 << bits) - 1); unsigned char *data = (unsigned char *)bitmap; unsigned data_size = width * height * 2; #define SWAP(a, b) \ { \ a ^= b; \ a ^= (b ^= a); \ } for (unsigned i = 0; i < data_size; i += 2) SWAP(data[i], data[i + 1]); #undef SWAP fwrite(data, data_size, 1, f); fclose(f); } /* == gamma curve and tiff writer - simplified cut'n'paste from dcraw.c */ #define SQR(x) ((x) * (x)) void gamma_curve(unsigned short *curve) { double pwr = 1.0 / 2.2; double ts = 0.0; int imax = 0xffff; int mode = 2; int i; double g[6], bnd[2] = {0, 0}, r; g[0] = pwr; g[1] = ts; g[2] = g[3] = g[4] = 0; bnd[g[1] >= 1] = 1; if (g[1] && (g[1] - 1) * (g[0] - 1) <= 0) { for (i = 0; i < 48; i++) { g[2] = (bnd[0] + bnd[1]) / 2; if (g[0]) bnd[(pow(g[2] / g[1], -g[0]) - 1) / g[0] - 1 / g[2] > -1] = g[2]; else bnd[g[2] / exp(1 - 1 / g[2]) < g[1]] = g[2]; } g[3] = g[2] / g[1]; if (g[0]) g[4] = g[2] * (1 / g[0] - 1); } if (g[0]) g[5] = 1 / (g[1] * SQR(g[3]) / 2 - g[4] * (1 - g[3]) + (1 - pow(g[3], 1 + g[0])) * (1 + g[4]) / (1 + g[0])) - 1; else g[5] = 1 / (g[1] * SQR(g[3]) / 2 + 1 - g[2] - g[3] - g[2] * g[3] * (log(g[3]) - 1)) - 1; for (i = 0; i < 0x10000; i++) { curve[i] = 0xffff; if ((r = (double)i / imax) < 1) curve[i] = 0x10000 * (mode ? (r < g[3] ? r * g[1] : (g[0] ? pow(r, g[0]) * (1 + g[4]) - g[4] : log(r) * g[2] + 1)) : (r < g[2] ? r / g[1] : (g[0] ? pow((r + g[4]) / (1 + g[4]), 1 / g[0]) : exp((r - 1) / g[2])))); } } void tiff_set(ushort *ntag, ushort tag, ushort type, int count, int val) { struct libraw_tiff_tag *tt; int c; tt = (struct libraw_tiff_tag *)(ntag + 1) + (*ntag)++; tt->tag = tag; tt->type = type; tt->count = count; if ((type < LIBRAW_EXIFTAG_TYPE_SHORT) && (count <= 4)) for (c = 0; c < 4; c++) tt->val.c[c] = val >> (c << 3); else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) && (count <= 2)) for (c = 0; c < 2; c++) tt->val.s[c] = val >> (c << 4); else tt->val.i = val; } #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th) void tiff_head(int width, int height, struct tiff_hdr *th) { int c; time_t timestamp = time(NULL); struct tm *t; memset(th, 0, sizeof *th); th->t_order = htonl(0x4d4d4949) >> 16; th->magic = 42; th->ifd = 10; tiff_set(&th->ntag, 254, 4, 1, 0); tiff_set(&th->ntag, 256, 4, 1, width); tiff_set(&th->ntag, 257, 4, 1, height); tiff_set(&th->ntag, 258, 3, 1, 16); for (c = 0; c < 4; c++) th->bps[c] = 16; tiff_set(&th->ntag, 259, 3, 1, 1); tiff_set(&th->ntag, 262, 3, 1, 1); tiff_set(&th->ntag, 273, 4, 1, sizeof *th); tiff_set(&th->ntag, 277, 3, 1, 1); tiff_set(&th->ntag, 278, 4, 1, height); tiff_set(&th->ntag, 279, 4, 1, height * width * 2); tiff_set(&th->ntag, 282, 5, 1, TOFF(th->rat[0])); tiff_set(&th->ntag, 283, 5, 1, TOFF(th->rat[2])); tiff_set(&th->ntag, 284, 3, 1, 1); tiff_set(&th->ntag, 296, 3, 1, 2); tiff_set(&th->ntag, 306, 2, 20, TOFF(th->date)); th->rat[0] = th->rat[2] = 300; th->rat[1] = th->rat[3] = 1; t = localtime(×tamp); if (t) sprintf(th->date, "%04d:%02d:%02d %02d:%02d:%02d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); } void write_tiff(int width, int height, unsigned short *bitmap, const char *fn) { struct tiff_hdr th; FILE *ofp = fopen(fn, "wb"); if (!ofp) return; tiff_head(width, height, &th); fwrite(&th, sizeof th, 1, ofp); fwrite(bitmap, 2, width * height, ofp); fclose(ofp); } LibRaw-0.21.4/shlib-version.sh000077500000000000000000000004551477673233700161300ustar00rootroot00000000000000#!/bin/sh vfile=./libraw/libraw_version.h major=`grep LIBRAW_SHLIB_CURRENT $vfile |head -1 | awk '{print $3}'` minor=`grep LIBRAW_SHLIB_REVISION $vfile | head -1 | awk '{print $3}'` patch=`grep LIBRAW_SHLIB_AGE $vfile | head -1 | awk '{print $3}'` echo "$major:$minor:$patch" | awk '{printf $1}' LibRaw-0.21.4/src/000077500000000000000000000000001477673233700135705ustar00rootroot00000000000000LibRaw-0.21.4/src/Makefile000066400000000000000000000000351477673233700152260ustar00rootroot00000000000000all: (cd ..; make library) LibRaw-0.21.4/src/decoders/000077500000000000000000000000001477673233700153605ustar00rootroot00000000000000LibRaw-0.21.4/src/decoders/canon_600.cpp000066400000000000000000000137001477673233700175500ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" void LibRaw::canon_600_fixed_wb(int temp) { static const short mul[4][5] = {{667, 358, 397, 565, 452}, {731, 390, 367, 499, 517}, {1119, 396, 348, 448, 537}, {1399, 485, 431, 508, 688}}; int lo, hi, i; float frac = 0; for (lo = 4; --lo;) if (*mul[lo] <= temp) break; for (hi = 0; hi < 3; hi++) if (*mul[hi] >= temp) break; if (lo != hi) frac = (float)(temp - *mul[lo]) / (*mul[hi] - *mul[lo]); for (i = 1; i < 5; i++) pre_mul[i - 1] = 1 / (frac * mul[hi][i] + (1 - frac) * mul[lo][i]); } /* Return values: 0 = white 1 = near white 2 = not white */ int LibRaw::canon_600_color(int ratio[2], int mar) { int clipped = 0, target, miss; if (flash_used) { if (ratio[1] < -104) { ratio[1] = -104; clipped = 1; } if (ratio[1] > 12) { ratio[1] = 12; clipped = 1; } } else { if (ratio[1] < -264 || ratio[1] > 461) return 2; if (ratio[1] < -50) { ratio[1] = -50; clipped = 1; } if (ratio[1] > 307) { ratio[1] = 307; clipped = 1; } } target = flash_used || ratio[1] < 197 ? -38 - (398 * ratio[1] >> 10) : -123 + (48 * ratio[1] >> 10); if (target - mar <= ratio[0] && target + 20 >= ratio[0] && !clipped) return 0; miss = target - ratio[0]; if (abs(miss) >= mar * 4) return 2; if (miss < -20) miss = -20; if (miss > mar) miss = mar; ratio[0] = target - miss; return 1; } void LibRaw::canon_600_auto_wb() { int mar, row, col, i, j, st, count[] = {0, 0}; int test[8], total[2][8], ratio[2][2], stat[2]; memset(&total, 0, sizeof total); i = int(canon_ev + 0.5); if (i < 10) mar = 150; else if (i > 12) mar = 20; else mar = 280 - 20 * i; if (flash_used) mar = 80; for (row = 14; row < height - 14; row += 4) for (col = 10; col < width; col += 2) { for (i = 0; i < 8; i++) test[(i & 4) + FC(row + (i >> 1), col + (i & 1))] = BAYER(row + (i >> 1), col + (i & 1)); for (i = 0; i < 8; i++) if (test[i] < 150 || test[i] > 1500) goto next; for (i = 0; i < 4; i++) if (abs(test[i] - test[i + 4]) > 50) goto next; for (i = 0; i < 2; i++) { for (j = 0; j < 4; j += 2) ratio[i][j >> 1] = ((test[i * 4 + j + 1] - test[i * 4 + j]) << 10) / test[i * 4 + j]; stat[i] = canon_600_color(ratio[i], mar); } if ((st = stat[0] | stat[1]) > 1) goto next; for (i = 0; i < 2; i++) if (stat[i]) for (j = 0; j < 2; j++) test[i * 4 + j * 2 + 1] = test[i * 4 + j * 2] * (0x400 + ratio[i][j]) >> 10; for (i = 0; i < 8; i++) total[st][i] += test[i]; count[st]++; next:; } if (count[0] | count[1]) { st = count[0] * 200 < count[1]; for (i = 0; i < 4; i++) if (total[st][i] + total[st][i + 4]) pre_mul[i] = 1.0f / (total[st][i] + total[st][i + 4]); } } void LibRaw::canon_600_coeff() { static const short table[6][12] = { {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105}, {-1203, 1715, -1136, 1648, 1388, -876, 267, 245, -1641, 2153, 3921, -3409}, {-615, 1127, -1563, 2075, 1437, -925, 509, 3, -756, 1268, 2519, -2007}, {-190, 702, -1886, 2398, 2153, -1641, 763, -251, -452, 964, 3040, -2528}, {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105}, {-807, 1319, -1785, 2297, 1388, -876, 769, -257, -230, 742, 2067, -1555}}; int t = 0, i, c; float mc, yc; mc = pre_mul[1] / pre_mul[2]; yc = pre_mul[3] / pre_mul[2]; if (mc > 1 && mc <= 1.28 && yc < 0.8789) t = 1; if (mc > 1.28 && mc <= 2) { if (yc < 0.8789) t = 3; else if (yc <= 2) t = 4; } if (flash_used) t = 5; for (raw_color = i = 0; i < 3; i++) FORCC rgb_cam[i][c] = float(table[t][i * 4 + c]) / 1024.f; } void LibRaw::canon_600_load_raw() { uchar data[1120], *dp; ushort *pix; int irow, row; for (irow = row = 0; irow < height; irow++) { checkCancel(); if (fread(data, 1, 1120, ifp) < 1120) derror(); pix = raw_image + row * raw_width; for (dp = data; dp < data + 1120; dp += 10, pix += 8) { pix[0] = (dp[0] << 2) + (dp[1] >> 6); pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3); pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3); pix[3] = (dp[4] << 2) + (dp[1] & 3); pix[4] = (dp[5] << 2) + (dp[9] & 3); pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3); pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3); pix[7] = (dp[8] << 2) + (dp[9] >> 6); } if ((row += 2) > height) row = 1; } } void LibRaw::canon_600_correct() { int row, col, val; static const short mul[4][2] = { {1141, 1145}, {1128, 1109}, {1178, 1149}, {1128, 1109}}; for (row = 0; row < height; row++) { checkCancel(); for (col = 0; col < width; col++) { if ((val = BAYER(row, col) - black) < 0) val = 0; val = val * mul[row & 3][col & 1] >> 9; BAYER(row, col) = val; } } canon_600_fixed_wb(1311); canon_600_auto_wb(); canon_600_coeff(); maximum = (0x3ff - black) * 1109 >> 9; black = 0; } LibRaw-0.21.4/src/decoders/crx.cpp000066400000000000000000002544511477673233700166730ustar00rootroot00000000000000/* -*- C++ -*- * File: libraw_crxdec.cpp * Copyright (C) 2018-2019 Alexey Danilchenko * Copyright (C) 2019 Alex Tutubalin, LibRaw LLC * Canon CR3 file decoder 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 "../../internal/libraw_cxx_defs.h" #ifdef _abs #undef _abs #undef _min #undef _constrain #endif #define _abs(x) (((x) ^ ((int32_t)(x) >> 31)) - ((int32_t)(x) >> 31)) #define _min(a, b) ((a) < (b) ? (a) : (b)) #define _constrain(x, l, u) ((x) < (l) ? (l) : ((x) > (u) ? (u) : (x))) #if defined(__clang__) || defined(__GNUG__) #define libraw_inline inline __attribute__((always_inline)) #elif defined(_MSC_VER) && _MSC_VER > 1400 #define libraw_inline __forceinline #else #define libraw_inline inline #endif // this should be divisible by 4 #define CRX_BUF_SIZE 0x10000 #if !defined(_WIN32) || (defined(__GNUC__) && !defined(__INTRINSIC_SPECIAL__BitScanReverse)) /* __INTRINSIC_SPECIAL__BitScanReverse found in MinGW32-W64 v7.30 headers, may be there is a better solution? */ typedef uint32_t DWORD; libraw_inline void _BitScanReverse(DWORD *Index, unsigned long Mask) { *Index = sizeof(unsigned long) * 8 - 1 - __builtin_clzl(Mask); } #if LibRawBigEndian #define _byteswap_ulong(x) (x) #else #define _byteswap_ulong(x) __builtin_bswap32(x) #endif #endif struct CrxBitstream { uint8_t mdatBuf[CRX_BUF_SIZE]; uint64_t mdatSize; uint64_t curBufOffset; uint32_t curPos; uint32_t curBufSize; uint32_t bitData; int32_t bitsLeft; LibRaw_abstract_datastream *input; }; struct CrxBandParam { CrxBitstream bitStream; int16_t subbandWidth; int16_t subbandHeight; int32_t roundedBitsMask; int32_t roundedBits; int16_t curLine; int32_t *lineBuf0; int32_t *lineBuf1; int32_t *lineBuf2; int32_t sParam; int32_t kParam; int32_t *paramData; int32_t *nonProgrData; bool supportsPartial; }; struct CrxWaveletTransform { int32_t *subband0Buf; int32_t *subband1Buf; int32_t *subband2Buf; int32_t *subband3Buf; int32_t *lineBuf[8]; int16_t curLine; int16_t curH; int8_t fltTapH; int16_t height; int16_t width; }; struct CrxSubband { CrxBandParam *bandParam; uint64_t mdatOffset; uint8_t *bandBuf; uint16_t width; uint16_t height; int32_t qParam; int32_t kParam; int32_t qStepBase; uint32_t qStepMult; bool supportsPartial; int32_t bandSize; uint64_t dataSize; int64_t dataOffset; short rowStartAddOn; short rowEndAddOn; short colStartAddOn; short colEndAddOn; short levelShift; }; struct CrxPlaneComp { uint8_t *compBuf; CrxSubband *subBands; CrxWaveletTransform *wvltTransform; int8_t compNumber; int64_t dataOffset; int32_t compSize; bool supportsPartial; int32_t roundedBitsMask; int8_t tileFlag; }; struct CrxQStep { uint32_t *qStepTbl; int width; int height; }; struct CrxTile { CrxPlaneComp *comps; int8_t tileFlag; int8_t tileNumber; int64_t dataOffset; int32_t tileSize; uint16_t width; uint16_t height; bool hasQPData; CrxQStep *qStep; uint32_t mdatQPDataSize; uint16_t mdatExtraSize; }; struct CrxImage { uint8_t nPlanes; uint16_t planeWidth; uint16_t planeHeight; uint8_t samplePrecision; uint8_t medianBits; uint8_t subbandCount; uint8_t levels; uint8_t nBits; uint8_t encType; uint8_t tileCols; uint8_t tileRows; CrxTile *tiles; uint64_t mdatOffset; uint64_t mdatSize; int16_t *outBufs[4]; // one per plane int16_t *planeBuf; LibRaw_abstract_datastream *input; #ifdef LIBRAW_CR3_MEMPOOL libraw_memmgr memmgr; CrxImage() : memmgr(0) {} #endif }; enum TileFlags { E_HAS_TILES_ON_THE_RIGHT = 1, E_HAS_TILES_ON_THE_LEFT = 2, E_HAS_TILES_ON_THE_BOTTOM = 4, E_HAS_TILES_ON_THE_TOP = 8 }; int32_t exCoefNumTbl[144] = {1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 2, 2, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 2, 2, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1}; int32_t q_step_tbl[8] = {0x28, 0x2D, 0x33, 0x39, 0x40, 0x48}; uint32_t JS[32] = {1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 8, 8, 8, 8, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000}; uint32_t J[32] = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; static inline void crxFillBuffer(CrxBitstream *bitStrm) { if (bitStrm->curPos >= bitStrm->curBufSize && bitStrm->mdatSize) { bitStrm->curPos = 0; bitStrm->curBufOffset += bitStrm->curBufSize; #ifdef LIBRAW_USE_OPENMP #pragma omp critical #endif { #ifndef LIBRAW_USE_OPENMP bitStrm->input->lock(); #endif bitStrm->input->seek(bitStrm->curBufOffset, SEEK_SET); bitStrm->curBufSize = bitStrm->input->read(bitStrm->mdatBuf, 1, _min(bitStrm->mdatSize, CRX_BUF_SIZE)); #ifndef LIBRAW_USE_OPENMP bitStrm->input->unlock(); #endif } if (bitStrm->curBufSize < 1) // nothing read throw LIBRAW_EXCEPTION_IO_EOF; bitStrm->mdatSize -= bitStrm->curBufSize; } } libraw_inline int crxBitstreamGetZeros(CrxBitstream *bitStrm) { uint32_t nonZeroBit = 0; uint64_t nextData = 0; int32_t result = 0; if (bitStrm->bitData) { _BitScanReverse((DWORD *)&nonZeroBit, (DWORD)bitStrm->bitData); result = 31 - nonZeroBit; bitStrm->bitData <<= 32 - nonZeroBit; bitStrm->bitsLeft -= 32 - nonZeroBit; } else { uint32_t bitsLeft = bitStrm->bitsLeft; while (1) { while (bitStrm->curPos + 4 <= bitStrm->curBufSize) { nextData = _byteswap_ulong(*(uint32_t *)(bitStrm->mdatBuf + bitStrm->curPos)); bitStrm->curPos += 4; crxFillBuffer(bitStrm); if (nextData) { _BitScanReverse((DWORD *)&nonZeroBit, (DWORD)nextData); result = bitsLeft + 31 - nonZeroBit; bitStrm->bitData = nextData << (32 - nonZeroBit); bitStrm->bitsLeft = nonZeroBit; return result; } bitsLeft += 32; } if (bitStrm->curBufSize < bitStrm->curPos + 1) break; // error nextData = bitStrm->mdatBuf[bitStrm->curPos++]; crxFillBuffer(bitStrm); if (nextData) break; bitsLeft += 8; } _BitScanReverse((DWORD *)&nonZeroBit, (DWORD)nextData); result = (uint32_t)(bitsLeft + 7 - nonZeroBit); bitStrm->bitData = nextData << (32 - nonZeroBit); bitStrm->bitsLeft = nonZeroBit; } return result; } libraw_inline uint32_t crxBitstreamGetBits(CrxBitstream *bitStrm, int bits) { int bitsLeft = bitStrm->bitsLeft; uint32_t bitData = bitStrm->bitData; uint32_t nextWord; uint8_t nextByte; uint32_t result; if (bitsLeft < bits) { // get them from stream if (bitStrm->curPos + 4 <= bitStrm->curBufSize) { nextWord = _byteswap_ulong(*(uint32_t *)(bitStrm->mdatBuf + bitStrm->curPos)); bitStrm->curPos += 4; crxFillBuffer(bitStrm); bitStrm->bitsLeft = 32 - (bits - bitsLeft); result = ((nextWord >> bitsLeft) | bitData) >> (32 - bits); bitStrm->bitData = nextWord << (bits - bitsLeft); return result; } // less than a word left - read byte at a time do { if (bitStrm->curPos >= bitStrm->curBufSize) break; // error bitsLeft += 8; nextByte = bitStrm->mdatBuf[bitStrm->curPos++]; crxFillBuffer(bitStrm); bitData |= nextByte << (32 - bitsLeft); } while (bitsLeft < bits); } result = bitData >> (32 - bits); // 32-bits bitStrm->bitData = bitData << bits; bitStrm->bitsLeft = bitsLeft - bits; return result; } libraw_inline int32_t crxPrediction(int32_t left, int32_t top, int32_t deltaH, int32_t deltaV) { int32_t symb[4] = {left + deltaH, left + deltaH, left, top}; return symb[(((deltaV < 0) ^ (deltaH < 0)) << 1) + ((left < top) ^ (deltaH < 0))]; } libraw_inline int32_t crxPredictKParameter(int32_t prevK, int32_t bitCode, int32_t maxVal = 0) { int32_t newKParam = prevK - (bitCode < (1 << prevK >> 1)) + ((bitCode >> prevK) > 2) + ((bitCode >> prevK) > 5); return !maxVal || newKParam < maxVal ? newKParam : maxVal; } libraw_inline void crxDecodeSymbolL1(CrxBandParam *param, int32_t doMedianPrediction, int32_t notEOL = 0) { if (doMedianPrediction) { int32_t symb[4]; int32_t delta = param->lineBuf0[1] - param->lineBuf0[0]; symb[2] = param->lineBuf1[0]; symb[0] = symb[1] = delta + symb[2]; symb[3] = param->lineBuf0[1]; param->lineBuf1[1] = symb[(((param->lineBuf0[0] < param->lineBuf1[0]) ^ (delta < 0)) << 1) + ((param->lineBuf1[0] < param->lineBuf0[1]) ^ (delta < 0))]; } else param->lineBuf1[1] = param->lineBuf0[1]; // get next error symbol uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); if (bitCode >= 41) bitCode = crxBitstreamGetBits(¶m->bitStream, 21); else if (param->kParam) bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); // add converted (+/-) error code to predicted value param->lineBuf1[1] += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); // for not end of the line - use one symbol ahead to estimate next K if (notEOL) { int32_t nextDelta = (param->lineBuf0[2] - param->lineBuf0[1]) << 1; bitCode = (bitCode + _abs(nextDelta)) >> 1; ++param->lineBuf0; } // update K parameter param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); ++param->lineBuf1; } int crxDecodeLine(CrxBandParam *param) { int length = param->subbandWidth; param->lineBuf1[0] = param->lineBuf0[1]; for (; length > 1; --length) { if (param->lineBuf1[0] != param->lineBuf0[1] || param->lineBuf1[0] != param->lineBuf0[2]) { crxDecodeSymbolL1(param, 1, 1); } else { int nSyms = 0; if (crxBitstreamGetBits(¶m->bitStream, 1)) { nSyms = 1; while (crxBitstreamGetBits(¶m->bitStream, 1)) { nSyms += JS[param->sParam]; if (nSyms > length) { nSyms = length; break; } if (param->sParam < 31) ++param->sParam; if (nSyms == length) break; } if (nSyms < length) { if (J[param->sParam]) nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); if (param->sParam > 0) --param->sParam; if (nSyms > length) return -1; } length -= nSyms; // copy symbol nSyms times param->lineBuf0 += nSyms; // copy symbol nSyms times while (nSyms-- > 0) { param->lineBuf1[1] = param->lineBuf1[0]; ++param->lineBuf1; } } if (length > 0) crxDecodeSymbolL1(param, 0, (length > 1)); } } if (length == 1) crxDecodeSymbolL1(param, 1, 0); param->lineBuf1[1] = param->lineBuf1[0] + 1; return 0; } libraw_inline void crxDecodeSymbolL1Rounded(CrxBandParam *param, int32_t doSym = 1, int32_t doCode = 1) { int32_t sym = param->lineBuf0[1]; if (doSym) { // calculate the next symbol gradient int32_t symb[4]; int32_t deltaH = param->lineBuf0[1] - param->lineBuf0[0]; symb[2] = param->lineBuf1[0]; symb[0] = symb[1] = deltaH + symb[2]; symb[3] = param->lineBuf0[1]; sym = symb[(((param->lineBuf0[0] < param->lineBuf1[0]) ^ (deltaH < 0)) << 1) + ((param->lineBuf1[0] < param->lineBuf0[1]) ^ (deltaH < 0))]; } uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); if (bitCode >= 41) bitCode = crxBitstreamGetBits(¶m->bitStream, 21); else if (param->kParam) bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); int32_t code = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); param->lineBuf1[1] = param->roundedBitsMask * 2 * code + (code >> 31) + sym; if (doCode) { if (param->lineBuf0[2] > param->lineBuf0[1]) code = (param->lineBuf0[2] - param->lineBuf0[1] + param->roundedBitsMask - 1) >> param->roundedBits; else code = -((param->lineBuf0[1] - param->lineBuf0[2] + param->roundedBitsMask) >> param->roundedBits); param->kParam = crxPredictKParameter(param->kParam, (bitCode + 2 * _abs(code)) >> 1, 15); } else param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); ++param->lineBuf1; } int crxDecodeLineRounded(CrxBandParam *param) { int32_t valueReached = 0; param->lineBuf0[0] = param->lineBuf0[1]; param->lineBuf1[0] = param->lineBuf0[1]; int32_t length = param->subbandWidth; for (; length > 1; --length) { if (_abs(param->lineBuf0[2] - param->lineBuf0[1]) > param->roundedBitsMask) { crxDecodeSymbolL1Rounded(param); ++param->lineBuf0; valueReached = 1; } else if (valueReached || _abs(param->lineBuf0[0] - param->lineBuf1[0]) > param->roundedBitsMask) { crxDecodeSymbolL1Rounded(param); ++param->lineBuf0; valueReached = 0; } else { int nSyms = 0; if (crxBitstreamGetBits(¶m->bitStream, 1)) { nSyms = 1; while (crxBitstreamGetBits(¶m->bitStream, 1)) { nSyms += JS[param->sParam]; if (nSyms > length) { nSyms = length; break; } if (param->sParam < 31) ++param->sParam; if (nSyms == length) break; } if (nSyms < length) { if (J[param->sParam]) nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); if (param->sParam > 0) --param->sParam; } if (nSyms > length) return -1; } length -= nSyms; // copy symbol nSyms times param->lineBuf0 += nSyms; // copy symbol nSyms times while (nSyms-- > 0) { param->lineBuf1[1] = param->lineBuf1[0]; ++param->lineBuf1; } if (length > 1) { crxDecodeSymbolL1Rounded(param, 0); ++param->lineBuf0; valueReached = _abs(param->lineBuf0[1] - param->lineBuf0[0]) > param->roundedBitsMask; } else if (length == 1) crxDecodeSymbolL1Rounded(param, 0, 0); } } if (length == 1) crxDecodeSymbolL1Rounded(param, 1, 0); param->lineBuf1[1] = param->lineBuf1[0] + 1; return 0; } int crxDecodeLineNoRefPrevLine(CrxBandParam *param) { int32_t i = 0; for (; i < param->subbandWidth - 1; i++) { if (param->lineBuf0[i + 2] | param->lineBuf0[i + 1] | param->lineBuf1[i]) { uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); if (bitCode >= 41) bitCode = crxBitstreamGetBits(¶m->bitStream, 21); else if (param->kParam) bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); param->lineBuf1[i + 1] = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); param->kParam = crxPredictKParameter(param->kParam, bitCode); if (param->lineBuf2[i + 1] - param->kParam <= 1) { if (param->kParam >= 15) param->kParam = 15; } else ++param->kParam; } else { int nSyms = 0; if (crxBitstreamGetBits(¶m->bitStream, 1)) { nSyms = 1; if (i != param->subbandWidth - 1) { while (crxBitstreamGetBits(¶m->bitStream, 1)) { nSyms += JS[param->sParam]; if (i + nSyms > param->subbandWidth) { nSyms = param->subbandWidth - i; break; } if (param->sParam < 31) ++param->sParam; if (i + nSyms == param->subbandWidth) break; } if (i + nSyms < param->subbandWidth) { if (J[param->sParam]) nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); if (param->sParam > 0) --param->sParam; } if (i + nSyms > param->subbandWidth) return -1; } } else if (i > param->subbandWidth) return -1; if (nSyms > 0) { memset(param->lineBuf1 + i + 1, 0, nSyms * sizeof(int32_t)); memset(param->lineBuf2 + i, 0, nSyms * sizeof(int32_t)); i += nSyms; } if (i >= param->subbandWidth - 1) { if (i == param->subbandWidth - 1) { uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); if (bitCode >= 41) bitCode = crxBitstreamGetBits(¶m->bitStream, 21); else if (param->kParam) bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); param->lineBuf1[i + 1] = -(int32_t)((bitCode + 1) & 1) ^ (int32_t)((bitCode + 1) >> 1); param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); param->lineBuf2[i] = param->kParam; } continue; } else { uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); if (bitCode >= 41) bitCode = crxBitstreamGetBits(¶m->bitStream, 21); else if (param->kParam) bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); param->lineBuf1[i + 1] = -(int32_t)((bitCode + 1) & 1) ^ (int32_t)((bitCode + 1) >> 1); param->kParam = crxPredictKParameter(param->kParam, bitCode); if (param->lineBuf2[i + 1] - param->kParam <= 1) { if (param->kParam >= 15) param->kParam = 15; } else ++param->kParam; } } param->lineBuf2[i] = param->kParam; } if (i == param->subbandWidth - 1) { int32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); if (bitCode >= 41) bitCode = crxBitstreamGetBits(¶m->bitStream, 21); else if (param->kParam) bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); param->lineBuf1[i + 1] = -(bitCode & 1) ^ (bitCode >> 1); param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); param->lineBuf2[i] = param->kParam; } return 0; } int crxDecodeTopLine(CrxBandParam *param) { param->lineBuf1[0] = 0; int32_t length = param->subbandWidth; // read the line from bitstream for (; length > 1; --length) { if (param->lineBuf1[0]) param->lineBuf1[1] = param->lineBuf1[0]; else { int nSyms = 0; if (crxBitstreamGetBits(¶m->bitStream, 1)) { nSyms = 1; while (crxBitstreamGetBits(¶m->bitStream, 1)) { nSyms += JS[param->sParam]; if (nSyms > length) { nSyms = length; break; } if (param->sParam < 31) ++param->sParam; if (nSyms == length) break; } if (nSyms < length) { if (J[param->sParam]) nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); if (param->sParam > 0) --param->sParam; if (nSyms > length) return -1; } length -= nSyms; // copy symbol nSyms times while (nSyms-- > 0) { param->lineBuf1[1] = param->lineBuf1[0]; ++param->lineBuf1; } if (length <= 0) break; } param->lineBuf1[1] = 0; } uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); if (bitCode >= 41) bitCode = crxBitstreamGetBits(¶m->bitStream, 21); else if (param->kParam) bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); param->lineBuf1[1] += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); ++param->lineBuf1; } if (length == 1) { param->lineBuf1[1] = param->lineBuf1[0]; uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); if (bitCode >= 41) bitCode = crxBitstreamGetBits(¶m->bitStream, 21); else if (param->kParam) bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); param->lineBuf1[1] += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); ++param->lineBuf1; } param->lineBuf1[1] = param->lineBuf1[0] + 1; return 0; } int crxDecodeTopLineRounded(CrxBandParam *param) { param->lineBuf1[0] = 0; int32_t length = param->subbandWidth; // read the line from bitstream for (; length > 1; --length) { if (_abs(param->lineBuf1[0]) > param->roundedBitsMask) param->lineBuf1[1] = param->lineBuf1[0]; else { int nSyms = 0; if (crxBitstreamGetBits(¶m->bitStream, 1)) { nSyms = 1; while (crxBitstreamGetBits(¶m->bitStream, 1)) { nSyms += JS[param->sParam]; if (nSyms > length) { nSyms = length; break; } if (param->sParam < 31) ++param->sParam; if (nSyms == length) break; } if (nSyms < length) { if (J[param->sParam]) nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); if (param->sParam > 0) --param->sParam; if (nSyms > length) return -1; } } length -= nSyms; // copy symbol nSyms times while (nSyms-- > 0) { param->lineBuf1[1] = param->lineBuf1[0]; ++param->lineBuf1; } if (length <= 0) break; param->lineBuf1[1] = 0; } uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); if (bitCode >= 41) bitCode = crxBitstreamGetBits(¶m->bitStream, 21); else if (param->kParam) bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); int32_t sVal = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); param->lineBuf1[1] += param->roundedBitsMask * 2 * sVal + (sVal >> 31); param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); ++param->lineBuf1; } if (length == 1) { uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); if (bitCode >= 41) bitCode = crxBitstreamGetBits(¶m->bitStream, 21); else if (param->kParam) bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); int32_t sVal = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); param->lineBuf1[1] += param->roundedBitsMask * 2 * sVal + (sVal >> 31); param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); ++param->lineBuf1; } param->lineBuf1[1] = param->lineBuf1[0] + 1; return 0; } int crxDecodeTopLineNoRefPrevLine(CrxBandParam *param) { param->lineBuf0[0] = 0; param->lineBuf1[0] = 0; int32_t length = param->subbandWidth; for (; length > 1; --length) { if (param->lineBuf1[0]) { uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); if (bitCode >= 41) bitCode = crxBitstreamGetBits(¶m->bitStream, 21); else if (param->kParam) bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); param->lineBuf1[1] = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); } else { int nSyms = 0; if (crxBitstreamGetBits(¶m->bitStream, 1)) { nSyms = 1; while (crxBitstreamGetBits(¶m->bitStream, 1)) { nSyms += JS[param->sParam]; if (nSyms > length) { nSyms = length; break; } if (param->sParam < 31) ++param->sParam; if (nSyms == length) break; } if (nSyms < length) { if (J[param->sParam]) nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); if (param->sParam > 0) --param->sParam; if (nSyms > length) return -1; } } length -= nSyms; // copy symbol nSyms times while (nSyms-- > 0) { param->lineBuf2[0] = 0; param->lineBuf1[1] = 0; ++param->lineBuf1; ++param->lineBuf2; } if (length <= 0) break; uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); if (bitCode >= 41) bitCode = crxBitstreamGetBits(¶m->bitStream, 21); else if (param->kParam) bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); param->lineBuf1[1] = -(int32_t)((bitCode + 1) & 1) ^ (int32_t)((bitCode + 1) >> 1); param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); } param->lineBuf2[0] = param->kParam; ++param->lineBuf2; ++param->lineBuf1; } if (length == 1) { uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); if (bitCode >= 41) bitCode = crxBitstreamGetBits(¶m->bitStream, 21); else if (param->kParam) bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); param->lineBuf1[1] = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); param->lineBuf2[0] = param->kParam; ++param->lineBuf1; } param->lineBuf1[1] = 0; return 0; } int crxDecodeLine(CrxBandParam *param, uint8_t *bandBuf) { if (!param || !bandBuf) return -1; if (param->curLine >= param->subbandHeight) return -1; if (param->curLine == 0) { int32_t lineLength = param->subbandWidth + 2; param->sParam = 0; param->kParam = 0; if (param->supportsPartial) { if (param->roundedBitsMask <= 0) { param->lineBuf0 = (int32_t *)param->paramData; param->lineBuf1 = param->lineBuf0 + lineLength; int32_t *lineBuf = param->lineBuf1 + 1; if (crxDecodeTopLine(param)) return -1; memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t)); ++param->curLine; } else { param->roundedBits = 1; if (param->roundedBitsMask & ~1) { while (param->roundedBitsMask >> param->roundedBits) ++param->roundedBits; } param->lineBuf0 = (int32_t *)param->paramData; param->lineBuf1 = param->lineBuf0 + lineLength; int32_t *lineBuf = param->lineBuf1 + 1; if (crxDecodeTopLineRounded(param)) return -1; memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t)); ++param->curLine; } } else { param->lineBuf2 = (int32_t *)param->nonProgrData; param->lineBuf0 = (int32_t *)param->paramData; param->lineBuf1 = param->lineBuf0 + lineLength; int32_t *lineBuf = param->lineBuf1 + 1; if (crxDecodeTopLineNoRefPrevLine(param)) return -1; memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t)); ++param->curLine; } } else if (!param->supportsPartial) { int32_t lineLength = param->subbandWidth + 2; param->lineBuf2 = (int32_t *)param->nonProgrData; if (param->curLine & 1) { param->lineBuf1 = (int32_t *)param->paramData; param->lineBuf0 = param->lineBuf1 + lineLength; } else { param->lineBuf0 = (int32_t *)param->paramData; param->lineBuf1 = param->lineBuf0 + lineLength; } int32_t *lineBuf = param->lineBuf1 + 1; if (crxDecodeLineNoRefPrevLine(param)) return -1; memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t)); ++param->curLine; } else if (param->roundedBitsMask <= 0) { int32_t lineLength = param->subbandWidth + 2; if (param->curLine & 1) { param->lineBuf1 = (int32_t *)param->paramData; param->lineBuf0 = param->lineBuf1 + lineLength; } else { param->lineBuf0 = (int32_t *)param->paramData; param->lineBuf1 = param->lineBuf0 + lineLength; } int32_t *lineBuf = param->lineBuf1 + 1; if (crxDecodeLine(param)) return -1; memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t)); ++param->curLine; } else { int32_t lineLength = param->subbandWidth + 2; if (param->curLine & 1) { param->lineBuf1 = (int32_t *)param->paramData; param->lineBuf0 = param->lineBuf1 + lineLength; } else { param->lineBuf0 = (int32_t *)param->paramData; param->lineBuf1 = param->lineBuf0 + lineLength; } int32_t *lineBuf = param->lineBuf1 + 1; if (crxDecodeLineRounded(param)) return -1; memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t)); ++param->curLine; } return 0; } int crxUpdateQparam(CrxSubband *subband) { uint32_t bitCode = crxBitstreamGetZeros(&subband->bandParam->bitStream); if (bitCode >= 23) bitCode = crxBitstreamGetBits(&subband->bandParam->bitStream, 8); else if (subband->kParam) bitCode = crxBitstreamGetBits(&subband->bandParam->bitStream, subband->kParam) | (bitCode << subband->kParam); subband->qParam += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); // converting encoded to signed integer subband->kParam = crxPredictKParameter(subband->kParam, bitCode); if (subband->kParam > 7) return -1; return 0; } libraw_inline int getSubbandRow(CrxSubband *band, int row) { return row < band->rowStartAddOn ? 0 : (row < band->height - band->rowEndAddOn ? row - band->rowEndAddOn : band->height - band->rowEndAddOn - band->rowStartAddOn - 1); } int crxDecodeLineWithIQuantization(CrxSubband *band, CrxQStep *qStep) { if (!band->dataSize) { memset(band->bandBuf, 0, band->bandSize); return 0; } if (band->supportsPartial && !qStep && crxUpdateQparam(band)) return -1; if (crxDecodeLine(band->bandParam, band->bandBuf)) return -1; if (band->width <= 0) return 0; // update band buffers int32_t *bandBuf = (int32_t *)band->bandBuf; if (qStep) { // new version uint32_t *qStepTblPtr = &qStep->qStepTbl[qStep->width * getSubbandRow(band, band->bandParam->curLine - 1)]; for (int i = 0; i < band->colStartAddOn; ++i) { int32_t quantVal = band->qStepBase + ((qStepTblPtr[0] * band->qStepMult) >> 3); bandBuf[i] *= _constrain(quantVal, 1, 0x168000); } for (int i = band->colStartAddOn; i < band->width - band->colEndAddOn; ++i) { int32_t quantVal = band->qStepBase + ((qStepTblPtr[(i - band->colStartAddOn) >> band->levelShift] * band->qStepMult) >> 3); bandBuf[i] *= _constrain(quantVal, 1, 0x168000); } int lastIdx = (band->width - band->colEndAddOn - band->colStartAddOn - 1) >> band->levelShift; for (int i = band->width - band->colEndAddOn; i < band->width; ++i) { int32_t quantVal = band->qStepBase + ((qStepTblPtr[lastIdx] * band->qStepMult) >> 3); bandBuf[i] *= _constrain(quantVal, 1, 0x168000); } } else { // prev. version int32_t qScale = q_step_tbl[band->qParam % 6] >> (6 - band->qParam / 6); if (band->qParam / 6 >= 6) qScale = q_step_tbl[band->qParam % 6] * (1 << (band->qParam / 6 + 26)); if (qScale != 1) for (int32_t i = 0; i < band->width; ++i) bandBuf[i] *= qScale; } return 0; } void crxHorizontal53(int32_t *lineBufLA, int32_t *lineBufLB, CrxWaveletTransform *wavelet, uint32_t tileFlag) { int32_t *band0Buf = wavelet->subband0Buf; int32_t *band1Buf = wavelet->subband1Buf; int32_t *band2Buf = wavelet->subband2Buf; int32_t *band3Buf = wavelet->subband3Buf; if (wavelet->width <= 1) { lineBufLA[0] = band0Buf[0]; lineBufLB[0] = band2Buf[0]; } else { if (tileFlag & E_HAS_TILES_ON_THE_LEFT) { lineBufLA[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); lineBufLB[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); ++band1Buf; ++band3Buf; } else { lineBufLA[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); lineBufLB[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1); } ++band0Buf; ++band2Buf; for (int i = 0; i < wavelet->width - 3; i += 2) { int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); lineBufLA[1] = band1Buf[0] + ((delta + lineBufLA[0]) >> 1); lineBufLA[2] = delta; delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); lineBufLB[1] = band3Buf[0] + ((delta + lineBufLB[0]) >> 1); lineBufLB[2] = delta; ++band0Buf; ++band1Buf; ++band2Buf; ++band3Buf; lineBufLA += 2; lineBufLB += 2; } if (tileFlag & E_HAS_TILES_ON_THE_RIGHT) { int32_t deltaA = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); lineBufLA[1] = band1Buf[0] + ((deltaA + lineBufLA[0]) >> 1); int32_t deltaB = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); lineBufLB[1] = band3Buf[0] + ((deltaB + lineBufLB[0]) >> 1); if (wavelet->width & 1) { lineBufLA[2] = deltaA; lineBufLB[2] = deltaB; } } else if (wavelet->width & 1) { lineBufLA[1] = band1Buf[0] + ((lineBufLA[0] + band0Buf[0] - ((band1Buf[0] + 1) >> 1)) >> 1); lineBufLA[2] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); lineBufLB[1] = band3Buf[0] + ((lineBufLB[0] + band2Buf[0] - ((band3Buf[0] + 1) >> 1)) >> 1); lineBufLB[2] = band2Buf[0] - ((band3Buf[0] + 1) >> 1); } else { lineBufLA[1] = lineBufLA[0] + band1Buf[0]; lineBufLB[1] = lineBufLB[0] + band3Buf[0]; } } } int32_t *crxIdwt53FilterGetLine(CrxPlaneComp *comp, int32_t level) { int32_t *result = comp->wvltTransform[level] .lineBuf[(comp->wvltTransform[level].fltTapH - comp->wvltTransform[level].curH + 5) % 5 + 3]; comp->wvltTransform[level].curH--; return result; } int crxIdwt53FilterDecode(CrxPlaneComp *comp, int32_t level, CrxQStep *qStep) { if (comp->wvltTransform[level].curH) return 0; CrxSubband *sband = comp->subBands + 3 * level; CrxQStep *qStepLevel = qStep ? qStep + level : 0; if (comp->wvltTransform[level].height - 3 <= comp->wvltTransform[level].curLine && !(comp->tileFlag & E_HAS_TILES_ON_THE_BOTTOM)) { if (comp->wvltTransform[level].height & 1) { if (level) { if (crxIdwt53FilterDecode(comp, level - 1, qStep)) return -1; } else if (crxDecodeLineWithIQuantization(sband, qStepLevel)) return -1; if (crxDecodeLineWithIQuantization(sband + 1, qStepLevel)) return -1; } } else { if (level) { if (crxIdwt53FilterDecode(comp, level - 1, qStep)) return -1; } else if (crxDecodeLineWithIQuantization(sband, qStepLevel)) // LL band return -1; if (crxDecodeLineWithIQuantization(sband + 1, qStepLevel) || // HL band crxDecodeLineWithIQuantization(sband + 2, qStepLevel) || // LH band crxDecodeLineWithIQuantization(sband + 3, qStepLevel)) // HH band return -1; } return 0; } int crxIdwt53FilterTransform(CrxPlaneComp *comp, uint32_t level) { CrxWaveletTransform *wavelet = comp->wvltTransform + level; if (wavelet->curH) return 0; if (wavelet->curLine >= wavelet->height - 3) { if (!(comp->tileFlag & E_HAS_TILES_ON_THE_BOTTOM)) { if (wavelet->height & 1) { if (level) { if (!wavelet[-1].curH) if (crxIdwt53FilterTransform(comp, level - 1)) return -1; wavelet->subband0Buf = crxIdwt53FilterGetLine(comp, level - 1); } int32_t *band0Buf = wavelet->subband0Buf; int32_t *band1Buf = wavelet->subband1Buf; int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3]; int32_t *lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3]; int32_t *lineBufH2 = wavelet->lineBuf[(wavelet->fltTapH + 2) % 5 + 3]; int32_t *lineBufL0 = wavelet->lineBuf[0]; int32_t *lineBufL1 = wavelet->lineBuf[1]; wavelet->lineBuf[1] = wavelet->lineBuf[2]; wavelet->lineBuf[2] = lineBufL1; // process L bands if (wavelet->width <= 1) { lineBufL0[0] = band0Buf[0]; } else { if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT) { lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); ++band1Buf; } else { lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); } ++band0Buf; for (int i = 0; i < wavelet->width - 3; i += 2) { int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1); lineBufL0[2] = delta; ++band0Buf; ++band1Buf; lineBufL0 += 2; } if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT) { int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1); if (wavelet->width & 1) lineBufL0[2] = delta; } else if (wavelet->width & 1) { int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1); lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1); lineBufL0[2] = delta; } else lineBufL0[1] = band1Buf[0] + lineBufL0[0]; } // process H bands lineBufL0 = wavelet->lineBuf[0]; lineBufL1 = wavelet->lineBuf[1]; for (int32_t i = 0; i < wavelet->width; i++) { int32_t delta = lineBufL0[i] - ((lineBufL1[i] + 1) >> 1); lineBufH1[i] = lineBufL1[i] + ((delta + lineBufH0[i]) >> 1); lineBufH2[i] = delta; } wavelet->curH += 3; wavelet->curLine += 3; wavelet->fltTapH = (wavelet->fltTapH + 3) % 5; } else { int32_t *lineBufL2 = wavelet->lineBuf[2]; int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3]; int32_t *lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3]; wavelet->lineBuf[1] = lineBufL2; wavelet->lineBuf[2] = wavelet->lineBuf[1]; for (int32_t i = 0; i < wavelet->width; i++) lineBufH1[i] = lineBufH0[i] + lineBufL2[i]; wavelet->curH += 2; wavelet->curLine += 2; wavelet->fltTapH = (wavelet->fltTapH + 2) % 5; } } } else { if (level) { if (!wavelet[-1].curH && crxIdwt53FilterTransform(comp, level - 1)) return -1; wavelet->subband0Buf = crxIdwt53FilterGetLine(comp, level - 1); } int32_t *band0Buf = wavelet->subband0Buf; int32_t *band1Buf = wavelet->subband1Buf; int32_t *band2Buf = wavelet->subband2Buf; int32_t *band3Buf = wavelet->subband3Buf; int32_t *lineBufL0 = wavelet->lineBuf[0]; int32_t *lineBufL1 = wavelet->lineBuf[1]; int32_t *lineBufL2 = wavelet->lineBuf[2]; int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3]; int32_t *lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3]; int32_t *lineBufH2 = wavelet->lineBuf[(wavelet->fltTapH + 2) % 5 + 3]; wavelet->lineBuf[1] = wavelet->lineBuf[2]; wavelet->lineBuf[2] = lineBufL1; // process L bands if (wavelet->width <= 1) { lineBufL0[0] = band0Buf[0]; lineBufL1[0] = band2Buf[0]; } else { if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT) { lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); lineBufL1[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); ++band1Buf; ++band3Buf; } else { lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); lineBufL1[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1); } ++band0Buf; ++band2Buf; for (int i = 0; i < wavelet->width - 3; i += 2) { int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); lineBufL0[1] = band1Buf[0] + ((delta + lineBufL0[0]) >> 1); lineBufL0[2] = delta; delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); lineBufL1[1] = band3Buf[0] + ((delta + lineBufL1[0]) >> 1); lineBufL1[2] = delta; ++band0Buf; ++band1Buf; ++band2Buf; ++band3Buf; lineBufL0 += 2; lineBufL1 += 2; } if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT) { int32_t deltaA = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); lineBufL0[1] = band1Buf[0] + ((deltaA + lineBufL0[0]) >> 1); int32_t deltaB = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); lineBufL1[1] = band3Buf[0] + ((deltaB + lineBufL1[0]) >> 1); if (wavelet->width & 1) { lineBufL0[2] = deltaA; lineBufL1[2] = deltaB; } } else if (wavelet->width & 1) { int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1); lineBufL0[1] = band1Buf[0] + ((delta + lineBufL0[0]) >> 1); lineBufL0[2] = delta; delta = band2Buf[0] - ((band3Buf[0] + 1) >> 1); lineBufL1[1] = band3Buf[0] + ((delta + lineBufL1[0]) >> 1); lineBufL1[2] = delta; } else { lineBufL0[1] = lineBufL0[0] + band1Buf[0]; lineBufL1[1] = lineBufL1[0] + band3Buf[0]; } } // process H bands lineBufL0 = wavelet->lineBuf[0]; lineBufL1 = wavelet->lineBuf[1]; lineBufL2 = wavelet->lineBuf[2]; for (int32_t i = 0; i < wavelet->width; i++) { int32_t delta = lineBufL0[i] - ((lineBufL2[i] + lineBufL1[i] + 2) >> 2); lineBufH1[i] = lineBufL1[i] + ((delta + lineBufH0[i]) >> 1); lineBufH2[i] = delta; } if (wavelet->curLine >= wavelet->height - 3 && wavelet->height & 1) { wavelet->curH += 3; wavelet->curLine += 3; wavelet->fltTapH = (wavelet->fltTapH + 3) % 5; } else { wavelet->curH += 2; wavelet->curLine += 2; wavelet->fltTapH = (wavelet->fltTapH + 2) % 5; } } return 0; } int crxIdwt53FilterInitialize(CrxPlaneComp *comp, int32_t level, CrxQStep *qStep) { if (level == 0) return 0; for (int curLevel = 0, curBand = 0; curLevel < level; curLevel++, curBand += 3) { CrxQStep *qStepLevel = qStep ? qStep + curLevel : 0; CrxWaveletTransform *wavelet = comp->wvltTransform + curLevel; if (curLevel) wavelet[0].subband0Buf = crxIdwt53FilterGetLine(comp, curLevel - 1); else if (crxDecodeLineWithIQuantization(comp->subBands + curBand, qStepLevel)) return -1; int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3]; if (wavelet->height > 1) { if (crxDecodeLineWithIQuantization(comp->subBands + curBand + 1, qStepLevel) || crxDecodeLineWithIQuantization(comp->subBands + curBand + 2, qStepLevel) || crxDecodeLineWithIQuantization(comp->subBands + curBand + 3, qStepLevel)) return -1; int32_t *lineBufL0 = wavelet->lineBuf[0]; int32_t *lineBufL1 = wavelet->lineBuf[1]; int32_t *lineBufL2 = wavelet->lineBuf[2]; if (comp->tileFlag & E_HAS_TILES_ON_THE_TOP) { crxHorizontal53(lineBufL0, wavelet->lineBuf[1], wavelet, comp->tileFlag); if (crxDecodeLineWithIQuantization(comp->subBands + curBand + 3, qStepLevel) || crxDecodeLineWithIQuantization(comp->subBands + curBand + 2, qStepLevel)) return -1; int32_t *band2Buf = wavelet->subband2Buf; int32_t *band3Buf = wavelet->subband3Buf; // process L band if (wavelet->width <= 1) lineBufL2[0] = band2Buf[0]; else { if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT) { lineBufL2[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); ++band3Buf; } else lineBufL2[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1); ++band2Buf; for (int i = 0; i < wavelet->width - 3; i += 2) { int32_t delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1); lineBufL2[2] = delta; ++band2Buf; ++band3Buf; lineBufL2 += 2; } if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT) { int32_t delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1); if (wavelet->width & 1) lineBufL2[2] = delta; } else if (wavelet->width & 1) { int32_t delta = band2Buf[0] - ((band3Buf[0] + 1) >> 1); lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1); lineBufL2[2] = delta; } else { lineBufL2[1] = band3Buf[0] + lineBufL2[0]; } } // process H band for (int32_t i = 0; i < wavelet->width; i++) lineBufH0[i] = lineBufL0[i] - ((lineBufL1[i] + lineBufL2[i] + 2) >> 2); } else { crxHorizontal53(lineBufL0, wavelet->lineBuf[2], wavelet, comp->tileFlag); for (int i = 0; i < wavelet->width; i++) lineBufH0[i] = lineBufL0[i] - ((lineBufL2[i] + 1) >> 1); } if (crxIdwt53FilterDecode(comp, curLevel, qStep) || crxIdwt53FilterTransform(comp, curLevel)) return -1; } else { if (crxDecodeLineWithIQuantization(comp->subBands + curBand + 1, qStepLevel)) return -1; int32_t *band0Buf = wavelet->subband0Buf; int32_t *band1Buf = wavelet->subband1Buf; // process H band if (wavelet->width <= 1) lineBufH0[0] = band0Buf[0]; else { if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT) { lineBufH0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); ++band1Buf; } else lineBufH0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); ++band0Buf; for (int i = 0; i < wavelet->width - 3; i += 2) { int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1); lineBufH0[2] = delta; ++band0Buf; ++band1Buf; lineBufH0 += 2; } if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT) { int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1); lineBufH0[2] = delta; } else if (wavelet->width & 1) { int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1); lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1); lineBufH0[2] = delta; } else { lineBufH0[1] = band1Buf[0] + lineBufH0[0]; } } ++wavelet->curLine; ++wavelet->curH; wavelet->fltTapH = (wavelet->fltTapH + 1) % 5; } } return 0; } void crxFreeSubbandData(CrxImage *image, CrxPlaneComp *comp) { if (comp->compBuf) { free(comp->compBuf); comp->compBuf = 0; } if (!comp->subBands) return; for (int32_t i = 0; i < image->subbandCount; i++) { if (comp->subBands[i].bandParam) { free(comp->subBands[i].bandParam); comp->subBands[i].bandParam = 0LL; } comp->subBands[i].bandBuf = 0; comp->subBands[i].bandSize = 0; } } void crxConvertPlaneLine(CrxImage *img, int imageRow, int imageCol = 0, int plane = 0, int32_t *lineData = 0, int lineLength = 0) { if (lineData) { uint64_t rawOffset = 4 * img->planeWidth * imageRow + 2 * imageCol; if (img->encType == 1) { int32_t maxVal = 1 << (img->nBits - 1); int32_t minVal = -maxVal; --maxVal; for (int i = 0; i < lineLength; i++) img->outBufs[plane][rawOffset + 2 * i] = _constrain(lineData[i], minVal, maxVal); } else if (img->encType == 3) { // copy to intermediate planeBuf rawOffset = plane * img->planeWidth * img->planeHeight + img->planeWidth * imageRow + imageCol; for (int i = 0; i < lineLength; i++) img->planeBuf[rawOffset + i] = lineData[i]; } else if (img->nPlanes == 4) { int32_t median = 1 << (img->nBits - 1); int32_t maxVal = (1 << img->nBits) - 1; for (int i = 0; i < lineLength; i++) img->outBufs[plane][rawOffset + 2 * i] = _constrain(median + lineData[i], 0, maxVal); } else if (img->nPlanes == 1) { int32_t maxVal = (1 << img->nBits) - 1; int32_t median = 1 << (img->nBits - 1); rawOffset = img->planeWidth * imageRow + imageCol; for (int i = 0; i < lineLength; i++) img->outBufs[0][rawOffset + i] = _constrain(median + lineData[i], 0, maxVal); } } else if (img->encType == 3 && img->planeBuf) { int32_t planeSize = img->planeWidth * img->planeHeight; int16_t *plane0 = img->planeBuf + imageRow * img->planeWidth; int16_t *plane1 = plane0 + planeSize; int16_t *plane2 = plane1 + planeSize; int16_t *plane3 = plane2 + planeSize; int32_t median = (1 << (img->medianBits - 1)) << 10; int32_t maxVal = (1 << img->medianBits) - 1; uint32_t rawLineOffset = 4 * img->planeWidth * imageRow; // for this stage - all except imageRow is ignored for (int i = 0; i < img->planeWidth; i++) { int32_t gr = median + (plane0[i] << 10) - 168 * plane1[i] - 585 * plane3[i]; int32_t val = 0; if (gr < 0) gr = -(((_abs(gr) + 512) >> 9) & ~1); else gr = ((_abs(gr) + 512) >> 9) & ~1; // Essentially R = round(median + P0 + 1.474*P3) val = (median + (plane0[i] << 10) + 1510 * plane3[i] + 512) >> 10; img->outBufs[0][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal); // Essentially G1 = round(median + P0 + P2 - 0.164*P1 - 0.571*P3) val = (plane2[i] + gr + 1) >> 1; img->outBufs[1][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal); // Essentially G2 = round(median + P0 - P2 - 0.164*P1 - 0.571*P3) val = (gr - plane2[i] + 1) >> 1; img->outBufs[2][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal); // Essentially B = round(median + P0 + 1.881*P1) val = (median + (plane0[i] << 10) + 1927 * plane1[i] + 512) >> 10; img->outBufs[3][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal); } } } int crxParamInit(CrxImage *img, CrxBandParam **param, uint64_t subbandMdatOffset, uint64_t subbandDataSize, uint32_t subbandWidth, uint32_t subbandHeight, bool supportsPartial, uint32_t roundedBitsMask) { int32_t progrDataSize = supportsPartial ? 0 : sizeof(int32_t) * subbandWidth; int32_t paramLength = 2 * subbandWidth + 4; uint8_t *paramBuf = 0; paramBuf = (uint8_t *) #ifdef LIBRAW_CR3_MEMPOOL img->memmgr. #endif calloc(1, sizeof(CrxBandParam) + sizeof(int32_t) * paramLength + progrDataSize); if (!paramBuf) return -1; *param = (CrxBandParam *)paramBuf; paramBuf += sizeof(CrxBandParam); (*param)->paramData = (int32_t *)paramBuf; (*param)->nonProgrData = progrDataSize ? (*param)->paramData + paramLength : 0; (*param)->subbandWidth = subbandWidth; (*param)->subbandHeight = subbandHeight; (*param)->roundedBits = 0; (*param)->curLine = 0; (*param)->roundedBitsMask = roundedBitsMask; (*param)->supportsPartial = supportsPartial; (*param)->bitStream.bitData = 0; (*param)->bitStream.bitsLeft = 0; (*param)->bitStream.mdatSize = subbandDataSize; (*param)->bitStream.curPos = 0; (*param)->bitStream.curBufSize = 0; (*param)->bitStream.curBufOffset = subbandMdatOffset; (*param)->bitStream.input = img->input; crxFillBuffer(&(*param)->bitStream); return 0; } int crxSetupSubbandData(CrxImage *img, CrxPlaneComp *planeComp, const CrxTile *tile, uint32_t mdatOffset) { long compDataSize = 0; long waveletDataOffset = 0; long compCoeffDataOffset = 0; int32_t toSubbands = 3 * img->levels + 1; int32_t transformWidth = 0; CrxSubband *subbands = planeComp->subBands; // calculate sizes for (int32_t subbandNum = 0; subbandNum < toSubbands; subbandNum++) { subbands[subbandNum].bandSize = subbands[subbandNum].width * sizeof(int32_t); // 4bytes compDataSize += subbands[subbandNum].bandSize; } if (img->levels) { int32_t encLevels = img->levels ? img->levels : 1; waveletDataOffset = (compDataSize + 7) & ~7; compDataSize = (sizeof(CrxWaveletTransform) * encLevels + waveletDataOffset + 7) & ~7; compCoeffDataOffset = compDataSize; // calc wavelet line buffer sizes (always at one level up from current) for (int level = 0; level < img->levels; ++level) if (level < img->levels - 1) compDataSize += 8 * sizeof(int32_t) * planeComp->subBands[3 * (level + 1) + 2].width; else compDataSize += 8 * sizeof(int32_t) * tile->width; } // buffer allocation planeComp->compBuf = (uint8_t *) #ifdef LIBRAW_CR3_MEMPOOL img->memmgr. #endif malloc(compDataSize); if (!planeComp->compBuf) return -1; // subbands buffer and sizes initialisation uint64_t subbandMdatOffset = img->mdatOffset + mdatOffset; uint8_t *subbandBuf = planeComp->compBuf; for (int32_t subbandNum = 0; subbandNum < toSubbands; subbandNum++) { subbands[subbandNum].bandBuf = subbandBuf; subbandBuf += subbands[subbandNum].bandSize; subbands[subbandNum].mdatOffset = subbandMdatOffset + subbands[subbandNum].dataOffset; } // wavelet data initialisation if (img->levels) { CrxWaveletTransform *waveletTransforms = (CrxWaveletTransform *)(planeComp->compBuf + waveletDataOffset); int32_t *paramData = (int32_t *)(planeComp->compBuf + compCoeffDataOffset); planeComp->wvltTransform = waveletTransforms; waveletTransforms[0].subband0Buf = (int32_t *)subbands->bandBuf; for (int level = 0; level < img->levels; ++level) { int32_t band = 3 * level + 1; if (level >= img->levels - 1) { waveletTransforms[level].height = tile->height; transformWidth = tile->width; } else { waveletTransforms[level].height = subbands[band + 3].height; transformWidth = subbands[band + 4].width; } waveletTransforms[level].width = transformWidth; waveletTransforms[level].lineBuf[0] = paramData; waveletTransforms[level].lineBuf[1] = waveletTransforms[level].lineBuf[0] + transformWidth; waveletTransforms[level].lineBuf[2] = waveletTransforms[level].lineBuf[1] + transformWidth; waveletTransforms[level].lineBuf[3] = waveletTransforms[level].lineBuf[2] + transformWidth; waveletTransforms[level].lineBuf[4] = waveletTransforms[level].lineBuf[3] + transformWidth; waveletTransforms[level].lineBuf[5] = waveletTransforms[level].lineBuf[4] + transformWidth; waveletTransforms[level].lineBuf[6] = waveletTransforms[level].lineBuf[5] + transformWidth; waveletTransforms[level].lineBuf[7] = waveletTransforms[level].lineBuf[6] + transformWidth; waveletTransforms[level].curLine = 0; waveletTransforms[level].curH = 0; waveletTransforms[level].fltTapH = 0; waveletTransforms[level].subband1Buf = (int32_t *)subbands[band].bandBuf; waveletTransforms[level].subband2Buf = (int32_t *)subbands[band + 1].bandBuf; waveletTransforms[level].subband3Buf = (int32_t *)subbands[band + 2].bandBuf; paramData = waveletTransforms[level].lineBuf[7] + transformWidth; } } // decoding params and bitstream initialisation for (int32_t subbandNum = 0; subbandNum < toSubbands; subbandNum++) { if (subbands[subbandNum].dataSize) { bool supportsPartial = false; uint32_t roundedBitsMask = 0; if (planeComp->supportsPartial && subbandNum == 0) { roundedBitsMask = planeComp->roundedBitsMask; supportsPartial = true; } if (crxParamInit(img, &subbands[subbandNum].bandParam, subbands[subbandNum].mdatOffset, subbands[subbandNum].dataSize, subbands[subbandNum].width, subbands[subbandNum].height, supportsPartial, roundedBitsMask)) return -1; } } return 0; } int LibRaw::crxDecodePlane(void *p, uint32_t planeNumber) { CrxImage *img = (CrxImage *)p; int imageRow = 0; for (int tRow = 0; tRow < img->tileRows; tRow++) { int imageCol = 0; for (int tCol = 0; tCol < img->tileCols; tCol++) { CrxTile *tile = img->tiles + tRow * img->tileCols + tCol; CrxPlaneComp *planeComp = tile->comps + planeNumber; uint64_t tileMdatOffset = tile->dataOffset + tile->mdatQPDataSize + tile->mdatExtraSize + planeComp->dataOffset; // decode single tile if (crxSetupSubbandData(img, planeComp, tile, tileMdatOffset)) return -1; if (img->levels) { if (crxIdwt53FilterInitialize(planeComp, img->levels, tile->qStep)) return -1; for (int i = 0; i < tile->height; ++i) { if (crxIdwt53FilterDecode(planeComp, img->levels - 1, tile->qStep) || crxIdwt53FilterTransform(planeComp, img->levels - 1)) return -1; int32_t *lineData = crxIdwt53FilterGetLine(planeComp, img->levels - 1); crxConvertPlaneLine(img, imageRow + i, imageCol, planeNumber, lineData, tile->width); } } else { // we have the only subband in this case if (!planeComp->subBands->dataSize) { memset(planeComp->subBands->bandBuf, 0, planeComp->subBands->bandSize); return 0; } for (int i = 0; i < tile->height; ++i) { if (crxDecodeLine(planeComp->subBands->bandParam, planeComp->subBands->bandBuf)) return -1; int32_t *lineData = (int32_t *)planeComp->subBands->bandBuf; crxConvertPlaneLine(img, imageRow + i, imageCol, planeNumber, lineData, tile->width); } } imageCol += tile->width; } imageRow += img->tiles[tRow * img->tileCols].height; } return 0; } uint32_t crxReadQP(CrxBitstream *bitStrm, int32_t kParam) { uint32_t qp = crxBitstreamGetZeros(bitStrm); if (qp >= 23) qp = crxBitstreamGetBits(bitStrm, 8); else if (kParam) qp = crxBitstreamGetBits(bitStrm, kParam) | (qp << kParam); return qp; } void crxDecodeGolombTop(CrxBitstream *bitStrm, int32_t width, int32_t *lineBuf, int32_t *kParam) { lineBuf[0] = 0; while (width-- > 0) { lineBuf[1] = lineBuf[0]; uint32_t qp = crxReadQP(bitStrm, *kParam); lineBuf[1] += -(int32_t)(qp & 1) ^ (int32_t)(qp >> 1); *kParam = crxPredictKParameter(*kParam, qp, 7); ++lineBuf; } lineBuf[1] = lineBuf[0] + 1; } void crxDecodeGolombNormal(CrxBitstream *bitStrm, int32_t width, int32_t *lineBuf0, int32_t *lineBuf1, int32_t *kParam) { lineBuf1[0] = lineBuf0[1]; int32_t deltaH = lineBuf0[1] - lineBuf0[0]; while (width-- > 0) { lineBuf1[1] = crxPrediction(lineBuf1[0], lineBuf0[1], deltaH, lineBuf0[0] - lineBuf1[0]); uint32_t qp = crxReadQP(bitStrm, *kParam); lineBuf1[1] += -(int32_t)(qp & 1) ^ (int32_t)(qp >> 1); if (width) { deltaH = lineBuf0[2] - lineBuf0[1]; *kParam = crxPredictKParameter(*kParam, (qp + 2 * _abs(deltaH)) >> 1, 7); ++lineBuf0; } else *kParam = crxPredictKParameter(*kParam, qp, 7); ++lineBuf1; } lineBuf1[1] = lineBuf1[0] + 1; } int crxMakeQStep(CrxImage *img, CrxTile *tile, int32_t *qpTable, uint32_t /*totalQP*/) { if (img->levels > 3 || img->levels < 1) return -1; int qpWidth = (tile->width >> 3) + ((tile->width & 7) != 0); int qpHeight = (tile->height >> 1) + (tile->height & 1); int qpHeight4 = (tile->height >> 2) + ((tile->height & 3) != 0); int qpHeight8 = (tile->height >> 3) + ((tile->height & 7) != 0); uint32_t totalHeight = qpHeight; if (img->levels > 1) totalHeight += qpHeight4; if (img->levels > 2) totalHeight += qpHeight8; tile->qStep = (CrxQStep *) #ifdef LIBRAW_CR3_MEMPOOL img->memmgr. #endif malloc(totalHeight * qpWidth * sizeof(uint32_t) + img->levels * sizeof(CrxQStep)); if (!tile->qStep) return -1; uint32_t *qStepTbl = (uint32_t *)(tile->qStep + img->levels); CrxQStep *qStep = tile->qStep; switch (img->levels) { case 3: qStep->qStepTbl = qStepTbl; qStep->width = qpWidth; qStep->height = qpHeight8; for (int qpRow = 0; qpRow < qpHeight8; ++qpRow) { int row0Idx = qpWidth * _min(4 * qpRow, qpHeight - 1); int row1Idx = qpWidth * _min(4 * qpRow + 1, qpHeight - 1); int row2Idx = qpWidth * _min(4 * qpRow + 2, qpHeight - 1); int row3Idx = qpWidth * _min(4 * qpRow + 3, qpHeight - 1); for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl) { int32_t quantVal = qpTable[row0Idx++] + qpTable[row1Idx++] + qpTable[row2Idx++] + qpTable[row3Idx++]; // not sure about this nonsense - why is it not just avg like with 2 levels? quantVal = ((quantVal < 0) * 3 + quantVal) >> 2; if (quantVal / 6 >= 6) *qStepTbl = q_step_tbl[quantVal % 6] << ((quantVal / 6 - 6 ) & 0x1f); else *qStepTbl = q_step_tbl[quantVal % 6] >> (6 - quantVal / 6); } } // continue to the next level - we always decode all levels ++qStep; case 2: qStep->qStepTbl = qStepTbl; qStep->width = qpWidth; qStep->height = qpHeight4; for (int qpRow = 0; qpRow < qpHeight4; ++qpRow) { int row0Idx = qpWidth * _min(2 * qpRow, qpHeight - 1); int row1Idx = qpWidth * _min(2 * qpRow + 1, qpHeight - 1); for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl) { int32_t quantVal = (qpTable[row0Idx++] + qpTable[row1Idx++]) / 2; if (quantVal / 6 >= 6) *qStepTbl = q_step_tbl[quantVal % 6] << ((quantVal / 6 - 6) & 0x1f); else *qStepTbl = q_step_tbl[quantVal % 6] >> (6 - quantVal / 6); } } // continue to the next level - we always decode all levels ++qStep; case 1: qStep->qStepTbl = qStepTbl; qStep->width = qpWidth; qStep->height = qpHeight; for (int qpRow = 0; qpRow < qpHeight; ++qpRow) for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl, ++qpTable) if (*qpTable / 6 >= 6) *qStepTbl = q_step_tbl[*qpTable % 6] << ((*qpTable / 6 - 6) & 0x1f); else *qStepTbl = q_step_tbl[*qpTable % 6] >> (6 - *qpTable / 6); break; } return 0; } libraw_inline void crxSetupSubbandIdx(crx_data_header_t *hdr, CrxImage * /*img*/, CrxSubband *band, int level, short colStartIdx, short bandWidthExCoef, short rowStartIdx, short bandHeightExCoef) { if (hdr->version == 0x200) { band->rowStartAddOn = rowStartIdx; band->rowEndAddOn = bandHeightExCoef; band->colStartAddOn = colStartIdx; band->colEndAddOn = bandWidthExCoef; band->levelShift = 3 - level; } else { band->rowStartAddOn = 0; band->rowEndAddOn = 0; band->colStartAddOn = 0; band->colEndAddOn = 0; band->levelShift = 0; } } int crxProcessSubbands(crx_data_header_t *hdr, CrxImage *img, CrxTile *tile, CrxPlaneComp *comp) { CrxSubband *band = comp->subBands + img->subbandCount - 1; // set to last band uint32_t bandHeight = tile->height; uint32_t bandWidth = tile->width; int32_t bandWidthExCoef = 0; int32_t bandHeightExCoef = 0; if (img->levels) { // Build up subband sequences to crxDecode to a level in a header // Coefficient structure is a bit unclear and convoluted: // 3 levels max - 8 groups (for tile width rounded to 8 bytes) // of 3 band per level 4 sets of coefficients for each int32_t *rowExCoef = exCoefNumTbl + 0x30 * (img->levels - 1) + 6 * (tile->width & 7); int32_t *colExCoef = exCoefNumTbl + 0x30 * (img->levels - 1) + 6 * (tile->height & 7); for (int level = 0; level < img->levels; ++level) { int32_t widthOddPixel = bandWidth & 1; int32_t heightOddPixel = bandHeight & 1; bandWidth = (widthOddPixel + bandWidth) >> 1; bandHeight = (heightOddPixel + bandHeight) >> 1; int32_t bandWidthExCoef0 = 0; int32_t bandWidthExCoef1 = 0; int32_t bandHeightExCoef0 = 0; int32_t bandHeightExCoef1 = 0; int32_t colStartIdx = 0; int32_t rowStartIdx = 0; if (tile->tileFlag & E_HAS_TILES_ON_THE_RIGHT) { bandWidthExCoef0 = rowExCoef[2 * level]; bandWidthExCoef1 = rowExCoef[2 * level + 1]; } if (tile->tileFlag & E_HAS_TILES_ON_THE_LEFT) { ++bandWidthExCoef0; colStartIdx = 1; } if (tile->tileFlag & E_HAS_TILES_ON_THE_BOTTOM) { bandHeightExCoef0 = colExCoef[2 * level]; bandHeightExCoef1 = colExCoef[2 * level + 1]; } if (tile->tileFlag & E_HAS_TILES_ON_THE_TOP) { ++bandHeightExCoef0; rowStartIdx = 1; } band[0].width = bandWidth + bandWidthExCoef0 - widthOddPixel; band[0].height = bandHeight + bandHeightExCoef0 - heightOddPixel; crxSetupSubbandIdx(hdr, img, band, level + 1, colStartIdx, bandWidthExCoef0 - colStartIdx, rowStartIdx, bandHeightExCoef0 - rowStartIdx); band[-1].width = bandWidth + bandWidthExCoef1; band[-1].height = bandHeight + bandHeightExCoef0 - heightOddPixel; crxSetupSubbandIdx(hdr, img, band - 1, level + 1, 0, bandWidthExCoef1, rowStartIdx, bandHeightExCoef0 - rowStartIdx); band[-2].width = bandWidth + bandWidthExCoef0 - widthOddPixel; band[-2].height = bandHeight + bandHeightExCoef1; crxSetupSubbandIdx(hdr, img, band - 2, level + 1, colStartIdx, bandWidthExCoef0 - colStartIdx, 0, bandHeightExCoef1); band -= 3; } bandWidthExCoef = bandHeightExCoef = 0; if (tile->tileFlag & E_HAS_TILES_ON_THE_RIGHT) bandWidthExCoef = rowExCoef[2 * img->levels - 1]; if (tile->tileFlag & E_HAS_TILES_ON_THE_BOTTOM) bandHeightExCoef = colExCoef[2 * img->levels - 1]; } band->width = bandWidthExCoef + bandWidth; band->height = bandHeightExCoef + bandHeight; if (img->levels) crxSetupSubbandIdx(hdr, img, band, img->levels, 0, bandWidthExCoef, 0, bandHeightExCoef); return 0; } int crxReadSubbandHeaders(crx_data_header_t * /*hdr*/, CrxImage *img, CrxTile * /*tile*/, CrxPlaneComp *comp, uint8_t **subbandMdatPtr, int32_t *mdatSize) { if (!img->subbandCount) return 0; int32_t subbandOffset = 0; CrxSubband *band = comp->subBands; for (int curSubband = 0; curSubband < img->subbandCount; curSubband++, band++) { if (*mdatSize < 4) return -1; int hdrSign = LibRaw::sgetn(2, *subbandMdatPtr); int hdrSize = LibRaw::sgetn(2, *subbandMdatPtr + 2); if (*mdatSize < hdrSize + 4) return -1; if ((hdrSign != 0xFF03 || hdrSize != 8) && (hdrSign != 0xFF13 || hdrSize != 16)) return -1; int32_t subbandSize = LibRaw::sgetn(4, *subbandMdatPtr + 4); if (curSubband != ((*subbandMdatPtr)[8] & 0xF0) >> 4) { band->dataSize = subbandSize; return -1; } band->dataOffset = subbandOffset; band->kParam = 0; band->bandParam = 0; band->bandBuf = 0; band->bandSize = 0; if (hdrSign == 0xFF03) { // old header uint32_t bitData = LibRaw::sgetn(4, *subbandMdatPtr + 8); band->dataSize = subbandSize - (bitData & 0x7FFFF); band->supportsPartial = bitData & 0x8000000; band->qParam = (bitData >> 19) & 0xFF; band->qStepBase = 0; band->qStepMult = 0; } else { // new header if (LibRaw::sgetn(2, *subbandMdatPtr + 8) & 0xFFF) // partial and qParam are not supported return -1; if (LibRaw::sgetn(2, *subbandMdatPtr + 18)) // new header terninated by 2 zero bytes return -1; band->supportsPartial = false; band->qParam = 0; band->dataSize = subbandSize - LibRaw::sgetn(2, *subbandMdatPtr + 16); band->qStepBase = LibRaw::sgetn(4, *subbandMdatPtr + 12); ; band->qStepMult = LibRaw::sgetn(2, *subbandMdatPtr + 10); ; } subbandOffset += subbandSize; *subbandMdatPtr += hdrSize + 4; *mdatSize -= hdrSize + 4; } return 0; } int crxReadImageHeaders(crx_data_header_t *hdr, CrxImage *img, uint8_t *mdatPtr, int32_t mdatHdrSize) { int nTiles = img->tileRows * img->tileCols; if (!nTiles) return -1; if (!img->tiles) { img->tiles = (CrxTile *) #ifdef LIBRAW_CR3_MEMPOOL img->memmgr. #endif calloc(sizeof(CrxTile) * nTiles + sizeof(CrxPlaneComp) * nTiles * img->nPlanes + sizeof(CrxSubband) * nTiles * img->nPlanes * img->subbandCount, 1); if (!img->tiles) return -1; // memory areas in allocated chunk CrxTile *tile = img->tiles; CrxPlaneComp *comps = (CrxPlaneComp *)(tile + nTiles); CrxSubband *bands = (CrxSubband *)(comps + img->nPlanes * nTiles); for (int curTile = 0; curTile < nTiles; curTile++, tile++) { tile->tileFlag = 0; // tile neighbouring flags tile->tileNumber = curTile; tile->tileSize = 0; tile->comps = comps + curTile * img->nPlanes; if ((curTile + 1) % img->tileCols) { // not the last tile in a tile row tile->width = hdr->tileWidth; if (img->tileCols > 1) { tile->tileFlag = E_HAS_TILES_ON_THE_RIGHT; if (curTile % img->tileCols) // not the first tile in tile row tile->tileFlag |= E_HAS_TILES_ON_THE_LEFT; } } else { // last tile in a tile row tile->width = img->planeWidth - hdr->tileWidth * (img->tileCols - 1); if (img->tileCols > 1) tile->tileFlag = E_HAS_TILES_ON_THE_LEFT; } if (curTile < nTiles - img->tileCols) { // in first tile row tile->height = hdr->tileHeight; if (img->tileRows > 1) { tile->tileFlag |= E_HAS_TILES_ON_THE_BOTTOM; if (curTile >= img->tileCols) tile->tileFlag |= E_HAS_TILES_ON_THE_TOP; } } else { // non first tile row tile->height = img->planeHeight - hdr->tileHeight * (img->tileRows - 1); if (img->tileRows > 1) tile->tileFlag |= E_HAS_TILES_ON_THE_TOP; } if (img->nPlanes) { CrxPlaneComp *comp = tile->comps; CrxSubband *band = bands + curTile * img->nPlanes * img->subbandCount; for (int curComp = 0; curComp < img->nPlanes; curComp++, comp++) { comp->compNumber = curComp; comp->supportsPartial = true; comp->tileFlag = tile->tileFlag; comp->subBands = band; comp->compBuf = 0; comp->wvltTransform = 0; if (img->subbandCount) { for (int curBand = 0; curBand < img->subbandCount; curBand++, band++) { band->supportsPartial = false; band->qParam = 4; band->bandParam = 0; band->dataSize = 0; } } } } } } uint32_t tileOffset = 0; int32_t dataSize = mdatHdrSize; uint8_t *dataPtr = mdatPtr; CrxTile *tile = img->tiles; for (int curTile = 0; curTile < nTiles; ++curTile, ++tile) { if (dataSize < 4) return -1; int hdrSign = LibRaw::sgetn(2, dataPtr); int hdrSize = LibRaw::sgetn(2, dataPtr + 2); if ((hdrSign != 0xFF01 || hdrSize != 8) && (hdrSign != 0xFF11 || (hdrSize != 8 && hdrSize != 16))) return -1; if (dataSize < hdrSize + 4) return -1; int tailSign = LibRaw::sgetn(2, dataPtr + 10); if ((hdrSize == 8 && tailSign) || (hdrSize == 16 && tailSign != 0x4000)) return -1; if (LibRaw::sgetn(2, dataPtr + 8) != (unsigned)curTile) return -1; dataSize -= hdrSize + 4; tile->tileSize = LibRaw::sgetn(4, dataPtr + 4); tile->dataOffset = tileOffset; tile->qStep = 0; if (hdrSize == 16) { // extended header data - terminated by 0 bytes if (LibRaw::sgetn(2, dataPtr + 18) != 0) return -1; tile->hasQPData = true; tile->mdatQPDataSize = LibRaw::sgetn(4, dataPtr + 12); tile->mdatExtraSize = LibRaw::sgetn(2, dataPtr + 16); } else { tile->hasQPData = false; tile->mdatQPDataSize = 0; tile->mdatExtraSize = 0; } dataPtr += hdrSize + 4; tileOffset += tile->tileSize; uint32_t compOffset = 0; CrxPlaneComp *comp = tile->comps; for (int compNum = 0; compNum < img->nPlanes; ++compNum, ++comp) { if (dataSize < 0xC) return -1; hdrSign = LibRaw::sgetn(2, dataPtr); hdrSize = LibRaw::sgetn(2, dataPtr + 2); if ((hdrSign != 0xFF02 && hdrSign != 0xFF12) || hdrSize != 8) return -1; if (compNum != dataPtr[8] >> 4) return -1; if (LibRaw::sgetn(3, dataPtr + 9) != 0) return -1; comp->compSize = LibRaw::sgetn(4, dataPtr + 4); int32_t compHdrRoundedBits = (dataPtr[8] >> 1) & 3; comp->supportsPartial = (dataPtr[8] & 8) != 0; comp->dataOffset = compOffset; comp->tileFlag = tile->tileFlag; compOffset += comp->compSize; dataSize -= 0xC; dataPtr += 0xC; comp->roundedBitsMask = 0; if (compHdrRoundedBits) { if (img->levels || !comp->supportsPartial) return -1; comp->roundedBitsMask = 1 << (compHdrRoundedBits - 1); } if (crxReadSubbandHeaders(hdr, img, tile, comp, &dataPtr, &dataSize) || crxProcessSubbands(hdr, img, tile, comp)) return -1; } } if (hdr->version != 0x200) return 0; tile = img->tiles; for (int curTile = 0; curTile < nTiles; ++curTile, ++tile) { if (tile->hasQPData) { CrxBitstream bitStrm; bitStrm.bitData = 0; bitStrm.bitsLeft = 0; bitStrm.curPos = 0; bitStrm.curBufSize = 0; bitStrm.mdatSize = tile->mdatQPDataSize; bitStrm.curBufOffset = img->mdatOffset + tile->dataOffset; bitStrm.input = img->input; crxFillBuffer(&bitStrm); unsigned int qpWidth = (tile->width >> 3) + ((tile->width & 7) != 0); unsigned int qpHeight = (tile->height >> 1) + (tile->height & 1); unsigned long totalQP = qpHeight * qpWidth; try { std::vector qpTable(totalQP + 2 * (qpWidth + 2)); int32_t *qpCurElem = qpTable.data(); // 2 lines padded with extra pixels at the start and at the end int32_t *qpLineBuf = qpTable.data() + totalQP; int32_t kParam = 0; for (unsigned qpRow = 0; qpRow < qpHeight; ++qpRow) { int32_t *qpLine0 = qpRow & 1 ? qpLineBuf + qpWidth + 2 : qpLineBuf; int32_t *qpLine1 = qpRow & 1 ? qpLineBuf : qpLineBuf + qpWidth + 2; if (qpRow) crxDecodeGolombNormal(&bitStrm, qpWidth, qpLine0, qpLine1, &kParam); else crxDecodeGolombTop(&bitStrm, qpWidth, qpLine1, &kParam); for (unsigned qpCol = 0; qpCol < qpWidth; ++qpCol) *qpCurElem++ = qpLine1[qpCol + 1] + 4; } // now we read QP data - build tile QStep if (crxMakeQStep(img, tile, qpTable.data(), totalQP)) return -1; } catch (...) { return -1; } } } return 0; } int crxSetupImageData(crx_data_header_t *hdr, CrxImage *img, int16_t *outBuf, uint64_t mdatOffset, uint32_t mdatSize, uint8_t *mdatHdrPtr, int32_t mdatHdrSize) { int IncrBitTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0}; img->planeWidth = hdr->f_width; img->planeHeight = hdr->f_height; if (hdr->tileWidth < 0x16 || hdr->tileHeight < 0x16 || img->planeWidth > 0x7FFF || img->planeHeight > 0x7FFF) return -1; img->tileCols = (img->planeWidth + hdr->tileWidth - 1) / hdr->tileWidth; img->tileRows = (img->planeHeight + hdr->tileHeight - 1) / hdr->tileHeight; if (img->tileCols > 0xFF || img->tileRows > 0xFF || img->planeWidth - hdr->tileWidth * (img->tileCols - 1) < 0x16 || img->planeHeight - hdr->tileHeight * (img->tileRows - 1) < 0x16) return -1; img->tiles = 0; img->levels = hdr->imageLevels; img->subbandCount = 3 * img->levels + 1; // 3 bands per level + one last LL img->nPlanes = hdr->nPlanes; img->nBits = hdr->nBits; img->encType = hdr->encType; img->samplePrecision = hdr->nBits + IncrBitTable[4 * hdr->encType + 2] + 1; img->mdatOffset = mdatOffset + hdr->mdatHdrSize; img->mdatSize = mdatSize; img->planeBuf = 0; img->outBufs[0] = img->outBufs[1] = img->outBufs[2] = img->outBufs[3] = 0; img->medianBits = hdr->medianBits; // The encoding type 3 needs all 4 planes to be decoded to generate row of // RGGB values. It seems to be using some other colour space for raw encoding // It is a massive buffer so ideallly it will need a different approach: // decode planes line by line and convert single line then without // intermediate plane buffer. At the moment though it's too many changes so // left as is. if (img->encType == 3 && img->nPlanes == 4 && img->nBits > 8) { img->planeBuf = (int16_t *) #ifdef LIBRAW_CR3_MEMPOOL img->memmgr. #endif malloc(img->planeHeight * img->planeWidth * img->nPlanes * ((img->samplePrecision + 7) >> 3)); if (!img->planeBuf) return -1; } int32_t rowSize = 2 * img->planeWidth; if (img->nPlanes == 1) img->outBufs[0] = outBuf; else switch (hdr->cfaLayout) { case 0: // R G // G B img->outBufs[0] = outBuf; img->outBufs[1] = outBuf + 1; img->outBufs[2] = outBuf + rowSize; img->outBufs[3] = img->outBufs[2] + 1; break; case 1: // G R // B G img->outBufs[1] = outBuf; img->outBufs[0] = outBuf + 1; img->outBufs[3] = outBuf + rowSize; img->outBufs[2] = img->outBufs[3] + 1; break; case 2: // G B // R G img->outBufs[2] = outBuf; img->outBufs[3] = outBuf + 1; img->outBufs[0] = outBuf + rowSize; img->outBufs[1] = img->outBufs[0] + 1; break; case 3: // B G // G R img->outBufs[3] = outBuf; img->outBufs[2] = outBuf + 1; img->outBufs[1] = outBuf + rowSize; img->outBufs[0] = img->outBufs[1] + 1; break; } // read header return crxReadImageHeaders(hdr, img, mdatHdrPtr, mdatHdrSize); } int crxFreeImageData(CrxImage *img) { #ifdef LIBRAW_CR3_MEMPOOL img->memmgr.cleanup(); #else CrxTile *tile = img->tiles; int nTiles = img->tileRows * img->tileCols; if (img->tiles) { for (int32_t curTile = 0; curTile < nTiles; curTile++) { if (tile[curTile].comps) for (int32_t curPlane = 0; curPlane < img->nPlanes; curPlane++) crxFreeSubbandData(img, tile[curTile].comps + curPlane); if (tile[curTile].qStep) free(tile[curTile].qStep); } free(img->tiles); img->tiles = 0; } if (img->planeBuf) { free(img->planeBuf); img->planeBuf = 0; } #endif return 0; } void LibRaw::crxLoadDecodeLoop(void *img, int nPlanes) { #ifdef LIBRAW_USE_OPENMP int results[4] ={0,0,0,0}; // nPlanes is always <= 4 #pragma omp parallel for for (int32_t plane = 0; plane < nPlanes; ++plane) try { results[plane] = crxDecodePlane(img, plane); } catch (...) { results[plane] = 1; } for (int32_t plane = 0; plane < nPlanes; ++plane) if (results[plane]) derror(); #else for (int32_t plane = 0; plane < nPlanes; ++plane) if (crxDecodePlane(img, plane)) derror(); #endif } void LibRaw::crxConvertPlaneLineDf(void *p, int imageRow) { crxConvertPlaneLine((CrxImage *)p, imageRow); } void LibRaw::crxLoadFinalizeLoopE3(void *p, int planeHeight) { #ifdef LIBRAW_USE_OPENMP #pragma omp parallel for #endif for (int i = 0; i < planeHeight; ++i) crxConvertPlaneLineDf(p, i); } void LibRaw::crxLoadRaw() { CrxImage img; if (libraw_internal_data.unpacker_data.crx_track_selected < 0 || libraw_internal_data.unpacker_data.crx_track_selected >= LIBRAW_CRXTRACKS_MAXCOUNT) derror(); crx_data_header_t hdr = libraw_internal_data.unpacker_data.crx_header[libraw_internal_data.unpacker_data.crx_track_selected]; if (libraw_internal_data.unpacker_data.data_size < (unsigned)hdr.mdatHdrSize) derror(); img.input = libraw_internal_data.internal_data.input; // update sizes for the planes if (hdr.nPlanes == 4) { hdr.f_width >>= 1; hdr.f_height >>= 1; hdr.tileWidth >>= 1; hdr.tileHeight >>= 1; } imgdata.color.maximum = (1 << hdr.nBits) - 1; std::vector hdrBuf(hdr.mdatHdrSize); unsigned bytes = 0; // read image header #ifdef LIBRAW_USE_OPENMP #pragma omp critical #endif { #ifndef LIBRAW_USE_OPENMP libraw_internal_data.internal_data.input->lock(); #endif libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET); bytes = libraw_internal_data.internal_data.input->read(hdrBuf.data(), 1, hdr.mdatHdrSize); #ifndef LIBRAW_USE_OPENMP libraw_internal_data.internal_data.input->unlock(); #endif } if (bytes != hdr.mdatHdrSize) throw LIBRAW_EXCEPTION_IO_EOF; // parse and setup the image data if (crxSetupImageData(&hdr, &img, (int16_t *)imgdata.rawdata.raw_image, libraw_internal_data.unpacker_data.data_offset, libraw_internal_data.unpacker_data.data_size, hdrBuf.data(), hdr.mdatHdrSize)) throw LIBRAW_EXCEPTION_IO_CORRUPT; crxLoadDecodeLoop(&img, hdr.nPlanes); if (img.encType == 3) crxLoadFinalizeLoopE3(&img, img.planeHeight); crxFreeImageData(&img); } int LibRaw::crxParseImageHeader(uchar *cmp1TagData, int nTrack, int size) { if (nTrack < 0 || nTrack >= LIBRAW_CRXTRACKS_MAXCOUNT) return -1; if (!cmp1TagData) return -1; crx_data_header_t *hdr = &libraw_internal_data.unpacker_data.crx_header[nTrack]; hdr->version = sgetn(2, cmp1TagData + 4); hdr->f_width = sgetn(4, cmp1TagData + 8); hdr->f_height = sgetn(4, cmp1TagData + 12); hdr->tileWidth = sgetn(4, cmp1TagData + 16); hdr->tileHeight = sgetn(4, cmp1TagData + 20); hdr->nBits = cmp1TagData[24]; hdr->nPlanes = cmp1TagData[25] >> 4; hdr->cfaLayout = cmp1TagData[25] & 0xF; hdr->encType = cmp1TagData[26] >> 4; hdr->imageLevels = cmp1TagData[26] & 0xF; hdr->hasTileCols = cmp1TagData[27] >> 7; hdr->hasTileRows = (cmp1TagData[27] >> 6) & 1; hdr->mdatHdrSize = sgetn(4, cmp1TagData + 28); int extHeader = cmp1TagData[32] >> 7; int useMedianBits = 0; hdr->medianBits = hdr->nBits; if (extHeader && size >= 56 && hdr->nPlanes == 4) useMedianBits = cmp1TagData[56] >> 6 & 1; if (useMedianBits && size >= 84) hdr->medianBits = cmp1TagData[84]; // validation if ((hdr->version != 0x100 && hdr->version != 0x200) || !hdr->mdatHdrSize) return -1; if (hdr->encType == 1) { if (hdr->nBits > 15) return -1; } else { if (hdr->encType && hdr->encType != 3) return -1; if (hdr->nBits > 14) return -1; } if (hdr->nPlanes == 1) { if (hdr->cfaLayout || hdr->encType || hdr->nBits != 8) return -1; } else if (hdr->nPlanes != 4 || hdr->f_width & 1 || hdr->f_height & 1 || hdr->tileWidth & 1 || hdr->tileHeight & 1 || hdr->cfaLayout > 3 || hdr->nBits == 8) return -1; if (hdr->tileWidth > hdr->f_width || hdr->tileHeight > hdr->f_height) return -1; if (hdr->imageLevels > 3 || hdr->hasTileCols > 1 || hdr->hasTileRows > 1) return -1; return 0; } #undef _abs #undef _min #undef _constrain #undef libraw_inline LibRaw-0.21.4/src/decoders/decoders_dcraw.cpp000066400000000000000000001504341477673233700210430ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" #include "../../internal/libraw_cameraids.h" unsigned LibRaw::getbithuff(int nbits, ushort *huff) { #ifdef LIBRAW_NOTHREADS static unsigned bitbuf = 0; static int vbits = 0, reset = 0; #else #define bitbuf tls->getbits.bitbuf #define vbits tls->getbits.vbits #define reset tls->getbits.reset #endif unsigned c; if (nbits > 25) return 0; if (nbits < 0) return bitbuf = vbits = reset = 0; if (nbits == 0 || vbits < 0) return 0; while (!reset && vbits < nbits && (c = fgetc(ifp)) != (unsigned)EOF && !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) { bitbuf = (bitbuf << 8) + (uchar)c; vbits += 8; } c = vbits == 0 ? 0 : bitbuf << (32 - vbits) >> (32 - nbits); if (huff) { vbits -= huff[c] >> 8; c = (uchar)huff[c]; } else vbits -= nbits; if (vbits < 0) derror(); return c; #ifndef LIBRAW_NOTHREADS #undef bitbuf #undef vbits #undef reset #endif } /* Construct a decode tree according the specification in *source. The first 16 bytes specify how many codes should be 1-bit, 2-bit 3-bit, etc. Bytes after that are the leaf values. For example, if the source is { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, then the code is 00 0x04 010 0x03 011 0x05 100 0x06 101 0x02 1100 0x07 1101 0x01 11100 0x08 11101 0x09 11110 0x00 111110 0x0a 1111110 0x0b 1111111 0xff */ ushort *LibRaw::make_decoder_ref(const uchar **source) { int max, len, h, i, j; const uchar *count; ushort *huff; count = (*source += 16) - 17; for (max = 16; max && !count[max]; max--) ; huff = (ushort *)calloc(1 + (1 << max), sizeof *huff); huff[0] = max; for (h = len = 1; len <= max; len++) for (i = 0; i < count[len]; i++, ++*source) for (j = 0; j < 1 << (max - len); j++) if (h <= 1 << max) huff[h++] = len << 8 | **source; return huff; } ushort *LibRaw::make_decoder(const uchar *source) { return make_decoder_ref(&source); } void LibRaw::crw_init_tables(unsigned table, ushort *huff[2]) { static const uchar first_tree[3][29] = { {0, 1, 4, 2, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x04, 0x03, 0x05, 0x06, 0x02, 0x07, 0x01, 0x08, 0x09, 0x00, 0x0a, 0x0b, 0xff}, {0, 2, 2, 3, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0x03, 0x02, 0x04, 0x01, 0x05, 0x00, 0x06, 0x07, 0x09, 0x08, 0x0a, 0x0b, 0xff}, {0, 0, 6, 3, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x06, 0x05, 0x07, 0x04, 0x08, 0x03, 0x09, 0x02, 0x00, 0x0a, 0x01, 0x0b, 0xff}, }; static const uchar second_tree[3][180] = { {0, 2, 2, 2, 1, 4, 2, 1, 2, 5, 1, 1, 0, 0, 0, 139, 0x03, 0x04, 0x02, 0x05, 0x01, 0x06, 0x07, 0x08, 0x12, 0x13, 0x11, 0x14, 0x09, 0x15, 0x22, 0x00, 0x21, 0x16, 0x0a, 0xf0, 0x23, 0x17, 0x24, 0x31, 0x32, 0x18, 0x19, 0x33, 0x25, 0x41, 0x34, 0x42, 0x35, 0x51, 0x36, 0x37, 0x38, 0x29, 0x79, 0x26, 0x1a, 0x39, 0x56, 0x57, 0x28, 0x27, 0x52, 0x55, 0x58, 0x43, 0x76, 0x59, 0x77, 0x54, 0x61, 0xf9, 0x71, 0x78, 0x75, 0x96, 0x97, 0x49, 0xb7, 0x53, 0xd7, 0x74, 0xb6, 0x98, 0x47, 0x48, 0x95, 0x69, 0x99, 0x91, 0xfa, 0xb8, 0x68, 0xb5, 0xb9, 0xd6, 0xf7, 0xd8, 0x67, 0x46, 0x45, 0x94, 0x89, 0xf8, 0x81, 0xd5, 0xf6, 0xb4, 0x88, 0xb1, 0x2a, 0x44, 0x72, 0xd9, 0x87, 0x66, 0xd4, 0xf5, 0x3a, 0xa7, 0x73, 0xa9, 0xa8, 0x86, 0x62, 0xc7, 0x65, 0xc8, 0xc9, 0xa1, 0xf4, 0xd1, 0xe9, 0x5a, 0x92, 0x85, 0xa6, 0xe7, 0x93, 0xe8, 0xc1, 0xc6, 0x7a, 0x64, 0xe1, 0x4a, 0x6a, 0xe6, 0xb3, 0xf1, 0xd3, 0xa5, 0x8a, 0xb2, 0x9a, 0xba, 0x84, 0xa4, 0x63, 0xe5, 0xc5, 0xf3, 0xd2, 0xc4, 0x82, 0xaa, 0xda, 0xe4, 0xf2, 0xca, 0x83, 0xa3, 0xa2, 0xc3, 0xea, 0xc2, 0xe2, 0xe3, 0xff, 0xff}, {0, 2, 2, 1, 4, 1, 4, 1, 3, 3, 1, 0, 0, 0, 0, 140, 0x02, 0x03, 0x01, 0x04, 0x05, 0x12, 0x11, 0x06, 0x13, 0x07, 0x08, 0x14, 0x22, 0x09, 0x21, 0x00, 0x23, 0x15, 0x31, 0x32, 0x0a, 0x16, 0xf0, 0x24, 0x33, 0x41, 0x42, 0x19, 0x17, 0x25, 0x18, 0x51, 0x34, 0x43, 0x52, 0x29, 0x35, 0x61, 0x39, 0x71, 0x62, 0x36, 0x53, 0x26, 0x38, 0x1a, 0x37, 0x81, 0x27, 0x91, 0x79, 0x55, 0x45, 0x28, 0x72, 0x59, 0xa1, 0xb1, 0x44, 0x69, 0x54, 0x58, 0xd1, 0xfa, 0x57, 0xe1, 0xf1, 0xb9, 0x49, 0x47, 0x63, 0x6a, 0xf9, 0x56, 0x46, 0xa8, 0x2a, 0x4a, 0x78, 0x99, 0x3a, 0x75, 0x74, 0x86, 0x65, 0xc1, 0x76, 0xb6, 0x96, 0xd6, 0x89, 0x85, 0xc9, 0xf5, 0x95, 0xb4, 0xc7, 0xf7, 0x8a, 0x97, 0xb8, 0x73, 0xb7, 0xd8, 0xd9, 0x87, 0xa7, 0x7a, 0x48, 0x82, 0x84, 0xea, 0xf4, 0xa6, 0xc5, 0x5a, 0x94, 0xa4, 0xc6, 0x92, 0xc3, 0x68, 0xb5, 0xc8, 0xe4, 0xe5, 0xe6, 0xe9, 0xa2, 0xa3, 0xe3, 0xc2, 0x66, 0x67, 0x93, 0xaa, 0xd4, 0xd5, 0xe7, 0xf8, 0x88, 0x9a, 0xd7, 0x77, 0xc4, 0x64, 0xe2, 0x98, 0xa5, 0xca, 0xda, 0xe8, 0xf3, 0xf6, 0xa9, 0xb2, 0xb3, 0xf2, 0xd2, 0x83, 0xba, 0xd3, 0xff, 0xff}, {0, 0, 6, 2, 1, 3, 3, 2, 5, 1, 2, 2, 8, 10, 0, 117, 0x04, 0x05, 0x03, 0x06, 0x02, 0x07, 0x01, 0x08, 0x09, 0x12, 0x13, 0x14, 0x11, 0x15, 0x0a, 0x16, 0x17, 0xf0, 0x00, 0x22, 0x21, 0x18, 0x23, 0x19, 0x24, 0x32, 0x31, 0x25, 0x33, 0x38, 0x37, 0x34, 0x35, 0x36, 0x39, 0x79, 0x57, 0x58, 0x59, 0x28, 0x56, 0x78, 0x27, 0x41, 0x29, 0x77, 0x26, 0x42, 0x76, 0x99, 0x1a, 0x55, 0x98, 0x97, 0xf9, 0x48, 0x54, 0x96, 0x89, 0x47, 0xb7, 0x49, 0xfa, 0x75, 0x68, 0xb6, 0x67, 0x69, 0xb9, 0xb8, 0xd8, 0x52, 0xd7, 0x88, 0xb5, 0x74, 0x51, 0x46, 0xd9, 0xf8, 0x3a, 0xd6, 0x87, 0x45, 0x7a, 0x95, 0xd5, 0xf6, 0x86, 0xb4, 0xa9, 0x94, 0x53, 0x2a, 0xa8, 0x43, 0xf5, 0xf7, 0xd4, 0x66, 0xa7, 0x5a, 0x44, 0x8a, 0xc9, 0xe8, 0xc8, 0xe7, 0x9a, 0x6a, 0x73, 0x4a, 0x61, 0xc7, 0xf4, 0xc6, 0x65, 0xe9, 0x72, 0xe6, 0x71, 0x91, 0x93, 0xa6, 0xda, 0x92, 0x85, 0x62, 0xf3, 0xc5, 0xb2, 0xa4, 0x84, 0xba, 0x64, 0xa5, 0xb3, 0xd2, 0x81, 0xe5, 0xd3, 0xaa, 0xc4, 0xca, 0xf2, 0xb1, 0xe4, 0xd1, 0x83, 0x63, 0xea, 0xc3, 0xe2, 0x82, 0xf1, 0xa3, 0xc2, 0xa1, 0xc1, 0xe3, 0xa2, 0xe1, 0xff, 0xff}}; if (table > 2) table = 2; huff[0] = make_decoder(first_tree[table]); huff[1] = make_decoder(second_tree[table]); } /* Return 0 if the image starts with compressed data, 1 if it starts with uncompressed low-order bits. In Canon compressed data, 0xff is always followed by 0x00. */ int LibRaw::canon_has_lowbits() { uchar test[0x4000]; int ret = 1, i; fseek(ifp, 0, SEEK_SET); fread(test, 1, sizeof test, ifp); for (i = 540; i < int(sizeof test - 1); i++) if (test[i] == 0xff) { if (test[i + 1]) return 1; ret = 0; } return ret; } void LibRaw::canon_load_raw() { ushort *pixel, *prow, *huff[2]; int nblocks, lowbits, i, c, row, r, val; INT64 save; int block, diffbuf[64], leaf, len, diff, carry = 0, pnum = 0, base[2]; crw_init_tables(tiff_compress, huff); lowbits = canon_has_lowbits(); if (!lowbits) maximum = 0x3ff; fseek(ifp, 540 + lowbits * raw_height * raw_width / 4, SEEK_SET); zero_after_ff = 1; getbits(-1); try { for (row = 0; row < raw_height; row += 8) { checkCancel(); pixel = raw_image + row * raw_width; nblocks = MIN(8, raw_height - row) * raw_width >> 6; for (block = 0; block < nblocks; block++) { memset(diffbuf, 0, sizeof diffbuf); for (i = 0; i < 64; i++) { leaf = gethuff(huff[i > 0]); if (leaf == 0 && i) break; if (leaf == 0xff) continue; i += leaf >> 4; len = leaf & 15; if (len == 0) continue; diff = getbits(len); if ((diff & (1 << (len - 1))) == 0) diff -= (1 << len) - 1; if (i < 64) diffbuf[i] = diff; } diffbuf[0] += carry; carry = diffbuf[0]; for (i = 0; i < 64; i++) { if (pnum++ % raw_width == 0) base[0] = base[1] = 512; if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10) derror(); } } if (lowbits) { save = ftell(ifp); fseek(ifp, 26 + row * raw_width / 4, SEEK_SET); for (prow = pixel, i = 0; i < raw_width * 2; i++) { c = fgetc(ifp); for (r = 0; r < 8; r += 2, prow++) { val = (*prow << 2) + ((c >> r) & 3); if (raw_width == 2672 && val < 512) val += 2; *prow = val; } } fseek(ifp, save, SEEK_SET); } } } catch (...) { FORC(2) free(huff[c]); throw; } FORC(2) free(huff[c]); } int LibRaw::ljpeg_start(struct jhead *jh, int info_only) { ushort c, tag, len; int cnt = 0; std::vector data_buffer(0x10000); uchar* data = &data_buffer[0]; const uchar *dp; memset(jh, 0, sizeof *jh); jh->restart = INT_MAX; if (fread(data, 2, 1, ifp) != 1 || data[1] != 0xd8) return 0; do { if (feof(ifp)) return 0; if (cnt++ > 1024) return 0; // 1024 tags limit if (fread(data, 2, 2, ifp) != 2) return 0; tag = data[0] << 8 | data[1]; len = (data[2] << 8 | data[3]) - 2; if (tag <= 0xff00) return 0; if (fread(data, 1, len, ifp) != len) return 0; switch (tag) { case 0xffc3: // start of frame; lossless, Huffman jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; case 0xffc1: case 0xffc0: jh->algo = tag & 0xff; jh->bits = data[0]; jh->high = data[1] << 8 | data[2]; jh->wide = data[3] << 8 | data[4]; jh->clrs = data[5] + jh->sraw; if (len == 9 && !dng_version) getc(ifp); break; case 0xffc4: // define Huffman tables if (info_only) break; for (dp = data; dp < data + len && !((c = *dp++) & -20);) jh->free[c] = jh->huff[c] = make_decoder_ref(&dp); break; case 0xffda: // start of scan jh->psv = data[1 + data[0] * 2]; jh->bits -= data[3 + data[0] * 2] & 15; break; case 0xffdb: FORC(64) jh->quant[c] = data[c * 2 + 1] << 8 | data[c * 2 + 2]; break; case 0xffdd: jh->restart = data[0] << 8 | data[1]; } } while (tag != 0xffda); if (jh->bits > 16 || jh->clrs > 6 || !jh->bits || !jh->high || !jh->wide || !jh->clrs) return 0; if (info_only) return 1; if (!jh->huff[0]) return 0; FORC(19) if (!jh->huff[c + 1]) jh->huff[c + 1] = jh->huff[c]; if (jh->sraw) { FORC(4) jh->huff[2 + c] = jh->huff[1]; FORC(jh->sraw) jh->huff[1 + c] = jh->huff[0]; } jh->row = (ushort *)calloc(jh->wide * jh->clrs, 16); return zero_after_ff = 1; } void LibRaw::ljpeg_end(struct jhead *jh) { int c; FORC4 if (jh->free[c]) free(jh->free[c]); free(jh->row); } int LibRaw::ljpeg_diff(ushort *huff) { int len, diff; if (!huff) throw LIBRAW_EXCEPTION_IO_CORRUPT; len = gethuff(huff); if (len == 16 && (!dng_version || dng_version >= 0x1010000)) return -32768; diff = getbits(len); if ((diff & (1 << (len - 1))) == 0) diff -= (1 << len) - 1; return diff; } ushort *LibRaw::ljpeg_row(int jrow, struct jhead *jh) { int col, c, diff, pred, spred = 0; ushort mark = 0, *row[3]; // Use the optimized, unrolled version if possible. if (!jh->sraw) return ljpeg_row_unrolled(jrow, jh); if (jh->restart != 0 && jrow * jh->wide % jh->restart == 0) { FORC(6) jh->vpred[c] = 1 << (jh->bits - 1); if (jrow) { fseek(ifp, -2, SEEK_CUR); do mark = (mark << 8) + (c = fgetc(ifp)); while (c != EOF && mark >> 4 != 0xffd); } getbits(-1); } FORC3 row[c] = jh->row + jh->wide * jh->clrs * ((jrow + c) & 1); for (col = 0; col < jh->wide; col++) FORC(jh->clrs) { diff = ljpeg_diff(jh->huff[c]); if (jh->sraw && c <= jh->sraw && (col | c)) pred = spred; else if (col) pred = row[0][-jh->clrs]; else pred = (jh->vpred[c] += diff) - diff; if (jrow && col) switch (jh->psv) { case 1: break; case 2: pred = row[1][0]; break; case 3: pred = row[1][-jh->clrs]; break; case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break; case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break; case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break; case 7: pred = (pred + row[1][0]) >> 1; break; default: pred = 0; } if ((**row = pred + diff) >> jh->bits) if(!(load_flags & 512)) derror(); if (c <= jh->sraw) spred = **row; row[0]++; row[1]++; } return row[2]; } ushort *LibRaw::ljpeg_row_unrolled(int jrow, struct jhead *jh) { int col, c, diff, pred; ushort mark = 0, *row[3]; if (jh->restart != 0 && jrow * jh->wide % jh->restart == 0) { FORC(6) jh->vpred[c] = 1 << (jh->bits - 1); if (jrow) { fseek(ifp, -2, SEEK_CUR); do mark = (mark << 8) + (c = fgetc(ifp)); while (c != EOF && mark >> 4 != 0xffd); } getbits(-1); } FORC3 row[c] = jh->row + jh->wide * jh->clrs * ((jrow + c) & 1); // The first column uses one particular predictor. FORC(jh->clrs) { diff = ljpeg_diff(jh->huff[c]); pred = (jh->vpred[c] += diff) - diff; if ((**row = pred + diff) >> jh->bits) derror(); row[0]++; row[1]++; } if (!jrow) { for (col = 1; col < jh->wide; col++) FORC(jh->clrs) { diff = ljpeg_diff(jh->huff[c]); pred = row[0][-jh->clrs]; if ((**row = pred + diff) >> jh->bits) derror(); row[0]++; row[1]++; } } else if (jh->psv == 1) { for (col = 1; col < jh->wide; col++) FORC(jh->clrs) { diff = ljpeg_diff(jh->huff[c]); pred = row[0][-jh->clrs]; if ((**row = pred + diff) >> jh->bits) derror(); row[0]++; } } else { for (col = 1; col < jh->wide; col++) FORC(jh->clrs) { diff = ljpeg_diff(jh->huff[c]); pred = row[0][-jh->clrs]; switch (jh->psv) { case 1: break; case 2: pred = row[1][0]; break; case 3: pred = row[1][-jh->clrs]; break; case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break; case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break; case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break; case 7: pred = (pred + row[1][0]) >> 1; break; default: pred = 0; } if ((**row = pred + diff) >> jh->bits) derror(); row[0]++; row[1]++; } } return row[2]; } void LibRaw::lossless_jpeg_load_raw() { int jwide, jhigh, jrow, jcol, val, jidx, i, j, row = 0, col = 0; struct jhead jh; ushort *rp; if (!ljpeg_start(&jh, 0)) return; if (jh.wide < 1 || jh.high < 1 || jh.clrs < 1 || jh.bits < 1) throw LIBRAW_EXCEPTION_IO_CORRUPT; if(cr2_slice[0] && !cr2_slice[1]) throw LIBRAW_EXCEPTION_IO_CORRUPT; jwide = jh.wide * jh.clrs; jhigh = jh.high; if (jh.clrs == 4 && jwide >= raw_width * 2) jhigh *= 2; try { for (jrow = 0; jrow < jh.high; jrow++) { checkCancel(); rp = ljpeg_row(jrow, &jh); if (load_flags & 1) row = jrow & 1 ? height - 1 - jrow / 2 : jrow / 2; for (jcol = 0; jcol < jwide; jcol++) { val = curve[*rp++]; if (cr2_slice[0]) { jidx = jrow * jwide + jcol; i = jidx / (cr2_slice[1] * raw_height); if ((j = i >= cr2_slice[0])) i = cr2_slice[0]; if(!cr2_slice[1+j]) throw LIBRAW_EXCEPTION_IO_CORRUPT; jidx -= i * (cr2_slice[1] * raw_height); row = jidx / cr2_slice[1 + j]; col = jidx % cr2_slice[1 + j] + i * cr2_slice[1]; } if (raw_width == 3984 && (col -= 2) < 0) col += (row--, raw_width); if (row > raw_height) throw LIBRAW_EXCEPTION_IO_CORRUPT; if ((unsigned)row < raw_height) RAW(row, col) = val; if (++col >= raw_width) col = (row++, 0); } } } catch (...) { ljpeg_end(&jh); throw; } ljpeg_end(&jh); } void LibRaw::canon_sraw_load_raw() { struct jhead jh; short *rp = 0, (*ip)[4]; int jwide, slice, scol, ecol, row, col, jrow = 0, jcol = 0, pix[3], c; int v[3] = {0, 0, 0}, ver, hue; int saved_w = width, saved_h = height; char *cp; if(!image) throw LIBRAW_EXCEPTION_IO_CORRUPT; if (!ljpeg_start(&jh, 0) || jh.clrs < 4) return; jwide = (jh.wide >>= 1) * jh.clrs; if (jwide < 32 || jwide > 65535) throw LIBRAW_EXCEPTION_IO_CORRUPT; if (load_flags & 256) { width = raw_width; height = raw_height; } try { for (ecol = slice = 0; slice <= cr2_slice[0]; slice++) { scol = ecol; ecol += cr2_slice[1] * 2 / jh.clrs; if (!cr2_slice[0] || ecol > raw_width - 1) ecol = raw_width & -2; for (row = 0; row < height; row += (jh.clrs >> 1) - 1) { checkCancel(); ip = (short(*)[4])image + row * width; for (col = scol; col < ecol; col += 2, jcol += jh.clrs) { if ((jcol %= jwide) == 0) rp = (short *)ljpeg_row(jrow++, &jh); if (col >= width) continue; if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE) { FORC(jh.clrs - 2) { ip[col + (c >> 1) * width + (c & 1)][0] = rp[jcol + c]; ip[col + (c >> 1) * width + (c & 1)][1] = ip[col + (c >> 1) * width + (c & 1)][2] = 8192; } ip[col][1] = rp[jcol + jh.clrs - 2] - 8192; ip[col][2] = rp[jcol + jh.clrs - 1] - 8192; } else if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_RGB) { FORC(jh.clrs - 2) ip[col + (c >> 1) * width + (c & 1)][0] = rp[jcol + c]; ip[col][1] = rp[jcol + jh.clrs - 2] - 8192; ip[col][2] = rp[jcol + jh.clrs - 1] - 8192; } else { FORC(jh.clrs - 2) ip[col + (c >> 1) * width + (c & 1)][0] = rp[jcol + c]; ip[col][1] = rp[jcol + jh.clrs - 2] - 16384; ip[col][2] = rp[jcol + jh.clrs - 1] - 16384; } } } } } catch (...) { ljpeg_end(&jh); throw; } if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE) { ljpeg_end(&jh); maximum = 0x3fff; height = saved_h; width = saved_w; return; } try { for (cp = model2; *cp && !isdigit(*cp); cp++) ; sscanf(cp, "%d.%d.%d", v, v + 1, v + 2); ver = (v[0] * 1000 + v[1]) * 1000 + v[2]; hue = (jh.sraw + 1) << 2; if (unique_id >= 0x80000281ULL || (unique_id == 0x80000218ULL && ver > 1000006)) hue = jh.sraw << 1; ip = (short(*)[4])image; rp = ip[0]; for (row = 0; row < height; row++, ip += width) { checkCancel(); if (row & (jh.sraw >> 1)) { for (col = 0; col < width; col += 2) for (c = 1; c < 3; c++) if (row == height - 1) { ip[col][c] = ip[col - width][c]; } else { ip[col][c] = (ip[col - width][c] + ip[col + width][c] + 1) >> 1; } } for (col = 1; col < width; col += 2) for (c = 1; c < 3; c++) if (col == width - 1) ip[col][c] = ip[col - 1][c]; else ip[col][c] = (ip[col - 1][c] + ip[col + 1][c] + 1) >> 1; } if (!(imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_RGB)) for (; rp < ip[0]; rp += 4) { checkCancel(); if ((unique_id == CanonID_EOS_5D_Mark_II) || (unique_id == CanonID_EOS_7D) || (unique_id == CanonID_EOS_50D) || (unique_id == CanonID_EOS_1D_Mark_IV) || (unique_id == CanonID_EOS_60D)) { rp[1] = (rp[1] << 2) + hue; rp[2] = (rp[2] << 2) + hue; pix[0] = rp[0] + ((50 * rp[1] + 22929 * rp[2]) >> 14); pix[1] = rp[0] + ((-5640 * rp[1] - 11751 * rp[2]) >> 14); pix[2] = rp[0] + ((29040 * rp[1] - 101 * rp[2]) >> 14); } else { if (unique_id < CanonID_EOS_5D_Mark_II) rp[0] -= 512; pix[0] = rp[0] + rp[2]; pix[2] = rp[0] + rp[1]; pix[1] = rp[0] + ((-778 * rp[1] - (rp[2] << 11)) >> 12); } FORC3 rp[c] = CLIP15(pix[c] * sraw_mul[c] >> 10); } } catch (...) { ljpeg_end(&jh); throw; } height = saved_h; width = saved_w; ljpeg_end(&jh); maximum = 0x3fff; } void LibRaw::ljpeg_idct(struct jhead *jh) { int c, i, j, len, skip, coef; float work[3][8][8]; static float cs[106] = {0}; static const uchar zigzag[80] = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63}; if (!cs[0]) FORC(106) cs[c] = cos((c & 31) * M_PI / 16) / 2; memset(work, 0, sizeof work); work[0][0][0] = jh->vpred[0] += ljpeg_diff(jh->huff[0]) * jh->quant[0]; for (i = 1; i < 64; i++) { len = gethuff(jh->huff[16]); i += skip = len >> 4; if (!(len &= 15) && skip < 15) break; coef = getbits(len); if ((coef & (1 << (len - 1))) == 0) coef -= (1 << len) - 1; ((float *)work)[zigzag[i]] = coef * jh->quant[i]; } FORC(8) work[0][0][c] *= float(M_SQRT1_2); FORC(8) work[0][c][0] *= float(M_SQRT1_2); for (i = 0; i < 8; i++) for (j = 0; j < 8; j++) FORC(8) work[1][i][j] += work[0][i][c] * cs[(j * 2 + 1) * c]; for (i = 0; i < 8; i++) for (j = 0; j < 8; j++) FORC(8) work[2][i][j] += work[1][c][j] * cs[(i * 2 + 1) * c]; FORC(64) jh->idct[c] = CLIP(((float *)work[2])[c] + 0.5); } void LibRaw::pentax_load_raw() { ushort bit[2][15], huff[4097]; int dep, row, col, diff, c, i; ushort vpred[2][2] = {{0, 0}, {0, 0}}, hpred[2]; fseek(ifp, meta_offset, SEEK_SET); dep = (get2() + 12) & 15; fseek(ifp, 12, SEEK_CUR); FORC(dep) bit[0][c] = get2(); FORC(dep) bit[1][c] = fgetc(ifp); FORC(dep) for (i = bit[0][c]; i <= ((bit[0][c] + (4096 >> bit[1][c]) - 1) & 4095);) huff[++i] = bit[1][c] << 8 | c; huff[0] = 12; fseek(ifp, data_offset, SEEK_SET); getbits(-1); for (row = 0; row < raw_height; row++) { checkCancel(); for (col = 0; col < raw_width; col++) { diff = ljpeg_diff(huff); if (col < 2) hpred[col] = vpred[row & 1][col] += diff; else hpred[col & 1] += diff; RAW(row, col) = hpred[col & 1]; if (hpred[col & 1] >> tiff_bps) derror(); } } } void LibRaw::nikon_read_curve() { ushort ver0, ver1, vpred[2][2], csize; int i, step, max; fseek(ifp, meta_offset, SEEK_SET); ver0 = fgetc(ifp); ver1 = fgetc(ifp); if (ver0 == 0x49 || ver1 == 0x58) fseek(ifp, 2110, SEEK_CUR); read_shorts(vpred[0], 4); step = max = 1 << tiff_bps & 0x7fff; if ((csize = get2()) > 1) step = max / (csize - 1); if (ver0 == 0x44 && (ver1 == 0x20 || (ver1 == 0x40 && step > 3)) && step > 0) { if (ver1 == 0x40) { step /= 4; max /= 4; } for (i = 0; i < csize; i++) curve[i * step] = get2(); for (i = 0; i < max; i++) curve[i] = (curve[i - i % step] * (step - i % step) + curve[i - i % step + step] * (i % step)) / step; } else if (ver0 != 0x46 && csize <= 0x4001) read_shorts(curve, max = csize); } void LibRaw::nikon_load_raw() { static const uchar nikon_tree[][32] = { {0, 1, 5, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, /* 12-bit lossy */ 5, 4, 3, 6, 2, 7, 1, 0, 8, 9, 11, 10, 12}, {0, 1, 5, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, /* 12-bit lossy after split */ 0x39, 0x5a, 0x38, 0x27, 0x16, 5, 4, 3, 2, 1, 0, 11, 12, 12}, {0, 1, 4, 2, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 12-bit lossless */ 5, 4, 6, 3, 7, 2, 8, 1, 9, 0, 10, 11, 12}, {0, 1, 4, 3, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, /* 14-bit lossy */ 5, 6, 4, 7, 8, 3, 9, 2, 1, 0, 10, 11, 12, 13, 14}, {0, 1, 5, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, /* 14-bit lossy after split */ 8, 0x5c, 0x4b, 0x3a, 0x29, 7, 6, 5, 4, 3, 2, 1, 0, 13, 14}, {0, 1, 4, 2, 2, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, /* 14-bit lossless */ 7, 6, 8, 5, 9, 4, 10, 3, 11, 12, 2, 0, 1, 13, 14}}; ushort *huff, ver0, ver1, vpred[2][2], hpred[2]; int i, min, max, tree = 0, split = 0, row, col, len, shl, diff; fseek(ifp, meta_offset, SEEK_SET); ver0 = fgetc(ifp); ver1 = fgetc(ifp); if (ver0 == 0x49 || ver1 == 0x58) fseek(ifp, 2110, SEEK_CUR); if (ver0 == 0x46) tree = 2; if (tiff_bps == 14) tree += 3; read_shorts(vpred[0], 4); max = 1 << tiff_bps & 0x7fff; if (ver0 == 0x44 && (ver1 == 0x20 || ver1 == 0x40)) { if (ver1 == 0x40) max /= 4; fseek(ifp, meta_offset + 562, SEEK_SET); split = get2(); } while (max > 2 && (curve[max - 2] == curve[max - 1])) max--; huff = make_decoder(nikon_tree[tree]); fseek(ifp, data_offset, SEEK_SET); getbits(-1); try { for (min = row = 0; row < height; row++) { checkCancel(); if (split && row == split) { free(huff); huff = make_decoder(nikon_tree[tree + 1]); max += (min = 16) << 1; } for (col = 0; col < raw_width; col++) { i = gethuff(huff); len = i & 15; shl = i >> 4; diff = ((getbits(len - shl) << 1) + 1) << shl >> 1; if (len > 0 && (diff & (1 << (len - 1))) == 0) diff -= (1 << len) - !shl; if (col < 2) hpred[col] = vpred[row & 1][col] += diff; else hpred[col & 1] += diff; if ((ushort)(hpred[col & 1] + min) >= max) derror(); RAW(row, col) = curve[LIM((short)hpred[col & 1], 0, 0x3fff)]; } } } catch (...) { free(huff); throw; } free(huff); } void LibRaw::nikon_yuv_load_raw() { if (!image) throw LIBRAW_EXCEPTION_IO_CORRUPT; int row, col, yuv[4]={0,0,0,0}, rgb[3], b, c; UINT64 bitbuf = 0; float cmul[4]; FORC4 { cmul[c] = cam_mul[c] > 0.001f ? cam_mul[c] : 1.f; } for (row = 0; row < raw_height; row++) { checkCancel(); for (col = 0; col < raw_width; col++) { if (!(b = col & 1)) { bitbuf = 0; FORC(6) bitbuf |= (UINT64)fgetc(ifp) << c * 8; FORC(4) yuv[c] = (bitbuf >> c * 12 & 0xfff) - (c >> 1 << 11); } rgb[0] = yuv[b] + 1.370705 * yuv[3]; rgb[1] = yuv[b] - 0.337633 * yuv[2] - 0.698001 * yuv[3]; rgb[2] = yuv[b] + 1.732446 * yuv[2]; FORC3 image[row * width + col][c] = curve[LIM(rgb[c], 0, 0xfff)] / cmul[c]; } } } void LibRaw::rollei_load_raw() { uchar pixel[10]; unsigned iten = 0, isix, i, buffer = 0, todo[16]; if (raw_width > 32767 || raw_height > 32767) throw LIBRAW_EXCEPTION_IO_BADFILE; unsigned maxpixel = raw_width * (raw_height + 7); isix = raw_width * raw_height * 5 / 8; while (fread(pixel, 1, 10, ifp) == 10) { checkCancel(); for (i = 0; i < 10; i += 2) { todo[i] = iten++; todo[i + 1] = pixel[i] << 8 | pixel[i + 1]; buffer = pixel[i] >> 2 | buffer << 6; } for (; i < 16; i += 2) { todo[i] = isix++; todo[i + 1] = buffer >> (14 - i) * 5; } for (i = 0; i < 16; i += 2) if (todo[i] < maxpixel) raw_image[todo[i]] = (todo[i + 1] & 0x3ff); else derror(); } maximum = 0x3ff; } void LibRaw::nokia_load_raw() { uchar *dp; int rev, dwide, row, col, c; double sum[] = {0, 0}; rev = 3 * (order == 0x4949); dwide = (raw_width * 5 + 1) / 4; #ifdef USE_6BY9RPI if (raw_stride) dwide = raw_stride; #endif std::vector data(dwide * 2 + 4,0); for (row = 0; row < raw_height; row++) { checkCancel(); if (fread(data.data() + dwide, 1, dwide, ifp) < dwide) derror(); FORC(dwide) data[c] = data[dwide + (c ^ rev)]; for (dp = data.data(), col = 0; col < raw_width; dp += 5, col += 4) FORC4 RAW(row, col + c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3); } maximum = 0x3ff; #ifdef USE_6BY9RPI if (!strcmp(make, "OmniVision") || !strcmp(make, "Sony") || !strcmp(make, "RaspberryPi")) return; #else if (strncmp(make, "OmniVision", 10)) return; #endif row = raw_height / 2; FORC(width - 1) { sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); } if (sum[1] > sum[0]) filters = 0x4b4b4b4b; } #ifdef LIBRAW_OLD_VIDEO_SUPPORT void LibRaw::canon_rmf_load_raw() { int row, col, bits, orow, ocol, c; int *words = (int *)malloc(sizeof(int) * (raw_width / 3 + 1)); for (row = 0; row < raw_height; row++) { checkCancel(); fread(words, sizeof(int), raw_width / 3, ifp); for (col = 0; col < raw_width - 2; col += 3) { bits = words[col / 3]; FORC3 { orow = row; if ((ocol = col + c - 4) < 0) { ocol += raw_width; if ((orow -= 2) < 0) orow += raw_height; } RAW(orow, ocol) = curve[bits >> (10 * c + 2) & 0x3ff]; } } } free(words); maximum = curve[0x3ff]; } #endif unsigned LibRaw::pana_data(int nb, unsigned *bytes) { #ifndef LIBRAW_NOTHREADS #define vpos tls->pana_data.vpos #define buf tls->pana_data.buf #else static uchar buf[0x4002]; static int vpos; #endif int byte; if (!nb && !bytes) { memset(buf, 0, sizeof(buf)); return vpos = 0; } if (load_flags > 0x4000) throw LIBRAW_EXCEPTION_IO_BADFILE; if (!vpos) { if(load_flags < 0x4000) fread(buf + load_flags, 1, 0x4000 - load_flags, ifp); fread(buf, 1, load_flags, ifp); } if (pana_encoding == 5) { for (byte = 0; byte < 16; byte++) { bytes[byte] = buf[vpos++]; vpos &= 0x3FFF; } } else { vpos = (vpos - nb) & 0x1ffff; byte = vpos >> 3 ^ 0x3ff0; return (buf[byte] | buf[byte + 1] << 8) >> (vpos & 7) & ~((~0u) << nb); } return 0; #ifndef LIBRAW_NOTHREADS #undef vpos #undef buf #endif } void LibRaw::panasonic_load_raw() { int row, col, i, j, sh = 0, pred[2], nonz[2]; unsigned bytes[16]; memset(bytes,0,sizeof(bytes)); // make gcc11 happy ushort *raw_block_data; pana_data(0, 0); int enc_blck_size = pana_bpp == 12 ? 10 : 9; if (pana_encoding == 5) { for (row = 0; row < raw_height; row++) { raw_block_data = raw_image + row * raw_width; checkCancel(); for (col = 0; col < raw_width; col += enc_blck_size) { pana_data(0, bytes); if (pana_bpp == 12) { raw_block_data[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; raw_block_data[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); raw_block_data[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; raw_block_data[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); raw_block_data[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; raw_block_data[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); raw_block_data[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; raw_block_data[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); raw_block_data[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; raw_block_data[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); } else if (pana_bpp == 14) { raw_block_data[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); raw_block_data[col + 1] = (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10); raw_block_data[col + 2] = (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12); raw_block_data[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); raw_block_data[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); raw_block_data[col + 5] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); raw_block_data[col + 6] = (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); raw_block_data[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); raw_block_data[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); } } } } else { if (load_flags >= 0x4000) throw LIBRAW_EXCEPTION_IO_CORRUPT; for (row = 0; row < raw_height; row++) { checkCancel(); for (col = 0; col < raw_width; col++) { if ((i = col % 14) == 0) pred[0] = pred[1] = nonz[0] = nonz[1] = 0; if (i % 3 == 2) sh = 4 >> (3 - pana_data(2, 0)); if (nonz[i & 1]) { if ((j = pana_data(8, 0))) { if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) pred[i & 1] &= ~((~0u) << sh); pred[i & 1] += j << sh; } } else if ((nonz[i & 1] = pana_data(8, 0)) || i > 11) pred[i & 1] = nonz[i & 1] << 4 | pana_data(4, 0); if ((RAW(row, col) = pred[col & 1]) > 4098 && col < width && row < height) derror(); } } } } void LibRaw::olympus_load_raw() { ushort huff[4096]; int row, col, nbits, sign, low, high, i, c, w, n, nw; int acarry[2][3], *carry, pred, diff; huff[n = 0] = 0xc0c; for (i = 12; i--;) FORC(2048 >> i) huff[++n] = (i + 1) << 8 | i; fseek(ifp, 7, SEEK_CUR); getbits(-1); for (row = 0; row < height; row++) { checkCancel(); memset(acarry, 0, sizeof acarry); for (col = 0; col < raw_width; col++) { carry = acarry[col & 1]; i = 2 * (carry[2] < 3); for (nbits = 2 + i; (ushort)carry[0] >> (nbits + i); nbits++) ; low = (sign = getbits(3)) & 3; sign = sign << 29 >> 31; if ((high = getbithuff(12, huff)) == 12) high = getbits(16 - nbits) >> 1; carry[0] = (high << nbits) | getbits(nbits); diff = (carry[0] ^ sign) + carry[1]; carry[1] = (diff * 3 + carry[1]) >> 5; carry[2] = carry[0] > 16 ? 0 : carry[2] + 1; if (col >= width) continue; if (row < 2 && col < 2) pred = 0; else if (row < 2) pred = RAW(row, col - 2); else if (col < 2) pred = RAW(row - 2, col); else { w = RAW(row, col - 2); n = RAW(row - 2, col); nw = RAW(row - 2, col - 2); if ((w < nw && nw < n) || (n < nw && nw < w)) { if (ABS(w - nw) > 32 || ABS(n - nw) > 32) pred = w + n - nw; else pred = (w + n) >> 1; } else pred = ABS(w - nw) > ABS(n - nw) ? w : n; } if ((RAW(row, col) = pred + ((diff << 2) | low)) >> 12) derror(); } } } void LibRaw::minolta_rd175_load_raw() { uchar pixel[768]; unsigned irow, box, row, col; for (irow = 0; irow < 1481; irow++) { checkCancel(); if (fread(pixel, 1, 768, ifp) < 768) derror(); box = irow / 82; row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box - 12) * 2); switch (irow) { case 1477: case 1479: continue; case 1476: row = 984; break; case 1480: row = 985; break; case 1478: row = 985; box = 1; } if ((box < 12) && (box & 1)) { for (col = 0; col < 1533; col++, row ^= 1) if (col != 1) RAW(row, col) = (col + 1) & 2 ? pixel[col / 2 - 1] + pixel[col / 2 + 1] : pixel[col / 2] << 1; RAW(row, 1) = pixel[1] << 1; RAW(row, 1533) = pixel[765] << 1; } else for (col = row & 1; col < 1534; col += 2) RAW(row, col) = pixel[col / 2] << 1; } maximum = 0xff << 1; } void LibRaw::quicktake_100_load_raw() { std::vector pixel_buffer(484 * 644, 0x80); uchar* pixel = &pixel_buffer[0]; static const short gstep[16] = {-89, -60, -44, -32, -22, -15, -8, -2, 2, 8, 15, 22, 32, 44, 60, 89}; static const short rstep[6][4] = {{-3, -1, 1, 3}, {-5, -1, 1, 5}, {-8, -2, 2, 8}, {-13, -3, 3, 13}, {-19, -4, 4, 19}, {-28, -6, 6, 28}}; static const short t_curve[256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 86, 88, 90, 92, 94, 97, 99, 101, 103, 105, 107, 110, 112, 114, 116, 118, 120, 123, 125, 127, 129, 131, 134, 136, 138, 140, 142, 144, 147, 149, 151, 153, 155, 158, 160, 162, 164, 166, 168, 171, 173, 175, 177, 179, 181, 184, 186, 188, 190, 192, 195, 197, 199, 201, 203, 205, 208, 210, 212, 214, 216, 218, 221, 223, 226, 230, 235, 239, 244, 248, 252, 257, 261, 265, 270, 274, 278, 283, 287, 291, 296, 300, 305, 309, 313, 318, 322, 326, 331, 335, 339, 344, 348, 352, 357, 361, 365, 370, 374, 379, 383, 387, 392, 396, 400, 405, 409, 413, 418, 422, 426, 431, 435, 440, 444, 448, 453, 457, 461, 466, 470, 474, 479, 483, 487, 492, 496, 500, 508, 519, 531, 542, 553, 564, 575, 587, 598, 609, 620, 631, 643, 654, 665, 676, 687, 698, 710, 721, 732, 743, 754, 766, 777, 788, 799, 810, 822, 833, 844, 855, 866, 878, 889, 900, 911, 922, 933, 945, 956, 967, 978, 989, 1001, 1012, 1023}; int rb, row, col, sharp, val = 0; if (width > 640 || height > 480) throw LIBRAW_EXCEPTION_IO_CORRUPT; getbits(-1); for (row = 2; row < height + 2; row++) { checkCancel(); for (col = 2 + (row & 1); col < width + 2; col += 2) { val = ((pixel[(row - 1) * 644 + col - 1] + 2 * pixel[(row - 1) * 644 + col + 1] + pixel[row * 644 + col - 2]) >> 2) + gstep[getbits(4)]; pixel[row * 644 + col] = val = LIM(val, 0, 255); if (col < 4) pixel[row * 644 + col - 2] = pixel[(row + 1) * 644 + (~row & 1)] = val; if (row == 2) pixel[(row - 1) * 644 + col + 1] = pixel[(row - 1) * 644 + col + 3] = val; } pixel[row * 644 + col] = val; } for (rb = 0; rb < 2; rb++) for (row = 2 + rb; row < height + 2; row += 2) { checkCancel(); for (col = 3 - (row & 1); col < width + 2; col += 2) { if (row < 4 || col < 4) sharp = 2; else { val = ABS(pixel[(row - 2) * 644 + col] - pixel[row * 644 + col - 2]) + ABS(pixel[(row - 2) * 644 + col] - pixel[(row - 2) * 644 + col - 2]) + ABS(pixel[row * 644 + col - 2] - pixel[(row - 2) * 644 + col - 2]); sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 : val < 32 ? 3 : val < 48 ? 4 : 5; } val = ((pixel[(row - 2) * 644 + col] + pixel[row * 644 + col - 2]) >> 1) + rstep[sharp][getbits(2)]; pixel[row * 644 + col] = val = LIM(val, 0, 255); if (row < 4) pixel[(row - 2) * 644 + col + 2] = val; if (col < 4) pixel[(row + 2) * 644 + col - 2] = val; } } for (row = 2; row < height + 2; row++) { checkCancel(); for (col = 3 - (row & 1); col < width + 2; col += 2) { val = ((pixel[row * 644 + col - 1] + (pixel[row * 644 + col] << 2) + pixel[row * 644 + col + 1]) >> 1) - 0x100; pixel[row * 644 + col] = LIM(val, 0, 255); } } for (row = 0; row < height; row++) { checkCancel(); for (col = 0; col < width; col++) RAW(row, col) = t_curve[pixel[(row + 2) * 644 + col + 2]]; } maximum = 0x3ff; } void LibRaw::sony_load_raw() { uchar head[40]; ushort *pixel; unsigned i, key, row, col; fseek(ifp, 200896, SEEK_SET); fseek(ifp, (unsigned)fgetc(ifp) * 4 - 1, SEEK_CUR); order = 0x4d4d; key = get4(); fseek(ifp, 164600, SEEK_SET); fread(head, 1, 40, ifp); sony_decrypt((unsigned *)head, 10, 1, key); for (i = 26; i-- > 22;) key = key << 8 | head[i]; fseek(ifp, data_offset, SEEK_SET); for (row = 0; row < raw_height; row++) { checkCancel(); pixel = raw_image + row * raw_width; if (fread(pixel, 2, raw_width, ifp) < raw_width) derror(); sony_decrypt((unsigned *)pixel, raw_width / 2, !row, key); for (col = 0; col < raw_width; col++) if ((pixel[col] = ntohs(pixel[col])) >> 14) derror(); } maximum = 0x3ff0; } void LibRaw::sony_arw_load_raw() { std::vector huff_buffer(32770,0); ushort* huff = &huff_buffer[0]; static const ushort tab[18] = {0xf11, 0xf10, 0xe0f, 0xd0e, 0xc0d, 0xb0c, 0xa0b, 0x90a, 0x809, 0x708, 0x607, 0x506, 0x405, 0x304, 0x303, 0x300, 0x202, 0x201}; int i, c, n, col, row, sum = 0; huff[0] = 15; for (n = i = 0; i < 18; i++) FORC(32768 >> (tab[i] >> 8)) huff[++n] = tab[i]; getbits(-1); for (col = raw_width; col--;) { checkCancel(); for (row = 0; row < raw_height + 1; row += 2) { if (row == raw_height) row = 1; if ((sum += ljpeg_diff(huff)) >> 12) derror(); if (row < height) RAW(row, col) = sum; } } } void LibRaw::sony_arw2_load_raw() { uchar *data, *dp; ushort pix[16]; int row, col, val, max, min, imax, imin, sh, bit, i; data = (uchar *)calloc(raw_width + 1,1); try { for (row = 0; row < height; row++) { checkCancel(); fread(data, 1, raw_width, ifp); for (dp = data, col = 0; col < raw_width - 30; dp += 16) { max = 0x7ff & (val = sget4(dp)); min = 0x7ff & val >> 11; imax = 0x0f & val >> 22; imin = 0x0f & val >> 26; for (sh = 0; sh < 4 && 0x80 << sh <= max - min; sh++) ; /* flag checks if outside of loop */ if (!(imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_ALLFLAGS) // no flag set || (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_DELTATOVALUE)) { for (bit = 30, i = 0; i < 16; i++) if (i == imax) pix[i] = max; else if (i == imin) pix[i] = min; else { pix[i] = ((sget2(dp + (bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min; if (pix[i] > 0x7ff) pix[i] = 0x7ff; bit += 7; } } else if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_BASEONLY) { for (bit = 30, i = 0; i < 16; i++) if (i == imax) pix[i] = max; else if (i == imin) pix[i] = min; else pix[i] = 0; } else if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_DELTAONLY) { for (bit = 30, i = 0; i < 16; i++) if (i == imax) pix[i] = 0; else if (i == imin) pix[i] = 0; else { pix[i] = ((sget2(dp + (bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min; if (pix[i] > 0x7ff) pix[i] = 0x7ff; bit += 7; } } else if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_DELTAZEROBASE) { for (bit = 30, i = 0; i < 16; i++) if (i == imax) pix[i] = 0; else if (i == imin) pix[i] = 0; else { pix[i] = ((sget2(dp + (bit >> 3)) >> (bit & 7) & 0x7f) << sh); if (pix[i] > 0x7ff) pix[i] = 0x7ff; bit += 7; } } if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_DELTATOVALUE) { for (i = 0; i < 16; i++, col += 2) { unsigned slope = pix[i] < 1001 ? 2 : curve[pix[i] << 1] - curve[(pix[i] << 1) - 2]; unsigned step = 1 << sh; RAW(row, col) = curve[pix[i] << 1] > black + imgdata.rawparams.sony_arw2_posterization_thr ? LIM(((slope * step * 1000) / (curve[pix[i] << 1] - black)), 0, 10000) : 0; } } else for (i = 0; i < 16; i++, col += 2) RAW(row, col) = curve[pix[i] << 1]; col -= col & 1 ? 1 : 31; } } } catch (...) { free(data); throw; } if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_DELTATOVALUE) maximum = 10000; free(data); } void LibRaw::samsung_load_raw() { int row, col, c, i, dir, op[4], len[4]; if (raw_width > 32768 || raw_height > 32768) // definitely too much for old samsung throw LIBRAW_EXCEPTION_IO_BADFILE; unsigned maxpixels = raw_width * (raw_height + 7); order = 0x4949; for (row = 0; row < raw_height; row++) { checkCancel(); fseek(ifp, strip_offset + row * 4, SEEK_SET); fseek(ifp, data_offset + get4(), SEEK_SET); ph1_bits(-1); FORC4 len[c] = row < 2 ? 7 : 4; for (col = 0; col < raw_width; col += 16) { dir = ph1_bits(1); FORC4 op[c] = ph1_bits(2); FORC4 switch (op[c]) { case 3: len[c] = ph1_bits(4); break; case 2: len[c]--; break; case 1: len[c]++; } for (c = 0; c < 16; c += 2) { i = len[((c & 1) << 1) | (c >> 3)]; unsigned idest = RAWINDEX(row, col + c); unsigned isrc = (dir ? RAWINDEX(row + (~c | -2), col + c) : col ? RAWINDEX(row, col + (c | -2)) : 0); if (idest < maxpixels && isrc < maxpixels) // less than zero is handled by unsigned conversion RAW(row, col + c) = (i > 0 ? ((signed)ph1_bits(i) << (32 - i) >> (32 - i)) : 0) + (dir ? RAW(row + (~c | -2), col + c) : col ? RAW(row, col + (c | -2)) : 128); else derror(); if (c == 14) c = -1; } } } for (row = 0; row < raw_height - 1; row += 2) for (col = 0; col < raw_width - 1; col += 2) SWAP(RAW(row, col + 1), RAW(row + 1, col)); } void LibRaw::samsung2_load_raw() { static const ushort tab[14] = {0x304, 0x307, 0x206, 0x205, 0x403, 0x600, 0x709, 0x80a, 0x90b, 0xa0c, 0xa0d, 0x501, 0x408, 0x402}; ushort huff[1026], vpred[2][2] = {{0, 0}, {0, 0}}, hpred[2]; int i, c, n, row, col, diff; huff[0] = 10; for (n = i = 0; i < 14; i++) FORC(1024 >> (tab[i] >> 8)) huff[++n] = tab[i]; getbits(-1); for (row = 0; row < raw_height; row++) { checkCancel(); for (col = 0; col < raw_width; col++) { diff = ljpeg_diff(huff); if (col < 2) hpred[col] = vpred[row & 1][col] += diff; else hpred[col & 1] += diff; RAW(row, col) = hpred[col & 1]; if (hpred[col & 1] >> tiff_bps) derror(); } } } void LibRaw::samsung3_load_raw() { int opt, init, mag, pmode, row, tab, col, pred, diff, i, c; ushort lent[3][2], len[4], *prow[2]; order = 0x4949; fseek(ifp, 9, SEEK_CUR); opt = fgetc(ifp); init = (get2(), get2()); for (row = 0; row < raw_height; row++) { checkCancel(); fseek(ifp, (data_offset - ftell(ifp)) & 15, SEEK_CUR); ph1_bits(-1); mag = 0; pmode = 7; FORC(6)((ushort *)lent)[c] = row < 2 ? 7 : 4; prow[row & 1] = &RAW(row - 1, 1 - ((row & 1) << 1)); // green prow[~row & 1] = &RAW(row - 2, 0); // red and blue for (tab = 0; tab + 15 < raw_width; tab += 16) { if (~opt & 4 && !(tab & 63)) { i = ph1_bits(2); mag = i < 3 ? mag - '2' + "204"[i] : ph1_bits(12); } if (opt & 2) pmode = 7 - 4 * ph1_bits(1); else if (!ph1_bits(1)) pmode = ph1_bits(3); if (opt & 1 || !ph1_bits(1)) { FORC4 len[c] = ph1_bits(2); FORC4 { i = ((row & 1) << 1 | (c & 1)) % 3; if (i < 0) throw LIBRAW_EXCEPTION_IO_CORRUPT; len[c] = len[c] < 3 ? lent[i][0] - '1' + "120"[len[c]] : ph1_bits(4); lent[i][0] = lent[i][1]; lent[i][1] = len[c]; } } FORC(16) { col = tab + (((c & 7) << 1) ^ (c >> 3) ^ (row & 1)); if (col < 0) throw LIBRAW_EXCEPTION_IO_CORRUPT; if (pmode < 0) throw LIBRAW_EXCEPTION_IO_CORRUPT; if (pmode != 7 && row >= 2 && (col - '4' + "0224468"[pmode]) < 0) throw LIBRAW_EXCEPTION_IO_CORRUPT; pred = (pmode == 7 || row < 2) ? (tab ? RAW(row, tab - 2 + (col & 1)) : init) : (prow[col & 1][col - '4' + "0224468"[pmode]] + prow[col & 1][col - '4' + "0244668"[pmode]] + 1) >> 1; diff = ph1_bits(i = len[c >> 2]); if (i > 0 && diff >> (i - 1)) diff -= 1 << i; diff = diff * (mag * 2 + 1) + mag; RAW(row, col) = pred + diff; } } } } #ifdef LIBRAW_OLD_VIDEO_SUPPORT void LibRaw::redcine_load_raw() { #ifndef NO_JASPER int c, row, col; jas_stream_t *in; jas_image_t *jimg; jas_matrix_t *jmat; jas_seqent_t *data; ushort *img, *pix; jas_init(); in = (jas_stream_t *)ifp->make_jas_stream(); if (!in) throw LIBRAW_EXCEPTION_DECODE_JPEG2000; jas_stream_seek(in, data_offset + 20, SEEK_SET); jimg = jas_image_decode(in, -1, 0); if (!jimg) { jas_stream_close(in); throw LIBRAW_EXCEPTION_DECODE_JPEG2000; } jmat = jas_matrix_create(height / 2, width / 2); img = (ushort *)calloc((height + 2), (width + 2) * 2); bool fastexitflag = false; try { FORC4 { checkCancel(); jas_image_readcmpt(jimg, c, 0, 0, width / 2, height / 2, jmat); data = jas_matrix_getref(jmat, 0, 0); for (row = c >> 1; row < height; row += 2) for (col = c & 1; col < width; col += 2) img[(row + 1) * (width + 2) + col + 1] = data[(row / 2) * (width / 2) + col / 2]; } for (col = 1; col <= width; col++) { img[col] = img[2 * (width + 2) + col]; img[(height + 1) * (width + 2) + col] = img[(height - 1) * (width + 2) + col]; } for (row = 0; row < height + 2; row++) { img[row * (width + 2)] = img[row * (width + 2) + 2]; img[(row + 1) * (width + 2) - 1] = img[(row + 1) * (width + 2) - 3]; } for (row = 1; row <= height; row++) { checkCancel(); pix = img + row * (width + 2) + (col = 1 + (FC(row, 1) & 1)); for (; col <= width; col += 2, pix += 2) { c = (((pix[0] - 0x800) << 3) + pix[-(width + 2)] + pix[width + 2] + pix[-1] + pix[1]) >> 2; pix[0] = LIM(c, 0, 4095); } } for (row = 0; row < height; row++) { checkCancel(); for (col = 0; col < width; col++) RAW(row, col) = curve[img[(row + 1) * (width + 2) + col + 1]]; } } catch (...) { fastexitflag = true; } free(img); jas_matrix_destroy(jmat); jas_image_destroy(jimg); jas_stream_close(in); if (fastexitflag) throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; #endif } #endif LibRaw-0.21.4/src/decoders/decoders_libraw.cpp000066400000000000000000000753651477673233700212340ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2022 LibRaw LLC (info@libraw.org) * * PhaseOne IIQ-Sv2 decoder is inspired by code provided by Daniel Vogelbacher * 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 "../../internal/libraw_cxx_defs.h" #include #include // for std::sort void LibRaw::sony_arq_load_raw() { int row, col; if (imgdata.idata.filters || imgdata.idata.colors < 3) throw LIBRAW_EXCEPTION_IO_CORRUPT; read_shorts(imgdata.rawdata.raw_image, imgdata.sizes.raw_width * imgdata.sizes.raw_height * 4); libraw_internal_data.internal_data.input->seek( -2, SEEK_CUR); // avoid wrong eof error if(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_ARQ_SKIP_CHANNEL_SWAP) return; for (row = 0; row < imgdata.sizes.raw_height; row++) { unsigned short(*rowp)[4] = (unsigned short(*)[4]) & imgdata.rawdata.raw_image[row * imgdata.sizes.raw_width * 4]; for (col = 0; col < imgdata.sizes.raw_width; col++) { unsigned short g2 = rowp[col][2]; rowp[col][2] = rowp[col][3]; rowp[col][3] = g2; if (((unsigned)(row - imgdata.sizes.top_margin) < imgdata.sizes.height) && ((unsigned)(col - imgdata.sizes.left_margin) < imgdata.sizes.width) && (MAX(MAX(rowp[col][0], rowp[col][1]), MAX(rowp[col][2], rowp[col][3])) > imgdata.color.maximum)) derror(); } } } void LibRaw::pentax_4shot_load_raw() { #ifdef LIBRAW_CALLOC_RAWSTORE ushort *plane = (ushort *)calloc(size_t(imgdata.sizes.raw_width) * size_t(imgdata.sizes.raw_height), sizeof(ushort)); #else ushort *plane = (ushort *)malloc(size_t(imgdata.sizes.raw_width) * size_t(imgdata.sizes.raw_height) * sizeof(ushort)); #endif int alloc_sz = imgdata.sizes.raw_width * (imgdata.sizes.raw_height + 16) * 4 * sizeof(ushort); #ifdef LIBRAW_CALLOC_RAWSTORE ushort(*result)[4] = (ushort(*)[4])calloc(alloc_sz,1); #else ushort(*result)[4] = (ushort(*)[4])malloc(alloc_sz); #endif struct movement_t { int row, col; } _move[4] = { {1, 1}, {0, 1}, {0, 0}, {1, 0}, }; int tidx = 0; for (int i = 0; i < 4; i++) { int move_row, move_col; if (imgdata.rawparams.p4shot_order[i] >= '0' && imgdata.rawparams.p4shot_order[i] <= '3') { move_row = ((imgdata.rawparams.p4shot_order[i] - '0') & 2) ? 1 : 0; move_col = ((imgdata.rawparams.p4shot_order[i] - '0') & 1) ? 1 : 0; } else { move_row = _move[i].row; move_col = _move[i].col; } for (; tidx < 16; tidx++) if (tiff_ifd[tidx].t_width == imgdata.sizes.raw_width && tiff_ifd[tidx].t_height == imgdata.sizes.raw_height && tiff_ifd[tidx].bps > 8 && tiff_ifd[tidx].samples == 1) break; if (tidx >= 16) break; imgdata.rawdata.raw_image = plane; ID.input->seek(tiff_ifd[tidx].offset, SEEK_SET); imgdata.idata.filters = 0xb4b4b4b4; libraw_internal_data.unpacker_data.data_offset = tiff_ifd[tidx].offset; (this->*pentax_component_load_raw)(); for (int row = 0; row < imgdata.sizes.raw_height - move_row; row++) { int colors[2]; for (int c = 0; c < 2; c++) colors[c] = COLOR(row, c); ushort *srcrow = &plane[imgdata.sizes.raw_width * row]; ushort(*dstrow)[4] = &result[(imgdata.sizes.raw_width) * (row + move_row) + move_col]; for (int col = 0; col < imgdata.sizes.raw_width - move_col; col++) dstrow[col][colors[col % 2]] = srcrow[col]; } tidx++; } if (imgdata.color.cblack[4] == 2 && imgdata.color.cblack[5] == 2) for (int c = 0; c < 4; c++) imgdata.color.cblack[FC(c / 2, c % 2)] += imgdata.color.cblack[6 + c / 2 % imgdata.color.cblack[4] * imgdata.color.cblack[5] + c % 2 % imgdata.color.cblack[5]]; imgdata.color.cblack[4] = imgdata.color.cblack[5] = 0; // assign things back: imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 8; imgdata.idata.filters = 0; imgdata.rawdata.raw_alloc = imgdata.rawdata.color4_image = result; free(plane); imgdata.rawdata.raw_image = 0; } void LibRaw::hasselblad_full_load_raw() { int row, col; for (row = 0; row < S.height; row++) for (col = 0; col < S.width; col++) { read_shorts(&imgdata.image[row * S.width + col][2], 1); // B read_shorts(&imgdata.image[row * S.width + col][1], 1); // G read_shorts(&imgdata.image[row * S.width + col][0], 1); // R } } static inline void unpack7bytesto4x16(unsigned char *src, unsigned short *dest) { dest[0] = (src[0] << 6) | (src[1] >> 2); dest[1] = ((src[1] & 0x3) << 12) | (src[2] << 4) | (src[3] >> 4); dest[2] = (src[3] & 0xf) << 10 | (src[4] << 2) | (src[5] >> 6); dest[3] = ((src[5] & 0x3f) << 8) | src[6]; } static inline void unpack28bytesto16x16ns(unsigned char *src, unsigned short *dest) { dest[0] = (src[3] << 6) | (src[2] >> 2); dest[1] = ((src[2] & 0x3) << 12) | (src[1] << 4) | (src[0] >> 4); dest[2] = (src[0] & 0xf) << 10 | (src[7] << 2) | (src[6] >> 6); dest[3] = ((src[6] & 0x3f) << 8) | src[5]; dest[4] = (src[4] << 6) | (src[11] >> 2); dest[5] = ((src[11] & 0x3) << 12) | (src[10] << 4) | (src[9] >> 4); dest[6] = (src[9] & 0xf) << 10 | (src[8] << 2) | (src[15] >> 6); dest[7] = ((src[15] & 0x3f) << 8) | src[14]; dest[8] = (src[13] << 6) | (src[12] >> 2); dest[9] = ((src[12] & 0x3) << 12) | (src[19] << 4) | (src[18] >> 4); dest[10] = (src[18] & 0xf) << 10 | (src[17] << 2) | (src[16] >> 6); dest[11] = ((src[16] & 0x3f) << 8) | src[23]; dest[12] = (src[22] << 6) | (src[21] >> 2); dest[13] = ((src[21] & 0x3) << 12) | (src[20] << 4) | (src[27] >> 4); dest[14] = (src[27] & 0xf) << 10 | (src[26] << 2) | (src[25] >> 6); dest[15] = ((src[25] & 0x3f) << 8) | src[24]; } #define swab32(x) \ ((unsigned int)((((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \ (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \ (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \ (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24))) static inline void swab32arr(unsigned *arr, unsigned len) { for (unsigned i = 0; i < len; i++) arr[i] = swab32(arr[i]); } #undef swab32 static inline void unpack7bytesto4x16_nikon(unsigned char *src, unsigned short *dest) { dest[3] = (src[6] << 6) | (src[5] >> 2); dest[2] = ((src[5] & 0x3) << 12) | (src[4] << 4) | (src[3] >> 4); dest[1] = (src[3] & 0xf) << 10 | (src[2] << 2) | (src[1] >> 6); dest[0] = ((src[1] & 0x3f) << 8) | src[0]; } void LibRaw::nikon_14bit_load_raw() { const unsigned linelen = (unsigned)(ceilf((float)(S.raw_width * 7 / 4) / 16.0)) * 16; // 14512; // S.raw_width * 7 / 4; const unsigned pitch = S.raw_pitch ? S.raw_pitch / 2 : S.raw_width; unsigned char *buf = (unsigned char *)calloc(linelen,1); for (int row = 0; row < S.raw_height; row++) { unsigned bytesread = libraw_internal_data.internal_data.input->read(buf, 1, linelen); unsigned short *dest = &imgdata.rawdata.raw_image[pitch * row]; // swab32arr((unsigned *)buf, bytesread / 4); for (unsigned int sp = 0, dp = 0; dp < pitch - 3 && sp < linelen - 6 && sp < bytesread - 6; sp += 7, dp += 4) unpack7bytesto4x16_nikon(buf + sp, dest + dp); } free(buf); } void LibRaw::fuji_14bit_load_raw() { const unsigned linelen = S.raw_width * 7 / 4; const unsigned pitch = S.raw_pitch ? S.raw_pitch / 2 : S.raw_width; unsigned char *buf = (unsigned char *)calloc(linelen,1); for (int row = 0; row < S.raw_height; row++) { unsigned bytesread = libraw_internal_data.internal_data.input->read(buf, 1, linelen); unsigned short *dest = &imgdata.rawdata.raw_image[pitch * row]; if (bytesread % 28) { swab32arr((unsigned *)buf, bytesread / 4); for (unsigned int sp = 0, dp = 0; dp < pitch - 3 && sp < linelen - 6 && sp < bytesread - 6; sp += 7, dp += 4) unpack7bytesto4x16(buf + sp, dest + dp); } else for (unsigned int sp = 0, dp = 0; dp < pitch - 15 && sp < linelen - 27 && sp < bytesread - 27; sp += 28, dp += 16) unpack28bytesto16x16ns(buf + sp, dest + dp); } free(buf); } void LibRaw::nikon_load_padded_packed_raw() // 12 bit per pixel, padded to 16 // bytes { // libraw_internal_data.unpacker_data.load_flags -> row byte count if (libraw_internal_data.unpacker_data.load_flags < 2000 || libraw_internal_data.unpacker_data.load_flags > 64000) return; unsigned char *buf = (unsigned char *)calloc(libraw_internal_data.unpacker_data.load_flags,1); for (int row = 0; row < S.raw_height; row++) { checkCancel(); libraw_internal_data.internal_data.input->read( buf, libraw_internal_data.unpacker_data.load_flags, 1); for (int icol = 0; icol < S.raw_width / 2; icol++) { imgdata.rawdata.raw_image[(row)*S.raw_width + (icol * 2)] = ((buf[icol * 3 + 1] & 0xf) << 8) | buf[icol * 3]; imgdata.rawdata.raw_image[(row)*S.raw_width + (icol * 2 + 1)] = buf[icol * 3 + 2] << 4 | ((buf[icol * 3 + 1] & 0xf0) >> 4); } } free(buf); } void LibRaw::nikon_load_striped_packed_raw() { int vbits = 0, bwide, rbits, bite, row, col, i; UINT64 bitbuf = 0; unsigned load_flags = 24; // libraw_internal_data.unpacker_data.load_flags; unsigned tiff_bps = libraw_internal_data.unpacker_data.tiff_bps; struct tiff_ifd_t *ifd = &tiff_ifd[0]; while (ifd < &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds] && ifd->offset != libraw_internal_data.unpacker_data.data_offset) ++ifd; if (ifd == &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds]) throw LIBRAW_EXCEPTION_DECODE_RAW; if (!ifd->rows_per_strip || !ifd->strip_offsets_count) return; // not unpacked int stripcnt = 0; bwide = S.raw_width * tiff_bps / 8; bwide += bwide & load_flags >> 7; rbits = bwide * 8 - S.raw_width * tiff_bps; if (load_flags & 1) bwide = bwide * 16 / 15; bite = 8 + (load_flags & 24); for (row = 0; row < S.raw_height; row++) { checkCancel(); if (!(row % ifd->rows_per_strip)) { if (stripcnt >= ifd->strip_offsets_count) return; // run out of data libraw_internal_data.internal_data.input->seek( ifd->strip_offsets[stripcnt], SEEK_SET); stripcnt++; } for (col = 0; col < S.raw_width; col++) { for (vbits -= tiff_bps; vbits < 0; vbits += bite) { bitbuf <<= bite; for (i = 0; i < bite; i += 8) bitbuf |= (unsigned)(libraw_internal_data.internal_data.input->get_char() << i); } imgdata.rawdata.raw_image[(row)*S.raw_width + (col)] = bitbuf << (64 - tiff_bps - vbits) >> (64 - tiff_bps); } vbits -= rbits; } } struct pana_cs6_page_decoder { unsigned int pixelbuffer[18], lastoffset, maxoffset; unsigned char current, *buffer; pana_cs6_page_decoder(unsigned char *_buffer, unsigned int bsize) : lastoffset(0), maxoffset(bsize), current(0), buffer(_buffer) { } void read_page(); // will throw IO error if not enough space in buffer void read_page12(); // 12-bit variant unsigned int nextpixel() { return current < 14 ? pixelbuffer[current++] : 0; } unsigned int nextpixel12() { return current < 18 ? pixelbuffer[current++] : 0; } }; void pana_cs6_page_decoder::read_page() { if (!buffer || (maxoffset - lastoffset < 16)) throw LIBRAW_EXCEPTION_IO_EOF; #define wbuffer(i) ((unsigned short)buffer[lastoffset + 15 - i]) pixelbuffer[0] = (wbuffer(0) << 6) | (wbuffer(1) >> 2); // 14 bit pixelbuffer[1] = (((wbuffer(1) & 0x3) << 12) | (wbuffer(2) << 4) | (wbuffer(3) >> 4)) & 0x3fff; // 14 bit pixelbuffer[2] = (wbuffer(3) >> 2) & 0x3; // 2 pixelbuffer[3] = ((wbuffer(3) & 0x3) << 8) | wbuffer(4); // 10 pixelbuffer[4] = (wbuffer(5) << 2) | (wbuffer(6) >> 6); // 10 pixelbuffer[5] = ((wbuffer(6) & 0x3f) << 4) | (wbuffer(7) >> 4); // 10 pixelbuffer[6] = (wbuffer(7) >> 2) & 0x3; pixelbuffer[7] = ((wbuffer(7) & 0x3) << 8) | wbuffer(8); pixelbuffer[8] = ((wbuffer(9) << 2) & 0x3fc) | (wbuffer(10) >> 6); pixelbuffer[9] = ((wbuffer(10) << 4) | (wbuffer(11) >> 4)) & 0x3ff; pixelbuffer[10] = (wbuffer(11) >> 2) & 0x3; pixelbuffer[11] = ((wbuffer(11) & 0x3) << 8) | wbuffer(12); pixelbuffer[12] = (((wbuffer(13) << 2) & 0x3fc) | wbuffer(14) >> 6) & 0x3ff; pixelbuffer[13] = ((wbuffer(14) << 4) | (wbuffer(15) >> 4)) & 0x3ff; #undef wbuffer current = 0; lastoffset += 16; } void pana_cs6_page_decoder::read_page12() { if (!buffer || (maxoffset - lastoffset < 16)) throw LIBRAW_EXCEPTION_IO_EOF; #define wb(i) ((unsigned short)buffer[lastoffset + 15 - i]) pixelbuffer[0] = (wb(0) << 4) | (wb(1) >> 4); // 12 bit: 8/0 + 4 upper bits of /1 pixelbuffer[1] = (((wb(1) & 0xf) << 8) | (wb(2))) & 0xfff; // 12 bit: 4l/1 + 8/2 pixelbuffer[2] = (wb(3) >> 6) & 0x3; // 2; 2u/3, 6 low bits remains in wb(3) pixelbuffer[3] = ((wb(3) & 0x3f) << 2) | (wb(4) >> 6); // 8; 6l/3 + 2u/4; 6 low bits remains in wb(4) pixelbuffer[4] = ((wb(4) & 0x3f) << 2) | (wb(5) >> 6); // 8: 6l/4 + 2u/5; 6 low bits remains in wb(5) pixelbuffer[5] = ((wb(5) & 0x3f) << 2) | (wb(6) >> 6); // 8: 6l/5 + 2u/6, 6 low bits remains in wb(6) pixelbuffer[6] = (wb(6) >> 4) & 0x3; // 2, 4 low bits remains in wb(6) pixelbuffer[7] = ((wb(6) & 0xf) << 4) | (wb(7) >> 4); // 8: 4 low bits from wb(6), 4 upper bits from wb(7) pixelbuffer[8] = ((wb(7) & 0xf) << 4) | (wb(8) >> 4); // 8: 4 low bits from wb7, 4 upper bits from wb8 pixelbuffer[9] = ((wb(8) & 0xf) << 4) | (wb(9) >> 4); // 8: 4 low bits from wb8, 4 upper bits from wb9 pixelbuffer[10] = (wb(9) >> 2) & 0x3; // 2: bits 2-3 from wb9, two low bits remain in wb9 pixelbuffer[11] = ((wb(9) & 0x3) << 6) | (wb(10) >> 2); // 8: 2 bits from wb9, 6 bits from wb10 pixelbuffer[12] = ((wb(10) & 0x3) << 6) | (wb(11) >> 2); // 8: 2 bits from wb10, 6 bits from wb11 pixelbuffer[13] = ((wb(11) & 0x3) << 6) | (wb(12) >> 2); // 8: 2 bits from wb11, 6 bits from wb12 pixelbuffer[14] = wb(12) & 0x3; // 2: low bits from wb12 pixelbuffer[15] = wb(13); pixelbuffer[16] = wb(14); pixelbuffer[17] = wb(15); #undef wb current = 0; lastoffset += 16; } void LibRaw::panasonicC6_load_raw() { const int rowstep = 16; const bool _12bit = libraw_internal_data.unpacker_data.pana_bpp == 12; const int pixperblock = _12bit ? 14 : 11; const int blocksperrow = imgdata.sizes.raw_width / pixperblock; const int rowbytes = blocksperrow * 16; const unsigned pixelbase0 = _12bit ? 0x80 : 0x200; const unsigned pixelbase_compare = _12bit ? 0x800 : 0x2000; const unsigned spix_compare = _12bit ? 0x3fff : 0xffff; const unsigned pixel_mask = _12bit ? 0xfff : 0x3fff; std::vector iobuf; try { iobuf.resize(rowbytes * rowstep); } catch (...) { throw LIBRAW_EXCEPTION_ALLOC; } for (int row = 0; row < imgdata.sizes.raw_height - rowstep + 1; row += rowstep) { int rowstoread = MIN(rowstep, imgdata.sizes.raw_height - row); if (libraw_internal_data.internal_data.input->read( iobuf.data(), rowbytes, rowstoread) != rowstoread) throw LIBRAW_EXCEPTION_IO_EOF; pana_cs6_page_decoder page(iobuf.data(), rowbytes * rowstoread); for (int crow = 0, col = 0; crow < rowstoread; crow++, col = 0) { unsigned short *rowptr = &imgdata.rawdata .raw_image[(row + crow) * imgdata.sizes.raw_pitch / 2]; for (int rblock = 0; rblock < blocksperrow; rblock++) { if (_12bit) page.read_page12(); else page.read_page(); unsigned oddeven[2] = {0, 0}, nonzero[2] = {0, 0}; unsigned pmul = 0, pixel_base = 0; for (int pix = 0; pix < pixperblock; pix++) { if (pix % 3 == 2) { unsigned base = _12bit ? page.nextpixel12(): page.nextpixel(); if (base > 3) throw LIBRAW_EXCEPTION_IO_CORRUPT; // not possible b/c of 2-bit // field, but.... if (base == 3) base = 4; pixel_base = pixelbase0 << base; pmul = 1 << base; } unsigned epixel = _12bit ? page.nextpixel12() : page.nextpixel(); if (oddeven[pix % 2]) { epixel *= pmul; if (pixel_base < pixelbase_compare && nonzero[pix % 2] > pixel_base) epixel += nonzero[pix % 2] - pixel_base; nonzero[pix % 2] = epixel; } else { oddeven[pix % 2] = epixel; if (epixel) nonzero[pix % 2] = epixel; else epixel = nonzero[pix % 2]; } unsigned spix = epixel - 0xf; if (spix <= spix_compare) rowptr[col++] = spix & spix_compare; else { epixel = (((signed int)(epixel + 0x7ffffff1)) >> 0x1f); rowptr[col++] = epixel & pixel_mask; } } } } } } void LibRaw::panasonicC7_load_raw() { const int rowstep = 16; int pixperblock = libraw_internal_data.unpacker_data.pana_bpp == 14 ? 9 : 10; int rowbytes = imgdata.sizes.raw_width / pixperblock * 16; unsigned char *iobuf = (unsigned char *)calloc(rowbytes * rowstep,1); for (int row = 0; row < imgdata.sizes.raw_height - rowstep + 1; row += rowstep) { int rowstoread = MIN(rowstep, imgdata.sizes.raw_height - row); if (libraw_internal_data.internal_data.input->read( iobuf, rowbytes, rowstoread) != rowstoread) throw LIBRAW_EXCEPTION_IO_EOF; unsigned char *bytes = iobuf; for (int crow = 0; crow < rowstoread; crow++) { unsigned short *rowptr = &imgdata.rawdata .raw_image[(row + crow) * imgdata.sizes.raw_pitch / 2]; for (int col = 0; col < imgdata.sizes.raw_width - pixperblock + 1; col += pixperblock, bytes += 16) { if (libraw_internal_data.unpacker_data.pana_bpp == 14) { rowptr[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); rowptr[col + 1] = (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10); rowptr[col + 2] = (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12); rowptr[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); rowptr[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); rowptr[col + 5] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); rowptr[col + 6] = (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); rowptr[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); rowptr[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); } else if (libraw_internal_data.unpacker_data.pana_bpp == 12) // have not seen in the wild yet { rowptr[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; rowptr[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); rowptr[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; rowptr[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); rowptr[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; rowptr[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); rowptr[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; rowptr[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); rowptr[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; rowptr[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); } } } } free(iobuf); } void LibRaw::unpacked_load_raw_fuji_f700s20() { int base_offset = 0; int row_size = imgdata.sizes.raw_width * 2; // in bytes if (imgdata.idata.raw_count == 2 && imgdata.rawparams.shot_select) { libraw_internal_data.internal_data.input->seek(-row_size, SEEK_CUR); base_offset = row_size; // in bytes } unsigned char *buffer = (unsigned char *)calloc(row_size,2); for (int row = 0; row < imgdata.sizes.raw_height; row++) { read_shorts((ushort *)buffer, imgdata.sizes.raw_width * 2); memmove(&imgdata.rawdata.raw_image[row * imgdata.sizes.raw_pitch / 2], buffer + base_offset, row_size); } free(buffer); } void LibRaw::nikon_load_sraw() { // We're already seeked to data! unsigned char *rd = (unsigned char *)calloc(3 * (imgdata.sizes.raw_width + 2),1); if (!rd) throw LIBRAW_EXCEPTION_ALLOC; try { int row, col; for (row = 0; row < imgdata.sizes.raw_height; row++) { checkCancel(); libraw_internal_data.internal_data.input->read(rd, 3, imgdata.sizes.raw_width); for (col = 0; col < imgdata.sizes.raw_width - 1; col += 2) { int bi = col * 3; ushort bits1 = (rd[bi + 1] & 0xf) << 8 | rd[bi]; // 3,0,1 ushort bits2 = rd[bi + 2] << 4 | ((rd[bi + 1] >> 4) & 0xf); // 452 ushort bits3 = ((rd[bi + 4] & 0xf) << 8) | rd[bi + 3]; // 967 ushort bits4 = rd[bi + 5] << 4 | ((rd[bi + 4] >> 4) & 0xf); // ab8 imgdata.image[row * imgdata.sizes.raw_width + col][0] = bits1; imgdata.image[row * imgdata.sizes.raw_width + col][1] = bits3; imgdata.image[row * imgdata.sizes.raw_width + col][2] = bits4; imgdata.image[row * imgdata.sizes.raw_width + col + 1][0] = bits2; imgdata.image[row * imgdata.sizes.raw_width + col + 1][1] = 2048; imgdata.image[row * imgdata.sizes.raw_width + col + 1][2] = 2048; } } } catch (...) { free(rd); throw; } free(rd); C.maximum = 0xfff; // 12 bit? if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE) { return; // no CbCr interpolation } // Interpolate CC channels int row, col; for (row = 0; row < imgdata.sizes.raw_height; row++) { checkCancel(); // will throw out for (col = 0; col < imgdata.sizes.raw_width; col += 2) { int col2 = col < imgdata.sizes.raw_width - 2 ? col + 2 : col; imgdata.image[row * imgdata.sizes.raw_width + col + 1][1] = (unsigned short)(int(imgdata.image[row * imgdata.sizes.raw_width + col][1] + imgdata.image[row * imgdata.sizes.raw_width + col2][1]) / 2); imgdata.image[row * imgdata.sizes.raw_width + col + 1][2] = (unsigned short)(int(imgdata.image[row * imgdata.sizes.raw_width + col][2] + imgdata.image[row * imgdata.sizes.raw_width + col2][2]) / 2); } } if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_RGB) return; for (row = 0; row < imgdata.sizes.raw_height; row++) { checkCancel(); // will throw out for (col = 0; col < imgdata.sizes.raw_width; col++) { float Y = float(imgdata.image[row * imgdata.sizes.raw_width + col][0]) / 2549.f; float Ch2 = float(imgdata.image[row * imgdata.sizes.raw_width + col][1] - 1280) / 1536.f; float Ch3 = float(imgdata.image[row * imgdata.sizes.raw_width + col][2] - 1280) / 1536.f; if (Y > 1.f) Y = 1.f; if (Y > 0.803f) Ch2 = Ch3 = 0.5f; float r = Y + 1.40200f * (Ch3 - 0.5f); if (r < 0.f) r = 0.f; if (r > 1.f) r = 1.f; float g = Y - 0.34414f * (Ch2 - 0.5f) - 0.71414 * (Ch3 - 0.5f); if (g > 1.f) g = 1.f; if (g < 0.f) g = 0.f; float b = Y + 1.77200 * (Ch2 - 0.5f); if (b > 1.f) b = 1.f; if (b < 0.f) b = 0.f; imgdata.image[row * imgdata.sizes.raw_width + col][0] = imgdata.color.curve[int(r * 3072.f)]; imgdata.image[row * imgdata.sizes.raw_width + col][1] = imgdata.color.curve[int(g * 3072.f)]; imgdata.image[row * imgdata.sizes.raw_width + col][2] = imgdata.color.curve[int(b * 3072.f)]; } } C.maximum = 16383; } /* Each row is decoded independently. Each row starts with a 16 bit prefix. The hi byte is zero, the lo byte (first 3 bits) indicates a bit_base. Other bits remain unused. |0000 0000|0000 0XXX| => XXX is bit_base After the prefix the pixel data starts. Pixels are grouped into clusters forming 8 output pixel. Each cluster starts with a variable length of bits, indicating decompression flags. */ #undef MIN #undef MAX #undef LIM #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define LIM(x, min, max) MAX(min, MIN(x, max)) struct iiq_bitstream_t { uint64_t curr; uint32_t *input; uint8_t used; iiq_bitstream_t(uint32_t *img_input): curr(0),input(img_input),used(0){} void fill() { if (used <= 32) { uint64_t bitpump_next = *input++; curr = (curr << 32) | bitpump_next; used += 32; } } uint64_t peek(uint8_t len) { if (len >= used) fill(); uint64_t res = curr >> (used - len); return res & ((1 << (uint8_t)len) - 1); } void consume(uint8_t len) { peek(len); // fill buffer if needed used -= len; } uint64_t get(char len) { uint64_t val = peek(len); consume(len); return val; } }; void decode_S_type(int32_t out_width, uint32_t *img_input, ushort *outbuf /*, int bit_depth*/) { #if 0 if (((bit_depth - 12) & 0xFFFFFFFD) != 0) return 0; #endif iiq_bitstream_t stream(img_input); const int pix_corr_shift = 2; // 16 - bit_depth; unsigned int bit_check[2] = { 0, 0 }; const uint8_t used_corr[8] = { 3, 3, 3, 3, 1, 1, 1, 1, }; const uint8_t extra_bits[8] = { 1, 2, 3, 4, 0, 0, 0, 0, }; const uint8_t bit_indicator[8 * 4] = { 9, 8, 0, 7, 6, 6, 5, 5, 1, 1, 1, 1, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, }; const uint8_t skip_bits[8 * 4] = {5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; int block_count = ((out_width - 8) >> 3) + 1; int block_total_bytes = 8 * block_count; int32_t prev_pix_value[2] = { 0, 0 }; uint8_t init_bits = stream.get(16) & 7; if (out_width - 7 > 0) { uint8_t pix_sub_init = 17 - init_bits; for (int blk_id = 0; blk_id < block_count; ++blk_id) { int8_t idx_even = stream.peek(7); stream.consume(2); if ((unsigned int)idx_even >= 32) bit_check[0] = ((unsigned int)idx_even >> 5) + bit_check[0] - 2; else { bit_check[0] = bit_indicator[idx_even]; stream.consume(skip_bits[idx_even]); } int8_t idx_odd = stream.peek(7); stream.consume(2); if ((unsigned int)idx_odd >= 32) bit_check[1] = ((unsigned int)idx_odd >> 5) + bit_check[1] - 2; else { bit_check[1] = bit_indicator[idx_odd]; stream.consume(skip_bits[idx_odd]); } uint8_t bidx = stream.peek(3); stream.consume(used_corr[bidx]); uint8_t take_bits = init_bits + extra_bits[bidx]; // 11 or less uint32_t bp_shift[2] = {bit_check[0] - extra_bits[bidx], bit_check[1] - extra_bits[bidx]}; int pix_sub[2] = {0xFFFF >> (pix_sub_init - bit_check[0]), 0xFFFF >> (pix_sub_init - bit_check[1])}; for (int i = 0; i < 8; i++) // MAIN LOOP for pixel decoding { int32_t value = 0; if (bit_check[i & 1] == 9) value = stream.get(14); else value = prev_pix_value[i & 1] + ((uint32_t)stream.get(take_bits) << bp_shift[i & 1]) - pix_sub[i & 1]; outbuf[i] = LIM(value << pix_corr_shift, 0, 0xffff); prev_pix_value[i & 1] = value; } outbuf += 8; // always produce 8 pixels from this cluster } } // if width > 7 // End main if // Final block // maybe fill/unpack extra bytes if width % 8 <> 0? if (block_total_bytes < out_width) { do { stream.fill(); uint32_t pix_value = stream.get(14); ++block_total_bytes; *outbuf++ = pix_value << pix_corr_shift; } while (block_total_bytes < out_width); } } struct p1_row_info_t { unsigned row; INT64 offset; p1_row_info_t(): row(0),offset(0){} p1_row_info_t(const p1_row_info_t& q): row(q.row),offset(q.offset){} bool operator < (const p1_row_info_t & rhs) const { return offset < rhs.offset; } }; void LibRaw::phase_one_load_raw_s() { if(!libraw_internal_data.unpacker_data.strip_offset || !imgdata.rawdata.raw_image || !libraw_internal_data.unpacker_data.data_offset) throw LIBRAW_EXCEPTION_IO_CORRUPT; std::vector stripes(imgdata.sizes.raw_height+1); libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.strip_offset, SEEK_SET); for (unsigned row = 0; row < imgdata.sizes.raw_height; row++) { stripes[row].row = row; stripes[row].offset = INT64(get4()) + libraw_internal_data.unpacker_data.data_offset; } stripes[imgdata.sizes.raw_height].row = imgdata.sizes.raw_height; stripes[imgdata.sizes.raw_height].offset = libraw_internal_data.unpacker_data.data_offset + INT64(libraw_internal_data.unpacker_data.data_size); std::sort(stripes.begin(), stripes.end()); INT64 maxsz = imgdata.sizes.raw_width * 3 + 2; // theor max: 17 bytes per 8 pix + row header std::vector datavec(maxsz); for (unsigned row = 0; row < imgdata.sizes.raw_height; row++) { if (stripes[row].row >= imgdata.sizes.raw_height) continue; ushort *datap = imgdata.rawdata.raw_image + stripes[row].row * imgdata.sizes.raw_width; libraw_internal_data.internal_data.input->seek(stripes[row].offset, SEEK_SET); INT64 readsz = stripes[row + 1].offset - stripes[row].offset; if (readsz > maxsz) throw LIBRAW_EXCEPTION_IO_CORRUPT; if(libraw_internal_data.internal_data.input->read(datavec.data(), 1, readsz) != readsz) derror(); // TODO: check read state decode_S_type(imgdata.sizes.raw_width, (uint32_t *)datavec.data(), datap /*, 14 */); } } LibRaw-0.21.4/src/decoders/decoders_libraw_dcrdefs.cpp000066400000000000000000000255371477673233700227220ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" void LibRaw::packed_tiled_dng_load_raw() { ushort *rp; unsigned row, col; int ss = shot_select; shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss, 0, (LIBRAW_IFD_MAXCOUNT * 2 - 1))] & 0xff; std::vector pixel; try { int ntiles = 1 + (raw_width) / tile_width; if ((unsigned)ntiles * tile_width > raw_width * 2u) throw LIBRAW_EXCEPTION_ALLOC; pixel.resize(tile_width * ntiles * tiff_samples); } catch (...) { throw LIBRAW_EXCEPTION_ALLOC; // rethrow } try { unsigned trow = 0, tcol = 0; INT64 save; while (trow < raw_height) { checkCancel(); save = ftell(ifp); if (tile_length < INT_MAX) fseek(ifp, get4(), SEEK_SET); for (row = 0; row < tile_length && (row + trow) < raw_height; row++) { if (tiff_bps == 16) read_shorts(pixel.data(), tile_width * tiff_samples); else { getbits(-1); for (col = 0; col < tile_width * tiff_samples; col++) pixel[col] = getbits(tiff_bps); } for (rp = pixel.data(), col = 0; col < tile_width; col++) adobe_copy_pixel(trow+row, tcol+col, &rp); } fseek(ifp, save + 4, SEEK_SET); if ((tcol += tile_width) >= raw_width) trow += tile_length + (tcol = 0); } } catch (...) { shot_select = ss; throw; } shot_select = ss; } void LibRaw::sony_ljpeg_load_raw() { unsigned trow = 0, tcol = 0, jrow, jcol, row, col; INT64 save; struct jhead jh; while (trow < raw_height) { checkCancel(); save = ftell(ifp); // We're at if (tile_length < INT_MAX) fseek(ifp, get4(), SEEK_SET); if (!ljpeg_start(&jh, 0)) break; try { for (row = jrow = 0; jrow < (unsigned)jh.high && trow+row < raw_height-1; jrow++, row += 2) { checkCancel(); ushort(*rowp)[4] = (ushort(*)[4])ljpeg_row(jrow, &jh); for (col = jcol = 0; jcol < (unsigned)jh.wide && tcol+col < raw_width-1; jcol++, col += 2) { RAW(trow + row, tcol + col) = rowp[jcol][0]; RAW(trow + row, tcol + col + 1) = rowp[jcol][1]; RAW(trow + row + 1, tcol + col) = rowp[jcol][2]; RAW(trow + row + 1, tcol + col + 1) = rowp[jcol][3]; } } } catch (...) { ljpeg_end(&jh); throw; } fseek(ifp, save + 4, SEEK_SET); if ((tcol += tile_width) >= raw_width) trow += tile_length + (tcol = 0); ljpeg_end(&jh); } } void LibRaw::nikon_he_load_raw_placeholder() { throw LIBRAW_EXCEPTION_UNSUPPORTED_FORMAT; } void LibRaw::nikon_coolscan_load_raw() { int clrs = colors == 3 ? 3 : 1; if (clrs == 3 && !image) throw LIBRAW_EXCEPTION_IO_CORRUPT; if(clrs == 1 && !raw_image) throw LIBRAW_EXCEPTION_IO_CORRUPT; int bypp = tiff_bps <= 8 ? 1 : 2; int bufsize = width * clrs * bypp; unsigned char *buf = (unsigned char *)calloc(bufsize,1); unsigned short *ubuf = (unsigned short *)buf; if (tiff_bps <= 8) gamma_curve(1.0 / imgdata.rawparams.coolscan_nef_gamma, 0., 1, 255); else gamma_curve(1.0 / imgdata.rawparams.coolscan_nef_gamma, 0., 1, 65535); fseek(ifp, data_offset, SEEK_SET); for (int row = 0; row < raw_height; row++) { if(tiff_bps <=8) fread(buf, 1, bufsize, ifp); else read_shorts(ubuf,width*clrs); unsigned short(*ip)[4] = (unsigned short(*)[4])image + row * width; unsigned short *rp = raw_image + row * raw_width; if (is_NikonTransfer == 2) { // it is also (tiff_bps == 8) if (clrs == 3) { for (int col = 0; col < width; col++) { ip[col][0] = ((float)curve[buf[col * 3]]) / 255.0f; ip[col][1] = ((float)curve[buf[col * 3 + 1]]) / 255.0f; ip[col][2] = ((float)curve[buf[col * 3 + 2]]) / 255.0f; ip[col][3] = 0; } } else { for (int col = 0; col < width; col++) rp[col] = ((float)curve[buf[col]]) / 255.0f; } } else if (tiff_bps <= 8) { if (clrs == 3) { for (int col = 0; col < width; col++) { ip[col][0] = curve[buf[col * 3]]; ip[col][1] = curve[buf[col * 3 + 1]]; ip[col][2] = curve[buf[col * 3 + 2]]; ip[col][3] = 0; } } else { for (int col = 0; col < width; col++) rp[col] = curve[buf[col]]; } } else { if (clrs == 3) { for (int col = 0; col < width; col++) { ip[col][0] = curve[ubuf[col * 3]]; ip[col][1] = curve[ubuf[col * 3 + 1]]; ip[col][2] = curve[ubuf[col * 3 + 2]]; ip[col][3] = 0; } } else { for (int col = 0; col < width; col++) rp[col] = curve[ubuf[col]]; } } } free(buf); } void LibRaw::broadcom_load_raw() { uchar *dp; int rev, row, col, c; rev = 3 * (order == 0x4949); std::vector data(raw_stride * 2); for (row = 0; row < raw_height; row++) { if (fread(data.data() + raw_stride, 1, raw_stride, ifp) < raw_stride) derror(); FORC(raw_stride) data[c] = data[raw_stride + (c ^ rev)]; for (dp = data.data(), col = 0; col < raw_width; dp += 5, col += 4) FORC4 RAW(row, col + c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3); } } void LibRaw::android_tight_load_raw() { uchar *data, *dp; int bwide, row, col, c; bwide = -(-5 * raw_width >> 5) << 3; data = (uchar *)calloc(bwide,1); for (row = 0; row < raw_height; row++) { if (fread(data, 1, bwide, ifp) < bwide) derror(); for (dp = data, col = 0; col < raw_width; dp += 5, col += 4) FORC4 RAW(row, col + c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3); } free(data); } void LibRaw::android_loose_load_raw() { uchar *data, *dp; int bwide, row, col, c; UINT64 bitbuf = 0; bwide = (raw_width + 5) / 6 << 3; data = (uchar *)calloc(bwide,1); for (row = 0; row < raw_height; row++) { if (fread(data, 1, bwide, ifp) < bwide) derror(); for (dp = data, col = 0; col < raw_width; dp += 8, col += 6) { FORC(8) bitbuf = (bitbuf << 8) | dp[c ^ 7]; FORC(6) RAW(row, col + c) = (bitbuf >> c * 10) & 0x3ff; } } free(data); } void LibRaw::unpacked_load_raw_reversed() { int row, col, bits = 0; while (1 << ++bits < (int)maximum) ; for (row = raw_height - 1; row >= 0; row--) { checkCancel(); read_shorts(&raw_image[row * raw_width], raw_width); for (col = 0; col < raw_width; col++) if ((RAW(row, col) >>= load_flags) >> bits && (unsigned)(row - top_margin) < height && (unsigned)(col - left_margin) < width) derror(); } } #ifdef USE_6BY9RPI void LibRaw::rpi_load_raw8() { uchar *data, *dp; int rev, dwide, row, col, c; double sum[] = { 0,0 }; rev = 3 * (order == 0x4949); if (raw_stride == 0) dwide = raw_width; else dwide = raw_stride; data = (uchar *)calloc(dwide, 2); for (row = 0; row < raw_height; row++) { if (fread(data + dwide, 1, dwide, ifp) < dwide) derror(); FORC(dwide) data[c] = data[dwide + (c ^ rev)]; for (dp = data, col = 0; col < raw_width; dp++, col++) RAW(row, col + c) = dp[c]; } free(data); maximum = 0xff; if (!strcmp(make, "OmniVision") || !strcmp(make, "Sony") || !strcmp(make, "RaspberryPi")) return; row = raw_height / 2; FORC(width - 1) { sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); } if (sum[1] > sum[0]) filters = 0x4b4b4b4b; } void LibRaw::rpi_load_raw12() { uchar *data, *dp; int rev, dwide, row, col, c; double sum[] = { 0,0 }; rev = 3 * (order == 0x4949); if (raw_stride == 0) dwide = (raw_width * 3 + 1) / 2; else dwide = raw_stride; data = (uchar *)calloc(dwide, 2); for (row = 0; row < raw_height; row++) { if (fread(data + dwide, 1, dwide, ifp) < dwide) derror(); FORC(dwide) data[c] = data[dwide + (c ^ rev)]; for (dp = data, col = 0; col < raw_width; dp += 3, col += 2) FORC(2) RAW(row, col + c) = (dp[c] << 4) | (dp[2] >> (c << 2) & 0xF); } free(data); maximum = 0xfff; if (!strcmp(make, "OmniVision") || !strcmp(make, "Sony") || !strcmp(make, "RaspberryPi")) return; row = raw_height / 2; FORC(width - 1) { sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); } if (sum[1] > sum[0]) filters = 0x4b4b4b4b; } void LibRaw::rpi_load_raw14() { uchar *data, *dp; int rev, dwide, row, col, c; double sum[] = { 0,0 }; rev = 3 * (order == 0x4949); if (raw_stride == 0) dwide = ((raw_width * 7) + 3) >> 2; else dwide = raw_stride; data = (uchar *)calloc(dwide, 2); for (row = 0; row < raw_height; row++) { if (fread(data + dwide, 1, dwide, ifp) < dwide) derror(); FORC(dwide) data[c] = data[dwide + (c ^ rev)]; for (dp = data, col = 0; col < raw_width; dp += 7, col += 4) { RAW(row, col + 0) = (dp[0] << 6) | (dp[4] >> 2); RAW(row, col + 1) = (dp[1] << 6) | ((dp[4] & 0x3) << 4) | ((dp[5] & 0xf0) >> 4); RAW(row, col + 2) = (dp[2] << 6) | ((dp[5] & 0xf) << 2) | ((dp[6] & 0xc0) >> 6); RAW(row, col + 3) = (dp[3] << 6) | ((dp[6] & 0x3f) << 2); } } free(data); maximum = 0x3fff; if (!strcmp(make, "OmniVision") || !strcmp(make, "Sony") || !strcmp(make, "RaspberryPi")) return; row = raw_height / 2; FORC(width - 1) { sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); } if (sum[1] > sum[0]) filters = 0x4b4b4b4b; } void LibRaw::rpi_load_raw16() { uchar *data, *dp; int rev, dwide, row, col, c; double sum[] = { 0,0 }; rev = 3 * (order == 0x4949); if (raw_stride == 0) dwide = (raw_width * 2); else dwide = raw_stride; data = (uchar *)calloc(dwide, 2); for (row = 0; row < raw_height; row++) { if (fread(data + dwide, 1, dwide, ifp) < dwide) derror(); FORC(dwide) data[c] = data[dwide + (c ^ rev)]; for (dp = data, col = 0; col < raw_width; dp += 2, col++) RAW(row, col + c) = (dp[1] << 8) | dp[0]; } free(data); maximum = 0xffff; if (!strcmp(make, "OmniVision") || !strcmp(make, "Sony") || !strcmp(make, "RaspberryPi")) return; row = raw_height / 2; FORC(width - 1) { sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); } if (sum[1] > sum[0]) filters = 0x4b4b4b4b; } #endif LibRaw-0.21.4/src/decoders/dng.cpp000066400000000000000000000162001477673233700166330ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" void LibRaw::vc5_dng_load_raw_placeholder() { // placeholder only, real decoding implemented in GPR SDK throw LIBRAW_EXCEPTION_DECODE_RAW; } void LibRaw::adobe_copy_pixel(unsigned row, unsigned col, ushort **rp) { int c; if (tiff_samples == 2 && shot_select) (*rp)++; if (raw_image) { if (row < raw_height && col < raw_width) RAW(row, col) = curve[**rp]; *rp += tiff_samples; } else { if (row < raw_height && col < raw_width) FORC(int(tiff_samples)) image[row * raw_width + col][c] = curve[(*rp)[c]]; *rp += tiff_samples; } if (tiff_samples == 2 && shot_select) (*rp)--; } void LibRaw::lossless_dng_load_raw() { unsigned trow = 0, tcol = 0, jwide, jrow, jcol, row, col, i, j; INT64 save; struct jhead jh; ushort *rp; int ss = shot_select; shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss,0,(LIBRAW_IFD_MAXCOUNT*2-1))] & 0xff; while (trow < raw_height) { checkCancel(); save = ftell(ifp); if (tile_length < INT_MAX) fseek(ifp, get4(), SEEK_SET); if (!ljpeg_start(&jh, 0)) break; jwide = jh.wide; if (filters) jwide *= jh.clrs; if(filters && (tiff_samples == 2)) // Fuji Super CCD jwide /= 2; try { switch (jh.algo) { case 0xc1: jh.vpred[0] = 16384; getbits(-1); for (jrow = 0; jrow + 7 < (unsigned)jh.high; jrow += 8) { checkCancel(); for (jcol = 0; jcol + 7 < (unsigned)jh.wide; jcol += 8) { ljpeg_idct(&jh); rp = jh.idct; row = trow + jcol / tile_width + jrow * 2; col = tcol + jcol % tile_width; for (i = 0; i < 16; i += 2) for (j = 0; j < 8; j++) adobe_copy_pixel(row + i, col + j, &rp); } } break; case 0xc3: for (row = col = jrow = 0; jrow < (unsigned)jh.high; jrow++) { checkCancel(); rp = ljpeg_row(jrow, &jh); if (tiff_samples == 1 && jh.clrs > 1 && jh.clrs * jwide == raw_width) for (jcol = 0; jcol < jwide * jh.clrs; jcol++) { adobe_copy_pixel(trow + row, tcol + col, &rp); if (++col >= tile_width || col >= raw_width) row += 1 + (col = 0); } else for (jcol = 0; jcol < jwide; jcol++) { adobe_copy_pixel(trow + row, tcol + col, &rp); if (++col >= tile_width || col >= raw_width) row += 1 + (col = 0); } } } } catch (...) { ljpeg_end(&jh); shot_select = ss; throw; } fseek(ifp, save + 4, SEEK_SET); if ((tcol += tile_width) >= raw_width) trow += tile_length + (tcol = 0); ljpeg_end(&jh); } shot_select = ss; } void LibRaw::packed_dng_load_raw() { ushort *pixel, *rp; unsigned row, col; if (tile_length < INT_MAX) { packed_tiled_dng_load_raw(); return; } int ss = shot_select; shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss,0,(LIBRAW_IFD_MAXCOUNT*2-1))] & 0xff; pixel = (ushort *)calloc(raw_width, tiff_samples * sizeof *pixel); try { for (row = 0; row < raw_height; row++) { checkCancel(); if (tiff_bps == 16) read_shorts(pixel, raw_width * tiff_samples); else { getbits(-1); for (col = 0; col < raw_width * tiff_samples; col++) pixel[col] = getbits(tiff_bps); } for (rp = pixel, col = 0; col < raw_width; col++) adobe_copy_pixel(row, col, &rp); } } catch (...) { free(pixel); shot_select = ss; throw; } free(pixel); shot_select = ss; } #ifdef NO_JPEG void LibRaw::lossy_dng_load_raw() {} #else static void jpegErrorExit_d(j_common_ptr /*cinfo*/) { throw LIBRAW_EXCEPTION_DECODE_JPEG; } void LibRaw::lossy_dng_load_raw() { if (!image) throw LIBRAW_EXCEPTION_IO_CORRUPT; struct jpeg_decompress_struct cinfo; unsigned sorder = order, ntags, opcode, deg, i, j, c; unsigned trow = 0, tcol = 0, row, col; INT64 save = data_offset - 4; ushort cur[4][256]; double coeff[9], tot; if (meta_offset) { fseek(ifp, meta_offset, SEEK_SET); order = 0x4d4d; ntags = get4(); while (ntags--) { opcode = get4(); get4(); get4(); if (opcode != 8) { fseek(ifp, get4(), SEEK_CUR); continue; } fseek(ifp, 20, SEEK_CUR); if ((c = get4()) > 3) break; fseek(ifp, 12, SEEK_CUR); if ((deg = get4()) > 8) break; for (i = 0; i <= deg && i < 9; i++) coeff[i] = getreal(LIBRAW_EXIFTAG_TYPE_DOUBLE); for (i = 0; i < 256; i++) { for (tot = j = 0; j <= deg; j++) tot += coeff[j] * pow(i / 255.0, (int)j); cur[c][i] = (ushort)(tot * 0xffff); } } order = sorder; } else { gamma_curve(1 / 2.4, 12.92, 1, 255); FORC4 memcpy(cur[c], curve, sizeof cur[0]); } struct jpeg_error_mgr pub; cinfo.err = jpeg_std_error(&pub); pub.error_exit = jpegErrorExit_d; std::vector buf; jpeg_create_decompress(&cinfo); while (trow < raw_height) { fseek(ifp, save += 4, SEEK_SET); if (tile_length < INT_MAX) fseek(ifp, get4(), SEEK_SET); if (libraw_internal_data.internal_data.input->jpeg_src(&cinfo) == -1) { jpeg_destroy_decompress(&cinfo); throw LIBRAW_EXCEPTION_DECODE_JPEG; } jpeg_read_header(&cinfo, TRUE); jpeg_start_decompress(&cinfo); if (cinfo.output_components != colors) throw LIBRAW_EXCEPTION_DECODE_JPEG; if (buf.size() < cinfo.output_width * cinfo.output_components) buf = std::vector(cinfo.output_width * cinfo.output_components,0); try { JSAMPLE *buffer_array[1]; buffer_array[0] = buf.data(); while (cinfo.output_scanline < cinfo.output_height && (row = trow + cinfo.output_scanline) < height) { checkCancel(); jpeg_read_scanlines(&cinfo, buffer_array, 1); for (col = 0; col < cinfo.output_width && tcol + col < width; col++) { FORC(colors) image[row * width + tcol + col][c] = cur[c][buf[col*colors+c]]; } } } catch (...) { jpeg_destroy_decompress(&cinfo); throw; } jpeg_abort_decompress(&cinfo); if ((tcol += tile_width) >= raw_width) trow += tile_length + (tcol = 0); } jpeg_destroy_decompress(&cinfo); maximum = 0xffff; } #endif LibRaw-0.21.4/src/decoders/fp_dng.cpp000066400000000000000000000522221477673233700173240ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" inline unsigned int __DNG_HalfToFloat(ushort halfValue) { int sign = (halfValue >> 15) & 0x00000001; int exponent = (halfValue >> 10) & 0x0000001f; int mantissa = halfValue & 0x000003ff; if (exponent == 0) { if (mantissa == 0) { return (unsigned int)(sign << 31); } else { while (!(mantissa & 0x00000400)) { mantissa <<= 1; exponent -= 1; } exponent += 1; mantissa &= ~0x00000400; } } else if (exponent == 31) { if (mantissa == 0) { return (unsigned int)((sign << 31) | ((0x1eL + 127 - 15) << 23) | (0x3ffL << 13)); } else { return 0; } } exponent += (127 - 15); mantissa <<= 13; return (unsigned int)((sign << 31) | (exponent << 23) | mantissa); } inline unsigned int __DNG_FP24ToFloat(const unsigned char *input) { int sign = (input[0] >> 7) & 0x01; int exponent = (input[0]) & 0x7F; int mantissa = (((int)input[1]) << 8) | input[2]; if (exponent == 0) { if (mantissa == 0) { return (unsigned int)(sign << 31); } else { while (!(mantissa & 0x00010000)) { mantissa <<= 1; exponent -= 1; } exponent += 1; mantissa &= ~0x00010000; } } else if (exponent == 127) { if (mantissa == 0) { return (unsigned int)((sign << 31) | ((0x7eL + 128 - 64) << 23) | (0xffffL << 7)); } else { // Nan -- Just set to zero. return 0; } } exponent += (128 - 64); mantissa <<= 7; return (uint32_t)((sign << 31) | (exponent << 23) | mantissa); } inline void DecodeDeltaBytes(unsigned char *bytePtr, int cols, int channels) { if (channels == 1) { unsigned char b0 = bytePtr[0]; bytePtr += 1; for (int col = 1; col < cols; ++col) { b0 += bytePtr[0]; bytePtr[0] = b0; bytePtr += 1; } } else if (channels == 3) { unsigned char b0 = bytePtr[0]; unsigned char b1 = bytePtr[1]; unsigned char b2 = bytePtr[2]; bytePtr += 3; for (int col = 1; col < cols; ++col) { b0 += bytePtr[0]; b1 += bytePtr[1]; b2 += bytePtr[2]; bytePtr[0] = b0; bytePtr[1] = b1; bytePtr[2] = b2; bytePtr += 3; } } else if (channels == 4) { unsigned char b0 = bytePtr[0]; unsigned char b1 = bytePtr[1]; unsigned char b2 = bytePtr[2]; unsigned char b3 = bytePtr[3]; bytePtr += 4; for (int col = 1; col < cols; ++col) { b0 += bytePtr[0]; b1 += bytePtr[1]; b2 += bytePtr[2]; b3 += bytePtr[3]; bytePtr[0] = b0; bytePtr[1] = b1; bytePtr[2] = b2; bytePtr[3] = b3; bytePtr += 4; } } else { for (int col = 1; col < cols; ++col) { for (int chan = 0; chan < channels; ++chan) { bytePtr[chan + channels] += bytePtr[chan]; } bytePtr += channels; } } } #ifdef USE_ZLIB static void DecodeFPDelta(unsigned char *input, unsigned char *output, int cols, int channels, int bytesPerSample) { DecodeDeltaBytes(input, cols * bytesPerSample, channels); int32_t rowIncrement = cols * channels; if (bytesPerSample == 2) { #if LibRawBigEndian const unsigned char *input0 = input; const unsigned char *input1 = input + rowIncrement; #else const unsigned char *input1 = input; const unsigned char *input0 = input + rowIncrement; #endif for (int col = 0; col < rowIncrement; ++col) { output[0] = input0[col]; output[1] = input1[col]; output += 2; } } else if (bytesPerSample == 3) { const unsigned char *input0 = input; const unsigned char *input1 = input + rowIncrement; const unsigned char *input2 = input + rowIncrement * 2; for (int col = 0; col < rowIncrement; ++col) { output[0] = input0[col]; output[1] = input1[col]; output[2] = input2[col]; output += 3; } } else { #if LibRawBigEndian const unsigned char *input0 = input; const unsigned char *input1 = input + rowIncrement; const unsigned char *input2 = input + rowIncrement * 2; const unsigned char *input3 = input + rowIncrement * 3; #else const unsigned char *input3 = input; const unsigned char *input2 = input + rowIncrement; const unsigned char *input1 = input + rowIncrement * 2; const unsigned char *input0 = input + rowIncrement * 3; #endif for (int col = 0; col < rowIncrement; ++col) { output[0] = input0[col]; output[1] = input1[col]; output[2] = input2[col]; output[3] = input3[col]; output += 4; } } } #endif static float expandFloats(unsigned char *dst, int tileWidth, int bytesps) { float max = 0.f; if (bytesps == 2) { uint16_t *dst16 = (ushort *)dst; uint32_t *dst32 = (unsigned int *)dst; float *f32 = (float *)dst; for (int index = tileWidth - 1; index >= 0; --index) { dst32[index] = __DNG_HalfToFloat(dst16[index]); max = MAX(max, f32[index]); } } else if (bytesps == 3) { uint8_t *dst8 = ((unsigned char *)dst) + (tileWidth - 1) * 3; uint32_t *dst32 = (unsigned int *)dst; float *f32 = (float *)dst; for (int index = tileWidth - 1; index >= 0; --index, dst8 -= 3) { dst32[index] = __DNG_FP24ToFloat(dst8); max = MAX(max, f32[index]); } } else if (bytesps == 4) { float *f32 = (float *)dst; for (int index = 0; index < tileWidth; index++) max = MAX(max, f32[index]); } return max; } struct tile_stripe_data_t { bool tiled, striped; int tileCnt; unsigned tileWidth, tileHeight, tilesH, tilesV; size_t maxBytesInTile; std::vector tOffsets, tBytes; tile_stripe_data_t() : tiled(false), striped(false),tileCnt(0), tileWidth(0),tileHeight(0),tilesH(0),tilesV(0), maxBytesInTile(0){} void init(tiff_ifd_t *ifd, const libraw_image_sizes_t&, const unpacker_data_t&, short _order, LibRaw_abstract_datastream *stream); }; static unsigned static_get4(LibRaw_abstract_datastream *stream, short _order) { uchar str[4] = { 0xff, 0xff, 0xff, 0xff }; stream->read(str, 1, 4); return libraw_sget4_static(_order, str); } void tile_stripe_data_t::init(tiff_ifd_t *ifd, const libraw_image_sizes_t& sizes, const unpacker_data_t& unpacker_data, short _order, LibRaw_abstract_datastream *stream) { tiled = (unpacker_data.tile_width <= sizes.raw_width) && (unpacker_data.tile_length <= sizes.raw_height); striped = (ifd->rows_per_strip > 0 && ifd->rows_per_strip < sizes.raw_height) && ifd->strip_byte_counts_count > 0; tileWidth = tiled ? unpacker_data.tile_width : sizes.raw_width; tileHeight = tiled ? unpacker_data.tile_length :(striped ? ifd->rows_per_strip : sizes.raw_height); tilesH = tiled ? (sizes.raw_width + tileWidth - 1) / tileWidth : 1; tilesV = tiled ? (sizes.raw_height + tileHeight - 1) / tileHeight : (striped ? ((sizes.raw_height + ifd->rows_per_strip - 1) / ifd->rows_per_strip) : 1); tileCnt = tilesH * tilesV; if (tileCnt < 1 || tileCnt > 1000000) throw LIBRAW_EXCEPTION_DECODE_RAW; tOffsets = std::vector(tileCnt,0); tBytes = std::vector (tileCnt,0); if (tiled) for (int t = 0; t < tileCnt; ++t) tOffsets[t] = static_get4(stream, _order); else if (striped) for (int t = 0; t < tileCnt && t < ifd->strip_offsets_count; ++t) tOffsets[t] = ifd->strip_offsets[t]; else tOffsets[0] = ifd->offset; maxBytesInTile = 0; if (tileCnt == 1 || (!tiled && !striped)) tBytes[0] = maxBytesInTile = ifd->bytes; else if (tiled) { // ifd->bytes points to tile size table if more than 1 tile exists stream->seek(ifd->bytes, SEEK_SET); for (int t = 0; t < tileCnt; ++t) { tBytes[t] = static_get4(stream, _order); ; maxBytesInTile = MAX(maxBytesInTile, tBytes[t]); } } else if (striped) for (int t = 0; t < tileCnt && t < ifd->strip_byte_counts_count; ++t) { tBytes[t] = ifd->strip_byte_counts[t]; maxBytesInTile = MAX(maxBytesInTile, tBytes[t]); } } #ifdef USE_ZLIB void LibRaw::deflate_dng_load_raw() { int iifd = find_ifd_by_offset(libraw_internal_data.unpacker_data.data_offset); if(iifd < 0 || iifd > (int)libraw_internal_data.identify_data.tiff_nifds) throw LIBRAW_EXCEPTION_DECODE_RAW; struct tiff_ifd_t *ifd = &tiff_ifd[iifd]; float *float_raw_image = 0; float max = 0.f; if (ifd->samples != 1 && ifd->samples != 3 && ifd->samples != 4) throw LIBRAW_EXCEPTION_DECODE_RAW; if (libraw_internal_data.unpacker_data.tiff_samples != (unsigned)ifd->samples) throw LIBRAW_EXCEPTION_DECODE_RAW; // Wrong IFD if (imgdata.idata.filters && ifd->samples > 1) throw LIBRAW_EXCEPTION_DECODE_RAW; tile_stripe_data_t tiles; tiles.init(ifd, imgdata.sizes, libraw_internal_data.unpacker_data, libraw_internal_data.unpacker_data.order, libraw_internal_data.internal_data.input); if (ifd->sample_format == 3) float_raw_image = (float *)calloc(tiles.tileCnt * tiles.tileWidth * tiles.tileHeight *ifd->samples, sizeof(float)); else throw LIBRAW_EXCEPTION_DECODE_RAW; // Only float deflated supported int xFactor; switch (ifd->predictor) { case 3: default: xFactor = 1; break; case 34894: xFactor = 2; break; case 34895: xFactor = 4; break; } unsigned tilePixels = tiles.tileWidth * tiles.tileHeight; unsigned pixelSize = sizeof(float) * ifd->samples; unsigned tileBytes = tilePixels * pixelSize; unsigned tileRowBytes = tiles.tileWidth * pixelSize; if(INT64(tiles.maxBytesInTile) > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024) ) throw LIBRAW_EXCEPTION_TOOBIG; std::vector cBuffer(tiles.maxBytesInTile,0); std::vector uBuffer(tileBytes + tileRowBytes,0); // extra row for decoding for (size_t y = 0, t = 0; y < imgdata.sizes.raw_height; y += tiles.tileHeight) { for (size_t x = 0; x < imgdata.sizes.raw_width; x += tiles.tileWidth, ++t) { libraw_internal_data.internal_data.input->seek(tiles.tOffsets[t], SEEK_SET); libraw_internal_data.internal_data.input->read(cBuffer.data(), 1, tiles.tBytes[t]); unsigned long dstLen = tileBytes; int err = uncompress(uBuffer.data() + tileRowBytes, &dstLen, cBuffer.data(), (unsigned long)tiles.tBytes[t]); if (err != Z_OK) { throw LIBRAW_EXCEPTION_DECODE_RAW; return; } else { int bytesps = ifd->bps >> 3; size_t rowsInTile = y + tiles.tileHeight > imgdata.sizes.raw_height ? imgdata.sizes.raw_height - y : tiles.tileHeight; size_t colsInTile = x + tiles.tileWidth > imgdata.sizes.raw_width ? imgdata.sizes.raw_width - x : tiles.tileWidth; for (size_t row = 0; row < rowsInTile; ++row) // do not process full tile if not needed { unsigned char *dst = uBuffer.data() + row * tiles.tileWidth * bytesps * ifd->samples; unsigned char *src = dst + tileRowBytes; DecodeFPDelta(src, dst, tiles.tileWidth / xFactor, ifd->samples * xFactor, bytesps); float lmax = expandFloats(dst, tiles.tileWidth * ifd->samples, bytesps); max = MAX(max, lmax); unsigned char *dst2 = (unsigned char *)&float_raw_image [((y + row) * imgdata.sizes.raw_width + x) * ifd->samples]; memmove(dst2, dst, colsInTile * ifd->samples * sizeof(float)); } } } } imgdata.color.fmaximum = max; // Set fields according to data format imgdata.rawdata.raw_alloc = float_raw_image; if (ifd->samples == 1) { imgdata.rawdata.float_image = float_raw_image; imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 4; } else if (ifd->samples == 3) { imgdata.rawdata.float3_image = (float(*)[3])float_raw_image; imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 12; } else if (ifd->samples == 4) { imgdata.rawdata.float4_image = (float(*)[4])float_raw_image; imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 16; } if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT) convertFloatToInt(); // with default settings } #else void LibRaw::deflate_dng_load_raw() { throw LIBRAW_EXCEPTION_DECODE_RAW; } #endif int LibRaw::is_floating_point() { struct tiff_ifd_t *ifd = &tiff_ifd[0]; while (ifd < &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds] && ifd->offset != libraw_internal_data.unpacker_data.data_offset) ++ifd; if (ifd == &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds]) return 0; return ifd->sample_format == 3; } int LibRaw::have_fpdata() { return imgdata.rawdata.float_image || imgdata.rawdata.float3_image || imgdata.rawdata.float4_image; } void LibRaw::convertFloatToInt(float dmin /* =4096.f */, float dmax /* =32767.f */, float dtarget /*= 16383.f */) { int samples = 0; float *data = 0; void *orawalloc = imgdata.rawdata.raw_alloc; if (imgdata.rawdata.float_image) { samples = 1; data = imgdata.rawdata.float_image; } else if (imgdata.rawdata.float3_image) { samples = 3; data = (float *)imgdata.rawdata.float3_image; } else if (imgdata.rawdata.float4_image) { samples = 4; data = (float *)imgdata.rawdata.float4_image; } else return; ushort *raw_alloc = (ushort *)malloc( imgdata.sizes.raw_height * imgdata.sizes.raw_width * libraw_internal_data.unpacker_data.tiff_samples * sizeof(ushort)); float tmax = MAX(imgdata.color.maximum, 1); float datamax = imgdata.color.fmaximum; tmax = MAX(tmax, datamax); tmax = MAX(tmax, 1.f); float multip = 1.f; if (tmax < dmin || tmax > dmax) { imgdata.rawdata.color.fnorm = imgdata.color.fnorm = multip = dtarget / tmax; imgdata.rawdata.color.maximum = imgdata.color.maximum = dtarget; imgdata.rawdata.color.black = imgdata.color.black = (float)imgdata.color.black * multip; for (int i = 0; i < int(sizeof(imgdata.color.cblack)/sizeof(imgdata.color.cblack[0])); i++) if (i != 4 && i != 5) imgdata.rawdata.color.cblack[i] = imgdata.color.cblack[i] = (float)imgdata.color.cblack[i] * multip; } else imgdata.rawdata.color.fnorm = imgdata.color.fnorm = 0.f; for (size_t i = 0; i < imgdata.sizes.raw_height * imgdata.sizes.raw_width * libraw_internal_data.unpacker_data.tiff_samples; ++i) { float val = MAX(data[i], 0.f); raw_alloc[i] = (ushort)(val * multip); } if (samples == 1) { imgdata.rawdata.raw_alloc = imgdata.rawdata.raw_image = raw_alloc; imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 2; } else if (samples == 3) { imgdata.rawdata.raw_alloc = imgdata.rawdata.color3_image = (ushort(*)[3])raw_alloc; imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 6; } else if (samples == 4) { imgdata.rawdata.raw_alloc = imgdata.rawdata.color4_image = (ushort(*)[4])raw_alloc; imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 8; } if(orawalloc) free(orawalloc); // remove old allocation imgdata.rawdata.float_image = 0; imgdata.rawdata.float3_image = 0; imgdata.rawdata.float4_image = 0; } static #if (defined(_MSC_VER) && !defined(__clang__)) _forceinline #else inline #endif void libraw_swap24(uchar *data, int len) { for (int i = 0; i < len - 2; i += 3) { uchar t = data[i]; data[i] = data[i + 2]; data[i + 2] = t; } } static #if (defined(_MSC_VER) && !defined(__clang__)) _forceinline #else inline #endif void libraw_swap32(uchar *data, int len) { unsigned *d = (unsigned*)data; for (int i = 0; i < len / 4; i++) { unsigned x = d[i]; d[i] = (x << 24) + ((x << 8) & 0x00FF0000) + ((x >> 8) & 0x0000FF00) + (x >> 24); } } void LibRaw::uncompressed_fp_dng_load_raw() { int iifd = find_ifd_by_offset(libraw_internal_data.unpacker_data.data_offset); if (iifd < 0 || iifd > (int)libraw_internal_data.identify_data.tiff_nifds) throw LIBRAW_EXCEPTION_DECODE_RAW; struct tiff_ifd_t *ifd = &tiff_ifd[iifd]; float *float_raw_image = 0; if (ifd->samples != 1 && ifd->samples != 3 && ifd->samples != 4) throw LIBRAW_EXCEPTION_DECODE_RAW; if(imgdata.idata.filters && ifd->samples > 1) throw LIBRAW_EXCEPTION_DECODE_RAW; if ((int)libraw_internal_data.unpacker_data.tiff_samples != ifd->samples) throw LIBRAW_EXCEPTION_DECODE_RAW; // Wrong IFD int bytesps = (ifd->bps + 7) >> 3; // round to upper value if(bytesps < 1 || bytesps > 4) throw LIBRAW_EXCEPTION_DECODE_RAW; tile_stripe_data_t tiles; tiles.init(ifd, imgdata.sizes, libraw_internal_data.unpacker_data, libraw_internal_data.unpacker_data.order, libraw_internal_data.internal_data.input); INT64 allocsz = INT64(tiles.tileCnt) * INT64(tiles.tileWidth) * INT64(tiles.tileHeight) * INT64(ifd->samples) * INT64(sizeof(float)); if (allocsz > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) throw LIBRAW_EXCEPTION_TOOBIG; if (ifd->sample_format == 3) float_raw_image = (float *)calloc(tiles.tileCnt * tiles.tileWidth * tiles.tileHeight *ifd->samples, sizeof(float)); else throw LIBRAW_EXCEPTION_DECODE_RAW; // Only float supported bool difford = (libraw_internal_data.unpacker_data.order == 0x4949) == (ntohs(0x1234) == 0x1234); float max = 0.f; std::vector rowbuf(tiles.tileWidth *sizeof(float) * ifd->samples,0); // line buffer for last tile in tile row for (size_t y = 0, t = 0; y < imgdata.sizes.raw_height; y += tiles.tileHeight) { for (unsigned x = 0; x < imgdata.sizes.raw_width && t < (unsigned)tiles.tileCnt; x += tiles.tileWidth, ++t) { libraw_internal_data.internal_data.input->seek(tiles.tOffsets[t], SEEK_SET); size_t rowsInTile = y + tiles.tileHeight > imgdata.sizes.raw_height ? imgdata.sizes.raw_height - y : tiles.tileHeight; size_t colsInTile = x + tiles.tileWidth > imgdata.sizes.raw_width ? imgdata.sizes.raw_width - x : tiles.tileWidth; size_t inrowbytes = colsInTile * bytesps * ifd->samples; int fullrowbytes = tiles.tileWidth *bytesps * ifd->samples; size_t outrowbytes = colsInTile * sizeof(float) * ifd->samples; for (size_t row = 0; row < rowsInTile; ++row) // do not process full tile if not needed { unsigned char *dst = fullrowbytes > inrowbytes ? rowbuf.data(): // last tile in row, use buffer (unsigned char *)&float_raw_image [((y + row) * imgdata.sizes.raw_width + x) * ifd->samples]; libraw_internal_data.internal_data.input->read(dst, 1, fullrowbytes); if (bytesps == 2 && difford) libraw_swab(dst, fullrowbytes); else if (bytesps == 3 && (libraw_internal_data.unpacker_data.order == 0x4949)) // II-16bit libraw_swap24(dst, fullrowbytes); if (bytesps == 4 && difford) libraw_swap32(dst, fullrowbytes); float lmax = expandFloats( dst, tiles.tileWidth * ifd->samples, bytesps); if (fullrowbytes > inrowbytes) // last tile in row: copy buffer to destination memmove(&float_raw_image[((y + row) * imgdata.sizes.raw_width + x) * ifd->samples], dst, outrowbytes); max = MAX(max, lmax); } } } imgdata.color.fmaximum = max; // setup outpuf fields imgdata.rawdata.raw_alloc = float_raw_image; if (ifd->samples == 1) { imgdata.rawdata.float_image = float_raw_image; imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 4; } else if (ifd->samples == 3) { imgdata.rawdata.float3_image = (float(*)[3])float_raw_image; imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 12; } else if (ifd->samples == 4) { imgdata.rawdata.float4_image = (float(*)[4])float_raw_image; imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 16; } if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT) convertFloatToInt(); } LibRaw-0.21.4/src/decoders/fuji_compressed.cpp000066400000000000000000001147201477673233700212520ustar00rootroot00000000000000/* -*- C++ -*- * File: libraw_fuji_compressed.cpp * Copyright (C) 2016-2019 Alexey Danilchenko * * Adopted to LibRaw by Alex Tutubalin, lexa@lexa.ru * LibRaw Fujifilm/compressed decoder 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 "../../internal/libraw_cxx_defs.h" #ifdef _abs #undef _abs #undef _min #undef _max #endif #define _abs(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) #define _min(a, b) ((a) < (b) ? (a) : (b)) #define _max(a, b) ((a) > (b) ? (a) : (b)) struct int_pair { int value1; int value2; }; enum _xt_lines { _R0 = 0, _R1, _R2, _R3, _R4, _G0, _G1, _G2, _G3, _G4, _G5, _G6, _G7, _B0, _B1, _B2, _B3, _B4, _ltotal }; // tables of gradients for single sample level struct fuji_grads { int_pair grads[41]; int_pair lossy_grads[3][5]; }; struct fuji_compressed_block { int cur_bit; // current bit being read (from left to right) int cur_pos; // current position in a buffer INT64 cur_buf_offset; // offset of this buffer in a file unsigned max_read_size; // Amount of data to be read int cur_buf_size; // buffer size uchar *cur_buf; // currently read block int fillbytes; // Counter to add extra byte for block size N*16 LibRaw_abstract_datastream *input; fuji_grads even[3]; // tables of even gradients fuji_grads odd[3]; // tables of odd gradients ushort *linealloc; ushort *linebuf[_ltotal]; }; static inline int log2ceil(int val) { int result = 0; if (val--) do ++result; while (val >>= 1); return result; } void setup_qlut(int8_t *qt, int *q_point) { for (int curVal = -q_point[4]; curVal <= q_point[4]; ++qt, ++curVal) { if (curVal <= -q_point[3]) *qt = -4; else if (curVal <= -q_point[2]) *qt = -3; else if (curVal <= -q_point[1]) *qt = -2; else if (curVal < -q_point[0]) *qt = -1; else if (curVal <= q_point[0]) *qt = 0; else if (curVal < q_point[1]) *qt = 1; else if (curVal < q_point[2]) *qt = 2; else if (curVal < q_point[3]) *qt = 3; else *qt = 4; } } void init_main_qtable(fuji_compressed_params *params, uchar q_base) { fuji_q_table *qt = params->qt; int qp[5]; int maxVal = params->max_value + 1; qp[0] = q_base; qp[1] = 3 * q_base + 0x12; qp[2] = 5 * q_base + 0x43; qp[3] = 7 * q_base + 0x114; qp[4] = params->max_value; if (qp[1] >= maxVal || qp[1] < q_base + 1) qp[1] = q_base + 1; if (qp[2] < qp[1] || qp[2] >= maxVal) qp[2] = qp[1]; if (qp[3] < qp[2] || qp[3] >= maxVal) qp[3] = qp[2]; setup_qlut(qt->q_table, qp); qt->q_base = q_base; qt->max_grad = 0; qt->total_values = (qp[4] + 2 * q_base) / (2 * q_base + 1) + 1; qt->raw_bits = log2ceil(qt->total_values); qt->q_grad_mult = 9; params->max_bits = 4 * log2ceil(qp[4] + 1); } void LibRaw::init_fuji_compr(fuji_compressed_params *params) { if ((libraw_internal_data.unpacker_data.fuji_block_width % 3 && libraw_internal_data.unpacker_data.fuji_raw_type == 16) || (libraw_internal_data.unpacker_data.fuji_block_width & 1 && libraw_internal_data.unpacker_data.fuji_raw_type == 0)) derror(); size_t q_table_size = 2 << libraw_internal_data.unpacker_data.fuji_bits; if (libraw_internal_data.unpacker_data.fuji_lossless) params->buf = malloc(q_table_size); else params->buf = malloc(3 * q_table_size); if (libraw_internal_data.unpacker_data.fuji_raw_type == 16) params->line_width = (libraw_internal_data.unpacker_data.fuji_block_width * 2) / 3; else params->line_width = libraw_internal_data.unpacker_data.fuji_block_width >> 1; params->min_value = 0x40; params->max_value = (1 << libraw_internal_data.unpacker_data.fuji_bits) - 1; // setup qtables if (libraw_internal_data.unpacker_data.fuji_lossless) { // setup main qtable only, zero the rest memset(params->qt + 1, 0, 3 * sizeof(fuji_q_table)); params->qt[0].q_table = (int8_t *)params->buf; params->qt[0].q_base = -1; init_main_qtable(params, 0); } else { // setup 3 extra qtables - main one will be set for each block memset(params->qt, 0, sizeof(fuji_q_table)); int qp[5]; qp[0] = 0; qp[4] = params->max_value; // table 0 params->qt[1].q_table = (int8_t *)params->buf; params->qt[1].q_base = 0; params->qt[1].max_grad = 5; params->qt[1].q_grad_mult = 3; params->qt[1].total_values = qp[4] + 1; params->qt[1].raw_bits = log2ceil(params->qt[1].total_values); qp[1] = qp[4] >= 0x12 ? 0x12 : qp[0] + 1; qp[2] = qp[4] >= 0x43 ? 0x43 : qp[1]; qp[3] = qp[4] >= 0x114 ? 0x114 : qp[2]; setup_qlut(params->qt[1].q_table, qp); // table 1 params->qt[2].q_table = params->qt[1].q_table + q_table_size; params->qt[2].q_base = 1; params->qt[2].max_grad = 6; params->qt[2].q_grad_mult = 3; params->qt[2].total_values = (qp[4] + 2) / 3 + 1; params->qt[2].raw_bits = log2ceil(params->qt[2].total_values); qp[0] = params->qt[2].q_base; qp[1] = qp[4] >= 0x15 ? 0x15 : qp[0] + 1; qp[2] = qp[4] >= 0x48 ? 0x48 : qp[1]; qp[3] = qp[4] >= 0x11B ? 0x11B : qp[2]; setup_qlut(params->qt[2].q_table, qp); // table 2 params->qt[3].q_table = params->qt[2].q_table + q_table_size; params->qt[3].q_base = 2; params->qt[3].max_grad = 7; params->qt[3].q_grad_mult = 3; params->qt[3].total_values = (qp[4] + 4) / 5 + 1; params->qt[3].raw_bits = log2ceil(params->qt[3].total_values); qp[0] = params->qt[3].q_base; qp[1] = qp[4] >= 0x18 ? 0x18 : qp[0] + 1; qp[2] = qp[4] >= 0x4D ? 0x4D : qp[1]; qp[3] = qp[4] >= 0x122 ? 0x122 : qp[2]; setup_qlut(params->qt[3].q_table, qp); } } #define XTRANS_BUF_SIZE 0x10000 static inline void fuji_fill_buffer(fuji_compressed_block *info) { if (info->cur_pos >= info->cur_buf_size) { info->cur_pos = 0; info->cur_buf_offset += info->cur_buf_size; #ifdef LIBRAW_USE_OPENMP #pragma omp critical #endif { #ifndef LIBRAW_USE_OPENMP info->input->lock(); #endif info->input->seek(info->cur_buf_offset, SEEK_SET); info->cur_buf_size = info->input->read(info->cur_buf, 1, _min(info->max_read_size, XTRANS_BUF_SIZE)); #ifndef LIBRAW_USE_OPENMP info->input->unlock(); #endif if (info->cur_buf_size < 1) // nothing read { if (info->fillbytes > 0) { int ls = _max(1, _min(info->fillbytes, XTRANS_BUF_SIZE)); memset(info->cur_buf, 0, ls); info->fillbytes -= ls; } else throw LIBRAW_EXCEPTION_IO_EOF; } info->max_read_size -= info->cur_buf_size; } } } void init_main_grads(const fuji_compressed_params *params, fuji_compressed_block *info) { int max_diff = _max(2, (params->qt->total_values + 0x20) >> 6); for (int j = 0; j < 3; j++) for (int i = 0; i < 41; i++) { info->even[j].grads[i].value1 = max_diff; info->even[j].grads[i].value2 = 1; info->odd[j].grads[i].value1 = max_diff; info->odd[j].grads[i].value2 = 1; } } void LibRaw::init_fuji_block(fuji_compressed_block *info, const fuji_compressed_params *params, INT64 raw_offset, unsigned dsize) { info->linealloc = (ushort *)calloc(sizeof(ushort), _ltotal * (params->line_width + 2)); INT64 fsize = libraw_internal_data.internal_data.input->size(); info->max_read_size = _min(unsigned(fsize - raw_offset), dsize); // Data size may be incorrect? info->fillbytes = 1; info->input = libraw_internal_data.internal_data.input; info->linebuf[_R0] = info->linealloc; for (int i = _R1; i <= _B4; i++) info->linebuf[i] = info->linebuf[i - 1] + params->line_width + 2; // init buffer info->cur_buf = (uchar *)malloc(XTRANS_BUF_SIZE); info->cur_bit = 0; info->cur_pos = 0; info->cur_buf_offset = raw_offset; info->cur_buf_size = 0; fuji_fill_buffer(info); // init grads for lossy and lossless if (libraw_internal_data.unpacker_data.fuji_lossless) init_main_grads(params, info); else { // init static grads for lossy only - main ones are done per line for (int k = 0; k < 3; ++k) { int max_diff = _max(2, ((params->qt[k + 1].total_values + 0x20) >> 6)); for (int j = 0; j < 3; ++j) for (int i = 0; i < 5; ++i) { info->even[j].lossy_grads[k][i].value1 = max_diff; info->even[j].lossy_grads[k][i].value2 = 1; info->odd[j].lossy_grads[k][i].value1 = max_diff; info->odd[j].lossy_grads[k][i].value2 = 1; } } } } void LibRaw::copy_line_to_xtrans(fuji_compressed_block *info, int cur_line, int cur_block, int cur_block_width) { ushort *lineBufB[3]; ushort *lineBufG[6]; ushort *lineBufR[3]; unsigned pixel_count; ushort *line_buf; int index; int offset = libraw_internal_data.unpacker_data.fuji_block_width * cur_block + 6 * imgdata.sizes.raw_width * cur_line; ushort *raw_block_data = imgdata.rawdata.raw_image + offset; int row_count = 0; for (int i = 0; i < 3; i++) { lineBufR[i] = info->linebuf[_R2 + i] + 1; lineBufB[i] = info->linebuf[_B2 + i] + 1; } for (int i = 0; i < 6; i++) lineBufG[i] = info->linebuf[_G2 + i] + 1; while (row_count < 6) { pixel_count = 0; while (pixel_count < (unsigned)cur_block_width) { switch (imgdata.idata.xtrans_abs[row_count][(pixel_count % 6)]) { case 0: // red line_buf = lineBufR[row_count >> 1]; break; case 1: // green default: // to make static analyzer happy line_buf = lineBufG[row_count]; break; case 2: // blue line_buf = lineBufB[row_count >> 1]; break; } index = (((pixel_count * 2 / 3) & 0x7FFFFFFE) | ((pixel_count % 3) & 1)) + ((pixel_count % 3) >> 1); raw_block_data[pixel_count] = line_buf[index]; ++pixel_count; } ++row_count; raw_block_data += imgdata.sizes.raw_width; } } void LibRaw::copy_line_to_bayer(fuji_compressed_block *info, int cur_line, int cur_block, int cur_block_width) { ushort *lineBufB[3]; ushort *lineBufG[6]; ushort *lineBufR[3]; unsigned pixel_count; ushort *line_buf; int fuji_bayer[2][2]; for (int r = 0; r < 2; r++) for (int c = 0; c < 2; c++) fuji_bayer[r][c] = FC(r, c); // We'll downgrade G2 to G below int offset = libraw_internal_data.unpacker_data.fuji_block_width * cur_block + 6 * imgdata.sizes.raw_width * cur_line; ushort *raw_block_data = imgdata.rawdata.raw_image + offset; int row_count = 0; for (int i = 0; i < 3; i++) { lineBufR[i] = info->linebuf[_R2 + i] + 1; lineBufB[i] = info->linebuf[_B2 + i] + 1; } for (int i = 0; i < 6; i++) lineBufG[i] = info->linebuf[_G2 + i] + 1; while (row_count < 6) { pixel_count = 0; while (pixel_count < (unsigned)cur_block_width) { switch (fuji_bayer[row_count & 1][pixel_count & 1]) { case 0: // red line_buf = lineBufR[row_count >> 1]; break; case 1: // green case 3: // second green default: // to make static analyzer happy line_buf = lineBufG[row_count]; break; case 2: // blue line_buf = lineBufB[row_count >> 1]; break; } raw_block_data[pixel_count] = line_buf[pixel_count >> 1]; ++pixel_count; } ++row_count; raw_block_data += imgdata.sizes.raw_width; } } #define fuji_quant_gradient(max, q, v1, v2) (q->q_grad_mult * q->q_table[(max) + (v1)] + q->q_table[(max) + (v2)]) static inline void fuji_zerobits(fuji_compressed_block *info, int *count) { uchar zero = 0; *count = 0; while (zero == 0) { zero = (info->cur_buf[info->cur_pos] >> (7 - info->cur_bit)) & 1; info->cur_bit++; info->cur_bit &= 7; if (!info->cur_bit) { ++info->cur_pos; fuji_fill_buffer(info); } if (zero) break; ++*count; } } static inline void fuji_read_code(fuji_compressed_block *info, int *data, int bits_to_read) { uchar bits_left = bits_to_read; uchar bits_left_in_byte = 8 - (info->cur_bit & 7); *data = 0; if (!bits_to_read) return; if (bits_to_read >= bits_left_in_byte) { do { *data <<= bits_left_in_byte; bits_left -= bits_left_in_byte; *data |= info->cur_buf[info->cur_pos] & ((1 << bits_left_in_byte) - 1); ++info->cur_pos; fuji_fill_buffer(info); bits_left_in_byte = 8; } while (bits_left >= 8); } if (!bits_left) { info->cur_bit = (8 - (bits_left_in_byte & 7)) & 7; return; } *data <<= bits_left; bits_left_in_byte -= bits_left; *data |= ((1 << bits_left) - 1) & ((unsigned)info->cur_buf[info->cur_pos] >> bits_left_in_byte); info->cur_bit = (8 - (bits_left_in_byte & 7)) & 7; } static inline int bitDiff(int value1, int value2) { int decBits = 0; if (value2 < value1) while (decBits <= 14 && (value2 << ++decBits) < value1) ; return decBits; } static inline int fuji_decode_sample_even(fuji_compressed_block *info, const fuji_compressed_params *params, ushort *line_buf, int pos, fuji_grads *grad_params) { int interp_val = 0; // ushort decBits; int errcnt = 0; int sample = 0, code = 0; ushort *line_buf_cur = line_buf + pos; int Rb = line_buf_cur[-2 - params->line_width]; int Rc = line_buf_cur[-3 - params->line_width]; int Rd = line_buf_cur[-1 - params->line_width]; int Rf = line_buf_cur[-4 - 2 * params->line_width]; int grad, gradient, diffRcRb, diffRfRb, diffRdRb; diffRcRb = _abs(Rc - Rb); diffRfRb = _abs(Rf - Rb); diffRdRb = _abs(Rd - Rb); const fuji_q_table *qt = params->qt; int_pair *grads = grad_params->grads; for (int i = 1; params->qt[0].q_base >= i && i < 4; ++i) if (diffRfRb + diffRcRb <= params->qt[i].max_grad) { qt = params->qt + i; grads = grad_params->lossy_grads[i - 1]; break; } grad = fuji_quant_gradient(params->max_value, qt, Rb - Rf, Rc - Rb); gradient = _abs(grad); if (diffRcRb > diffRfRb && diffRcRb > diffRdRb) interp_val = Rf + Rd + 2 * Rb; else if (diffRdRb > diffRcRb && diffRdRb > diffRfRb) interp_val = Rf + Rc + 2 * Rb; else interp_val = Rd + Rc + 2 * Rb; fuji_zerobits(info, &sample); if (sample < params->max_bits - qt->raw_bits - 1) { int decBits = bitDiff(grads[gradient].value1, grads[gradient].value2); fuji_read_code(info, &code, decBits); code += sample << decBits; } else { fuji_read_code(info, &code, qt->raw_bits); ++code; } if (code < 0 || code >= qt->total_values) ++errcnt; if (code & 1) code = -1 - code / 2; else code /= 2; grads[gradient].value1 += _abs(code); if (grads[gradient].value2 == params->min_value) { grads[gradient].value1 >>= 1; grads[gradient].value2 >>= 1; } ++grads[gradient].value2; if (grad < 0) interp_val = (interp_val >> 2) - code * (2 * qt->q_base + 1); else interp_val = (interp_val >> 2) + code * (2 * qt->q_base + 1); if (interp_val < -qt->q_base) interp_val += qt->total_values * (2 * qt->q_base + 1); else if (interp_val > qt->q_base + params->max_value) interp_val -= qt->total_values * (2 * qt->q_base + 1); if (interp_val >= 0) line_buf_cur[0] = _min(interp_val, params->max_value); else line_buf_cur[0] = 0; return errcnt; } static inline int fuji_decode_sample_odd(fuji_compressed_block *info, const fuji_compressed_params *params, ushort *line_buf, int pos, fuji_grads *grad_params) { int interp_val = 0; int errcnt = 0; int sample = 0, code = 0; ushort *line_buf_cur = line_buf + pos; int Ra = line_buf_cur[-1]; int Rb = line_buf_cur[-2 - params->line_width]; int Rc = line_buf_cur[-3 - params->line_width]; int Rd = line_buf_cur[-1 - params->line_width]; int Rg = line_buf_cur[1]; int grad, gradient; int diffRcRa = _abs(Rc - Ra); int diffRbRc = _abs(Rb - Rc); const fuji_q_table *qt = params->qt; int_pair *grads = grad_params->grads; for (int i = 1; params->qt[0].q_base >= i && i < 4; ++i) if (diffRbRc + diffRcRa <= params->qt[i].max_grad) { qt = params->qt + i; grads = grad_params->lossy_grads[i - 1]; break; } grad = fuji_quant_gradient(params->max_value, qt, Rb - Rc, Rc - Ra); gradient = _abs(grad); if ((Rb > Rc && Rb > Rd) || (Rb < Rc && Rb < Rd)) interp_val = (Rg + Ra + 2 * Rb) >> 2; else interp_val = (Ra + Rg) >> 1; fuji_zerobits(info, &sample); if (sample < params->max_bits - qt->raw_bits - 1) { int decBits = bitDiff(grads[gradient].value1, grads[gradient].value2); fuji_read_code(info, &code, decBits); code += sample << decBits; } else { fuji_read_code(info, &code, qt->raw_bits); ++code; } if (code < 0 || code >= qt->total_values) ++errcnt; if (code & 1) code = -1 - code / 2; else code /= 2; grads[gradient].value1 += _abs(code); if (grads[gradient].value2 == params->min_value) { grads[gradient].value1 >>= 1; grads[gradient].value2 >>= 1; } ++grads[gradient].value2; if (grad < 0) interp_val -= code * (2 * qt->q_base + 1); else interp_val += code * (2 * qt->q_base + 1); if (interp_val < -qt->q_base) interp_val += qt->total_values * (2 * qt->q_base + 1); else if (interp_val > qt->q_base + params->max_value) interp_val -= qt->total_values * (2 * qt->q_base + 1); if (interp_val >= 0) line_buf_cur[0] = _min(interp_val, params->max_value); else line_buf_cur[0] = 0; return errcnt; } static void fuji_decode_interpolation_even(int line_width, ushort *line_buf, int pos) { ushort *line_buf_cur = line_buf + pos; int Rb = line_buf_cur[-2 - line_width]; int Rc = line_buf_cur[-3 - line_width]; int Rd = line_buf_cur[-1 - line_width]; int Rf = line_buf_cur[-4 - 2 * line_width]; int diffRcRb = _abs(Rc - Rb); int diffRfRb = _abs(Rf - Rb); int diffRdRb = _abs(Rd - Rb); if (diffRcRb > diffRfRb && diffRcRb > diffRdRb) *line_buf_cur = (Rf + Rd + 2 * Rb) >> 2; else if (diffRdRb > diffRcRb && diffRdRb > diffRfRb) *line_buf_cur = (Rf + Rc + 2 * Rb) >> 2; else *line_buf_cur = (Rd + Rc + 2 * Rb) >> 2; } static void fuji_extend_generic(ushort *linebuf[_ltotal], int line_width, int start, int end) { for (int i = start; i <= end; i++) { linebuf[i][0] = linebuf[i - 1][1]; linebuf[i][line_width + 1] = linebuf[i - 1][line_width]; } } static void fuji_extend_red(ushort *linebuf[_ltotal], int line_width) { fuji_extend_generic(linebuf, line_width, _R2, _R4); } static void fuji_extend_green(ushort *linebuf[_ltotal], int line_width) { fuji_extend_generic(linebuf, line_width, _G2, _G7); } static void fuji_extend_blue(ushort *linebuf[_ltotal], int line_width) { fuji_extend_generic(linebuf, line_width, _B2, _B4); } void LibRaw::xtrans_decode_block(fuji_compressed_block *info, const fuji_compressed_params *params, int /*cur_line*/) { int r_even_pos = 0, r_odd_pos = 1; int g_even_pos = 0, g_odd_pos = 1; int b_even_pos = 0, b_odd_pos = 1; int errcnt = 0; const int line_width = params->line_width; while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { fuji_decode_interpolation_even(line_width, info->linebuf[_R2] + 1, r_even_pos); r_even_pos += 2; errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G2] + 1, g_even_pos, &info->even[0]); g_even_pos += 2; } if (g_even_pos > 8) { errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R2] + 1, r_odd_pos, &info->odd[0]); r_odd_pos += 2; errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G2] + 1, g_odd_pos, &info->odd[0]); g_odd_pos += 2; } } fuji_extend_red(info->linebuf, line_width); fuji_extend_green(info->linebuf, line_width); g_even_pos = 0, g_odd_pos = 1; while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G3] + 1, g_even_pos, &info->even[1]); g_even_pos += 2; fuji_decode_interpolation_even(line_width, info->linebuf[_B2] + 1, b_even_pos); b_even_pos += 2; } if (g_even_pos > 8) { errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G3] + 1, g_odd_pos, &info->odd[1]); g_odd_pos += 2; errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B2] + 1, b_odd_pos, &info->odd[1]); b_odd_pos += 2; } } fuji_extend_green(info->linebuf, line_width); fuji_extend_blue(info->linebuf, line_width); r_even_pos = 0, r_odd_pos = 1; g_even_pos = 0, g_odd_pos = 1; while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { if (r_even_pos & 3) errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R3] + 1, r_even_pos, &info->even[2]); else fuji_decode_interpolation_even(line_width, info->linebuf[_R3] + 1, r_even_pos); r_even_pos += 2; fuji_decode_interpolation_even(line_width, info->linebuf[_G4] + 1, g_even_pos); g_even_pos += 2; } if (g_even_pos > 8) { errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R3] + 1, r_odd_pos, &info->odd[2]); r_odd_pos += 2; errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G4] + 1, g_odd_pos, &info->odd[2]); g_odd_pos += 2; } } fuji_extend_red(info->linebuf, line_width); fuji_extend_green(info->linebuf, line_width); g_even_pos = 0, g_odd_pos = 1; b_even_pos = 0, b_odd_pos = 1; while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G5] + 1, g_even_pos, &info->even[0]); g_even_pos += 2; if ((b_even_pos & 3) == 2) fuji_decode_interpolation_even(line_width, info->linebuf[_B3] + 1, b_even_pos); else errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B3] + 1, b_even_pos, &info->even[0]); b_even_pos += 2; } if (g_even_pos > 8) { errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G5] + 1, g_odd_pos, &info->odd[0]); g_odd_pos += 2; errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B3] + 1, b_odd_pos, &info->odd[0]); b_odd_pos += 2; } } fuji_extend_green(info->linebuf, line_width); fuji_extend_blue(info->linebuf, line_width); r_even_pos = 0, r_odd_pos = 1; g_even_pos = 0, g_odd_pos = 1; while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { if ((r_even_pos & 3) == 2) fuji_decode_interpolation_even(line_width, info->linebuf[_R4] + 1, r_even_pos); else errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R4] + 1, r_even_pos, &info->even[1]); r_even_pos += 2; errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G6] + 1, g_even_pos, &info->even[1]); g_even_pos += 2; } if (g_even_pos > 8) { errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R4] + 1, r_odd_pos, &info->odd[1]); r_odd_pos += 2; errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G6] + 1, g_odd_pos, &info->odd[1]); g_odd_pos += 2; } } fuji_extend_red(info->linebuf, line_width); fuji_extend_green(info->linebuf, line_width); g_even_pos = 0, g_odd_pos = 1; b_even_pos = 0, b_odd_pos = 1; while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { fuji_decode_interpolation_even(line_width, info->linebuf[_G7] + 1, g_even_pos); g_even_pos += 2; if (b_even_pos & 3) errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B4] + 1, b_even_pos, &info->even[2]); else fuji_decode_interpolation_even(line_width, info->linebuf[_B4] + 1, b_even_pos); b_even_pos += 2; } if (g_even_pos > 8) { errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G7] + 1, g_odd_pos, &info->odd[2]); g_odd_pos += 2; errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B4] + 1, b_odd_pos, &info->odd[2]); b_odd_pos += 2; } } fuji_extend_green(info->linebuf, line_width); fuji_extend_blue(info->linebuf, line_width); if (errcnt) derror(); } void LibRaw::fuji_bayer_decode_block(fuji_compressed_block *info, const fuji_compressed_params *params, int /*cur_line*/) { int r_even_pos = 0, r_odd_pos = 1; int g_even_pos = 0, g_odd_pos = 1; int b_even_pos = 0, b_odd_pos = 1; int errcnt = 0; const int line_width = params->line_width; while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R2] + 1, r_even_pos, &info->even[0]); r_even_pos += 2; errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G2] + 1, g_even_pos, &info->even[0]); g_even_pos += 2; } if (g_even_pos > 8) { errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R2] + 1, r_odd_pos, &info->odd[0]); r_odd_pos += 2; errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G2] + 1, g_odd_pos, &info->odd[0]); g_odd_pos += 2; } } fuji_extend_red(info->linebuf, line_width); fuji_extend_green(info->linebuf, line_width); g_even_pos = 0, g_odd_pos = 1; while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G3] + 1, g_even_pos, &info->even[1]); g_even_pos += 2; errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B2] + 1, b_even_pos, &info->even[1]); b_even_pos += 2; } if (g_even_pos > 8) { errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G3] + 1, g_odd_pos, &info->odd[1]); g_odd_pos += 2; errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B2] + 1, b_odd_pos, &info->odd[1]); b_odd_pos += 2; } } fuji_extend_green(info->linebuf, line_width); fuji_extend_blue(info->linebuf, line_width); r_even_pos = 0, r_odd_pos = 1; g_even_pos = 0, g_odd_pos = 1; while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R3] + 1, r_even_pos, &info->even[2]); r_even_pos += 2; errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G4] + 1, g_even_pos, &info->even[2]); g_even_pos += 2; } if (g_even_pos > 8) { errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R3] + 1, r_odd_pos, &info->odd[2]); r_odd_pos += 2; errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G4] + 1, g_odd_pos, &info->odd[2]); g_odd_pos += 2; } } fuji_extend_red(info->linebuf, line_width); fuji_extend_green(info->linebuf, line_width); g_even_pos = 0, g_odd_pos = 1; b_even_pos = 0, b_odd_pos = 1; while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G5] + 1, g_even_pos, &info->even[0]); g_even_pos += 2; errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B3] + 1, b_even_pos, &info->even[0]); b_even_pos += 2; } if (g_even_pos > 8) { errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G5] + 1, g_odd_pos, &info->odd[0]); g_odd_pos += 2; errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B3] + 1, b_odd_pos, &info->odd[0]); b_odd_pos += 2; } } fuji_extend_green(info->linebuf, line_width); fuji_extend_blue(info->linebuf, line_width); r_even_pos = 0, r_odd_pos = 1; g_even_pos = 0, g_odd_pos = 1; while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R4] + 1, r_even_pos, &info->even[1]); r_even_pos += 2; errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G6] + 1, g_even_pos, &info->even[1]); g_even_pos += 2; } if (g_even_pos > 8) { errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R4] + 1, r_odd_pos, &info->odd[1]); r_odd_pos += 2; errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G6] + 1, g_odd_pos, &info->odd[1]); g_odd_pos += 2; } } fuji_extend_red(info->linebuf, line_width); fuji_extend_green(info->linebuf, line_width); g_even_pos = 0, g_odd_pos = 1; b_even_pos = 0, b_odd_pos = 1; while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G7] + 1, g_even_pos, &info->even[2]); g_even_pos += 2; errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B4] + 1, b_even_pos, &info->even[2]); b_even_pos += 2; } if (g_even_pos > 8) { errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G7] + 1, g_odd_pos, &info->odd[2]); g_odd_pos += 2; errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B4] + 1, b_odd_pos, &info->odd[2]); b_odd_pos += 2; } } fuji_extend_green(info->linebuf, line_width); fuji_extend_blue(info->linebuf, line_width); if (errcnt) derror(); } void LibRaw::fuji_decode_strip(fuji_compressed_params *params, int cur_block, INT64 raw_offset, unsigned dsize, uchar *q_bases) { int cur_block_width, cur_line; unsigned line_size; fuji_compressed_block info; fuji_compressed_params *info_common = params; if (!libraw_internal_data.unpacker_data.fuji_lossless) { int buf_size = sizeof(fuji_compressed_params) + (2 << libraw_internal_data.unpacker_data.fuji_bits); info_common = (fuji_compressed_params *)malloc(buf_size); memcpy(info_common, params, sizeof(fuji_compressed_params)); info_common->qt[0].q_table = (int8_t *)(info_common + 1); info_common->qt[0].q_base = -1; } init_fuji_block(&info, info_common, raw_offset, dsize); line_size = sizeof(ushort) * (info_common->line_width + 2); cur_block_width = libraw_internal_data.unpacker_data.fuji_block_width; if (cur_block + 1 == libraw_internal_data.unpacker_data.fuji_total_blocks) { cur_block_width = imgdata.sizes.raw_width - (libraw_internal_data.unpacker_data.fuji_block_width * cur_block); /* Old code, may get incorrect results on GFX50, but luckily large optical black cur_block_width = imgdata.sizes.raw_width % libraw_internal_data.unpacker_data.fuji_block_width; */ } struct i_pair { int a, b; }; const i_pair mtable[6] = {{_R0, _R3}, {_R1, _R4}, {_G0, _G6}, {_G1, _G7}, {_B0, _B3}, {_B1, _B4}}, ztable[3] = {{_R2, 3}, {_G2, 6}, {_B2, 3}}; for (cur_line = 0; cur_line < libraw_internal_data.unpacker_data.fuji_total_lines; cur_line++) { // init grads and main qtable if (!libraw_internal_data.unpacker_data.fuji_lossless) { int q_base = q_bases ? q_bases[cur_line] : 0; if (!cur_line || q_base != info_common->qt[0].q_base) { init_main_qtable(info_common, q_bases[cur_line]); init_main_grads(info_common, &info); } } if (libraw_internal_data.unpacker_data.fuji_raw_type == 16) xtrans_decode_block(&info, info_common, cur_line); else fuji_bayer_decode_block(&info, info_common, cur_line); // copy data from line buffers and advance for (int i = 0; i < 6; i++) memcpy(info.linebuf[mtable[i].a], info.linebuf[mtable[i].b], line_size); if (libraw_internal_data.unpacker_data.fuji_raw_type == 16) copy_line_to_xtrans(&info, cur_line, cur_block, cur_block_width); else copy_line_to_bayer(&info, cur_line, cur_block, cur_block_width); for (int i = 0; i < 3; i++) { memset(info.linebuf[ztable[i].a], 0, ztable[i].b * line_size); info.linebuf[ztable[i].a][0] = info.linebuf[ztable[i].a - 1][1]; info.linebuf[ztable[i].a][info_common->line_width + 1] = info.linebuf[ztable[i].a - 1][info_common->line_width]; } } // release data if (!libraw_internal_data.unpacker_data.fuji_lossless) free(info_common); free(info.linealloc); free(info.cur_buf); } void LibRaw::fuji_compressed_load_raw() { fuji_compressed_params common_info; int cur_block; unsigned *block_sizes; uchar *q_bases = 0; INT64 raw_offset, *raw_block_offsets; init_fuji_compr(&common_info); // read block sizes block_sizes = (unsigned *)malloc(sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks); raw_block_offsets = (INT64 *)malloc(sizeof(INT64) * libraw_internal_data.unpacker_data.fuji_total_blocks); libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET); int sizesToRead = sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks; if (libraw_internal_data.internal_data.input->read(block_sizes, 1, sizesToRead) != sizesToRead) { free(block_sizes); free(raw_block_offsets); throw LIBRAW_EXCEPTION_IO_EOF; } raw_offset = ((sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks) + 0xF) & ~0xF; // read q bases for lossy if (!libraw_internal_data.unpacker_data.fuji_lossless) { int total_q_bases = libraw_internal_data.unpacker_data.fuji_total_blocks * ((libraw_internal_data.unpacker_data.fuji_total_lines + 0xF) & ~0xF); q_bases = (uchar *)malloc(total_q_bases); libraw_internal_data.internal_data.input->seek(raw_offset + libraw_internal_data.unpacker_data.data_offset, SEEK_SET); libraw_internal_data.internal_data.input->read(q_bases, 1, total_q_bases); raw_offset += total_q_bases; } raw_offset += libraw_internal_data.unpacker_data.data_offset; // calculating raw block offsets raw_block_offsets[0] = raw_offset; for (cur_block = 0; cur_block < libraw_internal_data.unpacker_data.fuji_total_blocks; cur_block++) { unsigned bsize = sgetn(4, (uchar *)(block_sizes + cur_block)); block_sizes[cur_block] = bsize; } for (cur_block = 1; cur_block < libraw_internal_data.unpacker_data.fuji_total_blocks; cur_block++) raw_block_offsets[cur_block] = raw_block_offsets[cur_block - 1] + block_sizes[cur_block - 1]; fuji_decode_loop(&common_info, libraw_internal_data.unpacker_data.fuji_total_blocks, raw_block_offsets, block_sizes, q_bases); free(q_bases); free(block_sizes); free(raw_block_offsets); free(common_info.buf); } void LibRaw::fuji_decode_loop(fuji_compressed_params *common_info, int count, INT64 *raw_block_offsets, unsigned *block_sizes, uchar *q_bases) { int cur_block; const int lineStep = (libraw_internal_data.unpacker_data.fuji_total_lines + 0xF) & ~0xF; #ifdef LIBRAW_USE_OPENMP #pragma omp parallel for private(cur_block) #endif for (cur_block = 0; cur_block < count; cur_block++) { fuji_decode_strip(common_info, cur_block, raw_block_offsets[cur_block], block_sizes[cur_block], q_bases ? q_bases + cur_block * lineStep : 0); } } void LibRaw::parse_fuji_compressed_header() { unsigned signature, lossless, h_raw_type, h_raw_bits, h_raw_height, h_raw_rounded_width, h_raw_width, h_block_size, h_blocks_in_row, h_total_lines; uchar header[16]; libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET); if (libraw_internal_data.internal_data.input->read(header, 1, sizeof(header)) != sizeof(header)) return; // read all header signature = sgetn(2, header); lossless = header[2]; h_raw_type = header[3]; h_raw_bits = header[4]; h_raw_height = sgetn(2, header + 5); h_raw_rounded_width = sgetn(2, header + 7); h_raw_width = sgetn(2, header + 9); h_block_size = sgetn(2, header + 11); h_blocks_in_row = header[13]; h_total_lines = sgetn(2, header + 14); // general validation if (signature != 0x4953 || lossless > 1 || h_raw_height > 0x4002 || h_raw_height < 6 || h_raw_height % 6 || h_block_size < 1 || h_raw_width > 0x4200 || h_raw_width < 0x300 || h_raw_width % 24 || h_raw_rounded_width > 0x4200 || h_raw_rounded_width < h_block_size || h_raw_rounded_width % h_block_size || h_raw_rounded_width - h_raw_width >= h_block_size || h_block_size != 0x300 || h_blocks_in_row > 0x10 || h_blocks_in_row == 0 || h_blocks_in_row != h_raw_rounded_width / h_block_size || h_total_lines > 0xAAB || h_total_lines == 0 || h_total_lines != h_raw_height / 6 || (h_raw_bits != 12 && h_raw_bits != 14 && h_raw_bits != 16) || (h_raw_type != 16 && h_raw_type != 0)) return; // modify data libraw_internal_data.unpacker_data.fuji_total_lines = h_total_lines; libraw_internal_data.unpacker_data.fuji_total_blocks = h_blocks_in_row; libraw_internal_data.unpacker_data.fuji_block_width = h_block_size; libraw_internal_data.unpacker_data.fuji_bits = h_raw_bits; libraw_internal_data.unpacker_data.fuji_raw_type = h_raw_type; libraw_internal_data.unpacker_data.fuji_lossless = lossless; imgdata.sizes.raw_width = h_raw_width; imgdata.sizes.raw_height = h_raw_height; libraw_internal_data.unpacker_data.data_offset += 16; load_raw = &LibRaw::fuji_compressed_load_raw; } #undef _abs #undef _min LibRaw-0.21.4/src/decoders/generic.cpp000066400000000000000000000056161477673233700175100ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" void LibRaw::unpacked_load_raw() { int row, col, bits = 0; while (1 << ++bits < (int)maximum) ; read_shorts(raw_image, raw_width * raw_height); fseek(ifp, -2, SEEK_CUR); // avoid EOF error if (maximum < 0xffff || load_flags) for (row = 0; row < raw_height; row++) { checkCancel(); for (col = 0; col < raw_width; col++) if ((RAW(row, col) >>= load_flags) >> bits && (unsigned)(row - top_margin) < height && (unsigned)(col - left_margin) < width) derror(); } } void LibRaw::packed_load_raw() { int vbits = 0, bwide, rbits, bite, half, irow, row, col, val, i; UINT64 bitbuf = 0; bwide = raw_width * tiff_bps / 8; bwide += bwide & load_flags >> 7; rbits = bwide * 8 - raw_width * tiff_bps; if (load_flags & 1) bwide = bwide * 16 / 15; bite = 8 + (load_flags & 24); half = (raw_height + 1) >> 1; for (irow = 0; irow < raw_height; irow++) { checkCancel(); row = irow; if (load_flags & 2 && (row = irow % half * 2 + irow / half) == 1 && load_flags & 4) { if (vbits = 0, tiff_compress) fseek(ifp, data_offset - (-half * bwide & -2048), SEEK_SET); else { fseek(ifp, 0, SEEK_END); fseek(ifp, ftell(ifp) >> 3 << 2, SEEK_SET); } } if (feof(ifp)) throw LIBRAW_EXCEPTION_IO_EOF; for (col = 0; col < raw_width; col++) { for (vbits -= tiff_bps; vbits < 0; vbits += bite) { bitbuf <<= bite; for (i = 0; i < bite; i += 8) bitbuf |= (unsigned(fgetc(ifp)) << i); } val = bitbuf << (64 - tiff_bps - vbits) >> (64 - tiff_bps); RAW(row, col ^ (load_flags >> 6 & 1)) = val; if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) && row < height + top_margin && col < width + left_margin) derror(); } vbits -= rbits; } } void LibRaw::eight_bit_load_raw() { unsigned row, col; std::vector pixel(raw_width); for (row = 0; row < raw_height; row++) { checkCancel(); if (fread(pixel.data(), 1, raw_width, ifp) < raw_width) derror(); for (col = 0; col < raw_width; col++) RAW(row, col) = curve[pixel[col]]; } maximum = curve[0xff]; } LibRaw-0.21.4/src/decoders/kodak_decoders.cpp000066400000000000000000000362751477673233700210420ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" #define radc_token(tree) ((signed char)getbithuff(8, huff + (tree) * 256)) #define FORYX \ for (y = 1; y < 3; y++) \ for (x = col + 1; x >= col; x--) #define PREDICTOR \ (c ? (buf[c][y - 1][x] + buf[c][y][x + 1]) / 2 \ : (buf[c][y - 1][x + 1] + 2 * buf[c][y - 1][x] + buf[c][y][x + 1]) / 4) #ifdef __GNUC__ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) #pragma GCC optimize("no-aggressive-loop-optimizations") #endif #endif void LibRaw::kodak_radc_load_raw() { // All kodak radc images are 768x512 if (width > 768 || raw_width > 768 || height > 512 || raw_height > 512) throw LIBRAW_EXCEPTION_IO_CORRUPT; static const signed char src[] = { 1, 1, 2, 3, 3, 4, 4, 2, 5, 7, 6, 5, 7, 6, 7, 8, 1, 0, 2, 1, 3, 3, 4, 4, 5, 2, 6, 7, 7, 6, 8, 5, 8, 8, 2, 1, 2, 3, 3, 0, 3, 2, 3, 4, 4, 6, 5, 5, 6, 7, 6, 8, 2, 0, 2, 1, 2, 3, 3, 2, 4, 4, 5, 6, 6, 7, 7, 5, 7, 8, 2, 1, 2, 4, 3, 0, 3, 2, 3, 3, 4, 7, 5, 5, 6, 6, 6, 8, 2, 3, 3, 1, 3, 2, 3, 4, 3, 5, 3, 6, 4, 7, 5, 0, 5, 8, 2, 3, 2, 6, 3, 0, 3, 1, 4, 4, 4, 5, 4, 7, 5, 2, 5, 8, 2, 4, 2, 7, 3, 3, 3, 6, 4, 1, 4, 2, 4, 5, 5, 0, 5, 8, 2, 6, 3, 1, 3, 3, 3, 5, 3, 7, 3, 8, 4, 0, 5, 2, 5, 4, 2, 0, 2, 1, 3, 2, 3, 3, 4, 4, 4, 5, 5, 6, 5, 7, 4, 8, 1, 0, 2, 2, 2, -2, 1, -3, 1, 3, 2, -17, 2, -5, 2, 5, 2, 17, 2, -7, 2, 2, 2, 9, 2, 18, 2, -18, 2, -9, 2, -2, 2, 7, 2, -28, 2, 28, 3, -49, 3, -9, 3, 9, 4, 49, 5, -79, 5, 79, 2, -1, 2, 13, 2, 26, 3, 39, 4, -16, 5, 55, 6, -37, 6, 76, 2, -26, 2, -13, 2, 1, 3, -39, 4, 16, 5, -55, 6, -76, 6, 37}; std::vector huff_buffer(19 * 256,0); ushort* huff = &huff_buffer[0]; int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val; short last[3] = {16, 16, 16}, mul[3], buf[3][3][386]; static const ushort pt[] = {0, 0, 1280, 1344, 2320, 3616, 3328, 8000, 4095, 16383, 65535, 16383}; for (i = 2; i < 12; i += 2) for (c = pt[i - 2]; c <= pt[i]; c++) curve[c] = (float)(c - pt[i - 2]) / (pt[i] - pt[i - 2]) * (pt[i + 1] - pt[i - 1]) + pt[i - 1] + 0.5; for (s = i = 0; i < int(sizeof src); i += 2) FORC(256 >> src[i]) ((ushort *)huff)[s++] = src[i] << 8 | (uchar)src[i + 1]; s = kodak_cbpp == 243 ? 2 : 3; FORC(256) huff[18 * 256 + c] = (8 - s) << 8 | c >> s << s | 1 << (s - 1); getbits(-1); for (i = 0; i < int(sizeof(buf) / sizeof(short)); i++) ((short *)buf)[i] = 2048; for (row = 0; row < height; row += 4) { checkCancel(); FORC3 mul[c] = getbits(6); if (!mul[0] || !mul[1] || !mul[2]) throw LIBRAW_EXCEPTION_IO_CORRUPT; FORC3 { val = ((0x1000000 / last[c] + 0x7ff) >> 12) * mul[c]; s = val > 65564 ? 10 : 12; x = ~((~0u) << (s - 1)); val <<= 12 - s; for (i = 0; i < int(sizeof(buf[0]) / sizeof(short)); i++) ((short *)buf[c])[i] = MIN(0x7FFFFFFF, (((short *)buf[c])[i] * static_cast(val) + x)) >> s; last[c] = mul[c]; for (r = 0; r <= int(!c); r++) { buf[c][1][width / 2] = buf[c][2][width / 2] = mul[c] << 7; for (tree = 1, col = width / 2; col > 0;) { if ((tree = radc_token(tree))) { col -= 2; if (col >= 0) { if (tree == 8) FORYX buf[c][y][x] = (uchar)radc_token(18) * mul[c]; else FORYX buf[c][y][x] = radc_token(tree + 10) * 16 + PREDICTOR; } } else do { nreps = (col > 2) ? radc_token(9) + 1 : 1; for (rep = 0; rep < 8 && rep < nreps && col > 0; rep++) { col -= 2; if (col >= 0) FORYX buf[c][y][x] = PREDICTOR; if (rep & 1) { step = radc_token(10) << 4; FORYX buf[c][y][x] += step; } } } while (nreps == 9); } for (y = 0; y < 2; y++) for (x = 0; x < width / 2; x++) { val = (buf[c][y + 1][x] << 4) / mul[c]; if (val < 0) val = 0; if (c) RAW(row + y * 2 + c - 1, x * 2 + 2 - c) = val; else RAW(row + r * 2 + y, x * 2 + y) = val; } memcpy(buf[c][0] + !c, buf[c][2], sizeof buf[c][0] - 2 * !c); } } for (y = row; y < row + 4; y++) for (x = 0; x < width; x++) if ((x + y) & 1) { r = x ? x - 1 : x + 1; s = x + 1 < width ? x + 1 : x - 1; val = (RAW(y, x) - 2048) * 2 + (RAW(y, r) + RAW(y, s)) / 2; if (val < 0) val = 0; RAW(y, x) = val; } } for (i = 0; i < height * width; i++) raw_image[i] = curve[raw_image[i]]; maximum = 0x3fff; } #undef FORYX #undef PREDICTOR #ifdef NO_JPEG void LibRaw::kodak_jpeg_load_raw() {} #else static void jpegErrorExit_k(j_common_ptr /*cinfo*/) { throw LIBRAW_EXCEPTION_DECODE_JPEG; } // LibRaw's Kodak_jpeg_load_raw void LibRaw::kodak_jpeg_load_raw() { if (data_size < 1) throw LIBRAW_EXCEPTION_DECODE_JPEG; int row, col; struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr pub; cinfo.err = jpeg_std_error(&pub); pub.error_exit = jpegErrorExit_k; if (INT64(data_size) > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) throw LIBRAW_EXCEPTION_TOOBIG; unsigned char *jpg_buf = (unsigned char *)calloc(data_size,1); std::vector pixel_buf(width * 3, 0); jpeg_create_decompress(&cinfo); fread(jpg_buf, data_size, 1, ifp); libraw_swab(jpg_buf, data_size); try { jpeg_mem_src(&cinfo, jpg_buf, data_size); int rc = jpeg_read_header(&cinfo, TRUE); if (rc != 1) throw LIBRAW_EXCEPTION_DECODE_JPEG; jpeg_start_decompress(&cinfo); if ((cinfo.output_width != width) || (cinfo.output_height * 2 != height) || (cinfo.output_components != 3)) { throw LIBRAW_EXCEPTION_DECODE_JPEG; } unsigned char *buf[1]; buf[0] = pixel_buf.data(); while (cinfo.output_scanline < cinfo.output_height) { checkCancel(); row = cinfo.output_scanline * 2; jpeg_read_scanlines(&cinfo, buf, 1); unsigned char(*pixel)[3] = (unsigned char(*)[3])buf[0]; for (col = 0; col < width; col += 2) { RAW(row + 0, col + 0) = pixel[col + 0][1] << 1; RAW(row + 1, col + 1) = pixel[col + 1][1] << 1; RAW(row + 0, col + 1) = pixel[col][0] + pixel[col + 1][0]; RAW(row + 1, col + 0) = pixel[col][2] + pixel[col + 1][2]; } } } catch (...) { jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); free(jpg_buf); throw; } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); free(jpg_buf); maximum = 0xff << 1; } #endif void LibRaw::kodak_dc120_load_raw() { static const int mul[4] = {162, 192, 187, 92}; static const int add[4] = {0, 636, 424, 212}; uchar pixel[848]; int row, shift, col; for (row = 0; row < height; row++) { checkCancel(); if (fread(pixel, 1, 848, ifp) < 848) derror(); shift = row * mul[row & 3] + add[row & 3]; for (col = 0; col < width; col++) RAW(row, col) = (ushort)pixel[(col + shift) % 848]; } maximum = 0xff; } void LibRaw::kodak_c330_load_raw() { if (!image) throw LIBRAW_EXCEPTION_IO_CORRUPT; int row, col, y, cb, cr, rgb[3], c; std::vector pixel(raw_width*2 + 4); for (row = 0; row < height; row++) { checkCancel(); if (fread(pixel.data(), raw_width, 2, ifp) < 2) derror(); if (load_flags && (row & 31) == 31) fseek(ifp, raw_width * 32, SEEK_CUR); for (col = 0; col < width; col++) { y = pixel[col * 2]; cb = pixel[(col * 2 & -4) | 1] - 128; cr = pixel[(col * 2 & -4) | 3] - 128; rgb[1] = y - ((cb + cr + 2) >> 2); rgb[2] = rgb[1] + cb; rgb[0] = rgb[1] + cr; FORC3 image[row * width + col][c] = curve[LIM(rgb[c], 0, 255)]; } } maximum = curve[0xff]; } void LibRaw::kodak_c603_load_raw() { if (!image) throw LIBRAW_EXCEPTION_IO_CORRUPT; int row, col, y, cb, cr, rgb[3], c; std::vector pixel(raw_width * 3); for (row = 0; row < height; row++) { checkCancel(); if (~row & 1) if (fread(pixel.data(), raw_width, 3, ifp) < 3) derror(); for (col = 0; col < width; col++) { y = pixel[width * 2 * (row & 1) + col]; cb = pixel[width + (col & -2)] - 128; cr = pixel[width + (col & -2) + 1] - 128; rgb[1] = y - ((cb + cr + 2) >> 2); rgb[2] = rgb[1] + cb; rgb[0] = rgb[1] + cr; FORC3 image[row * width + col][c] = curve[LIM(rgb[c], 0, 255)]; } } maximum = curve[0xff]; } void LibRaw::kodak_262_load_raw() { static const uchar kodak_tree[2][26] = { {0, 1, 5, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, {0, 3, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}; ushort *huff[2]; int *strip, ns, c, row, col, chess, pi = 0, pi1, pi2, pred, val; FORC(2) huff[c] = make_decoder(kodak_tree[c]); ns = (raw_height + 63) >> 5; std::vector pixel(raw_width * 32 + ns * 4); strip = (int *)(pixel.data() + raw_width * 32); order = 0x4d4d; FORC(ns) strip[c] = get4(); try { for (row = 0; row < raw_height; row++) { checkCancel(); if ((row & 31) == 0) { fseek(ifp, strip[row >> 5], SEEK_SET); getbits(-1); pi = 0; } for (col = 0; col < raw_width; col++) { chess = (row + col) & 1; pi1 = chess ? pi - 2 : pi - raw_width - 1; pi2 = chess ? pi - 2 * raw_width : pi - raw_width + 1; if (col <= chess) pi1 = -1; if (pi1 < 0) pi1 = pi2; if (pi2 < 0) pi2 = pi1; if (pi1 < 0 && col > 1) pi1 = pi2 = pi - 2; pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1; pixel[pi] = val = pred + ljpeg_diff(huff[chess]); if (val >> 8) derror(); val = curve[pixel[pi++]]; RAW(row, col) = val; } } } catch (...) { FORC(2) free(huff[c]); throw; } FORC(2) free(huff[c]); } int LibRaw::kodak_65000_decode(short *out, int bsize) { uchar c, blen[768]; ushort raw[6]; INT64 bitbuf = 0; int save, bits = 0, i, j, len, diff; save = ftell(ifp); bsize = (bsize + 3) & -4; for (i = 0; i < bsize; i += 2) { c = fgetc(ifp); if ((blen[i] = c & 15) > 12 || (blen[i + 1] = c >> 4) > 12) { fseek(ifp, save, SEEK_SET); for (i = 0; i < bsize; i += 8) { read_shorts(raw, 6); out[i] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12; out[i + 1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12; for (j = 0; j < 6; j++) out[i + 2 + j] = raw[j] & 0xfff; } return 1; } } if ((bsize & 7) == 4) { bitbuf = fgetc(ifp) << 8; bitbuf += fgetc(ifp); bits = 16; } for (i = 0; i < bsize; i++) { len = blen[i]; if (bits < len) { for (j = 0; j < 32; j += 8) bitbuf += (INT64)fgetc(ifp) << (bits + (j ^ 8)); bits += 32; } diff = bitbuf & (0xffff >> (16 - len)); bitbuf >>= len; bits -= len; if (len > 0 && (diff & (1 << (len - 1))) == 0) diff -= (1 << len) - 1; out[i] = diff; } return 0; } void LibRaw::kodak_65000_load_raw() { short buf[272]; /* 264 looks enough */ int row, col, len, pred[2], ret, i; for (row = 0; row < height; row++) { checkCancel(); for (col = 0; col < width; col += 256) { pred[0] = pred[1] = 0; len = MIN(256, width - col); ret = kodak_65000_decode(buf, len); for (i = 0; i < len; i++) { int idx = ret ? buf[i] : (pred[i & 1] += buf[i]); if (idx >= 0 && idx < 0xffff) { if ((RAW(row, col + i) = curve[idx]) >> 12) derror(); } else derror(); } } } } void LibRaw::kodak_ycbcr_load_raw() { if (!image) throw LIBRAW_EXCEPTION_IO_CORRUPT; short buf[384], *bp; int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3]; ushort *ip; unsigned int bits = (load_flags && load_flags > 9 && load_flags < 17) ? load_flags : 10; const int pixels = int(width)*int(height); for (row = 0; row < height; row += 2) { checkCancel(); for (col = 0; col < width; col += 128) { len = MIN(128, width - col); kodak_65000_decode(buf, len * 3); y[0][1] = y[1][1] = cb = cr = 0; for (bp = buf, i = 0; i < len; i += 2, bp += 2) { cb += bp[4]; cr += bp[5]; rgb[1] = -((cb + cr + 2) >> 2); rgb[2] = rgb[1] + cb; rgb[0] = rgb[1] + cr; for (j = 0; j < 2; j++) for (k = 0; k < 2; k++) { if ((y[j][k] = y[j][k ^ 1] + *bp++) >> bits) derror(); int indx = (row + j) * width + col + i + k; if(indx>=0 && indx < pixels) { ip = image[indx]; FORC3 ip[c] = curve[LIM(y[j][k] + rgb[c], 0, 0xfff)]; } } } } } } void LibRaw::kodak_rgb_load_raw() { if (!image) throw LIBRAW_EXCEPTION_IO_CORRUPT; short buf[768], *bp; int row, col, len, c, i, rgb[3], ret; ushort *ip = image[0]; for (row = 0; row < height; row++) { checkCancel(); for (col = 0; col < width; col += 256) { len = MIN(256, width - col); ret = kodak_65000_decode(buf, len * 3); memset(rgb, 0, sizeof rgb); for (bp = buf, i = 0; i < len; i++, ip += 4) if (load_flags == 12) FORC3 ip[c] = ret ? (*bp++) : (rgb[c] += *bp++); else FORC3 if ((ip[c] = ret ? (*bp++) : (rgb[c] += *bp++)) >> 12) derror(); } } } void LibRaw::kodak_thumb_load_raw() { if (!image) throw LIBRAW_EXCEPTION_IO_CORRUPT; int row, col; colors = thumb_misc >> 5; for (row = 0; row < height; row++) for (col = 0; col < width; col++) read_shorts(image[row * width + col], colors); maximum = (1 << (thumb_misc & 31)) - 1; } LibRaw-0.21.4/src/decoders/load_mfbacks.cpp000066400000000000000000000646121477673233700205020ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" inline uint32_t abs32(int32_t x) { // Branchless version. uint32_t sm = x >> 31; return (uint32_t) ((x + sm) ^ sm); } inline uint32_t min32(uint32_t x, uint32_t y) { return x < y ? x : y; } inline uint32_t max32(uint32_t x, uint32_t y) { return x > y ? x : y; } inline uint32_t constain32(uint32_t x, uint32_t l, uint32_t u) { return x < l ? l : (x > u ? u : x); } int unsigned_cmp(const void *a, const void *b) { if (!a || !b) return 0; return *(unsigned *)a > *(unsigned *)b ? 1 : (*(unsigned *)a < *(unsigned *)b ? -1 : 0); } int LibRaw::p1rawc(unsigned row, unsigned col, unsigned& count) { return (row < raw_height && col < raw_width) ? (++count, RAW(row, col)) : 0; } int LibRaw::p1raw(unsigned row, unsigned col) { return (row < raw_height && col < raw_width) ? RAW(row, col) : 0; } // DNG SDK version of fixing pixels in bad column using averages sets // corrected not to use pixels in the same column void LibRaw::phase_one_fix_col_pixel_avg(unsigned row, unsigned col) { static const int8_t dir[3][8][2] = { { {-2,-2}, {-2, 2}, {2,-2}, {2, 2}, { 0, 0}, { 0, 0}, {0, 0}, {0, 0} }, { {-2,-4}, {-4,-2}, {2,-4}, {4,-2}, {-2, 4}, {-4, 2}, {2, 4}, {4, 2} }, { {-4,-4}, {-4, 4}, {4,-4}, {4, 4}, { 0, 0}, { 0, 0}, {0, 0}, {0, 0} } }; for (int set=0; set < 3; ++set) { uint32_t total = 0; uint32_t count = 0; for (int i = 0; i < 8; ++i) { if (!dir[set][i][0] && !dir[set][i][1]) break; total += p1rawc(row+dir[set][i][0], col+dir[set][i][1], count); } if (count) { RAW(row,col) = (uint16_t)((total + (count >> 1)) / count); break; } } } // DNG SDK version of fixing pixels in bad column using gradient prediction void LibRaw::phase_one_fix_pixel_grad(unsigned row, unsigned col) { static const int8_t grad_sets[7][12][2] = { { {-4,-2}, { 4, 2}, {-3,-1}, { 1, 1}, {-1,-1}, { 3, 1}, {-4,-1}, { 0, 1}, {-2,-1}, { 2, 1}, { 0,-1}, { 4, 1} }, { {-2,-2}, { 2, 2}, {-3,-1}, {-1, 1}, {-1,-1}, { 1, 1}, { 1,-1}, { 3, 1}, {-2,-1}, { 0, 1}, { 0,-1}, { 2, 1} }, { {-2,-4}, { 2, 4}, {-1,-3}, { 1, 1}, {-1,-1}, { 1, 3}, {-2,-1}, { 0, 3}, {-1,-2}, { 1, 2}, { 0,-3}, { 2, 1} }, { { 0,-2}, { 0, 2}, {-1,-1}, {-1, 1}, { 1,-1}, { 1, 1}, {-1,-2}, {-1, 2}, { 0,-1}, { 0,-1}, { 1,-2}, { 1, 2} }, { {-2, 4}, { 2,-4}, {-1, 3}, { 1,-1}, {-1, 1}, { 1,-3}, {-2, 1}, { 0,-3}, {-1, 2}, { 1,-2}, { 0, 3}, { 2,-1} }, { {-2, 2}, { 2,-2}, {-3, 1}, {-1,-1}, {-1, 1}, { 1,-1}, { 1, 1}, { 3,-1}, {-2, 1}, { 0,-1}, { 0, 1}, { 2,-1} }, { {-4, 2}, { 4,-2}, {-3, 1}, { 1,-1}, {-1, 1}, { 3,-1}, {-4, 1}, { 0,-1}, {-2, 1}, { 2,-1}, { 0, 1}, { 4,-1} } }; uint32_t est[7], grad[7]; uint32_t lower = min32(p1raw(row,col-2), p1raw(row, col+2)); uint32_t upper = max32(p1raw(row,col-2), p1raw(row, col+2)); uint32_t minGrad = 0xFFFFFFFF; for (int i = 0; i<7; ++i) { est[i] = p1raw(row+grad_sets[i][0][0], col+grad_sets[i][0][1]) + p1raw(row+grad_sets[i][1][0], col+grad_sets[i][1][1]); grad[i] = 0; for (int j=0; j<12; j+=2) grad[i] += abs32(p1raw(row+grad_sets[i][j][0], col+grad_sets[i][j][1]) - p1raw(row+grad_sets[i][j+1][0], col+grad_sets[i][j+1][1])); minGrad = min32(minGrad, grad[i]); } uint32_t limit = (minGrad * 3) >> 1; uint32_t total = 0; uint32_t count = 0; for (int i = 0; i<7; ++i) if (grad[i] <= limit) { total += est[i]; count += 2; } RAW(row, col) = constain32((total + (count >> 1)) / count, lower, upper); } void LibRaw::phase_one_flat_field(int is_float, int nc) { ushort head[8]; unsigned wide, high, y, x, c, rend, cend, row, col; float *mrow, num, mult[4]; read_shorts(head, 8); if (head[2] == 0 || head[3] == 0 || head[4] == 0 || head[5] == 0) return; wide = head[2] / head[4] + (head[2] % head[4] != 0); high = head[3] / head[5] + (head[3] % head[5] != 0); mrow = (float *)calloc(nc * wide, sizeof *mrow); for (y = 0; y < high; y++) { checkCancel(); for (x = 0; x < wide; x++) for (c = 0; c < (unsigned)nc; c += 2) { num = is_float ? getreal(LIBRAW_EXIFTAG_TYPE_FLOAT) : get2() / 32768.0; if (y == 0) mrow[c * wide + x] = num; else mrow[(c + 1) * wide + x] = (num - mrow[c * wide + x]) / head[5]; } if (y == 0) continue; rend = head[1] + y * head[5]; for (row = rend - head[5]; row < raw_height && row < rend && row < unsigned(head[1] + head[3] - head[5]); row++) { for (x = 1; x < wide; x++) { for (c = 0; c < (unsigned)nc; c += 2) { mult[c] = mrow[c * wide + x - 1]; mult[c + 1] = (mrow[c * wide + x] - mult[c]) / head[4]; } cend = head[0] + x * head[4]; for (col = cend - head[4]; col < raw_width && col < cend && col < unsigned(head[0] + head[2] - head[4]); col++) { c = nc > 2 ? FC(row - top_margin, col - left_margin) : 0; if (!(c & 1)) { c = RAW(row, col) * mult[c]; RAW(row, col) = LIM(c, 0, 65535); } for (c = 0; c < (unsigned)nc; c += 2) mult[c] += mult[c + 1]; } } for (x = 0; x < wide; x++) for (c = 0; c < (unsigned)nc; c += 2) mrow[c * wide + x] += mrow[(c + 1) * wide + x]; } } free(mrow); } int LibRaw::phase_one_correct() { unsigned entries, tag, data, save, col, row, type; int len, i, j, k, cip, sum; #if 0 int val[4], dev[4], max; #endif int head[9], diff, mindiff = INT_MAX, off_412 = 0; /* static */ const signed char dir[12][2] = { {-1, -1}, {-1, 1}, {1, -1}, {1, 1}, {-2, 0}, {0, -2}, {0, 2}, {2, 0}, {-2, -2}, {-2, 2}, {2, -2}, {2, 2}}; float poly[8], num, cfrac, frac, mult[2], *yval[2] = {NULL, NULL}; ushort *xval[2]; int qmult_applied = 0, qlin_applied = 0; std::vector badCols; if (!meta_length) return 0; fseek(ifp, meta_offset, SEEK_SET); order = get2(); fseek(ifp, 6, SEEK_CUR); fseek(ifp, meta_offset + get4(), SEEK_SET); entries = get4(); get4(); try { while (entries--) { checkCancel(); tag = get4(); len = get4(); data = get4(); save = ftell(ifp); fseek(ifp, meta_offset + data, SEEK_SET); #if 1 if (ifp->eof()) { // skip bad or unknown tag fseek(ifp, save, SEEK_SET); continue; } #endif if (tag == 0x0400) { /* Sensor defects */ while ((len -= 8) >= 0) { col = get2(); row = get2(); type = get2(); get2(); if (col >= raw_width) continue; if (type == 131 || type == 137) /* Bad column */ #if 0 // Original code by Dave Coffin - it works better by // not employing special logic for G1 channel below. // Alternatively this column remap (including G1 channel // logic) should be called prior to black subtraction // unlike other corrections for (row = 0; row < raw_height; row++) { if (FC(row - top_margin, col - left_margin)==1) { for (sum = i = 0; i < 4; i++) sum += val[i] = p1raw(row + dir[i][0], col + dir[i][1]); for (max = i = 0; i < 4; i++) { dev[i] = abs((val[i] << 2) - sum); if (dev[max] < dev[i]) max = i; } RAW(row, col) = (sum - val[max]) / 3.0 + 0.5; } else { for (sum = 0, i = 8; i < 12; i++) sum += p1raw(row + dir[i][0], col + dir[i][1]); RAW(row, col) = 0.5 + sum * 0.0732233 + (p1raw(row, col - 2) + p1raw(row, col + 2)) * 0.3535534; } } #else // accumulae bad columns to be sorted later badCols.push_back(col); #endif else if (type == 129) { /* Bad pixel */ if (row >= raw_height) continue; j = (FC(row - top_margin, col - left_margin) != 1) * 4; unsigned count = 0; for (sum = 0, i = j; i < j + 8; i++) sum += p1rawc(row + dir[i][0], col + dir[i][1], count); if (count) RAW(row, col) = (sum + (count >> 1)) / count; } } } else if (tag == 0x0419) { /* Polynomial curve - output calibraion */ for (get4(), i = 0; i < 8; i++) poly[i] = getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1; for (i = 0; i < 0x10000; i++) { num = (poly[5] * i + poly[3]) * i + poly[1]; curve[i] = LIM(num, 0, 65535); } goto apply; /* apply to right half */ } else if (tag == 0x041a) { /* Polynomial curve */ for (i = 0; i < 4; i++) poly[i] = getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); for (i = 0; i < 0x10000; i++) { for (num = 0, j = 4; j--;) num = num * i + poly[j]; curve[i] = LIM(num + i, 0, 65535); } apply: /* apply to whole image */ for (row = 0; row < raw_height; row++) { checkCancel(); for (col = (tag & 1) * ph1.split_col; col < raw_width; col++) RAW(row, col) = curve[RAW(row, col)]; } } else if (tag == 0x0401) { /* All-color flat fields - luma calibration*/ phase_one_flat_field(1, 2); } else if (tag == 0x0416 || tag == 0x0410) { // 0x410 - luma calibration phase_one_flat_field(0, 2); } else if (tag == 0x040b) { /* Red+blue flat field - croma calibration */ phase_one_flat_field(0, 4); } else if (tag == 0x0412) { fseek(ifp, 36, SEEK_CUR); diff = abs(get2() - ph1.tag_21a); if (mindiff > diff) { mindiff = diff; off_412 = ftell(ifp) - 38; } } else if (tag == 0x041f && !qlin_applied && ph1.split_col > 0 && ph1.split_col < raw_width && ph1.split_row > 0 && ph1.split_row < raw_height) { /* Quadrant linearization */ ushort lc[2][2][16], ref[16]; int qr, qc; bool baddiv = false; for (qr = 0; qr < 2; qr++) for (qc = 0; qc < 2; qc++) { for (i = 0; i < 16; i++) lc[qr][qc][i] = get4(); if (lc[qr][qc][15] == 0) baddiv = true; } if(baddiv) continue; for (i = 0; i < 16; i++) { int v = 0; for (qr = 0; qr < 2; qr++) for (qc = 0; qc < 2; qc++) v += lc[qr][qc][i]; ref[i] = (v + 2) >> 2; } for (qr = 0; qr < 2; qr++) { for (qc = 0; qc < 2; qc++) { int cx[19], cf[19]; for (i = 0; i < 16; i++) { cx[1 + i] = lc[qr][qc][i]; cf[1 + i] = ref[i]; } cx[0] = cf[0] = 0; cx[17] = cf[17] = ((unsigned int)ref[15] * 65535) / lc[qr][qc][15]; cf[18] = cx[18] = 65535; cubic_spline(cx, cf, 19); for (row = (qr ? ph1.split_row : 0); row < unsigned(qr ? raw_height : ph1.split_row); row++) { checkCancel(); for (col = (qc ? ph1.split_col : 0); col < unsigned(qc ? raw_width : ph1.split_col); col++) RAW(row, col) = curve[RAW(row, col)]; } } } qlin_applied = 1; } else if (tag == 0x041e && !qmult_applied) { /* Quadrant multipliers - output calibraion */ float qmult[2][2] = {{1, 1}, {1, 1}}; get4(); get4(); get4(); get4(); qmult[0][0] = 1.0 + getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); get4(); get4(); get4(); get4(); get4(); qmult[0][1] = 1.0 + getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); get4(); get4(); get4(); qmult[1][0] = 1.0 + getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); get4(); get4(); get4(); qmult[1][1] = 1.0 + getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); for (row = 0; row < raw_height; row++) { checkCancel(); for (col = 0; col < raw_width; col++) { i = qmult[row >= (unsigned)ph1.split_row][col >= (unsigned)ph1.split_col] * RAW(row, col); RAW(row, col) = LIM(i, 0, 65535); } } qmult_applied = 1; } else if (tag == 0x0431 && !qmult_applied && ph1.split_col > 0 && ph1.split_col < raw_width && ph1.split_row > 0 && ph1.split_row < raw_height) { /* Quadrant combined - four tile gain calibration */ ushort lc[2][2][7], ref[7]; int qr, qc; for (i = 0; i < 7; i++) ref[i] = get4(); for (qr = 0; qr < 2; qr++) for (qc = 0; qc < 2; qc++) for (i = 0; i < 7; i++) lc[qr][qc][i] = get4(); for (qr = 0; qr < 2; qr++) { for (qc = 0; qc < 2; qc++) { int cx[9], cf[9]; for (i = 0; i < 7; i++) { cx[1 + i] = ref[i]; cf[1 + i] = ((unsigned)ref[i] * lc[qr][qc][i]) / 10000; } cx[0] = cf[0] = 0; cx[8] = cf[8] = 65535; cubic_spline(cx, cf, 9); for (row = (qr ? ph1.split_row : 0); row < unsigned(qr ? raw_height : ph1.split_row); row++) { checkCancel(); for (col = (qc ? ph1.split_col : 0); col < unsigned(qc ? raw_width : ph1.split_col); col++) RAW(row, col) = curve[RAW(row, col)]; } } } qmult_applied = 1; qlin_applied = 1; } fseek(ifp, save, SEEK_SET); } if (!badCols.empty()) { qsort(badCols.data(), badCols.size(), sizeof(unsigned), unsigned_cmp); bool prevIsolated = true; for (i = 0; i < (int)badCols.size(); ++i) { bool nextIsolated = i == ((int)(badCols.size()-1)) || badCols[i+1]>badCols[i]+4; for (row = 0; row < raw_height; ++row) if (prevIsolated && nextIsolated) phase_one_fix_pixel_grad(row,badCols[i]); else phase_one_fix_col_pixel_avg(row,badCols[i]); prevIsolated = nextIsolated; } } if (off_412) { fseek(ifp, off_412, SEEK_SET); for (i = 0; i < 9; i++) head[i] = get4() & 0x7fff; unsigned w0 = head[1] * head[3], w1 = head[2] * head[4]; if (w0 > 10240000 || w1 > 10240000) throw LIBRAW_EXCEPTION_ALLOC; if (w0 < 1 || w1 < 1) throw LIBRAW_EXCEPTION_IO_CORRUPT; yval[0] = (float *)calloc(head[1] * head[3] + head[2] * head[4], 6); yval[1] = (float *)(yval[0] + head[1] * head[3]); xval[0] = (ushort *)(yval[1] + head[2] * head[4]); xval[1] = (ushort *)(xval[0] + head[1] * head[3]); get2(); for (i = 0; i < 2; i++) for (j = 0; j < head[i + 1] * head[i + 3]; j++) yval[i][j] = getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); for (i = 0; i < 2; i++) for (j = 0; j < head[i + 1] * head[i + 3]; j++) xval[i][j] = get2(); for (row = 0; row < raw_height; row++) { checkCancel(); for (col = 0; col < raw_width; col++) { cfrac = (float)col * head[3] / raw_width; cfrac -= cip = cfrac; num = RAW(row, col) * 0.5; for (i = cip; i < cip + 2; i++) { for (k = j = 0; j < head[1]; j++) if (num < xval[0][k = head[1] * i + j]) break; if (j == 0 || j == head[1] || k < 1 || k >= w0+w1) frac = 0; else { int xdiv = (xval[0][k] - xval[0][k - 1]); frac = xdiv ? (xval[0][k] - num) / (xval[0][k] - xval[0][k - 1]) : 0; } if (k < w0 + w1) mult[i - cip] = yval[0][k > 0 ? k - 1 : 0] * frac + yval[0][k] * (1 - frac); else mult[i - cip] = 0; } i = ((mult[0] * (1 - cfrac) + mult[1] * cfrac) * row + num) * 2; RAW(row, col) = LIM(i, 0, 65535); } } free(yval[0]); } } catch (...) { if (yval[0]) free(yval[0]); return LIBRAW_CANCELLED_BY_CALLBACK; } return 0; } void LibRaw::phase_one_load_raw() { int a, b, i; ushort akey, bkey, t_mask; fseek(ifp, ph1.key_off, SEEK_SET); akey = get2(); bkey = get2(); t_mask = ph1.format == 1 ? 0x5555 : 0x1354; if (ph1.black_col || ph1.black_row) { imgdata.rawdata.ph1_cblack = (short(*)[2])calloc(raw_height * 2, sizeof(ushort)); imgdata.rawdata.ph1_rblack = (short(*)[2])calloc(raw_width * 2, sizeof(ushort)); if (ph1.black_col) { fseek(ifp, ph1.black_col, SEEK_SET); read_shorts((ushort *)imgdata.rawdata.ph1_cblack[0], raw_height * 2); } if (ph1.black_row) { fseek(ifp, ph1.black_row, SEEK_SET); read_shorts((ushort *)imgdata.rawdata.ph1_rblack[0], raw_width * 2); } } fseek(ifp, data_offset, SEEK_SET); read_shorts(raw_image, raw_width * raw_height); if (ph1.format) for (i = 0; i < raw_width * raw_height; i += 2) { a = raw_image[i + 0] ^ akey; b = raw_image[i + 1] ^ bkey; raw_image[i + 0] = (a & t_mask) | (b & ~t_mask); raw_image[i + 1] = (b & t_mask) | (a & ~t_mask); } } unsigned LibRaw::ph1_bithuff(int nbits, ushort *huff) { #ifndef LIBRAW_NOTHREADS #define bitbuf tls->ph1_bits.bitbuf #define vbits tls->ph1_bits.vbits #else static UINT64 bitbuf = 0; static int vbits = 0; #endif unsigned c; if (nbits == -1) return bitbuf = vbits = 0; if (nbits == 0) return 0; if (vbits < nbits) { bitbuf = bitbuf << 32 | get4(); vbits += 32; } c = bitbuf << (64 - vbits) >> (64 - nbits); if (huff) { vbits -= huff[c] >> 8; return (uchar)huff[c]; } vbits -= nbits; return c; #ifndef LIBRAW_NOTHREADS #undef bitbuf #undef vbits #endif } void LibRaw::phase_one_load_raw_c() { static const int length[] = {8, 7, 6, 9, 11, 10, 5, 12, 14, 13}; int *offset, len[2], pred[2], row, col, i, j; ushort *pixel; short(*c_black)[2], (*r_black)[2]; if (ph1.format == 6) throw LIBRAW_EXCEPTION_IO_CORRUPT; pixel = (ushort *)calloc(raw_width * 3 + raw_height * 4, 2); offset = (int *)(pixel + raw_width); fseek(ifp, strip_offset, SEEK_SET); for (row = 0; row < raw_height; row++) offset[row] = get4(); c_black = (short(*)[2])(offset + raw_height); fseek(ifp, ph1.black_col, SEEK_SET); if (ph1.black_col) read_shorts((ushort *)c_black[0], raw_height * 2); r_black = c_black + raw_height; fseek(ifp, ph1.black_row, SEEK_SET); if (ph1.black_row) read_shorts((ushort *)r_black[0], raw_width * 2); // Copy data to internal copy (ever if not read) if (ph1.black_col || ph1.black_row) { imgdata.rawdata.ph1_cblack = (short(*)[2])calloc(raw_height * 2, sizeof(ushort)); memmove(imgdata.rawdata.ph1_cblack, (ushort *)c_black[0], raw_height * 2 * sizeof(ushort)); imgdata.rawdata.ph1_rblack = (short(*)[2])calloc(raw_width * 2, sizeof(ushort)); memmove(imgdata.rawdata.ph1_rblack, (ushort *)r_black[0], raw_width * 2 * sizeof(ushort)); } for (i = 0; i < 256; i++) curve[i] = i * i / 3.969 + 0.5; try { for (row = 0; row < raw_height; row++) { checkCancel(); fseek(ifp, data_offset + offset[row], SEEK_SET); ph1_bits(-1); pred[0] = pred[1] = 0; for (col = 0; col < raw_width; col++) { if (col >= (raw_width & -8)) len[0] = len[1] = 14; else if ((col & 7) == 0) for (i = 0; i < 2; i++) { for (j = 0; j < 5 && !ph1_bits(1); j++) ; if (j--) len[i] = length[j * 2 + ph1_bits(1)]; } if ((i = len[col & 1]) == 14) pixel[col] = pred[col & 1] = ph1_bits(16); else pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1)); if (pred[col & 1] >> 16) derror(); if (ph1.format == 5 && pixel[col] < 256) pixel[col] = curve[pixel[col]]; } if (ph1.format == 8) memmove(&RAW(row, 0), &pixel[0], raw_width * 2); else for (col = 0; col < raw_width; col++) RAW(row, col) = pixel[col] << 2; } } catch (...) { free(pixel); throw; } free(pixel); maximum = 0xfffc - ph1.t_black; } void LibRaw::hasselblad_load_raw() { struct jhead jh; int shot, row, col, *back[5]={0,0,0,0,0}, len[2], diff[12], pred, sh, f, c; unsigned s; unsigned upix, urow, ucol; ushort *ip; if (!ljpeg_start(&jh, 0)) return; order = 0x4949; ph1_bits(-1); try { back[4] = (int *)calloc(raw_width, 3 * sizeof **back); FORC3 back[c] = back[4] + c * raw_width; cblack[6] >>= sh = tiff_samples > 1; shot = LIM(shot_select, 1, tiff_samples) - 1; for (row = 0; row < raw_height; row++) { checkCancel(); FORC4 back[(c + 3) & 3] = back[c]; for (col = 0; col < raw_width; col += 2) { for (s = 0; s < tiff_samples * 2; s += 2) { FORC(2) len[c] = ph1_huff(jh.huff[0]); FORC(2) { diff[s + c] = ph1_bits(len[c]); if (len[c] > 0 && (diff[s + c] & (1 << (len[c] - 1))) == 0) diff[s + c] -= (1 << len[c]) - 1; if (diff[s + c] == 65535) diff[s + c] = -32768; } } for (s = col; s < unsigned(col + 2); s++) { pred = 0x8000 + load_flags; if (col) pred = back[2][s - 2]; if (col && row > 1) switch (jh.psv) { case 11: pred += back[0][s] / 2 - back[0][s - 2] / 2; break; } f = (row & 1) * 3 ^ ((col + s) & 1); FORC(int(tiff_samples)) { pred += diff[(s & 1) * tiff_samples + c]; upix = pred >> sh & 0xffff; if (raw_image && c == shot) RAW(row, s) = upix; if (image) { urow = row - top_margin + (c & 1); ucol = col - left_margin - ((c >> 1) & 1); ip = &image[urow * width + ucol][f]; if (urow < height && ucol < width) *ip = c < 4 ? upix : (*ip + upix) >> 1; } } back[2][s] = pred; } } } } catch (...) { if(back[4]) free(back[4]); ljpeg_end(&jh); throw; } if(back[4]) free(back[4]); ljpeg_end(&jh); if (image) mix_green = 1; } void LibRaw::leaf_hdr_load_raw() { ushort *pixel = 0; unsigned tile = 0, r, c, row, col; if (!filters || !raw_image) { if (!image) throw LIBRAW_EXCEPTION_IO_CORRUPT; pixel = (ushort *)calloc(raw_width, sizeof *pixel); } try { FORC(tiff_samples) for (r = 0; r < raw_height; r++) { checkCancel(); if (r % tile_length == 0) { fseek(ifp, data_offset + 4 * tile++, SEEK_SET); fseek(ifp, get4(), SEEK_SET); } if (filters && c != shot_select) continue; if (filters && raw_image) pixel = raw_image + r * raw_width; read_shorts(pixel, raw_width); if (!filters && image && (row = r - top_margin) < height) for (col = 0; col < width && col + left_margin < raw_width; col++) image[row * width + col][c] = pixel[col + left_margin]; } } catch (...) { if (!filters) free(pixel); throw; } if (!filters) { maximum = 0xffff; raw_color = 1; free(pixel); } } void LibRaw::unpacked_load_raw_FujiDBP() /* for Fuji DBP for GX680, aka DX-2000 DBP_tile_width = 688; DBP_tile_height = 3856; DBP_n_tiles = 8; */ { int scan_line, tile_n; int nTiles; nTiles = 8; tile_width = raw_width / nTiles; ushort *tile; tile = (ushort *)calloc(raw_height, tile_width * 2); for (tile_n = 0; tile_n < nTiles; tile_n++) { read_shorts(tile, tile_width * raw_height); for (scan_line = 0; scan_line < raw_height; scan_line++) { memcpy(&raw_image[scan_line * raw_width + tile_n * tile_width], &tile[scan_line * tile_width], tile_width * 2); } } free(tile); fseek(ifp, -2, SEEK_CUR); // avoid EOF error } void LibRaw::sinar_4shot_load_raw() { ushort *pixel; unsigned shot, row, col, r, c; if (raw_image) { shot = LIM(shot_select, 1, 4) - 1; fseek(ifp, data_offset + shot * 4, SEEK_SET); fseek(ifp, get4(), SEEK_SET); unpacked_load_raw(); return; } if (!image) throw LIBRAW_EXCEPTION_IO_CORRUPT; pixel = (ushort *)calloc(raw_width, sizeof *pixel); try { for (shot = 0; shot < 4; shot++) { checkCancel(); fseek(ifp, data_offset + shot * 4, SEEK_SET); fseek(ifp, get4(), SEEK_SET); for (row = 0; row < raw_height; row++) { read_shorts(pixel, raw_width); if ((r = row - top_margin - (shot >> 1 & 1)) >= height) continue; for (col = 0; col < raw_width; col++) { if ((c = col - left_margin - (shot & 1)) >= width) continue; image[r * width + c][(row & 1) * 3 ^ (~col & 1)] = pixel[col]; } } } } catch (...) { free(pixel); throw; } free(pixel); mix_green = 1; } void LibRaw::imacon_full_load_raw() { if (!image) throw LIBRAW_EXCEPTION_IO_CORRUPT; int row, col; unsigned short *buf = (unsigned short *)malloc(width * 3 * sizeof(unsigned short)); for (row = 0; row < height; row++) { checkCancel(); read_shorts(buf, width * 3); unsigned short(*rowp)[4] = &image[row * width]; for (col = 0; col < width; col++) { rowp[col][0] = buf[col * 3]; rowp[col][1] = buf[col * 3 + 1]; rowp[col][2] = buf[col * 3 + 2]; rowp[col][3] = 0; } } free(buf); } LibRaw-0.21.4/src/decoders/smal.cpp000066400000000000000000000117401477673233700170230ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" #define HOLE(row) ((holes >> (((row)-raw_height) & 7)) & 1) /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */ void LibRaw::smal_decode_segment(unsigned seg[2][2], int holes) { uchar hist[3][13] = {{7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0}, {7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0}, {3, 3, 0, 0, 63, 47, 31, 15, 0}}; int low, high = 0xff, carry = 0, nbits = 8; int s, count, bin, next, i, sym[3]; unsigned pix; uchar diff, pred[] = {0, 0}; ushort data = 0, range = 0; fseek(ifp, seg[0][1] + 1, SEEK_SET); getbits(-1); if (seg[1][0] > unsigned(raw_width * raw_height)) seg[1][0] = raw_width * raw_height; for (pix = seg[0][0]; pix < seg[1][0]; pix++) { for (s = 0; s < 3; s++) { data = data << nbits | getbits(nbits); if (carry < 0) carry = (nbits += carry + 1) < 1 ? nbits - 1 : 0; while (--nbits >= 0) if ((data >> nbits & 0xff) == 0xff) break; if (nbits > 0) data = ((data & ((1 << (nbits - 1)) - 1)) << 1) | ((data + (((data & (1 << (nbits - 1)))) << 1)) & ((~0u) << nbits)); if (nbits >= 0) { data += getbits(1); carry = nbits - 8; } count = ((((data - range + 1) & 0xffff) << 2) - 1) / (high >> 4); for (bin = 0; hist[s][bin + 5] > count; bin++) ; low = hist[s][bin + 5] * (high >> 4) >> 2; if (bin) high = hist[s][bin + 4] * (high >> 4) >> 2; high -= low; for (nbits = 0; high << nbits < 128; nbits++) ; range = (range + low) << nbits; high <<= nbits; next = hist[s][1]; if (++hist[s][2] > hist[s][3]) { next = (next + 1) & hist[s][0]; hist[s][3] = (hist[s][next + 4] - hist[s][next + 5]) >> 2; hist[s][2] = 1; } if (hist[s][hist[s][1] + 4] - hist[s][hist[s][1] + 5] > 1) { if (bin < hist[s][1]) for (i = bin; i < hist[s][1]; i++) hist[s][i + 5]--; else if (next <= bin) for (i = hist[s][1]; i < bin; i++) hist[s][i + 5]++; } hist[s][1] = next; sym[s] = bin; } diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3); if (sym[0] & 4) diff = diff ? -diff : 0x80; if (ftell(ifp) + 12 >= seg[1][1]) diff = 0; if (pix >= unsigned(raw_width * raw_height)) throw LIBRAW_EXCEPTION_IO_CORRUPT; raw_image[pix] = pred[pix & 1] += diff; if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2; } maximum = 0xff; } void LibRaw::smal_v6_load_raw() { unsigned seg[2][2]; fseek(ifp, 16, SEEK_SET); seg[0][0] = 0; seg[0][1] = get2(); seg[1][0] = raw_width * raw_height; seg[1][1] = INT_MAX; smal_decode_segment(seg, 0); } int LibRaw::median4(int *p) { int min, max, sum, i; min = max = sum = p[0]; for (i = 1; i < 4; i++) { sum += p[i]; if (min > p[i]) min = p[i]; if (max < p[i]) max = p[i]; } return (sum - min - max) >> 1; } void LibRaw::fill_holes(int holes) { int row, col, val[4]; for (row = 2; row < height - 2; row++) { if (!HOLE(row)) continue; for (col = 1; col < width - 1; col += 4) { val[0] = RAW(row - 1, col - 1); val[1] = RAW(row - 1, col + 1); val[2] = RAW(row + 1, col - 1); val[3] = RAW(row + 1, col + 1); RAW(row, col) = median4(val); } for (col = 2; col < width - 2; col += 4) if (HOLE(row - 2) || HOLE(row + 2)) RAW(row, col) = (RAW(row, col - 2) + RAW(row, col + 2)) >> 1; else { val[0] = RAW(row, col - 2); val[1] = RAW(row, col + 2); val[2] = RAW(row - 2, col); val[3] = RAW(row + 2, col); RAW(row, col) = median4(val); } } } void LibRaw::smal_v9_load_raw() { unsigned seg[256][2], offset, nseg, holes, i; fseek(ifp, 67, SEEK_SET); offset = get4(); nseg = (uchar)fgetc(ifp); fseek(ifp, offset, SEEK_SET); for (i = 0; i < nseg * 2; i++) ((unsigned *)seg)[i] = get4() + data_offset * (i & 1); fseek(ifp, 78, SEEK_SET); holes = fgetc(ifp); fseek(ifp, 88, SEEK_SET); seg[nseg][0] = raw_height * raw_width; seg[nseg][1] = get4() + data_offset; for (i = 0; i < nseg; i++) smal_decode_segment(seg + i, holes); if (holes) fill_holes(holes); } #undef HOLE LibRaw-0.21.4/src/decoders/unpack.cpp000066400000000000000000000461101477673233700173470ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cameraids.h" #include "../../internal/libraw_cxx_defs.h" #ifdef USE_RAWSPEED3 #include "rawspeed3_capi.h" #include #endif int LibRaw::unpack(void) { CHECK_ORDER_HIGH(LIBRAW_PROGRESS_LOAD_RAW); CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY); try { if (!libraw_internal_data.internal_data.input) return LIBRAW_INPUT_CLOSED; RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW, 0, 2); if (imgdata.rawparams.shot_select >= P1.raw_count) return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE; if (!load_raw) return LIBRAW_UNSPECIFIED_ERROR; // already allocated ? if (imgdata.image) { free(imgdata.image); imgdata.image = 0; } if (imgdata.rawdata.raw_alloc) { free(imgdata.rawdata.raw_alloc); imgdata.rawdata.raw_alloc = 0; } if (libraw_internal_data.unpacker_data.meta_length) { if (libraw_internal_data.unpacker_data.meta_length > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) throw LIBRAW_EXCEPTION_TOOBIG; #ifdef LIBRAW_CALLOC_RAWSTORE libraw_internal_data.internal_data.meta_data = (char *)calloc(libraw_internal_data.unpacker_data.meta_length,1); #else libraw_internal_data.internal_data.meta_data = (char *)malloc(libraw_internal_data.unpacker_data.meta_length); #endif } libraw_decoder_info_t decoder_info; get_decoder_info(&decoder_info); int save_iwidth = S.iwidth, save_iheight = S.iheight, save_shrink = IO.shrink; int rwidth = S.raw_width, rheight = S.raw_height; if (!IO.fuji_width) { // adjust non-Fuji allocation if (rwidth < S.width + S.left_margin) rwidth = S.width + S.left_margin; if (rheight < S.height + S.top_margin) rheight = S.height + S.top_margin; } if (rwidth > 65535 || rheight > 65535) // No way to make image larger than 64k pix throw LIBRAW_EXCEPTION_IO_CORRUPT; imgdata.rawdata.raw_image = 0; imgdata.rawdata.color4_image = 0; imgdata.rawdata.color3_image = 0; imgdata.rawdata.float_image = 0; imgdata.rawdata.float3_image = 0; #ifdef USE_DNGSDK if (imgdata.idata.dng_version && dnghost && libraw_internal_data.unpacker_data.tiff_samples != 2 // Fuji SuperCCD; it is better to detect is more rigid way && valid_for_dngsdk() && load_raw != &LibRaw::pentax_4shot_load_raw) { // Data size check INT64 pixcount = INT64(MAX(S.width, S.raw_width)) * INT64(MAX(S.height, S.raw_height)); INT64 planecount = (imgdata.idata.filters || P1.colors == 1) ? 1 : LIM(P1.colors, 3, 4); INT64 samplesize = is_floating_point() ? 4 : 2; INT64 bytes = pixcount * planecount * samplesize; if (bytes + INT64(libraw_internal_data.unpacker_data.meta_length ) > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) throw LIBRAW_EXCEPTION_TOOBIG; // find ifd to check sample try_dngsdk(); if (raw_was_read()) imgdata.process_warnings |= LIBRAW_WARN_DNGSDK_PROCESSED; } #endif #ifdef USE_RAWSPEED3 if (!raw_was_read() && (!IO.fuji_width) // Do not use for fuji rotated && ((imgdata.idata.raw_count == 1) // Canon dual pixel, 1st frame || (makeIs(LIBRAW_CAMERAMAKER_Canon) && imgdata.idata.raw_count == 2 && imgdata.rawparams.shot_select==0) ) #ifdef USE_RAWSPEED_BITS && (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV3_USE) #else && imgdata.rawparams.use_rawspeed #endif && (decoder_info.decoder_flags & LIBRAW_DECODER_TRYRAWSPEED3) ) { INT64 pixcount = INT64(MAX(S.width, S.raw_width)) * INT64(MAX(S.height, S.raw_height)); INT64 planecount = (imgdata.idata.filters || P1.colors == 1) ? 1 : LIM(P1.colors, 3, 4); INT64 bytes = pixcount * planecount * 2; // sample size is always 2 for rawspeed if (bytes + INT64(libraw_internal_data.unpacker_data.meta_length) > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) throw LIBRAW_EXCEPTION_TOOBIG; if (!_rawspeed3_handle) _rawspeed3_handle = rawspeed3_initdefault(); if (_rawspeed3_handle && ID.input->size() > 0) // large bound is checked at identify { void *_rawspeed_buffer = 0; try { ID.input->seek(0, SEEK_SET); INT64 _rawspeed_buffer_sz = ID.input->size() + 32; _rawspeed_buffer = malloc(_rawspeed_buffer_sz); if (!_rawspeed_buffer) throw LIBRAW_EXCEPTION_ALLOC; ID.input->read(_rawspeed_buffer, ID.input->size(), 1); rawspeed3_ret_t rs3ret; rawspeed3_clearresult(&rs3ret); int status = rawspeed3_decodefile(_rawspeed3_handle, &rs3ret, _rawspeed_buffer, ID.input->size(), #ifdef USE_RAWSPEED_BITS !(imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV3_FAILONUNKNOWN) #else false #endif ); if (status != rawspeed3_ok) imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_UNSUPPORTED; if (status == rawspeed3_not_supported) imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED3_NOTLISTED; if (status == rawspeed3_ok #ifdef USE_RAWSPEED_BITS || (status == rawspeed3_ok_warnings && (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV3_IGNOREERRORS)) #endif ) { if ((S.raw_width != rs3ret.width) || (S.raw_height != rs3ret.height)) throw "Size mismatch"; // DECODED w/ success if (rs3ret.filters>1) // Fuji or bayer imgdata.rawdata.raw_image = (ushort*)rs3ret.pixeldata; else if (rs3ret.cpp == 4) { imgdata.rawdata.color4_image = (ushort(*)[4])rs3ret.pixeldata; //if (r->whitePoint > 0 && r->whitePoint < 65536) // C.maximum = r->whitePoint; } else if (rs3ret.cpp == 3) { imgdata.rawdata.color3_image = (ushort(*)[3])rs3ret.pixeldata; //if (r->whitePoint > 0 && r->whitePoint < 65536) // C.maximum = r->whitePoint; } if (raw_was_read()) // buffers are assigned above { // set sizes S.raw_pitch = rs3ret.pitch; S.raw_width = rs3ret.width; S.raw_height = rs3ret.height; imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED3_PROCESSED; // if (r->whitePoint > 0 && r->whitePoint < 65536) // C.maximum = r->whitePoint; } } free(_rawspeed_buffer); } catch (...) { imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED3_PROBLEM; if (_rawspeed_buffer) free(_rawspeed_buffer); } } } #endif #ifdef USE_RAWSPEED if (!raw_was_read()) { int rawspeed_enabled = 1; if (imgdata.idata.dng_version && (libraw_internal_data.unpacker_data.tiff_samples == 2 || imgdata.idata.raw_count > 1)) rawspeed_enabled = 0; if (libraw_internal_data.unpacker_data.is_NikonTransfer) rawspeed_enabled = 0; if (libraw_internal_data.unpacker_data.pana_encoding == 5) rawspeed_enabled = 0; if (imgdata.idata.raw_count > 1) rawspeed_enabled = 0; if (!strncasecmp(imgdata.idata.software, "Magic", 5)) rawspeed_enabled = 0; // Disable rawspeed for double-sized Oly files if (makeIs(LIBRAW_CAMERAMAKER_Olympus) && ((imgdata.sizes.raw_width > 6000) || !strncasecmp(imgdata.idata.model, "SH-", 3) || !strncasecmp(imgdata.idata.model, "TG-", 3) )) rawspeed_enabled = 0; if (makeIs(LIBRAW_CAMERAMAKER_Canon) && (libraw_internal_data.identify_data.unique_id == CanonID_EOS_6D_Mark_II)) rawspeed_enabled = 0; if (imgdata.idata.dng_version && imgdata.idata.filters == 0 && libraw_internal_data.unpacker_data.tiff_bps == 8) // Disable for 8 bit rawspeed_enabled = 0; if (load_raw == &LibRaw::packed_load_raw && makeIs(LIBRAW_CAMERAMAKER_Nikon) && (!strncasecmp(imgdata.idata.model, "E", 1) || !strncasecmp(imgdata.idata.model, "COOLPIX B", 9) || !strncasecmp(imgdata.idata.model, "COOLPIX P9", 10) || !strncasecmp(imgdata.idata.model, "COOLPIX P1000", 13))) rawspeed_enabled = 0; if (load_raw == &LibRaw::nikon_load_raw && makeIs(LIBRAW_CAMERAMAKER_Nikon) && !strcasecmp(imgdata.idata.model, "D6")) rawspeed_enabled = 0; if (load_raw == &LibRaw::lossless_jpeg_load_raw && MN.canon.RecordMode && makeIs(LIBRAW_CAMERAMAKER_Kodak) && /* Not normalized models here, it is intentional */ (!strncasecmp(imgdata.idata.model, "EOS D2000", 9) || !strncasecmp(imgdata.idata.model, "EOS D6000", 9))) rawspeed_enabled = 0; if (load_raw == &LibRaw::nikon_load_raw && makeIs(LIBRAW_CAMERAMAKER_Nikon) && (!strncasecmp(imgdata.idata.model, "Z", 1) || !strncasecmp(imgdata.idata.model,"D780",4))) rawspeed_enabled = 0; if (load_raw == &LibRaw::panasonic_load_raw && libraw_internal_data.unpacker_data.pana_encoding > 4) rawspeed_enabled = 0; // RawSpeed Supported, if ( #ifdef USE_RAWSPEED_BITS (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV1_USE) #else imgdata.rawparams.use_rawspeed #endif && rawspeed_enabled && !(is_sraw() && (imgdata.rawparams.specials & (LIBRAW_RAWSPECIAL_SRAW_NO_RGB | LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE))) && (decoder_info.decoder_flags & LIBRAW_DECODER_TRYRAWSPEED) && _rawspeed_camerameta) { INT64 pixcount = INT64(MAX(S.width, S.raw_width)) * INT64(MAX(S.height, S.raw_height)); INT64 planecount = (imgdata.idata.filters || P1.colors == 1) ? 1 : LIM(P1.colors, 3, 4); INT64 bytes = pixcount * planecount * 2; // sample size is always 2 for rawspeed if (bytes + +INT64(libraw_internal_data.unpacker_data.meta_length) > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) throw LIBRAW_EXCEPTION_TOOBIG; /*int rr = */ try_rawspeed(); } } #endif if (!raw_was_read()) // RawSpeed failed or not run { // Not allocated on RawSpeed call, try call LibRaow int zero_rawimage = 0; if (decoder_info.decoder_flags & LIBRAW_DECODER_OWNALLOC) { // x3f foveon decoder and DNG float // Do nothing! Decoder will allocate data internally } if (decoder_info.decoder_flags & LIBRAW_DECODER_SINAR4SHOT) { if (imgdata.rawparams.shot_select) // single image extract { if (INT64(rwidth) * INT64(rheight + 8) * INT64(sizeof(imgdata.rawdata.raw_image[0])) + +INT64(libraw_internal_data.unpacker_data.meta_length) > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) throw LIBRAW_EXCEPTION_TOOBIG; #ifdef LIBRAW_CALLOC_RAWSTORE imgdata.rawdata.raw_alloc = calloc( rwidth * (rheight + 8), sizeof(imgdata.rawdata.raw_image[0])); #else imgdata.rawdata.raw_alloc = malloc( rwidth * (rheight + 8) * sizeof(imgdata.rawdata.raw_image[0])); #endif imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; if (!S.raw_pitch) S.raw_pitch = S.raw_width * 2; // Bayer case, not set before } else // Full image extract { if (INT64(rwidth) * INT64(rheight + 8) * INT64(sizeof(imgdata.rawdata.raw_image[0])) * 4 +INT64(libraw_internal_data.unpacker_data.meta_length) > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) throw LIBRAW_EXCEPTION_TOOBIG; S.raw_pitch = S.raw_width * 8; imgdata.rawdata.raw_alloc = 0; imgdata.image = (ushort(*)[4])calloc( unsigned(MAX(S.width, S.raw_width)) * unsigned(MAX(S.height, S.raw_height) + 8), sizeof(*imgdata.image)); } } else if (decoder_info.decoder_flags & LIBRAW_DECODER_3CHANNEL) { if (INT64(rwidth) * INT64(rheight + 8) * INT64(sizeof(imgdata.rawdata.raw_image[0])) * 3 + INT64(libraw_internal_data.unpacker_data.meta_length) > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) throw LIBRAW_EXCEPTION_TOOBIG; #ifdef LIBRAW_CALLOC_RAWSTORE imgdata.rawdata.raw_alloc = calloc( rwidth * (rheight + 8), sizeof(imgdata.rawdata.raw_image[0]) * 3); #else imgdata.rawdata.raw_alloc = malloc( rwidth * (rheight + 8) * sizeof(imgdata.rawdata.raw_image[0]) * 3); #endif imgdata.rawdata.color3_image = (ushort(*)[3])imgdata.rawdata.raw_alloc; if (!S.raw_pitch) S.raw_pitch = S.raw_width * 6; } else if (imgdata.idata.filters || P1.colors == 1) // Bayer image or single color -> decode to raw_image { if (INT64(rwidth) * INT64(rheight + 8) * INT64(sizeof(imgdata.rawdata.raw_image[0])) + INT64(libraw_internal_data.unpacker_data.meta_length) > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) throw LIBRAW_EXCEPTION_TOOBIG; imgdata.rawdata.raw_alloc = malloc( rwidth * (rheight + 8) * sizeof(imgdata.rawdata.raw_image[0])); imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; if (!S.raw_pitch) S.raw_pitch = S.raw_width * 2; // Bayer case, not set before } else // NO LEGACY FLAG if (decoder_info.decoder_flags & // LIBRAW_DECODER_LEGACY) { if (decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL) { S.raw_pitch = S.raw_width * 8; } else { S.iwidth = S.width; S.iheight = S.height; IO.shrink = 0; if (!S.raw_pitch) S.raw_pitch = (decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY_WITH_MARGINS) ? S.raw_width * 8 : S.width * 8; } // sRAW and old Foveon decoders only, so extra buffer size is just 1/4 // allocate image as temporary buffer, size if (INT64(MAX(S.width, S.raw_width)) * INT64(MAX(S.height, S.raw_height) + 8) * INT64(sizeof(*imgdata.image)) + INT64(libraw_internal_data.unpacker_data.meta_length) > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) throw LIBRAW_EXCEPTION_TOOBIG; imgdata.rawdata.raw_alloc = 0; imgdata.image = (ushort(*)[4])calloc(unsigned(MAX(S.width, S.raw_width)) * unsigned(MAX(S.height, S.raw_height) + 8), sizeof(*imgdata.image)); if (!(decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL)) { imgdata.rawdata.raw_image = (ushort *)imgdata.image; zero_rawimage = 1; } } ID.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET); unsigned m_save = C.maximum; if (load_raw == &LibRaw::unpacked_load_raw && (!strcasecmp(imgdata.idata.make, "Nikon") || !strcasecmp(imgdata.idata.make, "Hasselblad")) ) C.maximum = 65535; (this->*load_raw)(); if (zero_rawimage) imgdata.rawdata.raw_image = 0; if (load_raw == &LibRaw::unpacked_load_raw && (!strcasecmp(imgdata.idata.make, "Nikon") || !strcasecmp(imgdata.idata.make, "Hasselblad")) ) C.maximum = m_save; if (decoder_info.decoder_flags & LIBRAW_DECODER_OWNALLOC) { // x3f foveon decoder only: do nothing } else if (decoder_info.decoder_flags & LIBRAW_DECODER_SINAR4SHOT && imgdata.rawparams.shot_select == 0) { imgdata.rawdata.raw_alloc = imgdata.image; imgdata.rawdata.color4_image = (ushort(*)[4])imgdata.rawdata.raw_alloc; imgdata.image = 0; } else if (!(imgdata.idata.filters || P1.colors == 1)) // legacy decoder, ownalloc handled above { // successfully decoded legacy image, attach image to raw_alloc imgdata.rawdata.raw_alloc = imgdata.image; imgdata.rawdata.color4_image = (ushort(*)[4])imgdata.rawdata.raw_alloc; imgdata.image = 0; // Restore saved values. Note: Foveon have masked frame // Other 4-color legacy data: no borders if (!(libraw_internal_data.unpacker_data.load_flags & 256) && !(decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL) && !(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY_WITH_MARGINS)) { S.raw_width = S.width; S.left_margin = 0; S.raw_height = S.height; S.top_margin = 0; } } } if (imgdata.rawdata.raw_image) crop_masked_pixels(); // calculate black levels // recover image sizes S.iwidth = save_iwidth; S.iheight = save_iheight; IO.shrink = save_shrink; // adjust black to possible maximum unsigned int i = C.cblack[3]; unsigned int c; for (c = 0; c < 3; c++) if (i > C.cblack[c]) i = C.cblack[c]; for (c = 0; c < 4; c++) C.cblack[c] -= i; C.black += i; // Save color,sizes and internal data into raw_image fields memmove(&imgdata.rawdata.color, &imgdata.color, sizeof(imgdata.color)); memmove(&imgdata.rawdata.sizes, &imgdata.sizes, sizeof(imgdata.sizes)); memmove(&imgdata.rawdata.iparams, &imgdata.idata, sizeof(imgdata.idata)); memmove(&imgdata.rawdata.ioparams, &libraw_internal_data.internal_output_params, sizeof(libraw_internal_data.internal_output_params)); SET_PROC_FLAG(LIBRAW_PROGRESS_LOAD_RAW); RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW, 1, 2); return 0; } catch (const std::bad_alloc&) { EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); } catch (const LibRaw_exceptions& err) { EXCEPTION_HANDLER(err); } catch (const std::exception& ) { EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT); } } LibRaw-0.21.4/src/decoders/unpack_thumb.cpp000066400000000000000000000332061477673233700205500ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" #ifndef NO_JPEG struct jpegErrorManager { struct jpeg_error_mgr pub; jmp_buf setjmp_buffer; }; static void jpegErrorExit(j_common_ptr cinfo) { jpegErrorManager *myerr = (jpegErrorManager *)cinfo->err; longjmp(myerr->setjmp_buffer, 1); } #endif int LibRaw::unpack_thumb_ex(int idx) { if (idx < 0 || idx >= imgdata.thumbs_list.thumbcount || idx >= LIBRAW_THUMBNAIL_MAXCOUNT) return LIBRAW_REQUEST_FOR_NONEXISTENT_THUMBNAIL; // Set from thumb-list libraw_internal_data.internal_data.toffset = imgdata.thumbs_list.thumblist[idx].toffset; imgdata.thumbnail.tlength = imgdata.thumbs_list.thumblist[idx].tlength; libraw_internal_data.unpacker_data.thumb_format = imgdata.thumbs_list.thumblist[idx].tformat; imgdata.thumbnail.twidth = imgdata.thumbs_list.thumblist[idx].twidth; imgdata.thumbnail.theight = imgdata.thumbs_list.thumblist[idx].theight; libraw_internal_data.unpacker_data.thumb_misc = imgdata.thumbs_list.thumblist[idx].tmisc; int rc = unpack_thumb(); imgdata.progress_flags &= ~LIBRAW_PROGRESS_THUMB_LOAD; return rc; } int LibRaw::unpack_thumb(void) { CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY); CHECK_ORDER_BIT(LIBRAW_PROGRESS_THUMB_LOAD); #define THUMB_SIZE_CHECKT(A) \ do { \ if (INT64(A) > 1024LL * 1024LL * LIBRAW_MAX_THUMBNAIL_MB) return LIBRAW_UNSUPPORTED_THUMBNAIL; \ if (INT64(A) > 0 && INT64(A) < 64LL) return LIBRAW_NO_THUMBNAIL; \ } while (0) #define THUMB_SIZE_CHECKTNZ(A) \ do { \ if (INT64(A) > 1024LL * 1024LL * LIBRAW_MAX_THUMBNAIL_MB) return LIBRAW_UNSUPPORTED_THUMBNAIL; \ if (INT64(A) < 64LL) return LIBRAW_NO_THUMBNAIL; \ } while (0) #define THUMB_SIZE_CHECKWH(W,H) \ do { \ if (INT64(W)*INT64(H) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) return LIBRAW_UNSUPPORTED_THUMBNAIL; \ if (INT64(W)*INT64(H) < 64ULL) return LIBRAW_NO_THUMBNAIL; \ } while (0) #define Tformat libraw_internal_data.unpacker_data.thumb_format try { if (!libraw_internal_data.internal_data.input) return LIBRAW_INPUT_CLOSED; int t_colors = libraw_internal_data.unpacker_data.thumb_misc >> 5 & 7; int t_bytesps = (libraw_internal_data.unpacker_data.thumb_misc & 31) / 8; if (!ID.toffset && !(imgdata.thumbnail.tlength > 0 && load_raw == &LibRaw::broadcom_load_raw) // RPi #ifdef USE_6BY9RPI && !(imgdata.thumbnail.tlength > 0 && libraw_internal_data.unpacker_data.load_flags & 0x4000 && (load_raw == &LibRaw::rpi_load_raw8 || load_raw == &LibRaw::nokia_load_raw || load_raw == &LibRaw::rpi_load_raw12 || load_raw == &LibRaw::rpi_load_raw14)) #endif ) { return LIBRAW_NO_THUMBNAIL; } else if ((Tformat >= LIBRAW_INTERNAL_THUMBNAIL_KODAK_THUMB) && ((Tformat <= LIBRAW_INTERNAL_THUMBNAIL_KODAK_RGB))) { kodak_thumb_loader(); T.tformat = LIBRAW_THUMBNAIL_BITMAP; SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); return 0; } else { #ifdef USE_X3FTOOLS if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_X3F) { INT64 tsize = x3f_thumb_size(); if (tsize < 2048 || INT64(ID.toffset) + tsize < 1) throw LIBRAW_EXCEPTION_IO_CORRUPT; if (INT64(ID.toffset) + tsize > ID.input->size() + THUMB_READ_BEYOND) throw LIBRAW_EXCEPTION_IO_EOF; THUMB_SIZE_CHECKT(tsize); } #else if (0) {} #endif else { if (INT64(ID.toffset) + INT64(T.tlength) < 1) throw LIBRAW_EXCEPTION_IO_CORRUPT; if (INT64(ID.toffset) + INT64(T.tlength) > ID.input->size() + THUMB_READ_BEYOND) throw LIBRAW_EXCEPTION_IO_EOF; } ID.input->seek(ID.toffset, SEEK_SET); if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_JPEG) { THUMB_SIZE_CHECKTNZ(T.tlength); if (T.thumb) free(T.thumb); #ifdef LIBRAW_CALLOC_RAWSTORE T.thumb = (char *)calloc(T.tlength,1); #else T.thumb = (char *)malloc(T.tlength); #endif ID.input->read(T.thumb, 1, T.tlength); unsigned char *tthumb = (unsigned char *)T.thumb; if (load_raw == &LibRaw::crxLoadRaw && T.tlength > 0xE0) { // Check if it is canon H.265 preview: CISZ at bytes 4-6, CISZ prefix is 000n if (tthumb[0] == 0 && tthumb[1] == 0 && tthumb[2] == 0 && !memcmp(tthumb + 4, "CISZ", 4)) { T.tformat = LIBRAW_THUMBNAIL_H265; SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); return 0; } } tthumb[0] = 0xff; tthumb[1] = 0xd8; #ifdef NO_JPEG T.tcolors = 3; #else { jpegErrorManager jerr; struct jpeg_decompress_struct cinfo; cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = jpegErrorExit; if (setjmp(jerr.setjmp_buffer)) { err2: // Error in original JPEG thumb, read it again because // original bytes 0-1 was damaged above jpeg_destroy_decompress(&cinfo); T.tcolors = 3; T.tformat = LIBRAW_THUMBNAIL_UNKNOWN; ID.input->seek(ID.toffset, SEEK_SET); ID.input->read(T.thumb, 1, T.tlength); SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); return 0; } jpeg_create_decompress(&cinfo); jpeg_mem_src(&cinfo, (unsigned char *)T.thumb, T.tlength); int rc = jpeg_read_header(&cinfo, TRUE); if (rc != 1) goto err2; T.tcolors = (cinfo.num_components > 0 && cinfo.num_components <= 3) ? cinfo.num_components : 3; jpeg_destroy_decompress(&cinfo); } #endif T.tformat = LIBRAW_THUMBNAIL_JPEG; SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); return 0; } else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_LAYER) { int colors = libraw_internal_data.unpacker_data.thumb_misc >> 5 & 7; if (colors != 1 && colors != 3) return LIBRAW_UNSUPPORTED_THUMBNAIL; THUMB_SIZE_CHECKWH(T.twidth, T.theight); int tlength = T.twidth * T.theight; if (T.thumb) free(T.thumb); T.thumb = (char *)calloc(colors, tlength); unsigned char *tbuf = (unsigned char *)calloc(colors, tlength); // Avoid OOB of tbuf, should use tlength ID.input->read(tbuf, colors, tlength); if (libraw_internal_data.unpacker_data.thumb_misc >> 8 && colors == 3) // GRB order for (int i = 0; i < tlength; i++) { T.thumb[i * 3] = tbuf[i + tlength]; T.thumb[i * 3 + 1] = tbuf[i]; T.thumb[i * 3 + 2] = tbuf[i + 2 * tlength]; } else if (colors == 3) // RGB or 1-channel for (int i = 0; i < tlength; i++) { T.thumb[i * 3] = tbuf[i]; T.thumb[i * 3 + 1] = tbuf[i + tlength]; T.thumb[i * 3 + 2] = tbuf[i + 2 * tlength]; } else if (colors == 1) { free(T.thumb); T.thumb = (char *)tbuf; tbuf = 0; } if (tbuf) free(tbuf); T.tcolors = colors; T.tlength = colors * tlength; T.tformat = LIBRAW_THUMBNAIL_BITMAP; SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); return 0; } else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_ROLLEI) { int i; THUMB_SIZE_CHECKWH(T.twidth, T.theight); int tlength = T.twidth * T.theight; if (T.thumb) free(T.thumb); T.tcolors = 3; T.thumb = (char *)calloc(T.tcolors, tlength); unsigned short *tbuf = (unsigned short *)calloc(2, tlength); read_shorts(tbuf, tlength); for (i = 0; i < tlength; i++) { T.thumb[i * 3] = (tbuf[i] << 3) & 0xff; T.thumb[i * 3 + 1] = (tbuf[i] >> 5 << 2) & 0xff; T.thumb[i * 3 + 2] = (tbuf[i] >> 11 << 3) & 0xff; } free(tbuf); T.tlength = T.tcolors * tlength; T.tformat = LIBRAW_THUMBNAIL_BITMAP; SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); return 0; } else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_PPM) { if (t_bytesps > 1) throw LIBRAW_EXCEPTION_IO_CORRUPT; // 8-bit thumb, but parsed for more // bits THUMB_SIZE_CHECKWH(T.twidth, T.theight); int t_length = T.twidth * T.theight * t_colors; if (T.tlength && (int)T.tlength < t_length) // try to find tiff ifd with needed offset { int pifd = find_ifd_by_offset(libraw_internal_data.internal_data.toffset); if (pifd >= 0 && tiff_ifd[pifd].strip_offsets_count && tiff_ifd[pifd].strip_byte_counts_count) { // We found it, calculate final size INT64 total_size = 0; for (int i = 0; i < tiff_ifd[pifd].strip_byte_counts_count && i < tiff_ifd[pifd].strip_offsets_count; i++) total_size += tiff_ifd[pifd].strip_byte_counts[i]; if (total_size != (unsigned)t_length) // recalculate colors { if (total_size == T.twidth * T.tlength * 3) T.tcolors = 3; else if (total_size == T.twidth * T.tlength) T.tcolors = 1; } T.tlength = total_size; THUMB_SIZE_CHECKTNZ(T.tlength); if (T.thumb) free(T.thumb); #ifdef LIBRAW_CALLOC_RAWSTORE T.thumb = (char *)calloc(T.tlength,1); #else T.thumb = (char *)malloc(T.tlength); #endif char *dest = T.thumb; INT64 pos = ID.input->tell(); INT64 remain = T.tlength; for (int i = 0; i < tiff_ifd[pifd].strip_byte_counts_count && i < tiff_ifd[pifd].strip_offsets_count; i++) { int sz = tiff_ifd[pifd].strip_byte_counts[i]; INT64 off = tiff_ifd[pifd].strip_offsets[i]; if (off >= 0 && off + sz <= ID.input->size() && sz > 0 && INT64(sz) <= remain) { ID.input->seek(off, SEEK_SET); ID.input->read(dest, sz, 1); remain -= sz; dest += sz; } } ID.input->seek(pos, SEEK_SET); T.tformat = LIBRAW_THUMBNAIL_BITMAP; SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); return 0; } } if (!T.tlength) T.tlength = t_length; if (T.thumb) free(T.thumb); THUMB_SIZE_CHECKTNZ(T.tlength); #ifdef LIBRAW_CALLOC_RAWSTORE T.thumb = (char *)calloc(T.tlength,1); #else T.thumb = (char *)malloc(T.tlength); #endif if (!T.tcolors) T.tcolors = t_colors; ID.input->read(T.thumb, 1, T.tlength); T.tformat = LIBRAW_THUMBNAIL_BITMAP; SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); return 0; } else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_PPM16) { if (t_bytesps > 2) throw LIBRAW_EXCEPTION_IO_CORRUPT; // 16-bit thumb, but parsed for // more bits int o_bps = (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_USE_PPM16_THUMBS) ? 2 : 1; int o_length = T.twidth * T.theight * t_colors * o_bps; int i_length = T.twidth * T.theight * t_colors * 2; THUMB_SIZE_CHECKTNZ(o_length); THUMB_SIZE_CHECKTNZ(i_length); ushort *t_thumb = (ushort *)calloc(i_length, 1); if (!t_thumb) throw LIBRAW_EXCEPTION_ALLOC; ID.input->read(t_thumb, 1, i_length); if ((libraw_internal_data.unpacker_data.order == 0x4949) == (ntohs(0x1234) == 0x1234)) libraw_swab(t_thumb, i_length); if (T.thumb) free(T.thumb); if ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_USE_PPM16_THUMBS)) { T.thumb = (char *)t_thumb; T.tformat = LIBRAW_THUMBNAIL_BITMAP16; T.tlength = i_length; } else { #ifdef LIBRAW_CALLOC_RAWSTORE T.thumb = (char *)calloc(o_length,1); #else T.thumb = (char *)malloc(o_length); #endif if (!T.thumb) throw LIBRAW_EXCEPTION_ALLOC; for (int i = 0; i < o_length; i++) T.thumb[i] = t_thumb[i] >> 8; free(t_thumb); T.tformat = LIBRAW_THUMBNAIL_BITMAP; T.tlength = o_length; } SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); return 0; } #ifdef USE_X3FTOOLS else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_X3F) { x3f_thumb_loader(); SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); return 0; } #endif else { return LIBRAW_UNSUPPORTED_THUMBNAIL; } } // last resort return LIBRAW_UNSUPPORTED_THUMBNAIL; /* warned as unreachable*/ } catch (const LibRaw_exceptions& err) { EXCEPTION_HANDLER(err); } } LibRaw-0.21.4/src/demosaic/000077500000000000000000000000001477673233700153545ustar00rootroot00000000000000LibRaw-0.21.4/src/demosaic/aahd_demosaic.cpp000066400000000000000000000561501477673233700206300ustar00rootroot00000000000000/* -*- C++ -*- * File: aahd_demosaic.cpp * Copyright 2013 Anton Petrusevich * Created: Wed May 15, 2013 * * This code is licensed under 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 "../../internal/dmp_include.h" typedef ushort ushort3[3]; typedef int int3[3]; #ifndef Pnw #define Pnw (-1 - nr_width) #define Pn (-nr_width) #define Pne (+1 - nr_width) #define Pe (+1) #define Pse (+1 + nr_width) #define Ps (+nr_width) #define Psw (-1 + nr_width) #define Pw (-1) #endif struct AAHD { int nr_height, nr_width; static const int nr_margin = 4; static const int Thot = 4; static const int Tdead = 4; static const int OverFraction = 8; ushort3 *rgb_ahd[2]; int3 *yuv[2]; char *ndir, *homo[2]; ushort channel_maximum[3], channels_max; ushort channel_minimum[3]; static const float yuv_coeff[3][3]; static float gammaLUT[0x10000]; float yuv_cam[3][3]; LibRaw &libraw; enum { HVSH = 1, HOR = 2, VER = 4, HORSH = HOR | HVSH, VERSH = VER | HVSH, HOT = 8 }; static inline float calc_dist(int c1, int c2) throw() { return c1 > c2 ? (float)c1 / c2 : (float)c2 / c1; } int inline Y(ushort3 &rgb) throw() { return yuv_cam[0][0] * rgb[0] + yuv_cam[0][1] * rgb[1] + yuv_cam[0][2] * rgb[2]; } int inline U(ushort3 &rgb) throw() { return yuv_cam[1][0] * rgb[0] + yuv_cam[1][1] * rgb[1] + yuv_cam[1][2] * rgb[2]; } int inline V(ushort3 &rgb) throw() { return yuv_cam[2][0] * rgb[0] + yuv_cam[2][1] * rgb[1] + yuv_cam[2][2] * rgb[2]; } inline int nr_offset(int row, int col) throw() { return (row * nr_width + col); } ~AAHD(); AAHD(LibRaw &_libraw); void make_ahd_greens(); void make_ahd_gline(int i); void make_ahd_rb(); void make_ahd_rb_hv(int i); void make_ahd_rb_last(int i); void evaluate_ahd(); void combine_image(); void hide_hots(); void refine_hv_dirs(); void refine_hv_dirs(int i, int js); void refine_ihv_dirs(int i); void illustrate_dirs(); void illustrate_dline(int i); }; const float AAHD::yuv_coeff[3][3] = { // YPbPr // { // 0.299f, // 0.587f, // 0.114f }, // { // -0.168736, // -0.331264f, // 0.5f }, // { // 0.5f, // -0.418688f, // -0.081312f } // // Rec. 2020 // Y'= 0,2627R' + 0,6780G' + 0,0593B' // U = (B-Y)/1.8814 = (-0,2627R' - 0,6780G' + 0.9407B) / 1.8814 = //-0.13963R - 0.36037G + 0.5B // V = (R-Y)/1.4647 = (0.7373R - 0,6780G - 0,0593B) / 1.4647 = 0.5R - //0.4629G - 0.04049B {+0.2627f, +0.6780f, +0.0593f}, {-0.13963f, -0.36037f, +0.5f}, {+0.5034f, -0.4629f, -0.0405f} }; float AAHD::gammaLUT[0x10000] = {-1.f}; AAHD::AAHD(LibRaw &_libraw) : libraw(_libraw) { nr_height = libraw.imgdata.sizes.iheight + nr_margin * 2; nr_width = libraw.imgdata.sizes.iwidth + nr_margin * 2; rgb_ahd[0] = (ushort3 *)calloc(nr_height * nr_width, (sizeof(ushort3) * 2 + sizeof(int3) * 2 + 3)); if (!rgb_ahd[0]) throw LIBRAW_EXCEPTION_ALLOC; rgb_ahd[1] = rgb_ahd[0] + nr_height * nr_width; yuv[0] = (int3 *)(rgb_ahd[1] + nr_height * nr_width); yuv[1] = yuv[0] + nr_height * nr_width; ndir = (char *)(yuv[1] + nr_height * nr_width); homo[0] = ndir + nr_height * nr_width; homo[1] = homo[0] + nr_height * nr_width; channel_maximum[0] = channel_maximum[1] = channel_maximum[2] = 0; channel_minimum[0] = libraw.imgdata.image[0][0]; channel_minimum[1] = libraw.imgdata.image[0][1]; channel_minimum[2] = libraw.imgdata.image[0][2]; int iwidth = libraw.imgdata.sizes.iwidth; for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) { yuv_cam[i][j] = 0; for (int k = 0; k < 3; ++k) yuv_cam[i][j] += yuv_coeff[i][k] * libraw.imgdata.color.rgb_cam[k][j]; } if (gammaLUT[0] < -0.1f) { float r; for (int i = 0; i < 0x10000; i++) { r = (float)i / 0x10000; gammaLUT[i] = 0x10000 * (r < 0.0181 ? 4.5f * r : 1.0993f * pow(r, 0.45f) - .0993f); } } for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { int col_cache[48]; for (int j = 0; j < 48; ++j) { int c = libraw.COLOR(i, j); if (c == 3) c = 1; col_cache[j] = c; } int moff = nr_offset(i + nr_margin, nr_margin); for (int j = 0; j < iwidth; ++j, ++moff) { int c = col_cache[j % 48]; unsigned short d = libraw.imgdata.image[i * iwidth + j][c]; if (d != 0) { if (channel_maximum[c] < d) channel_maximum[c] = d; if (channel_minimum[c] > d) channel_minimum[c] = d; rgb_ahd[1][moff][c] = rgb_ahd[0][moff][c] = d; } } } channels_max = MAX(MAX(channel_maximum[0], channel_maximum[1]), channel_maximum[2]); } void AAHD::hide_hots() { int iwidth = libraw.imgdata.sizes.iwidth; for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { int js = libraw.COLOR(i, 0) & 1; int kc = libraw.COLOR(i, js); /* * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ */ int moff = nr_offset(i + nr_margin, nr_margin + js); for (int j = js; j < iwidth; j += 2, moff += 2) { ushort3 *rgb = &rgb_ahd[0][moff]; int c = rgb[0][kc]; if ((c > rgb[2 * Pe][kc] && c > rgb[2 * Pw][kc] && c > rgb[2 * Pn][kc] && c > rgb[2 * Ps][kc] && c > rgb[Pe][1] && c > rgb[Pw][1] && c > rgb[Pn][1] && c > rgb[Ps][1]) || (c < rgb[2 * Pe][kc] && c < rgb[2 * Pw][kc] && c < rgb[2 * Pn][kc] && c < rgb[2 * Ps][kc] && c < rgb[Pe][1] && c < rgb[Pw][1] && c < rgb[Pn][1] && c < rgb[Ps][1])) { int chot = c >> Thot; int cdead = c << Tdead; int avg = 0; for (int k = -2; k < 3; k += 2) for (int m = -2; m < 3; m += 2) if (m == 0 && k == 0) continue; else avg += rgb[nr_offset(k, m)][kc]; avg /= 8; if (chot > avg || cdead < avg) { ndir[moff] |= HOT; int dh = ABS(rgb[2 * Pw][kc] - rgb[2 * Pe][kc]) + ABS(rgb[Pw][1] - rgb[Pe][1]) + ABS(rgb[Pw][1] - rgb[Pe][1] + rgb[2 * Pe][kc] - rgb[2 * Pw][kc]); int dv = ABS(rgb[2 * Pn][kc] - rgb[2 * Ps][kc]) + ABS(rgb[Pn][1] - rgb[Ps][1]) + ABS(rgb[Pn][1] - rgb[Ps][1] + rgb[2 * Ps][kc] - rgb[2 * Pn][kc]); int d; if (dv > dh) d = Pw; else d = Pn; rgb_ahd[1][moff][kc] = rgb[0][kc] = (rgb[+2 * d][kc] + rgb[-2 * d][kc]) / 2; } } } js ^= 1; moff = nr_offset(i + nr_margin, nr_margin + js); for (int j = js; j < iwidth; j += 2, moff += 2) { ushort3 *rgb = &rgb_ahd[0][moff]; int c = rgb[0][1]; if ((c > rgb[2 * Pe][1] && c > rgb[2 * Pw][1] && c > rgb[2 * Pn][1] && c > rgb[2 * Ps][1] && c > rgb[Pe][kc] && c > rgb[Pw][kc] && c > rgb[Pn][kc ^ 2] && c > rgb[Ps][kc ^ 2]) || (c < rgb[2 * Pe][1] && c < rgb[2 * Pw][1] && c < rgb[2 * Pn][1] && c < rgb[2 * Ps][1] && c < rgb[Pe][kc] && c < rgb[Pw][kc] && c < rgb[Pn][kc ^ 2] && c < rgb[Ps][kc ^ 2])) { int chot = c >> Thot; int cdead = c << Tdead; int avg = 0; for (int k = -2; k < 3; k += 2) for (int m = -2; m < 3; m += 2) if (k == 0 && m == 0) continue; else avg += rgb[nr_offset(k, m)][1]; avg /= 8; if (chot > avg || cdead < avg) { ndir[moff] |= HOT; int dh = ABS(rgb[2 * Pw][1] - rgb[2 * Pe][1]) + ABS(rgb[Pw][kc] - rgb[Pe][kc]) + ABS(rgb[Pw][kc] - rgb[Pe][kc] + rgb[2 * Pe][1] - rgb[2 * Pw][1]); int dv = ABS(rgb[2 * Pn][1] - rgb[2 * Ps][1]) + ABS(rgb[Pn][kc ^ 2] - rgb[Ps][kc ^ 2]) + ABS(rgb[Pn][kc ^ 2] - rgb[Ps][kc ^ 2] + rgb[2 * Ps][1] - rgb[2 * Pn][1]); int d; if (dv > dh) d = Pw; else d = Pn; rgb_ahd[1][moff][1] = rgb[0][1] = (rgb[+2 * d][1] + rgb[-2 * d][1]) / 2; } } } } } void AAHD::evaluate_ahd() { int hvdir[4] = {Pw, Pe, Pn, Ps}; /* * YUV * */ for (int d = 0; d < 2; ++d) { for (int i = 0; i < nr_width * nr_height; ++i) { ushort3 rgb; for (int c = 0; c < 3; ++c) { rgb[c] = gammaLUT[rgb_ahd[d][i][c]]; } yuv[d][i][0] = Y(rgb); yuv[d][i][1] = U(rgb); yuv[d][i][2] = V(rgb); } } /* */ /* * Lab * float r, cbrt[0x10000], xyz[3], xyz_cam[3][4]; for (int i = 0; i < 0x10000; i++) { r = i / 65535.0; cbrt[i] = r > 0.008856 ? pow((double) r, (double) (1 / 3.0)) : 7.787 * r + 16 / 116.0; } for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) { xyz_cam[i][j] = 0; for (int k = 0; k < 3; k++) xyz_cam[i][j] += xyz_rgb[i][k] * libraw.imgdata.color.rgb_cam[k][j] / d65_white[i]; } for (int d = 0; d < 2; ++d) for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { int moff = nr_offset(i + nr_margin, nr_margin); for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff) { xyz[0] = xyz[1] = xyz[2] = 0.5; for (int c = 0; c < 3; c++) { xyz[0] += xyz_cam[0][c] * rgb_ahd[d][moff][c]; xyz[1] += xyz_cam[1][c] * rgb_ahd[d][moff][c]; xyz[2] += xyz_cam[2][c] * rgb_ahd[d][moff][c]; } xyz[0] = cbrt[CLIP((int) xyz[0])]; xyz[1] = cbrt[CLIP((int) xyz[1])]; xyz[2] = cbrt[CLIP((int) xyz[2])]; yuv[d][moff][0] = 64 * (116 * xyz[1] - 16); yuv[d][moff][1] = 64 * 500 * (xyz[0] - xyz[1]); yuv[d][moff][2] = 64 * 200 * (xyz[1] - xyz[2]); } } * Lab */ for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { int moff = nr_offset(i + nr_margin, nr_margin); for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff) { int3 *ynr; float ydiff[2][4]; int uvdiff[2][4]; for (int d = 0; d < 2; ++d) { ynr = &yuv[d][moff]; for (int k = 0; k < 4; k++) { ydiff[d][k] = ABS(ynr[0][0] - ynr[hvdir[k]][0]); uvdiff[d][k] = SQR(ynr[0][1] - ynr[hvdir[k]][1]) + SQR(ynr[0][2] - ynr[hvdir[k]][2]); } } float yeps = MIN(MAX(ydiff[0][0], ydiff[0][1]), MAX(ydiff[1][2], ydiff[1][3])); int uveps = MIN(MAX(uvdiff[0][0], uvdiff[0][1]), MAX(uvdiff[1][2], uvdiff[1][3])); for (int d = 0; d < 2; d++) { ynr = &yuv[d][moff]; for (int k = 0; k < 4; k++) if (ydiff[d][k] <= yeps && uvdiff[d][k] <= uveps) { homo[d][moff + hvdir[k]]++; if (k / 2 == d) { // еÑли в Ñонаправленном направлении интеполÑции Ñледующие точки // так же гомогенны, учтём их тоже for (int m = 2; m < 4; ++m) { int hvd = m * hvdir[k]; if (ABS(ynr[0][0] - ynr[hvd][0]) < yeps && SQR(ynr[0][1] - ynr[hvd][1]) + SQR(ynr[0][2] - ynr[hvd][2]) < uveps) { homo[d][moff + hvd]++; } else break; } } } } } } for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { int moff = nr_offset(i + nr_margin, nr_margin); for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff) { char hm[2]; for (int d = 0; d < 2; d++) { hm[d] = 0; char *hh = &homo[d][moff]; for (int hx = -1; hx < 2; hx++) for (int hy = -1; hy < 2; hy++) hm[d] += hh[nr_offset(hy, hx)]; } char d = 0; if (hm[0] != hm[1]) { if (hm[1] > hm[0]) { d = VERSH; } else { d = HORSH; } } else { int3 *ynr = &yuv[1][moff]; int gv = SQR(2 * ynr[0][0] - ynr[Pn][0] - ynr[Ps][0]); gv += SQR(2 * ynr[0][1] - ynr[Pn][1] - ynr[Ps][1]) + SQR(2 * ynr[0][2] - ynr[Pn][2] - ynr[Ps][2]); ynr = &yuv[1][moff + Pn]; gv += (SQR(2 * ynr[0][0] - ynr[Pn][0] - ynr[Ps][0]) + SQR(2 * ynr[0][1] - ynr[Pn][1] - ynr[Ps][1]) + SQR(2 * ynr[0][2] - ynr[Pn][2] - ynr[Ps][2])) / 2; ynr = &yuv[1][moff + Ps]; gv += (SQR(2 * ynr[0][0] - ynr[Pn][0] - ynr[Ps][0]) + SQR(2 * ynr[0][1] - ynr[Pn][1] - ynr[Ps][1]) + SQR(2 * ynr[0][2] - ynr[Pn][2] - ynr[Ps][2])) / 2; ynr = &yuv[0][moff]; int gh = SQR(2 * ynr[0][0] - ynr[Pw][0] - ynr[Pe][0]); gh += SQR(2 * ynr[0][1] - ynr[Pw][1] - ynr[Pe][1]) + SQR(2 * ynr[0][2] - ynr[Pw][2] - ynr[Pe][2]); ynr = &yuv[0][moff + Pw]; gh += (SQR(2 * ynr[0][0] - ynr[Pw][0] - ynr[Pe][0]) + SQR(2 * ynr[0][1] - ynr[Pw][1] - ynr[Pe][1]) + SQR(2 * ynr[0][2] - ynr[Pw][2] - ynr[Pe][2])) / 2; ynr = &yuv[0][moff + Pe]; gh += (SQR(2 * ynr[0][0] - ynr[Pw][0] - ynr[Pe][0]) + SQR(2 * ynr[0][1] - ynr[Pw][1] - ynr[Pe][1]) + SQR(2 * ynr[0][2] - ynr[Pw][2] - ynr[Pe][2])) / 2; if (gv > gh) d = HOR; else d = VER; } ndir[moff] |= d; } } } void AAHD::combine_image() { for (int i = 0, i_out = 0; i < libraw.imgdata.sizes.iheight; ++i) { int moff = nr_offset(i + nr_margin, nr_margin); for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff, ++i_out) { if (ndir[moff] & HOT) { int c = libraw.COLOR(i, j); rgb_ahd[1][moff][c] = rgb_ahd[0][moff][c] = libraw.imgdata.image[i_out][c]; } if (ndir[moff] & VER) { libraw.imgdata.image[i_out][0] = rgb_ahd[1][moff][0]; libraw.imgdata.image[i_out][3] = libraw.imgdata.image[i_out][1] = rgb_ahd[1][moff][1]; libraw.imgdata.image[i_out][2] = rgb_ahd[1][moff][2]; } else { libraw.imgdata.image[i_out][0] = rgb_ahd[0][moff][0]; libraw.imgdata.image[i_out][3] = libraw.imgdata.image[i_out][1] = rgb_ahd[0][moff][1]; libraw.imgdata.image[i_out][2] = rgb_ahd[0][moff][2]; } } } } void AAHD::refine_hv_dirs() { for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { refine_hv_dirs(i, i & 1); } for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { refine_hv_dirs(i, (i & 1) ^ 1); } for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { refine_ihv_dirs(i); } } void AAHD::refine_ihv_dirs(int i) { int iwidth = libraw.imgdata.sizes.iwidth; int moff = nr_offset(i + nr_margin, nr_margin); for (int j = 0; j < iwidth; j++, ++moff) { if (ndir[moff] & HVSH) continue; int nv = (ndir[moff + Pn] & VER) + (ndir[moff + Ps] & VER) + (ndir[moff + Pw] & VER) + (ndir[moff + Pe] & VER); int nh = (ndir[moff + Pn] & HOR) + (ndir[moff + Ps] & HOR) + (ndir[moff + Pw] & HOR) + (ndir[moff + Pe] & HOR); nv /= VER; nh /= HOR; if ((ndir[moff] & VER) && nh > 3) { ndir[moff] &= ~VER; ndir[moff] |= HOR; } if ((ndir[moff] & HOR) && nv > 3) { ndir[moff] &= ~HOR; ndir[moff] |= VER; } } } void AAHD::refine_hv_dirs(int i, int js) { int iwidth = libraw.imgdata.sizes.iwidth; int moff = nr_offset(i + nr_margin, nr_margin + js); for (int j = js; j < iwidth; j += 2, moff += 2) { int nv = (ndir[moff + Pn] & VER) + (ndir[moff + Ps] & VER) + (ndir[moff + Pw] & VER) + (ndir[moff + Pe] & VER); int nh = (ndir[moff + Pn] & HOR) + (ndir[moff + Ps] & HOR) + (ndir[moff + Pw] & HOR) + (ndir[moff + Pe] & HOR); bool codir = (ndir[moff] & VER) ? ((ndir[moff + Pn] & VER) || (ndir[moff + Ps] & VER)) : ((ndir[moff + Pw] & HOR) || (ndir[moff + Pe] & HOR)); nv /= VER; nh /= HOR; if ((ndir[moff] & VER) && (nh > 2 && !codir)) { ndir[moff] &= ~VER; ndir[moff] |= HOR; } if ((ndir[moff] & HOR) && (nv > 2 && !codir)) { ndir[moff] &= ~HOR; ndir[moff] |= VER; } } } /* * вычиÑление недоÑтающих зелёных точек. */ void AAHD::make_ahd_greens() { for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { make_ahd_gline(i); } } void AAHD::make_ahd_gline(int i) { int iwidth = libraw.imgdata.sizes.iwidth; int js = libraw.COLOR(i, 0) & 1; int kc = libraw.COLOR(i, js); /* * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ */ int hvdir[2] = {Pe, Ps}; for (int d = 0; d < 2; ++d) { int moff = nr_offset(i + nr_margin, nr_margin + js); for (int j = js; j < iwidth; j += 2, moff += 2) { ushort3 *cnr; cnr = &rgb_ahd[d][moff]; int h1 = 2 * cnr[-hvdir[d]][1] - int(cnr[-2 * hvdir[d]][kc] + cnr[0][kc]); int h2 = 2 * cnr[+hvdir[d]][1] - int(cnr[+2 * hvdir[d]][kc] + cnr[0][kc]); int h0 = (h1 + h2) / 4; int eg = cnr[0][kc] + h0; int min = MIN(cnr[-hvdir[d]][1], cnr[+hvdir[d]][1]); int max = MAX(cnr[-hvdir[d]][1], cnr[+hvdir[d]][1]); min -= min / OverFraction; max += max / OverFraction; if (eg < min) eg = min - sqrt(float(min - eg)); else if (eg > max) eg = max + sqrt(float(eg - max)); if (eg > channel_maximum[1]) eg = channel_maximum[1]; else if (eg < channel_minimum[1]) eg = channel_minimum[1]; cnr[0][1] = eg; } } } /* * Ð¾Ñ‚Ð»Ð°Ð´Ð¾Ñ‡Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ */ void AAHD::illustrate_dirs() { for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { illustrate_dline(i); } } void AAHD::illustrate_dline(int i) { int iwidth = libraw.imgdata.sizes.iwidth; for (int j = 0; j < iwidth; j++) { int x = j + nr_margin; int y = i + nr_margin; rgb_ahd[1][nr_offset(y, x)][0] = rgb_ahd[1][nr_offset(y, x)][1] = rgb_ahd[1][nr_offset(y, x)][2] = rgb_ahd[0][nr_offset(y, x)][0] = rgb_ahd[0][nr_offset(y, x)][1] = rgb_ahd[0][nr_offset(y, x)][2] = 0; int l = ndir[nr_offset(y, x)] & HVSH; l /= HVSH; if (ndir[nr_offset(y, x)] & VER) rgb_ahd[1][nr_offset(y, x)][0] = l * channel_maximum[0] / 4 + channel_maximum[0] / 4; else rgb_ahd[0][nr_offset(y, x)][2] = l * channel_maximum[2] / 4 + channel_maximum[2] / 4; } } void AAHD::make_ahd_rb_hv(int i) { int iwidth = libraw.imgdata.sizes.iwidth; int js = libraw.COLOR(i, 0) & 1; int kc = libraw.COLOR(i, js); js ^= 1; // Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ ÐºÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð° зелёного int hvdir[2] = {Pe, Ps}; // интерполÑÑ†Ð¸Ñ Ð²ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»ÑŒÐ½Ñ‹Ñ… вертикально и горизонтальных горизонтально for (int j = js; j < iwidth; j += 2) { int x = j + nr_margin; int y = i + nr_margin; int moff = nr_offset(y, x); for (int d = 0; d < 2; ++d) { ushort3 *cnr; cnr = &rgb_ahd[d][moff]; int c = kc ^ (d << 1); // цвет ÑоответÑвенного направлениÑ, Ð´Ð»Ñ // горизонтального c = kc, Ð´Ð»Ñ Ð²ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ c=kc^2 int h1 = cnr[-hvdir[d]][c] - cnr[-hvdir[d]][1]; int h2 = cnr[+hvdir[d]][c] - cnr[+hvdir[d]][1]; int h0 = (h1 + h2) / 2; int eg = cnr[0][1] + h0; // int min = MIN(cnr[-hvdir[d]][c], cnr[+hvdir[d]][c]); // int max = MAX(cnr[-hvdir[d]][c], cnr[+hvdir[d]][c]); // min -= min / OverFraction; // max += max / OverFraction; // if (eg < min) // eg = min - sqrt(min - eg); // else if (eg > max) // eg = max + sqrt(eg - max); if (eg > channel_maximum[c]) eg = channel_maximum[c]; else if (eg < channel_minimum[c]) eg = channel_minimum[c]; cnr[0][c] = eg; } } } void AAHD::make_ahd_rb() { for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { make_ahd_rb_hv(i); } for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { make_ahd_rb_last(i); } } void AAHD::make_ahd_rb_last(int i) { int iwidth = libraw.imgdata.sizes.iwidth; int js = libraw.COLOR(i, 0) & 1; int kc = libraw.COLOR(i, js); /* * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ */ int dirs[2][3] = {{Pnw, Pn, Pne}, {Pnw, Pw, Psw}}; int moff = nr_offset(i + nr_margin, nr_margin); for (int j = 0; j < iwidth; j++) { for (int d = 0; d < 2; ++d) { ushort3 *cnr; cnr = &rgb_ahd[d][moff + j]; int c = kc ^ 2; if ((j & 1) != js) { // точка зелёного, Ð´Ð»Ñ Ð²ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½ÑƒÐ¶ÐµÐ½ альтернативный // Ñтрочному цвет c ^= d << 1; } int bh = 0, bk = 0; int bgd = 0; for (int k = 0; k < 3; ++k) for (int h = 0; h < 3; ++h) { // градиент зелёного Ð¿Ð»ÑŽÑ Ð³Ñ€Ð°Ð´Ð¸ÐµÐ½Ñ‚ {r,b} int gd = ABS(2 * cnr[0][1] - (cnr[+dirs[d][k]][1] + cnr[-dirs[d][h]][1])) + ABS(cnr[+dirs[d][k]][c] - cnr[-dirs[d][h]][c]) / 4 + ABS(cnr[+dirs[d][k]][c] - cnr[+dirs[d][k]][1] + cnr[-dirs[d][h]][1] - cnr[-dirs[d][h]][c]) / 4; if (bgd == 0 || gd < bgd) { bgd = gd; bh = h; bk = k; } } int h1 = cnr[+dirs[d][bk]][c] - cnr[+dirs[d][bk]][1]; int h2 = cnr[-dirs[d][bh]][c] - cnr[-dirs[d][bh]][1]; int eg = cnr[0][1] + (h1 + h2) / 2; // int min = MIN(cnr[+dirs[d][bk]][c], cnr[-dirs[d][bh]][c]); // int max = MAX(cnr[+dirs[d][bk]][c], cnr[-dirs[d][bh]][c]); // min -= min / OverFraction; // max += max / OverFraction; // if (eg < min) // eg = min - sqrt(min - eg); // else if (eg > max) // eg = max + sqrt(eg - max); if (eg > channel_maximum[c]) eg = channel_maximum[c]; else if (eg < channel_minimum[c]) eg = channel_minimum[c]; cnr[0][c] = eg; } } } AAHD::~AAHD() { free(rgb_ahd[0]); } void LibRaw::aahd_interpolate() { AAHD aahd(*this); aahd.hide_hots(); aahd.make_ahd_greens(); aahd.make_ahd_rb(); aahd.evaluate_ahd(); aahd.refine_hv_dirs(); // aahd.illustrate_dirs(); aahd.combine_image(); } LibRaw-0.21.4/src/demosaic/ahd_demosaic.cpp000066400000000000000000000245041477673233700204650ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" /* Adaptive Homogeneity-Directed interpolation is based on the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. */ void LibRaw::cielab(ushort rgb[3], short lab[3]) { int c, i, j, k; float r, xyz[3]; #ifdef LIBRAW_NOTHREADS static float cbrt[0x10000], xyz_cam[3][4]; #else #define cbrt tls->ahd_data.cbrt #define xyz_cam tls->ahd_data.xyz_cam #endif if (!rgb) { #ifndef LIBRAW_NOTHREADS if (cbrt[0] < -1.0f) #endif for (i = 0; i < 0x10000; i++) { r = i / 65535.0; cbrt[i] = r > 0.008856 ? pow(r, 1.f / 3.0f) : 7.787f * r + 16.f / 116.0f; } for (i = 0; i < 3; i++) for (j = 0; j < colors; j++) for (xyz_cam[i][j] = k = 0; k < 3; k++) xyz_cam[i][j] += LibRaw_constants::xyz_rgb[i][k] * rgb_cam[k][j] / LibRaw_constants::d65_white[i]; return; } xyz[0] = xyz[1] = xyz[2] = 0.5; FORCC { xyz[0] += xyz_cam[0][c] * rgb[c]; xyz[1] += xyz_cam[1][c] * rgb[c]; xyz[2] += xyz_cam[2][c] * rgb[c]; } xyz[0] = cbrt[CLIP((int)xyz[0])]; xyz[1] = cbrt[CLIP((int)xyz[1])]; xyz[2] = cbrt[CLIP((int)xyz[2])]; lab[0] = 64 * (116 * xyz[1] - 16); lab[1] = 64 * 500 * (xyz[0] - xyz[1]); lab[2] = 64 * 200 * (xyz[1] - xyz[2]); #ifndef LIBRAW_NOTHREADS #undef cbrt #undef xyz_cam #endif } void LibRaw::ahd_interpolate_green_h_and_v( int top, int left, ushort (*out_rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3]) { int row, col; int c, val; ushort(*pix)[4]; const int rowlimit = MIN(top + LIBRAW_AHD_TILE, height - 2); const int collimit = MIN(left + LIBRAW_AHD_TILE, width - 2); for (row = top; row < rowlimit; row++) { col = left + (FC(row, left) & 1); for (c = FC(row, col); col < collimit; col += 2) { pix = image + row * width + col; val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2 - pix[-2][c] - pix[2][c]) >> 2; out_rgb[0][row - top][col - left][1] = ULIM(val, pix[-1][1], pix[1][1]); val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2 - pix[-2 * width][c] - pix[2 * width][c]) >> 2; out_rgb[1][row - top][col - left][1] = ULIM(val, pix[-width][1], pix[width][1]); } } } void LibRaw::ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab( int top, int left, ushort (*inout_rgb)[LIBRAW_AHD_TILE][3], short (*out_lab)[LIBRAW_AHD_TILE][3]) { unsigned row, col; int c, val; ushort(*pix)[4]; ushort(*rix)[3]; short(*lix)[3]; const unsigned num_pix_per_row = 4 * width; const unsigned rowlimit = MIN(top + LIBRAW_AHD_TILE - 1, height - 3); const unsigned collimit = MIN(left + LIBRAW_AHD_TILE - 1, width - 3); ushort *pix_above; ushort *pix_below; int t1, t2; for (row = top + 1; row < rowlimit; row++) { pix = image + row * width + left; rix = &inout_rgb[row - top][0]; lix = &out_lab[row - top][0]; for (col = left + 1; col < collimit; col++) { pix++; pix_above = &pix[0][0] - num_pix_per_row; pix_below = &pix[0][0] + num_pix_per_row; rix++; lix++; c = 2 - FC(row, col); if (c == 1) { c = FC(row + 1, col); t1 = 2 - c; val = pix[0][1] + ((pix[-1][t1] + pix[1][t1] - rix[-1][1] - rix[1][1]) >> 1); rix[0][t1] = CLIP(val); val = pix[0][1] + ((pix_above[c] + pix_below[c] - rix[-LIBRAW_AHD_TILE][1] - rix[LIBRAW_AHD_TILE][1]) >> 1); } else { t1 = -4 + c; /* -4+c: pixel of color c to the left */ t2 = 4 + c; /* 4+c: pixel of color c to the right */ val = rix[0][1] + ((pix_above[t1] + pix_above[t2] + pix_below[t1] + pix_below[t2] - rix[-LIBRAW_AHD_TILE - 1][1] - rix[-LIBRAW_AHD_TILE + 1][1] - rix[+LIBRAW_AHD_TILE - 1][1] - rix[+LIBRAW_AHD_TILE + 1][1] + 1) >> 2); } rix[0][c] = CLIP(val); c = FC(row, col); rix[0][c] = pix[0][c]; cielab(rix[0], lix[0]); } } } void LibRaw::ahd_interpolate_r_and_b_and_convert_to_cielab( int top, int left, ushort (*inout_rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], short (*out_lab)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3]) { int direction; for (direction = 0; direction < 2; direction++) { ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab( top, left, inout_rgb[direction], out_lab[direction]); } } void LibRaw::ahd_interpolate_build_homogeneity_map( int top, int left, short (*lab)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], char (*out_homogeneity_map)[LIBRAW_AHD_TILE][2]) { int row, col; int tr; int direction; int i; short(*lix)[3]; short(*lixs[2])[3]; short *adjacent_lix; unsigned ldiff[2][4], abdiff[2][4], leps, abeps; static const int dir[4] = {-1, 1, -LIBRAW_AHD_TILE, LIBRAW_AHD_TILE}; const int rowlimit = MIN(top + LIBRAW_AHD_TILE - 2, height - 4); const int collimit = MIN(left + LIBRAW_AHD_TILE - 2, width - 4); int homogeneity; char(*homogeneity_map_p)[2]; memset(out_homogeneity_map, 0, 2 * LIBRAW_AHD_TILE * LIBRAW_AHD_TILE); for (row = top + 2; row < rowlimit; row++) { tr = row - top; homogeneity_map_p = &out_homogeneity_map[tr][1]; for (direction = 0; direction < 2; direction++) { lixs[direction] = &lab[direction][tr][1]; } for (col = left + 2; col < collimit; col++) { homogeneity_map_p++; for (direction = 0; direction < 2; direction++) { lix = ++lixs[direction]; for (i = 0; i < 4; i++) { adjacent_lix = lix[dir[i]]; ldiff[direction][i] = ABS(lix[0][0] - adjacent_lix[0]); abdiff[direction][i] = SQR(lix[0][1] - adjacent_lix[1]) + SQR(lix[0][2] - adjacent_lix[2]); } } leps = MIN(MAX(ldiff[0][0], ldiff[0][1]), MAX(ldiff[1][2], ldiff[1][3])); abeps = MIN(MAX(abdiff[0][0], abdiff[0][1]), MAX(abdiff[1][2], abdiff[1][3])); for (direction = 0; direction < 2; direction++) { homogeneity = 0; for (i = 0; i < 4; i++) { if (ldiff[direction][i] <= leps && abdiff[direction][i] <= abeps) { homogeneity++; } } homogeneity_map_p[0][direction] = homogeneity; } } } } void LibRaw::ahd_interpolate_combine_homogeneous_pixels( int top, int left, ushort (*rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], char (*homogeneity_map)[LIBRAW_AHD_TILE][2]) { int row, col; int tr, tc; int i, j; int direction; int hm[2]; int c; const int rowlimit = MIN(top + LIBRAW_AHD_TILE - 3, height - 5); const int collimit = MIN(left + LIBRAW_AHD_TILE - 3, width - 5); ushort(*pix)[4]; ushort(*rix[2])[3]; for (row = top + 3; row < rowlimit; row++) { tr = row - top; pix = &image[row * width + left + 2]; for (direction = 0; direction < 2; direction++) { rix[direction] = &rgb[direction][tr][2]; } for (col = left + 3; col < collimit; col++) { tc = col - left; pix++; for (direction = 0; direction < 2; direction++) { rix[direction]++; } for (direction = 0; direction < 2; direction++) { hm[direction] = 0; for (i = tr - 1; i <= tr + 1; i++) { for (j = tc - 1; j <= tc + 1; j++) { hm[direction] += homogeneity_map[i][j][direction]; } } } if (hm[0] != hm[1]) { memcpy(pix[0], rix[hm[1] > hm[0]][0], 3 * sizeof(ushort)); } else { FORC3 { pix[0][c] = (rix[0][0][c] + rix[1][0][c]) >> 1; } } } } } void LibRaw::ahd_interpolate() { int terminate_flag = 0; cielab(0, 0); border_interpolate(5); #ifdef LIBRAW_USE_OPENMP int buffer_count = omp_get_max_threads(); #else int buffer_count = 1; #endif size_t buffer_size = 26 * LIBRAW_AHD_TILE * LIBRAW_AHD_TILE; /* 1664 kB */ char** buffers = malloc_omp_buffers(buffer_count, buffer_size); #ifdef LIBRAW_USE_OPENMP #pragma omp parallel for schedule(dynamic) default(none) shared(terminate_flag) firstprivate(buffers) #endif for (int top = 2; top < height - 5; top += LIBRAW_AHD_TILE - 6) { #ifdef LIBRAW_USE_OPENMP if (0 == omp_get_thread_num()) #endif if (callbacks.progress_cb) { int rr = (*callbacks.progress_cb)(callbacks.progresscb_data, LIBRAW_PROGRESS_INTERPOLATE, top - 2, height - 7); if (rr) terminate_flag = 1; } #if defined(LIBRAW_USE_OPENMP) char* buffer = buffers[omp_get_thread_num()]; #else char* buffer = buffers[0]; #endif ushort(*rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3]; short(*lab)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3]; char(*homo)[LIBRAW_AHD_TILE][2]; rgb = (ushort(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3])buffer; lab = (short(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3])( buffer + 12 * LIBRAW_AHD_TILE * LIBRAW_AHD_TILE); homo = (char(*)[LIBRAW_AHD_TILE][2])(buffer + 24 * LIBRAW_AHD_TILE * LIBRAW_AHD_TILE); for (int left = 2; !terminate_flag && (left < width - 5); left += LIBRAW_AHD_TILE - 6) { ahd_interpolate_green_h_and_v(top, left, rgb); ahd_interpolate_r_and_b_and_convert_to_cielab(top, left, rgb, lab); ahd_interpolate_build_homogeneity_map(top, left, lab, homo); ahd_interpolate_combine_homogeneous_pixels(top, left, rgb, homo); } } free_omp_buffers(buffers, buffer_count); if (terminate_flag) throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; } LibRaw-0.21.4/src/demosaic/dcb_demosaic.cpp000066400000000000000000000770441477673233700204700ustar00rootroot00000000000000/* * Copyright (C) 2010, Jacek Gozdz (cuniek@kft.umcs.lublin.pl) * * This code is licensed under a (3-clause) BSD license as follows : * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following * conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the author nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ // DCB demosaicing by Jacek Gozdz (cuniek@kft.umcs.lublin.pl) // FBDD denoising by Jacek Gozdz (cuniek@kft.umcs.lublin.pl) and // Luis Sanz Rodríguez (luis.sanz.rodriguez@gmail.com) // last modification: 11.07.2010 #include "../../internal/dcraw_defs.h" // interpolates green vertically and saves it to image3 void LibRaw::dcb_ver(float (*image3)[3]) { int row, col, u = width, indx; for (row = 2; row < height - 2; row++) for (col = 2 + (FC(row, 2) & 1), indx = row * width + col; col < u - 2; col += 2, indx += 2) { image3[indx][1] = CLIP((image[indx + u][1] + image[indx - u][1]) / 2.0); } } // interpolates green horizontally and saves it to image2 void LibRaw::dcb_hor(float (*image2)[3]) { int row, col, u = width, indx; for (row = 2; row < height - 2; row++) for (col = 2 + (FC(row, 2) & 1), indx = row * width + col; col < u - 2; col += 2, indx += 2) { image2[indx][1] = CLIP((image[indx + 1][1] + image[indx - 1][1]) / 2.0); } } // missing colors are interpolated void LibRaw::dcb_color() { int row, col, c, d, u = width, indx; for (row = 1; row < height - 1; row++) for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, c = 2 - FC(row, col); col < u - 1; col += 2, indx += 2) { image[indx][c] = CLIP((4 * image[indx][1] - image[indx + u + 1][1] - image[indx + u - 1][1] - image[indx - u + 1][1] - image[indx - u - 1][1] + image[indx + u + 1][c] + image[indx + u - 1][c] + image[indx - u + 1][c] + image[indx - u - 1][c]) / 4.0); } for (row = 1; row < height - 1; row++) for (col = 1 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col + 1), d = 2 - c; col < width - 1; col += 2, indx += 2) { image[indx][c] = CLIP((2 * image[indx][1] - image[indx + 1][1] - image[indx - 1][1] + image[indx + 1][c] + image[indx - 1][c]) / 2.0); image[indx][d] = CLIP((2 * image[indx][1] - image[indx + u][1] - image[indx - u][1] + image[indx + u][d] + image[indx - u][d]) / 2.0); } } // missing R and B are interpolated horizontally and saved in image2 void LibRaw::dcb_color2(float (*image2)[3]) { int row, col, c, d, u = width, indx; for (row = 1; row < height - 1; row++) for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, c = 2 - FC(row, col); col < u - 1; col += 2, indx += 2) { image2[indx][c] = CLIP((4 * image2[indx][1] - image2[indx + u + 1][1] - image2[indx + u - 1][1] - image2[indx - u + 1][1] - image2[indx - u - 1][1] + image[indx + u + 1][c] + image[indx + u - 1][c] + image[indx - u + 1][c] + image[indx - u - 1][c]) / 4.0); } for (row = 1; row < height - 1; row++) for (col = 1 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col + 1), d = 2 - c; col < width - 1; col += 2, indx += 2) { image2[indx][c] = CLIP((image[indx + 1][c] + image[indx - 1][c]) / 2.0); image2[indx][d] = CLIP((2 * image2[indx][1] - image2[indx + u][1] - image2[indx - u][1] + image[indx + u][d] + image[indx - u][d]) / 2.0); } } // missing R and B are interpolated vertically and saved in image3 void LibRaw::dcb_color3(float (*image3)[3]) { int row, col, c, d, u = width, indx; for (row = 1; row < height - 1; row++) for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, c = 2 - FC(row, col); col < u - 1; col += 2, indx += 2) { image3[indx][c] = CLIP((4 * image3[indx][1] - image3[indx + u + 1][1] - image3[indx + u - 1][1] - image3[indx - u + 1][1] - image3[indx - u - 1][1] + image[indx + u + 1][c] + image[indx + u - 1][c] + image[indx - u + 1][c] + image[indx - u - 1][c]) / 4.0); } for (row = 1; row < height - 1; row++) for (col = 1 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col + 1), d = 2 - c; col < width - 1; col += 2, indx += 2) { image3[indx][c] = CLIP((2 * image3[indx][1] - image3[indx + 1][1] - image3[indx - 1][1] + image[indx + 1][c] + image[indx - 1][c]) / 2.0); image3[indx][d] = CLIP((image[indx + u][d] + image[indx - u][d]) / 2.0); } } // decides the primary green interpolation direction void LibRaw::dcb_decide(float (*image2)[3], float (*image3)[3]) { int row, col, c, d, u = width, v = 2 * u, indx; float current, current2, current3; for (row = 2; row < height - 2; row++) for (col = 2 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); col < u - 2; col += 2, indx += 2) { d = ABS(c - 2); current = MAX(image[indx + v][c], MAX(image[indx - v][c], MAX(image[indx - 2][c], image[indx + 2][c]))) - MIN(image[indx + v][c], MIN(image[indx - v][c], MIN(image[indx - 2][c], image[indx + 2][c]))) + MAX(image[indx + 1 + u][d], MAX(image[indx + 1 - u][d], MAX(image[indx - 1 + u][d], image[indx - 1 - u][d]))) - MIN(image[indx + 1 + u][d], MIN(image[indx + 1 - u][d], MIN(image[indx - 1 + u][d], image[indx - 1 - u][d]))); current2 = MAX(image2[indx + v][d], MAX(image2[indx - v][d], MAX(image2[indx - 2][d], image2[indx + 2][d]))) - MIN(image2[indx + v][d], MIN(image2[indx - v][d], MIN(image2[indx - 2][d], image2[indx + 2][d]))) + MAX(image2[indx + 1 + u][c], MAX(image2[indx + 1 - u][c], MAX(image2[indx - 1 + u][c], image2[indx - 1 - u][c]))) - MIN(image2[indx + 1 + u][c], MIN(image2[indx + 1 - u][c], MIN(image2[indx - 1 + u][c], image2[indx - 1 - u][c]))); current3 = MAX(image3[indx + v][d], MAX(image3[indx - v][d], MAX(image3[indx - 2][d], image3[indx + 2][d]))) - MIN(image3[indx + v][d], MIN(image3[indx - v][d], MIN(image3[indx - 2][d], image3[indx + 2][d]))) + MAX(image3[indx + 1 + u][c], MAX(image3[indx + 1 - u][c], MAX(image3[indx - 1 + u][c], image3[indx - 1 - u][c]))) - MIN(image3[indx + 1 + u][c], MIN(image3[indx + 1 - u][c], MIN(image3[indx - 1 + u][c], image3[indx - 1 - u][c]))); if (ABS(current - current2) < ABS(current - current3)) image[indx][1] = image2[indx][1]; else image[indx][1] = image3[indx][1]; } } // saves red and blue in image2 void LibRaw::dcb_copy_to_buffer(float (*image2)[3]) { int indx; for (indx = 0; indx < height * width; indx++) { image2[indx][0] = image[indx][0]; // R image2[indx][2] = image[indx][2]; // B } } // restores red and blue from image2 void LibRaw::dcb_restore_from_buffer(float (*image2)[3]) { int indx; for (indx = 0; indx < height * width; indx++) { image[indx][0] = image2[indx][0]; // R image[indx][2] = image2[indx][2]; // B } } // R and B smoothing using green contrast, all pixels except 2 pixel wide border void LibRaw::dcb_pp() { int g1, r1, b1, u = width, indx, row, col; for (row = 2; row < height - 2; row++) for (col = 2, indx = row * u + col; col < width - 2; col++, indx++) { r1 = (image[indx - 1][0] + image[indx + 1][0] + image[indx - u][0] + image[indx + u][0] + image[indx - u - 1][0] + image[indx + u + 1][0] + image[indx - u + 1][0] + image[indx + u - 1][0]) / 8.0; g1 = (image[indx - 1][1] + image[indx + 1][1] + image[indx - u][1] + image[indx + u][1] + image[indx - u - 1][1] + image[indx + u + 1][1] + image[indx - u + 1][1] + image[indx + u - 1][1]) / 8.0; b1 = (image[indx - 1][2] + image[indx + 1][2] + image[indx - u][2] + image[indx + u][2] + image[indx - u - 1][2] + image[indx + u + 1][2] + image[indx - u + 1][2] + image[indx + u - 1][2]) / 8.0; image[indx][0] = CLIP(r1 + (image[indx][1] - g1)); image[indx][2] = CLIP(b1 + (image[indx][1] - g1)); } } // green blurring correction, helps to get the nyquist right void LibRaw::dcb_nyquist() { int row, col, c, u = width, v = 2 * u, indx; for (row = 2; row < height - 2; row++) for (col = 2 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); col < u - 2; col += 2, indx += 2) { image[indx][1] = CLIP((image[indx + v][1] + image[indx - v][1] + image[indx - 2][1] + image[indx + 2][1]) / 4.0 + image[indx][c] - (image[indx + v][c] + image[indx - v][c] + image[indx - 2][c] + image[indx + 2][c]) / 4.0); } } // missing colors are interpolated using high quality algorithm by Luis Sanz // Rodríguez void LibRaw::dcb_color_full() { int row, col, c, d, u = width, w = 3 * u, indx, g1, g2; float f[4], g[4], (*chroma)[2]; chroma = (float(*)[2])calloc(width * height, sizeof *chroma); for (row = 1; row < height - 1; row++) for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, c = FC(row, col), d = c / 2; col < u - 1; col += 2, indx += 2) chroma[indx][d] = image[indx][c] - image[indx][1]; for (row = 3; row < height - 3; row++) for (col = 3 + (FC(row, 1) & 1), indx = row * width + col, c = 1 - FC(row, col) / 2, d = 1 - c; col < u - 3; col += 2, indx += 2) { f[0] = 1.0 / (float)(1.0 + fabs(chroma[indx - u - 1][c] - chroma[indx + u + 1][c]) + fabs(chroma[indx - u - 1][c] - chroma[indx - w - 3][c]) + fabs(chroma[indx + u + 1][c] - chroma[indx - w - 3][c])); f[1] = 1.0 / (float)(1.0 + fabs(chroma[indx - u + 1][c] - chroma[indx + u - 1][c]) + fabs(chroma[indx - u + 1][c] - chroma[indx - w + 3][c]) + fabs(chroma[indx + u - 1][c] - chroma[indx - w + 3][c])); f[2] = 1.0 / (float)(1.0 + fabs(chroma[indx + u - 1][c] - chroma[indx - u + 1][c]) + fabs(chroma[indx + u - 1][c] - chroma[indx + w + 3][c]) + fabs(chroma[indx - u + 1][c] - chroma[indx + w - 3][c])); f[3] = 1.0 / (float)(1.0 + fabs(chroma[indx + u + 1][c] - chroma[indx - u - 1][c]) + fabs(chroma[indx + u + 1][c] - chroma[indx + w - 3][c]) + fabs(chroma[indx - u - 1][c] - chroma[indx + w + 3][c])); g[0] = 1.325 * chroma[indx - u - 1][c] - 0.175 * chroma[indx - w - 3][c] - 0.075 * chroma[indx - w - 1][c] - 0.075 * chroma[indx - u - 3][c]; g[1] = 1.325 * chroma[indx - u + 1][c] - 0.175 * chroma[indx - w + 3][c] - 0.075 * chroma[indx - w + 1][c] - 0.075 * chroma[indx - u + 3][c]; g[2] = 1.325 * chroma[indx + u - 1][c] - 0.175 * chroma[indx + w - 3][c] - 0.075 * chroma[indx + w - 1][c] - 0.075 * chroma[indx + u - 3][c]; g[3] = 1.325 * chroma[indx + u + 1][c] - 0.175 * chroma[indx + w + 3][c] - 0.075 * chroma[indx + w + 1][c] - 0.075 * chroma[indx + u + 3][c]; chroma[indx][c] = (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / (f[0] + f[1] + f[2] + f[3]); } for (row = 3; row < height - 3; row++) for (col = 3 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col + 1) / 2; col < u - 3; col += 2, indx += 2) for (d = 0; d <= 1; c = 1 - c, d++) { f[0] = 1.0 / (float)(1.0 + fabs(chroma[indx - u][c] - chroma[indx + u][c]) + fabs(chroma[indx - u][c] - chroma[indx - w][c]) + fabs(chroma[indx + u][c] - chroma[indx - w][c])); f[1] = 1.0 / (float)(1.0 + fabs(chroma[indx + 1][c] - chroma[indx - 1][c]) + fabs(chroma[indx + 1][c] - chroma[indx + 3][c]) + fabs(chroma[indx - 1][c] - chroma[indx + 3][c])); f[2] = 1.0 / (float)(1.0 + fabs(chroma[indx - 1][c] - chroma[indx + 1][c]) + fabs(chroma[indx - 1][c] - chroma[indx - 3][c]) + fabs(chroma[indx + 1][c] - chroma[indx - 3][c])); f[3] = 1.0 / (float)(1.0 + fabs(chroma[indx + u][c] - chroma[indx - u][c]) + fabs(chroma[indx + u][c] - chroma[indx + w][c]) + fabs(chroma[indx - u][c] - chroma[indx + w][c])); g[0] = 0.875 * chroma[indx - u][c] + 0.125 * chroma[indx - w][c]; g[1] = 0.875 * chroma[indx + 1][c] + 0.125 * chroma[indx + 3][c]; g[2] = 0.875 * chroma[indx - 1][c] + 0.125 * chroma[indx - 3][c]; g[3] = 0.875 * chroma[indx + u][c] + 0.125 * chroma[indx + w][c]; chroma[indx][c] = (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / (f[0] + f[1] + f[2] + f[3]); } for (row = 6; row < height - 6; row++) for (col = 6, indx = row * width + col; col < width - 6; col++, indx++) { image[indx][0] = CLIP(chroma[indx][0] + image[indx][1]); image[indx][2] = CLIP(chroma[indx][1] + image[indx][1]); g1 = MIN( image[indx + 1 + u][0], MIN(image[indx + 1 - u][0], MIN(image[indx - 1 + u][0], MIN(image[indx - 1 - u][0], MIN(image[indx - 1][0], MIN(image[indx + 1][0], MIN(image[indx - u][0], image[indx + u][0]))))))); g2 = MAX( image[indx + 1 + u][0], MAX(image[indx + 1 - u][0], MAX(image[indx - 1 + u][0], MAX(image[indx - 1 - u][0], MAX(image[indx - 1][0], MAX(image[indx + 1][0], MAX(image[indx - u][0], image[indx + u][0]))))))); image[indx][0] = ULIM(image[indx][0], g2, g1); g1 = MIN( image[indx + 1 + u][2], MIN(image[indx + 1 - u][2], MIN(image[indx - 1 + u][2], MIN(image[indx - 1 - u][2], MIN(image[indx - 1][2], MIN(image[indx + 1][2], MIN(image[indx - u][2], image[indx + u][2]))))))); g2 = MAX( image[indx + 1 + u][2], MAX(image[indx + 1 - u][2], MAX(image[indx - 1 + u][2], MAX(image[indx - 1 - u][2], MAX(image[indx - 1][2], MAX(image[indx + 1][2], MAX(image[indx - u][2], image[indx + u][2]))))))); image[indx][2] = ULIM(image[indx][2], g2, g1); } free(chroma); } // green is used to create an interpolation direction map saved in image[][3] // 1 = vertical // 0 = horizontal void LibRaw::dcb_map() { int row, col, u = width, indx; for (row = 1; row < height - 1; row++) { for (col = 1, indx = row * width + col; col < width - 1; col++, indx++) { if (image[indx][1] > (image[indx - 1][1] + image[indx + 1][1] + image[indx - u][1] + image[indx + u][1]) / 4.0) image[indx][3] = ((MIN(image[indx - 1][1], image[indx + 1][1]) + image[indx - 1][1] + image[indx + 1][1]) < (MIN(image[indx - u][1], image[indx + u][1]) + image[indx - u][1] + image[indx + u][1])); else image[indx][3] = ((MAX(image[indx - 1][1], image[indx + 1][1]) + image[indx - 1][1] + image[indx + 1][1]) > (MAX(image[indx - u][1], image[indx + u][1]) + image[indx - u][1] + image[indx + u][1])); } } } // interpolated green pixels are corrected using the map void LibRaw::dcb_correction() { int current, row, col, u = width, v = 2 * u, indx; for (row = 2; row < height - 2; row++) for (col = 2 + (FC(row, 2) & 1), indx = row * width + col; col < u - 2; col += 2, indx += 2) { current = 4 * image[indx][3] + 2 * (image[indx + u][3] + image[indx - u][3] + image[indx + 1][3] + image[indx - 1][3]) + image[indx + v][3] + image[indx - v][3] + image[indx + 2][3] + image[indx - 2][3]; image[indx][1] = ((16 - current) * (image[indx - 1][1] + image[indx + 1][1]) / 2.0 + current * (image[indx - u][1] + image[indx + u][1]) / 2.0) / 16.0; } } // interpolated green pixels are corrected using the map // with contrast correction void LibRaw::dcb_correction2() { int current, row, col, c, u = width, v = 2 * u, indx; for (row = 4; row < height - 4; row++) for (col = 4 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); col < u - 4; col += 2, indx += 2) { current = 4 * image[indx][3] + 2 * (image[indx + u][3] + image[indx - u][3] + image[indx + 1][3] + image[indx - 1][3]) + image[indx + v][3] + image[indx - v][3] + image[indx + 2][3] + image[indx - 2][3]; image[indx][1] = CLIP( ((16 - current) * ((image[indx - 1][1] + image[indx + 1][1]) / 2.0 + image[indx][c] - (image[indx + 2][c] + image[indx - 2][c]) / 2.0) + current * ((image[indx - u][1] + image[indx + u][1]) / 2.0 + image[indx][c] - (image[indx + v][c] + image[indx - v][c]) / 2.0)) / 16.0); } } void LibRaw::dcb_refinement() { int row, col, c, u = width, v = 2 * u, w = 3 * u, indx, current; float f[5], g1, g2; for (row = 4; row < height - 4; row++) for (col = 4 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); col < u - 4; col += 2, indx += 2) { current = 4 * image[indx][3] + 2 * (image[indx + u][3] + image[indx - u][3] + image[indx + 1][3] + image[indx - 1][3]) + image[indx + v][3] + image[indx - v][3] + image[indx - 2][3] + image[indx + 2][3]; if (image[indx][c] > 1) { f[0] = (float)(image[indx - u][1] + image[indx + u][1]) / (2 * image[indx][c]); if (image[indx - v][c] > 0) f[1] = 2 * (float)image[indx - u][1] / (image[indx - v][c] + image[indx][c]); else f[1] = f[0]; if (image[indx - v][c] > 0) f[2] = (float)(image[indx - u][1] + image[indx - w][1]) / (2 * image[indx - v][c]); else f[2] = f[0]; if (image[indx + v][c] > 0) f[3] = 2 * (float)image[indx + u][1] / (image[indx + v][c] + image[indx][c]); else f[3] = f[0]; if (image[indx + v][c] > 0) f[4] = (float)(image[indx + u][1] + image[indx + w][1]) / (2 * image[indx + v][c]); else f[4] = f[0]; g1 = (5 * f[0] + 3 * f[1] + f[2] + 3 * f[3] + f[4]) / 13.0; f[0] = (float)(image[indx - 1][1] + image[indx + 1][1]) / (2 * image[indx][c]); if (image[indx - 2][c] > 0) f[1] = 2 * (float)image[indx - 1][1] / (image[indx - 2][c] + image[indx][c]); else f[1] = f[0]; if (image[indx - 2][c] > 0) f[2] = (float)(image[indx - 1][1] + image[indx - 3][1]) / (2 * image[indx - 2][c]); else f[2] = f[0]; if (image[indx + 2][c] > 0) f[3] = 2 * (float)image[indx + 1][1] / (image[indx + 2][c] + image[indx][c]); else f[3] = f[0]; if (image[indx + 2][c] > 0) f[4] = (float)(image[indx + 1][1] + image[indx + 3][1]) / (2 * image[indx + 2][c]); else f[4] = f[0]; g2 = (5 * f[0] + 3 * f[1] + f[2] + 3 * f[3] + f[4]) / 13.0; image[indx][1] = CLIP((image[indx][c]) * (current * g1 + (16 - current) * g2) / 16.0); } else image[indx][1] = image[indx][c]; // get rid of overshooted pixels g1 = MIN( image[indx + 1 + u][1], MIN(image[indx + 1 - u][1], MIN(image[indx - 1 + u][1], MIN(image[indx - 1 - u][1], MIN(image[indx - 1][1], MIN(image[indx + 1][1], MIN(image[indx - u][1], image[indx + u][1]))))))); g2 = MAX( image[indx + 1 + u][1], MAX(image[indx + 1 - u][1], MAX(image[indx - 1 + u][1], MAX(image[indx - 1 - u][1], MAX(image[indx - 1][1], MAX(image[indx + 1][1], MAX(image[indx - u][1], image[indx + u][1]))))))); image[indx][1] = ULIM(image[indx][1], g2, g1); } } // converts RGB to LCH colorspace and saves it to image3 void LibRaw::rgb_to_lch(double (*image2)[3]) { int indx; for (indx = 0; indx < height * width; indx++) { image2[indx][0] = image[indx][0] + image[indx][1] + image[indx][2]; // L image2[indx][1] = 1.732050808 * (image[indx][0] - image[indx][1]); // C image2[indx][2] = 2.0 * image[indx][2] - image[indx][0] - image[indx][1]; // H } } // converts LCH to RGB colorspace and saves it back to image void LibRaw::lch_to_rgb(double (*image2)[3]) { int indx; for (indx = 0; indx < height * width; indx++) { image[indx][0] = CLIP(image2[indx][0] / 3.0 - image2[indx][2] / 6.0 + image2[indx][1] / 3.464101615); image[indx][1] = CLIP(image2[indx][0] / 3.0 - image2[indx][2] / 6.0 - image2[indx][1] / 3.464101615); image[indx][2] = CLIP(image2[indx][0] / 3.0 + image2[indx][2] / 3.0); } } // denoising using interpolated neighbours void LibRaw::fbdd_correction() { int row, col, c, u = width, indx; for (row = 2; row < height - 2; row++) { for (col = 2, indx = row * width + col; col < width - 2; col++, indx++) { c = fcol(row, col); image[indx][c] = ULIM(image[indx][c], MAX(image[indx - 1][c], MAX(image[indx + 1][c], MAX(image[indx - u][c], image[indx + u][c]))), MIN(image[indx - 1][c], MIN(image[indx + 1][c], MIN(image[indx - u][c], image[indx + u][c])))); } } } // corrects chroma noise void LibRaw::fbdd_correction2(double (*image2)[3]) { int indx, v = 2 * width; int col, row; double Co, Ho, ratio; for (row = 6; row < height - 6; row++) { for (col = 6; col < width - 6; col++) { indx = row * width + col; if (image2[indx][1] * image2[indx][2] != 0) { Co = (image2[indx + v][1] + image2[indx - v][1] + image2[indx - 2][1] + image2[indx + 2][1] - MAX(image2[indx - 2][1], MAX(image2[indx + 2][1], MAX(image2[indx - v][1], image2[indx + v][1]))) - MIN(image2[indx - 2][1], MIN(image2[indx + 2][1], MIN(image2[indx - v][1], image2[indx + v][1])))) / 2.0; Ho = (image2[indx + v][2] + image2[indx - v][2] + image2[indx - 2][2] + image2[indx + 2][2] - MAX(image2[indx - 2][2], MAX(image2[indx + 2][2], MAX(image2[indx - v][2], image2[indx + v][2]))) - MIN(image2[indx - 2][2], MIN(image2[indx + 2][2], MIN(image2[indx - v][2], image2[indx + v][2])))) / 2.0; ratio = sqrt((Co * Co + Ho * Ho) / (image2[indx][1] * image2[indx][1] + image2[indx][2] * image2[indx][2])); if (ratio < 0.85) { image2[indx][0] = -(image2[indx][1] + image2[indx][2] - Co - Ho) + image2[indx][0]; image2[indx][1] = Co; image2[indx][2] = Ho; } } } } } // Cubic Spline Interpolation by Li and Randhawa, modified by Jacek Gozdz and // Luis Sanz Rodríguez void LibRaw::fbdd_green() { int row, col, c, u = width, v = 2 * u, w = 3 * u, x = 4 * u, y = 5 * u, indx, min, max; float f[4], g[4]; for (row = 5; row < height - 5; row++) for (col = 5 + (FC(row, 1) & 1), indx = row * width + col, c = FC(row, col); col < u - 5; col += 2, indx += 2) { f[0] = 1.0 / (1.0 + abs(image[indx - u][1] - image[indx - w][1]) + abs(image[indx - w][1] - image[indx + y][1])); f[1] = 1.0 / (1.0 + abs(image[indx + 1][1] - image[indx + 3][1]) + abs(image[indx + 3][1] - image[indx - 5][1])); f[2] = 1.0 / (1.0 + abs(image[indx - 1][1] - image[indx - 3][1]) + abs(image[indx - 3][1] - image[indx + 5][1])); f[3] = 1.0 / (1.0 + abs(image[indx + u][1] - image[indx + w][1]) + abs(image[indx + w][1] - image[indx - y][1])); g[0] = CLIP((23 * image[indx - u][1] + 23 * image[indx - w][1] + 2 * image[indx - y][1] + 8 * (image[indx - v][c] - image[indx - x][c]) + 40 * (image[indx][c] - image[indx - v][c])) / 48.0); g[1] = CLIP((23 * image[indx + 1][1] + 23 * image[indx + 3][1] + 2 * image[indx + 5][1] + 8 * (image[indx + 2][c] - image[indx + 4][c]) + 40 * (image[indx][c] - image[indx + 2][c])) / 48.0); g[2] = CLIP((23 * image[indx - 1][1] + 23 * image[indx - 3][1] + 2 * image[indx - 5][1] + 8 * (image[indx - 2][c] - image[indx - 4][c]) + 40 * (image[indx][c] - image[indx - 2][c])) / 48.0); g[3] = CLIP((23 * image[indx + u][1] + 23 * image[indx + w][1] + 2 * image[indx + y][1] + 8 * (image[indx + v][c] - image[indx + x][c]) + 40 * (image[indx][c] - image[indx + v][c])) / 48.0); image[indx][1] = CLIP((f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / (f[0] + f[1] + f[2] + f[3])); min = MIN( image[indx + 1 + u][1], MIN(image[indx + 1 - u][1], MIN(image[indx - 1 + u][1], MIN(image[indx - 1 - u][1], MIN(image[indx - 1][1], MIN(image[indx + 1][1], MIN(image[indx - u][1], image[indx + u][1]))))))); max = MAX( image[indx + 1 + u][1], MAX(image[indx + 1 - u][1], MAX(image[indx - 1 + u][1], MAX(image[indx - 1 - u][1], MAX(image[indx - 1][1], MAX(image[indx + 1][1], MAX(image[indx - u][1], image[indx + u][1]))))))); image[indx][1] = ULIM(image[indx][1], max, min); } } // FBDD (Fake Before Demosaicing Denoising) void LibRaw::fbdd(int noiserd) { double(*image2)[3]; // safety net: disable for 4-color bayer or full-color images if (colors != 3 || !filters) return; image2 = (double(*)[3])calloc(width * height, sizeof *image2); border_interpolate(4); if (noiserd > 1) { fbdd_green(); // dcb_color_full(image2); dcb_color_full(); fbdd_correction(); dcb_color(); rgb_to_lch(image2); fbdd_correction2(image2); fbdd_correction2(image2); lch_to_rgb(image2); } else { fbdd_green(); // dcb_color_full(image2); dcb_color_full(); fbdd_correction(); } free(image2); } // DCB demosaicing main routine void LibRaw::dcb(int iterations, int dcb_enhance) { int i = 1; float(*image2)[3]; image2 = (float(*)[3])calloc(width * height, sizeof *image2); float(*image3)[3]; image3 = (float(*)[3])calloc(width * height, sizeof *image3); border_interpolate(6); dcb_hor(image2); dcb_color2(image2); dcb_ver(image3); dcb_color3(image3); dcb_decide(image2, image3); free(image3); dcb_copy_to_buffer(image2); while (i <= iterations) { dcb_nyquist(); dcb_nyquist(); dcb_nyquist(); dcb_map(); dcb_correction(); i++; } dcb_color(); dcb_pp(); dcb_map(); dcb_correction2(); dcb_map(); dcb_correction(); dcb_map(); dcb_correction(); dcb_map(); dcb_correction(); dcb_map(); dcb_restore_from_buffer(image2); dcb_color(); if (dcb_enhance) { dcb_refinement(); // dcb_color_full(image2); dcb_color_full(); } free(image2); } LibRaw-0.21.4/src/demosaic/dht_demosaic.cpp000066400000000000000000001025471477673233700205140ustar00rootroot00000000000000/* -*- C++ -*- * File: dht_demosaic.cpp * Copyright 2013 Anton Petrusevich * Created: Tue Apr 9, 2013 * * This code is licensed under 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). * */ /* * Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ñ‹Ñ‡Ð¸ÑлÑет ÑркоÑтную диÑтанцию. * еÑли две ÑркоÑти отличаютÑÑ Ð² два раза, например 10 и 20, то они имеют такой * же Ð²ÐµÑ Ð¿Ñ€Ð¸ принÑтии Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¾Ð± интерполировании, как и 100 и 200 -- * фотографичеÑÐºÐ°Ñ ÑркоÑть между ними 1 Ñтоп. диÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð²Ñегда >=1 */ #include "../../internal/dmp_include.h" static inline float calc_dist(float c1, float c2) { return c1 > c2 ? c1 / c2 : c2 / c1; } struct DHT { int nr_height, nr_width; static const int nr_topmargin = 4, nr_leftmargin = 4; float (*nraw)[3]; ushort channel_maximum[3]; float channel_minimum[3]; LibRaw &libraw; enum { HVSH = 1, HOR = 2, VER = 4, HORSH = HOR | HVSH, VERSH = VER | HVSH, DIASH = 8, LURD = 16, RULD = 32, LURDSH = LURD | DIASH, RULDSH = RULD | DIASH, HOT = 64 }; static inline float Thot(void) throw() { return 64.0f; } static inline float Tg(void) throw() { return 256.0f; } static inline float T(void) throw() { return 1.4f; } char *ndir; inline int nr_offset(int row, int col) throw() { return (row * nr_width + col); } int get_hv_grb(int x, int y, int kc) { float hv1 = 2 * nraw[nr_offset(y - 1, x)][1] / (nraw[nr_offset(y - 2, x)][kc] + nraw[nr_offset(y, x)][kc]); float hv2 = 2 * nraw[nr_offset(y + 1, x)][1] / (nraw[nr_offset(y + 2, x)][kc] + nraw[nr_offset(y, x)][kc]); float kv = calc_dist(hv1, hv2) * calc_dist(nraw[nr_offset(y, x)][kc] * nraw[nr_offset(y, x)][kc], (nraw[nr_offset(y - 2, x)][kc] * nraw[nr_offset(y + 2, x)][kc])); kv *= kv; kv *= kv; kv *= kv; float dv = kv * calc_dist(nraw[nr_offset(y - 3, x)][1] * nraw[nr_offset(y + 3, x)][1], nraw[nr_offset(y - 1, x)][1] * nraw[nr_offset(y + 1, x)][1]); float hh1 = 2 * nraw[nr_offset(y, x - 1)][1] / (nraw[nr_offset(y, x - 2)][kc] + nraw[nr_offset(y, x)][kc]); float hh2 = 2 * nraw[nr_offset(y, x + 1)][1] / (nraw[nr_offset(y, x + 2)][kc] + nraw[nr_offset(y, x)][kc]); float kh = calc_dist(hh1, hh2) * calc_dist(nraw[nr_offset(y, x)][kc] * nraw[nr_offset(y, x)][kc], (nraw[nr_offset(y, x - 2)][kc] * nraw[nr_offset(y, x + 2)][kc])); kh *= kh; kh *= kh; kh *= kh; float dh = kh * calc_dist(nraw[nr_offset(y, x - 3)][1] * nraw[nr_offset(y, x + 3)][1], nraw[nr_offset(y, x - 1)][1] * nraw[nr_offset(y, x + 1)][1]); float e = calc_dist(dh, dv); char d = dh < dv ? (e > Tg() ? HORSH : HOR) : (e > Tg() ? VERSH : VER); return d; } int get_hv_rbg(int x, int y, int hc) { float hv1 = 2 * nraw[nr_offset(y - 1, x)][hc ^ 2] / (nraw[nr_offset(y - 2, x)][1] + nraw[nr_offset(y, x)][1]); float hv2 = 2 * nraw[nr_offset(y + 1, x)][hc ^ 2] / (nraw[nr_offset(y + 2, x)][1] + nraw[nr_offset(y, x)][1]); float kv = calc_dist(hv1, hv2) * calc_dist(nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1], (nraw[nr_offset(y - 2, x)][1] * nraw[nr_offset(y + 2, x)][1])); kv *= kv; kv *= kv; kv *= kv; float dv = kv * calc_dist(nraw[nr_offset(y - 3, x)][hc ^ 2] * nraw[nr_offset(y + 3, x)][hc ^ 2], nraw[nr_offset(y - 1, x)][hc ^ 2] * nraw[nr_offset(y + 1, x)][hc ^ 2]); float hh1 = 2 * nraw[nr_offset(y, x - 1)][hc] / (nraw[nr_offset(y, x - 2)][1] + nraw[nr_offset(y, x)][1]); float hh2 = 2 * nraw[nr_offset(y, x + 1)][hc] / (nraw[nr_offset(y, x + 2)][1] + nraw[nr_offset(y, x)][1]); float kh = calc_dist(hh1, hh2) * calc_dist(nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1], (nraw[nr_offset(y, x - 2)][1] * nraw[nr_offset(y, x + 2)][1])); kh *= kh; kh *= kh; kh *= kh; float dh = kh * calc_dist( nraw[nr_offset(y, x - 3)][hc] * nraw[nr_offset(y, x + 3)][hc], nraw[nr_offset(y, x - 1)][hc] * nraw[nr_offset(y, x + 1)][hc]); float e = calc_dist(dh, dv); char d = dh < dv ? (e > Tg() ? HORSH : HOR) : (e > Tg() ? VERSH : VER); return d; } int get_diag_grb(int x, int y, int kc) { float hlu = nraw[nr_offset(y - 1, x - 1)][1] / nraw[nr_offset(y - 1, x - 1)][kc]; float hrd = nraw[nr_offset(y + 1, x + 1)][1] / nraw[nr_offset(y + 1, x + 1)][kc]; float dlurd = calc_dist(hlu, hrd) * calc_dist(nraw[nr_offset(y - 1, x - 1)][1] * nraw[nr_offset(y + 1, x + 1)][1], nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]); float druld = calc_dist(hlu, hrd) * calc_dist(nraw[nr_offset(y - 1, x + 1)][1] * nraw[nr_offset(y + 1, x - 1)][1], nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]); float e = calc_dist(dlurd, druld); char d = druld < dlurd ? (e > T() ? RULDSH : RULD) : (e > T() ? LURDSH : LURD); return d; } int get_diag_rbg(int x, int y, int /* hc */) { float dlurd = calc_dist( nraw[nr_offset(y - 1, x - 1)][1] * nraw[nr_offset(y + 1, x + 1)][1], nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]); float druld = calc_dist( nraw[nr_offset(y - 1, x + 1)][1] * nraw[nr_offset(y + 1, x - 1)][1], nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]); float e = calc_dist(dlurd, druld); char d = druld < dlurd ? (e > T() ? RULDSH : RULD) : (e > T() ? LURDSH : LURD); return d; } static inline float scale_over(float ec, float base) { float s = base * .4; float o = ec - base; return base + sqrt(s * (o + s)) - s; } static inline float scale_under(float ec, float base) { float s = base * .6; float o = base - ec; return base - sqrt(s * (o + s)) + s; } ~DHT(); DHT(LibRaw &_libraw); void copy_to_image(); void make_greens(); void make_diag_dirs(); void make_hv_dirs(); void refine_hv_dirs(int i, int js); void refine_diag_dirs(int i, int js); void refine_ihv_dirs(int i); void refine_idiag_dirs(int i); void illustrate_dirs(); void illustrate_dline(int i); void make_hv_dline(int i); void make_diag_dline(int i); void make_gline(int i); void make_rbdiag(int i); void make_rbhv(int i); void make_rb(); void hide_hots(); void restore_hots(); }; typedef float float3[3]; /* * Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ цветах копируетÑÑ Ð²Ð¾ float в общем то Ñ Ð¾Ð´Ð½Ð¾Ð¹ целью -- чтобы * вмеÑто 0 можно было пиÑать 0.5, что больше подходит Ð´Ð»Ñ Ð²Ñ‹Ñ‡Ð¸ÑÐ»ÐµÐ½Ð¸Ñ ÑркоÑтной * разницы. причина: в целых чиÑлах разница в 1 Ñтоп ÑоÑтавлÑет Ñ€Ñд 8,4,2,1,0 -- * поÑледнее чиÑло должно быть 0.5, которое непредÑтвамио в целых чиÑлах. так же * Ñто изменение позволÑет не думать о Ñпециальных ÑлучаÑÑ… Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð½Ð° ноль. * * альтернативное решение: умножить вÑе данные на 2 и в младший бит внеÑти 1. * правда, вÑÑ‘ равно придётÑÑ Ñледить, чтобы при интерпретации зелёного цвета не * получилÑÑ 0 при округлении, иначе проблема при интерпретации Ñиних и краÑных. * */ DHT::DHT(LibRaw &_libraw) : libraw(_libraw) { nr_height = libraw.imgdata.sizes.iheight + nr_topmargin * 2; nr_width = libraw.imgdata.sizes.iwidth + nr_leftmargin * 2; nraw = (float3 *)malloc(nr_height * nr_width * sizeof(float3)); int iwidth = libraw.imgdata.sizes.iwidth; ndir = (char *)calloc(nr_height * nr_width, 1); channel_maximum[0] = channel_maximum[1] = channel_maximum[2] = 0; channel_minimum[0] = libraw.imgdata.image[0][0]; channel_minimum[1] = libraw.imgdata.image[0][1]; channel_minimum[2] = libraw.imgdata.image[0][2]; for (int i = 0; i < nr_height * nr_width; ++i) nraw[i][0] = nraw[i][1] = nraw[i][2] = 0.5; for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { int col_cache[48]; for (int j = 0; j < 48; ++j) { int l = libraw.COLOR(i, j); if (l == 3) l = 1; col_cache[j] = l; } for (int j = 0; j < iwidth; ++j) { int l = col_cache[j % 48]; unsigned short c = libraw.imgdata.image[i * iwidth + j][l]; if (c != 0) { if (channel_maximum[l] < c) channel_maximum[l] = c; if (channel_minimum[l] > c) channel_minimum[l] = c; nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)][l] = (float)c; } } } channel_minimum[0] += .5; channel_minimum[1] += .5; channel_minimum[2] += .5; } void DHT::hide_hots() { int iwidth = libraw.imgdata.sizes.iwidth; #if defined(LIBRAW_USE_OPENMP) #pragma omp parallel for schedule(guided) firstprivate(iwidth) #endif for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { int js = libraw.COLOR(i, 0) & 1; int kc = libraw.COLOR(i, js); /* * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ */ for (int j = js; j < iwidth; j += 2) { int x = j + nr_leftmargin; int y = i + nr_topmargin; float c = nraw[nr_offset(y, x)][kc]; if ((c > nraw[nr_offset(y, x + 2)][kc] && c > nraw[nr_offset(y, x - 2)][kc] && c > nraw[nr_offset(y - 2, x)][kc] && c > nraw[nr_offset(y + 2, x)][kc] && c > nraw[nr_offset(y, x + 1)][1] && c > nraw[nr_offset(y, x - 1)][1] && c > nraw[nr_offset(y - 1, x)][1] && c > nraw[nr_offset(y + 1, x)][1]) || (c < nraw[nr_offset(y, x + 2)][kc] && c < nraw[nr_offset(y, x - 2)][kc] && c < nraw[nr_offset(y - 2, x)][kc] && c < nraw[nr_offset(y + 2, x)][kc] && c < nraw[nr_offset(y, x + 1)][1] && c < nraw[nr_offset(y, x - 1)][1] && c < nraw[nr_offset(y - 1, x)][1] && c < nraw[nr_offset(y + 1, x)][1])) { float avg = 0; for (int k = -2; k < 3; k += 2) for (int m = -2; m < 3; m += 2) if (m == 0 && k == 0) continue; else avg += nraw[nr_offset(y + k, x + m)][kc]; avg /= 8; // float dev = 0; // for (int k = -2; k < 3; k += 2) // for (int l = -2; l < 3; l += 2) // if (k == 0 && l == 0) // continue; // else { // float t = nraw[nr_offset(y + k, x + l)][kc] - //avg; dev += t * t; // } // dev /= 8; // dev = sqrt(dev); if (calc_dist(c, avg) > Thot()) { ndir[nr_offset(y, x)] |= HOT; float dv = calc_dist( nraw[nr_offset(y - 2, x)][kc] * nraw[nr_offset(y - 1, x)][1], nraw[nr_offset(y + 2, x)][kc] * nraw[nr_offset(y + 1, x)][1]); float dh = calc_dist( nraw[nr_offset(y, x - 2)][kc] * nraw[nr_offset(y, x - 1)][1], nraw[nr_offset(y, x + 2)][kc] * nraw[nr_offset(y, x + 1)][1]); if (dv > dh) nraw[nr_offset(y, x)][kc] = (nraw[nr_offset(y, x + 2)][kc] + nraw[nr_offset(y, x - 2)][kc]) / 2; else nraw[nr_offset(y, x)][kc] = (nraw[nr_offset(y - 2, x)][kc] + nraw[nr_offset(y + 2, x)][kc]) / 2; } } } for (int j = js ^ 1; j < iwidth; j += 2) { int x = j + nr_leftmargin; int y = i + nr_topmargin; float c = nraw[nr_offset(y, x)][1]; if ((c > nraw[nr_offset(y, x + 2)][1] && c > nraw[nr_offset(y, x - 2)][1] && c > nraw[nr_offset(y - 2, x)][1] && c > nraw[nr_offset(y + 2, x)][1] && c > nraw[nr_offset(y, x + 1)][kc] && c > nraw[nr_offset(y, x - 1)][kc] && c > nraw[nr_offset(y - 1, x)][kc ^ 2] && c > nraw[nr_offset(y + 1, x)][kc ^ 2]) || (c < nraw[nr_offset(y, x + 2)][1] && c < nraw[nr_offset(y, x - 2)][1] && c < nraw[nr_offset(y - 2, x)][1] && c < nraw[nr_offset(y + 2, x)][1] && c < nraw[nr_offset(y, x + 1)][kc] && c < nraw[nr_offset(y, x - 1)][kc] && c < nraw[nr_offset(y - 1, x)][kc ^ 2] && c < nraw[nr_offset(y + 1, x)][kc ^ 2])) { float avg = 0; for (int k = -2; k < 3; k += 2) for (int m = -2; m < 3; m += 2) if (k == 0 && m == 0) continue; else avg += nraw[nr_offset(y + k, x + m)][1]; avg /= 8; // float dev = 0; // for (int k = -2; k < 3; k += 2) // for (int l = -2; l < 3; l += 2) // if (k == 0 && l == 0) // continue; // else { // float t = nraw[nr_offset(y + k, x + l)][1] - //avg; dev += t * t; // } // dev /= 8; // dev = sqrt(dev); if (calc_dist(c, avg) > Thot()) { ndir[nr_offset(y, x)] |= HOT; float dv = calc_dist( nraw[nr_offset(y - 2, x)][1] * nraw[nr_offset(y - 1, x)][kc ^ 2], nraw[nr_offset(y + 2, x)][1] * nraw[nr_offset(y + 1, x)][kc ^ 2]); float dh = calc_dist( nraw[nr_offset(y, x - 2)][1] * nraw[nr_offset(y, x - 1)][kc], nraw[nr_offset(y, x + 2)][1] * nraw[nr_offset(y, x + 1)][kc]); if (dv > dh) nraw[nr_offset(y, x)][1] = (nraw[nr_offset(y, x + 2)][1] + nraw[nr_offset(y, x - 2)][1]) / 2; else nraw[nr_offset(y, x)][1] = (nraw[nr_offset(y - 2, x)][1] + nraw[nr_offset(y + 2, x)][1]) / 2; } } } } } void DHT::restore_hots() { int iwidth = libraw.imgdata.sizes.iwidth; #if defined(LIBRAW_USE_OPENMP) #ifdef _MSC_VER #pragma omp parallel for firstprivate(iwidth) #else #pragma omp parallel for schedule(guided) firstprivate(iwidth) collapse(2) #endif #endif for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { for (int j = 0; j < iwidth; ++j) { int x = j + nr_leftmargin; int y = i + nr_topmargin; if (ndir[nr_offset(y, x)] & HOT) { int l = libraw.COLOR(i, j); nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)][l] = libraw.imgdata.image[i * iwidth + j][l]; } } } } void DHT::make_diag_dirs() { #if defined(LIBRAW_USE_OPENMP) #pragma omp parallel for schedule(guided) #endif for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { make_diag_dline(i); } //#if defined(LIBRAW_USE_OPENMP) //#pragma omp parallel for schedule(guided) //#endif // for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { // refine_diag_dirs(i, i & 1); // } //#if defined(LIBRAW_USE_OPENMP) //#pragma omp parallel for schedule(guided) //#endif // for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { // refine_diag_dirs(i, (i & 1) ^ 1); // } #if defined(LIBRAW_USE_OPENMP) #pragma omp parallel for schedule(guided) #endif for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { refine_idiag_dirs(i); } } void DHT::make_hv_dirs() { #if defined(LIBRAW_USE_OPENMP) #pragma omp parallel for schedule(guided) #endif for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { make_hv_dline(i); } #if defined(LIBRAW_USE_OPENMP) #pragma omp parallel for schedule(guided) #endif for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { refine_hv_dirs(i, i & 1); } #if defined(LIBRAW_USE_OPENMP) #pragma omp parallel for schedule(guided) #endif for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { refine_hv_dirs(i, (i & 1) ^ 1); } #if defined(LIBRAW_USE_OPENMP) #pragma omp parallel for schedule(guided) #endif for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { refine_ihv_dirs(i); } } void DHT::refine_hv_dirs(int i, int js) { int iwidth = libraw.imgdata.sizes.iwidth; for (int j = js; j < iwidth; j += 2) { int x = j + nr_leftmargin; int y = i + nr_topmargin; if (ndir[nr_offset(y, x)] & HVSH) continue; int nv = (ndir[nr_offset(y - 1, x)] & VER) + (ndir[nr_offset(y + 1, x)] & VER) + (ndir[nr_offset(y, x - 1)] & VER) + (ndir[nr_offset(y, x + 1)] & VER); int nh = (ndir[nr_offset(y - 1, x)] & HOR) + (ndir[nr_offset(y + 1, x)] & HOR) + (ndir[nr_offset(y, x - 1)] & HOR) + (ndir[nr_offset(y, x + 1)] & HOR); bool codir = (ndir[nr_offset(y, x)] & VER) ? ((ndir[nr_offset(y - 1, x)] & VER) || (ndir[nr_offset(y + 1, x)] & VER)) : ((ndir[nr_offset(y, x - 1)] & HOR) || (ndir[nr_offset(y, x + 1)] & HOR)); nv /= VER; nh /= HOR; if ((ndir[nr_offset(y, x)] & VER) && (nh > 2 && !codir)) { ndir[nr_offset(y, x)] &= ~VER; ndir[nr_offset(y, x)] |= HOR; } if ((ndir[nr_offset(y, x)] & HOR) && (nv > 2 && !codir)) { ndir[nr_offset(y, x)] &= ~HOR; ndir[nr_offset(y, x)] |= VER; } } } void DHT::refine_ihv_dirs(int i) { int iwidth = libraw.imgdata.sizes.iwidth; for (int j = 0; j < iwidth; j++) { int x = j + nr_leftmargin; int y = i + nr_topmargin; if (ndir[nr_offset(y, x)] & HVSH) continue; int nv = (ndir[nr_offset(y - 1, x)] & VER) + (ndir[nr_offset(y + 1, x)] & VER) + (ndir[nr_offset(y, x - 1)] & VER) + (ndir[nr_offset(y, x + 1)] & VER); int nh = (ndir[nr_offset(y - 1, x)] & HOR) + (ndir[nr_offset(y + 1, x)] & HOR) + (ndir[nr_offset(y, x - 1)] & HOR) + (ndir[nr_offset(y, x + 1)] & HOR); nv /= VER; nh /= HOR; if ((ndir[nr_offset(y, x)] & VER) && nh > 3) { ndir[nr_offset(y, x)] &= ~VER; ndir[nr_offset(y, x)] |= HOR; } if ((ndir[nr_offset(y, x)] & HOR) && nv > 3) { ndir[nr_offset(y, x)] &= ~HOR; ndir[nr_offset(y, x)] |= VER; } } } void DHT::make_hv_dline(int i) { int iwidth = libraw.imgdata.sizes.iwidth; int js = libraw.COLOR(i, 0) & 1; int kc = libraw.COLOR(i, js); /* * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ */ for (int j = 0; j < iwidth; j++) { int x = j + nr_leftmargin; int y = i + nr_topmargin; char d = 0; if ((j & 1) == js) { d = get_hv_grb(x, y, kc); } else { d = get_hv_rbg(x, y, kc); } ndir[nr_offset(y, x)] |= d; } } void DHT::make_diag_dline(int i) { int iwidth = libraw.imgdata.sizes.iwidth; int js = libraw.COLOR(i, 0) & 1; int kc = libraw.COLOR(i, js); /* * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ */ for (int j = 0; j < iwidth; j++) { int x = j + nr_leftmargin; int y = i + nr_topmargin; char d = 0; if ((j & 1) == js) { d = get_diag_grb(x, y, kc); } else { d = get_diag_rbg(x, y, kc); } ndir[nr_offset(y, x)] |= d; } } void DHT::refine_diag_dirs(int i, int js) { int iwidth = libraw.imgdata.sizes.iwidth; for (int j = js; j < iwidth; j += 2) { int x = j + nr_leftmargin; int y = i + nr_topmargin; if (ndir[nr_offset(y, x)] & DIASH) continue; int nv = (ndir[nr_offset(y - 1, x)] & LURD) + (ndir[nr_offset(y + 1, x)] & LURD) + (ndir[nr_offset(y, x - 1)] & LURD) + (ndir[nr_offset(y, x + 1)] & LURD) + (ndir[nr_offset(y - 1, x - 1)] & LURD) + (ndir[nr_offset(y - 1, x + 1)] & LURD) + (ndir[nr_offset(y + 1, x - 1)] & LURD) + (ndir[nr_offset(y + 1, x + 1)] & LURD); int nh = (ndir[nr_offset(y - 1, x)] & RULD) + (ndir[nr_offset(y + 1, x)] & RULD) + (ndir[nr_offset(y, x - 1)] & RULD) + (ndir[nr_offset(y, x + 1)] & RULD) + (ndir[nr_offset(y - 1, x - 1)] & RULD) + (ndir[nr_offset(y - 1, x + 1)] & RULD) + (ndir[nr_offset(y + 1, x - 1)] & RULD) + (ndir[nr_offset(y + 1, x + 1)] & RULD); bool codir = (ndir[nr_offset(y, x)] & LURD) ? ((ndir[nr_offset(y - 1, x - 1)] & LURD) || (ndir[nr_offset(y + 1, x + 1)] & LURD)) : ((ndir[nr_offset(y - 1, x + 1)] & RULD) || (ndir[nr_offset(y + 1, x - 1)] & RULD)); nv /= LURD; nh /= RULD; if ((ndir[nr_offset(y, x)] & LURD) && (nh > 4 && !codir)) { ndir[nr_offset(y, x)] &= ~LURD; ndir[nr_offset(y, x)] |= RULD; } if ((ndir[nr_offset(y, x)] & RULD) && (nv > 4 && !codir)) { ndir[nr_offset(y, x)] &= ~RULD; ndir[nr_offset(y, x)] |= LURD; } } } void DHT::refine_idiag_dirs(int i) { int iwidth = libraw.imgdata.sizes.iwidth; for (int j = 0; j < iwidth; j++) { int x = j + nr_leftmargin; int y = i + nr_topmargin; if (ndir[nr_offset(y, x)] & DIASH) continue; int nv = (ndir[nr_offset(y - 1, x)] & LURD) + (ndir[nr_offset(y + 1, x)] & LURD) + (ndir[nr_offset(y, x - 1)] & LURD) + (ndir[nr_offset(y, x + 1)] & LURD) + (ndir[nr_offset(y - 1, x - 1)] & LURD) + (ndir[nr_offset(y - 1, x + 1)] & LURD) + (ndir[nr_offset(y + 1, x - 1)] & LURD) + (ndir[nr_offset(y + 1, x + 1)] & LURD); int nh = (ndir[nr_offset(y - 1, x)] & RULD) + (ndir[nr_offset(y + 1, x)] & RULD) + (ndir[nr_offset(y, x - 1)] & RULD) + (ndir[nr_offset(y, x + 1)] & RULD) + (ndir[nr_offset(y - 1, x - 1)] & RULD) + (ndir[nr_offset(y - 1, x + 1)] & RULD) + (ndir[nr_offset(y + 1, x - 1)] & RULD) + (ndir[nr_offset(y + 1, x + 1)] & RULD); nv /= LURD; nh /= RULD; if ((ndir[nr_offset(y, x)] & LURD) && nh > 7) { ndir[nr_offset(y, x)] &= ~LURD; ndir[nr_offset(y, x)] |= RULD; } if ((ndir[nr_offset(y, x)] & RULD) && nv > 7) { ndir[nr_offset(y, x)] &= ~RULD; ndir[nr_offset(y, x)] |= LURD; } } } /* * вычиÑление недоÑтающих зелёных точек. */ void DHT::make_greens() { #if defined(LIBRAW_USE_OPENMP) #pragma omp parallel for schedule(guided) #endif for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { make_gline(i); } } void DHT::make_gline(int i) { int iwidth = libraw.imgdata.sizes.iwidth; int js = libraw.COLOR(i, 0) & 1; int kc = libraw.COLOR(i, js); /* * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ */ for (int j = js; j < iwidth; j += 2) { int x = j + nr_leftmargin; int y = i + nr_topmargin; int dx, dy, dx2, dy2; float h1, h2; if (ndir[nr_offset(y, x)] & VER) { dx = dx2 = 0; dy = -1; dy2 = 1; h1 = 2 * nraw[nr_offset(y - 1, x)][1] / (nraw[nr_offset(y - 2, x)][kc] + nraw[nr_offset(y, x)][kc]); h2 = 2 * nraw[nr_offset(y + 1, x)][1] / (nraw[nr_offset(y + 2, x)][kc] + nraw[nr_offset(y, x)][kc]); } else { dy = dy2 = 0; dx = 1; dx2 = -1; h1 = 2 * nraw[nr_offset(y, x + 1)][1] / (nraw[nr_offset(y, x + 2)][kc] + nraw[nr_offset(y, x)][kc]); h2 = 2 * nraw[nr_offset(y, x - 1)][1] / (nraw[nr_offset(y, x - 2)][kc] + nraw[nr_offset(y, x)][kc]); } float b1 = 1 / calc_dist(nraw[nr_offset(y, x)][kc], nraw[nr_offset(y + dy * 2, x + dx * 2)][kc]); float b2 = 1 / calc_dist(nraw[nr_offset(y, x)][kc], nraw[nr_offset(y + dy2 * 2, x + dx2 * 2)][kc]); b1 *= b1; b2 *= b2; float eg = nraw[nr_offset(y, x)][kc] * (b1 * h1 + b2 * h2) / (b1 + b2); float min, max; min = MIN(nraw[nr_offset(y + dy, x + dx)][1], nraw[nr_offset(y + dy2, x + dx2)][1]); max = MAX(nraw[nr_offset(y + dy, x + dx)][1], nraw[nr_offset(y + dy2, x + dx2)][1]); min /= 1.2f; max *= 1.2f; if (eg < min) eg = scale_under(eg, min); else if (eg > max) eg = scale_over(eg, max); if (eg > channel_maximum[1]) eg = channel_maximum[1]; else if (eg < channel_minimum[1]) eg = channel_minimum[1]; nraw[nr_offset(y, x)][1] = eg; } } /* * Ð¾Ñ‚Ð»Ð°Ð´Ð¾Ñ‡Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ */ void DHT::illustrate_dirs() { #if defined(LIBRAW_USE_OPENMP) #pragma omp parallel for schedule(guided) #endif for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { illustrate_dline(i); } } void DHT::illustrate_dline(int i) { int iwidth = libraw.imgdata.sizes.iwidth; for (int j = 0; j < iwidth; j++) { int x = j + nr_leftmargin; int y = i + nr_topmargin; nraw[nr_offset(y, x)][0] = nraw[nr_offset(y, x)][1] = nraw[nr_offset(y, x)][2] = 0.5; int l = ndir[nr_offset(y, x)] & 8; // l >>= 3; // WTF? l = 1; if (ndir[nr_offset(y, x)] & HOT) nraw[nr_offset(y, x)][0] = l * channel_maximum[0] / 4 + channel_maximum[0] / 4; else nraw[nr_offset(y, x)][2] = l * channel_maximum[2] / 4 + channel_maximum[2] / 4; } } /* * интерполÑÑ†Ð¸Ñ ÐºÑ€Ð°Ñных и Ñиних. * * Ñначала интерполируютÑÑ Ð½ÐµÐ´Ð¾Ñтающие цвета, по диагональным направлениÑм от * которых находÑÑ‚ÑÑ Ð¸Ð·Ð²ÐµÑтные, затем ÑÐ¸Ñ‚ÑƒÐ°Ñ†Ð¸Ñ ÑводитÑÑ Ðº тому как * интерполировалиÑÑŒ зелёные. */ void DHT::make_rbdiag(int i) { int iwidth = libraw.imgdata.sizes.iwidth; int js = libraw.COLOR(i, 0) & 1; int uc = libraw.COLOR(i, js); int cl = uc ^ 2; /* * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ на уже интерполированный * зелёный al -- извеÑтный цвет (кроме зелёного) в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ cl * -- неизвеÑтный цвет */ for (int j = js; j < iwidth; j += 2) { int x = j + nr_leftmargin; int y = i + nr_topmargin; int dx, dy, dx2, dy2; if (ndir[nr_offset(y, x)] & LURD) { dx = -1; dx2 = 1; dy = -1; dy2 = 1; } else { dx = -1; dx2 = 1; dy = 1; dy2 = -1; } float g1 = 1 / calc_dist(nraw[nr_offset(y, x)][1], nraw[nr_offset(y + dy, x + dx)][1]); float g2 = 1 / calc_dist(nraw[nr_offset(y, x)][1], nraw[nr_offset(y + dy2, x + dx2)][1]); g1 *= g1 * g1; g2 *= g2 * g2; float eg; eg = nraw[nr_offset(y, x)][1] * (g1 * nraw[nr_offset(y + dy, x + dx)][cl] / nraw[nr_offset(y + dy, x + dx)][1] + g2 * nraw[nr_offset(y + dy2, x + dx2)][cl] / nraw[nr_offset(y + dy2, x + dx2)][1]) / (g1 + g2); float min, max; min = MIN(nraw[nr_offset(y + dy, x + dx)][cl], nraw[nr_offset(y + dy2, x + dx2)][cl]); max = MAX(nraw[nr_offset(y + dy, x + dx)][cl], nraw[nr_offset(y + dy2, x + dx2)][cl]); min /= 1.2f; max *= 1.2f; if (eg < min) eg = scale_under(eg, min); else if (eg > max) eg = scale_over(eg, max); if (eg > channel_maximum[cl]) eg = channel_maximum[cl]; else if (eg < channel_minimum[cl]) eg = channel_minimum[cl]; nraw[nr_offset(y, x)][cl] = eg; } } /* * интерполÑÑ†Ð¸Ñ ÐºÑ€Ð°Ñных и Ñиних в точках где был извеÑтен только зелёный, * Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð³Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ñ‹Ðµ или вертикальные */ void DHT::make_rbhv(int i) { int iwidth = libraw.imgdata.sizes.iwidth; int js = (libraw.COLOR(i, 0) & 1) ^ 1; for (int j = js; j < iwidth; j += 2) { int x = j + nr_leftmargin; int y = i + nr_topmargin; /* * поÑкольку Ñверху-Ñнизу и Ñправа-Ñлева уже еÑть вÑе необходимые краÑные и * Ñиние, то можно выбрать наилучшее направление иÑÑ…Ð¾Ð´Ñ Ð¸Ð· информации по * обоим цветам. */ int dx, dy, dx2, dy2; if (ndir[nr_offset(y, x)] & VER) { dx = dx2 = 0; dy = -1; dy2 = 1; } else { dy = dy2 = 0; dx = 1; dx2 = -1; } float g1 = 1 / calc_dist(nraw[nr_offset(y, x)][1], nraw[nr_offset(y + dy, x + dx)][1]); float g2 = 1 / calc_dist(nraw[nr_offset(y, x)][1], nraw[nr_offset(y + dy2, x + dx2)][1]); g1 *= g1; g2 *= g2; float eg_r, eg_b; eg_r = nraw[nr_offset(y, x)][1] * (g1 * nraw[nr_offset(y + dy, x + dx)][0] / nraw[nr_offset(y + dy, x + dx)][1] + g2 * nraw[nr_offset(y + dy2, x + dx2)][0] / nraw[nr_offset(y + dy2, x + dx2)][1]) / (g1 + g2); eg_b = nraw[nr_offset(y, x)][1] * (g1 * nraw[nr_offset(y + dy, x + dx)][2] / nraw[nr_offset(y + dy, x + dx)][1] + g2 * nraw[nr_offset(y + dy2, x + dx2)][2] / nraw[nr_offset(y + dy2, x + dx2)][1]) / (g1 + g2); float min_r, max_r; min_r = MIN(nraw[nr_offset(y + dy, x + dx)][0], nraw[nr_offset(y + dy2, x + dx2)][0]); max_r = MAX(nraw[nr_offset(y + dy, x + dx)][0], nraw[nr_offset(y + dy2, x + dx2)][0]); float min_b, max_b; min_b = MIN(nraw[nr_offset(y + dy, x + dx)][2], nraw[nr_offset(y + dy2, x + dx2)][2]); max_b = MAX(nraw[nr_offset(y + dy, x + dx)][2], nraw[nr_offset(y + dy2, x + dx2)][2]); min_r /= 1.2f; max_r *= 1.2f; min_b /= 1.2f; max_b *= 1.2f; if (eg_r < min_r) eg_r = scale_under(eg_r, min_r); else if (eg_r > max_r) eg_r = scale_over(eg_r, max_r); if (eg_b < min_b) eg_b = scale_under(eg_b, min_b); else if (eg_b > max_b) eg_b = scale_over(eg_b, max_b); if (eg_r > channel_maximum[0]) eg_r = channel_maximum[0]; else if (eg_r < channel_minimum[0]) eg_r = channel_minimum[0]; if (eg_b > channel_maximum[2]) eg_b = channel_maximum[2]; else if (eg_b < channel_minimum[2]) eg_b = channel_minimum[2]; nraw[nr_offset(y, x)][0] = eg_r; nraw[nr_offset(y, x)][2] = eg_b; } } void DHT::make_rb() { #if defined(LIBRAW_USE_OPENMP) #pragma omp barrier #pragma omp parallel for schedule(guided) #endif for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { make_rbdiag(i); } #if defined(LIBRAW_USE_OPENMP) #pragma omp barrier #pragma omp parallel for schedule(guided) #endif for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { make_rbhv(i); } } /* * Ð¿ÐµÑ€ÐµÐ½Ð¾Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð² выходной маÑÑив */ void DHT::copy_to_image() { int iwidth = libraw.imgdata.sizes.iwidth; #if defined(LIBRAW_USE_OPENMP) #ifdef _MSC_VER #pragma omp parallel for #else #pragma omp parallel for schedule(guided) collapse(2) #endif #endif for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { for (int j = 0; j < iwidth; ++j) { libraw.imgdata.image[i * iwidth + j][0] = (unsigned short)(nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)] [0]); libraw.imgdata.image[i * iwidth + j][2] = (unsigned short)(nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)] [2]); libraw.imgdata.image[i * iwidth + j][1] = libraw.imgdata.image[i * iwidth + j][3] = (unsigned short)(nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)][1]); } } } DHT::~DHT() { free(nraw); free(ndir); } void LibRaw::dht_interpolate() { if (imgdata.idata.filters != 0x16161616 && imgdata.idata.filters != 0x61616161 && imgdata.idata.filters != 0x49494949 && imgdata.idata.filters != 0x94949494 ) { ahd_interpolate(); return; } DHT dht(*this); dht.hide_hots(); dht.make_hv_dirs(); // dht.illustrate_dirs(); dht.make_greens(); dht.make_diag_dirs(); // dht.illustrate_dirs(); dht.make_rb(); dht.restore_hots(); dht.copy_to_image(); } LibRaw-0.21.4/src/demosaic/misc_demosaic.cpp000066400000000000000000000333311477673233700206620ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" void LibRaw::pre_interpolate() { ushort(*img)[4]; int row, col, c; RUN_CALLBACK(LIBRAW_PROGRESS_PRE_INTERPOLATE, 0, 2); if (shrink) { if (half_size) { height = iheight; width = iwidth; if (filters == 9) { for (row = 0; row < 3; row++) for (col = 1; col < 4; col++) if (!(image[row * width + col][0] | image[row * width + col][2])) goto break2; break2: for (; row < height; row += 3) for (col = (col - 1) % 3 + 1; col < width - 1; col += 3) { img = image + row * width + col; for (c = 0; c < 3; c += 2) img[0][c] = (img[-1][c] + img[1][c]) >> 1; } } } else { img = (ushort(*)[4])calloc(height, width * sizeof *img); for (row = 0; row < height; row++) for (col = 0; col < width; col++) { c = fcol(row, col); img[row * width + col][c] = image[(row >> 1) * iwidth + (col >> 1)][c]; } free(image); image = img; shrink = 0; } } if (filters > 1000 && colors == 3) { mix_green = four_color_rgb ^ half_size; if (four_color_rgb | half_size) colors++; else { for (row = FC(1, 0) >> 1; row < height; row += 2) for (col = FC(row, 1) & 1; col < width; col += 2) image[row * width + col][1] = image[row * width + col][3]; filters &= ~((filters & 0x55555555U) << 1); } } if (half_size) filters = 0; RUN_CALLBACK(LIBRAW_PROGRESS_PRE_INTERPOLATE, 1, 2); } void LibRaw::border_interpolate(int border) { unsigned row, col, y, x, f, c, sum[8]; for (row = 0; row < height; row++) for (col = 0; col < width; col++) { if (col == (unsigned)border && row >= (unsigned)border && row < (unsigned)(height - border)) col = width - border; memset(sum, 0, sizeof sum); for (y = row - 1; y != row + 2; y++) for (x = col - 1; x != col + 2; x++) if (y < height && x < width) { f = fcol(y, x); sum[f] += image[y * width + x][f]; sum[f + 4]++; } f = fcol(row, col); FORC(unsigned(colors)) if (c != f && sum[c + 4]) image[row * width + col][c] = sum[c] / sum[c + 4]; } } void LibRaw::lin_interpolate_loop(int *code, int size) { int row; for (row = 1; row < height - 1; row++) { int col, *ip; ushort *pix; for (col = 1; col < width - 1; col++) { int i; int sum[4]; pix = image[row * width + col]; ip = code + ((((row % size) * 16) + (col % size)) * 32); memset(sum, 0, sizeof sum); for (i = *ip++; i--; ip += 3) sum[ip[2]] += pix[ip[0]] << ip[1]; for (i = colors; --i; ip += 2) pix[ip[0]] = sum[ip[0]] * ip[1] >> 8; } } } void LibRaw::lin_interpolate() { std::vector code_buffer(16 * 16 * 32); int* code = &code_buffer[0], size = 16, *ip, sum[4]; int f, c, x, y, row, col, shift, color; RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 0, 3); if (filters == 9) size = 6; border_interpolate(1); for (row = 0; row < size; row++) for (col = 0; col < size; col++) { ip = code + (((row * 16) + col) * 32) + 1; f = fcol(row, col); memset(sum, 0, sizeof sum); for (y = -1; y <= 1; y++) for (x = -1; x <= 1; x++) { shift = (y == 0) + (x == 0); color = fcol(row + y + 48, col + x + 48); if (color == f) continue; *ip++ = (width * y + x) * 4 + color; *ip++ = shift; *ip++ = color; sum[color] += 1 << shift; } code[(row * 16 + col) * 32] = (ip - (code + ((row * 16) + col) * 32)) / 3; FORCC if (c != f) { *ip++ = c; *ip++ = sum[c] > 0 ? 256 / sum[c] : 0; } } RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 1, 3); lin_interpolate_loop(code, size); RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 2, 3); } /* This algorithm is officially called: "Interpolation using a Threshold-based variable number of gradients" described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html I've extended the basic idea to work with non-Bayer filter arrays. Gradients are numbered clockwise from NW=0 to W=7. */ void LibRaw::vng_interpolate() { static const signed char *cp, terms[] = {-2, -2, +0, -1, 0, 0x01, -2, -2, +0, +0, 1, 0x01, -2, -1, -1, +0, 0, 0x01, -2, -1, +0, -1, 0, 0x02, -2, -1, +0, +0, 0, 0x03, -2, -1, +0, +1, 1, 0x01, -2, +0, +0, -1, 0, 0x06, -2, +0, +0, +0, 1, 0x02, -2, +0, +0, +1, 0, 0x03, -2, +1, -1, +0, 0, 0x04, -2, +1, +0, -1, 1, 0x04, -2, +1, +0, +0, 0, 0x06, -2, +1, +0, +1, 0, 0x02, -2, +2, +0, +0, 1, 0x04, -2, +2, +0, +1, 0, 0x04, -1, -2, -1, +0, 0, -128, -1, -2, +0, -1, 0, 0x01, -1, -2, +1, -1, 0, 0x01, -1, -2, +1, +0, 1, 0x01, -1, -1, -1, +1, 0, -120, -1, -1, +1, -2, 0, 0x40, -1, -1, +1, -1, 0, 0x22, -1, -1, +1, +0, 0, 0x33, -1, -1, +1, +1, 1, 0x11, -1, +0, -1, +2, 0, 0x08, -1, +0, +0, -1, 0, 0x44, -1, +0, +0, +1, 0, 0x11, -1, +0, +1, -2, 1, 0x40, -1, +0, +1, -1, 0, 0x66, -1, +0, +1, +0, 1, 0x22, -1, +0, +1, +1, 0, 0x33, -1, +0, +1, +2, 1, 0x10, -1, +1, +1, -1, 1, 0x44, -1, +1, +1, +0, 0, 0x66, -1, +1, +1, +1, 0, 0x22, -1, +1, +1, +2, 0, 0x10, -1, +2, +0, +1, 0, 0x04, -1, +2, +1, +0, 1, 0x04, -1, +2, +1, +1, 0, 0x04, +0, -2, +0, +0, 1, -128, +0, -1, +0, +1, 1, -120, +0, -1, +1, -2, 0, 0x40, +0, -1, +1, +0, 0, 0x11, +0, -1, +2, -2, 0, 0x40, +0, -1, +2, -1, 0, 0x20, +0, -1, +2, +0, 0, 0x30, +0, -1, +2, +1, 1, 0x10, +0, +0, +0, +2, 1, 0x08, +0, +0, +2, -2, 1, 0x40, +0, +0, +2, -1, 0, 0x60, +0, +0, +2, +0, 1, 0x20, +0, +0, +2, +1, 0, 0x30, +0, +0, +2, +2, 1, 0x10, +0, +1, +1, +0, 0, 0x44, +0, +1, +1, +2, 0, 0x10, +0, +1, +2, -1, 1, 0x40, +0, +1, +2, +0, 0, 0x60, +0, +1, +2, +1, 0, 0x20, +0, +1, +2, +2, 0, 0x10, +1, -2, +1, +0, 0, -128, +1, -1, +1, +1, 0, -120, +1, +0, +1, +2, 0, 0x08, +1, +0, +2, -1, 0, 0x40, +1, +0, +2, +1, 0, 0x10}, chood[] = {-1, -1, -1, 0, -1, +1, 0, +1, +1, +1, +1, 0, +1, -1, 0, -1}; ushort(*brow[5])[4], *pix; int prow = 8, pcol = 2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4]; int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag; int g, diff, thold, num, c; lin_interpolate(); if (filters == 1) prow = pcol = 16; if (filters == 9) prow = pcol = 6; ip = (int *)calloc(prow * pcol, 1280); for (row = 0; row < prow; row++) /* Precalculate for VNG */ for (col = 0; col < pcol; col++) { code[row][col] = ip; for (cp = terms, t = 0; t < 64; t++) { y1 = *cp++; x1 = *cp++; y2 = *cp++; x2 = *cp++; weight = *cp++; grads = *cp++; color = fcol(row + y1 + 144, col + x1 + 144); if (fcol(row + y2 + 144, col + x2 + 144) != color) continue; diag = (fcol(row, col + 1) == color && fcol(row + 1, col) == color) ? 2 : 1; if (abs(y1 - y2) == diag && abs(x1 - x2) == diag) continue; *ip++ = (y1 * width + x1) * 4 + color; *ip++ = (y2 * width + x2) * 4 + color; *ip++ = weight; for (g = 0; g < 8; g++) if (grads & 1 << g) *ip++ = g; *ip++ = -1; } *ip++ = INT_MAX; for (cp = chood, g = 0; g < 8; g++) { y = *cp++; x = *cp++; *ip++ = (y * width + x) * 4; color = fcol(row, col); if (fcol(row + y + 144, col + x + 144) != color && fcol(row + y * 2 + 144, col + x * 2 + 144) == color) *ip++ = (y * width + x) * 8 + color; else *ip++ = 0; } } brow[4] = (ushort(*)[4])calloc(width * 3, sizeof **brow); for (row = 0; row < 3; row++) brow[row] = brow[4] + row * width; for (row = 2; row < height - 2; row++) { /* Do VNG interpolation */ if (!((row - 2) % 256)) RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, (row - 2) / 256 + 1, ((height - 3) / 256) + 1); for (col = 2; col < width - 2; col++) { pix = image[row * width + col]; ip = code[row % prow][col % pcol]; memset(gval, 0, sizeof gval); while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */ diff = ABS(pix[g] - pix[ip[1]]) << ip[2]; gval[ip[3]] += diff; ip += 5; if ((g = ip[-1]) == -1) continue; gval[g] += diff; while ((g = *ip++) != -1) gval[g] += diff; } ip++; gmin = gmax = gval[0]; /* Choose a threshold */ for (g = 1; g < 8; g++) { if (gmin > gval[g]) gmin = gval[g]; if (gmax < gval[g]) gmax = gval[g]; } if (gmax == 0) { memcpy(brow[2][col], pix, sizeof *image); continue; } thold = gmin + (gmax >> 1); memset(sum, 0, sizeof sum); color = fcol(row, col); for (num = g = 0; g < 8; g++, ip += 2) { /* Average the neighbors */ if (gval[g] <= thold) { FORCC if (c == color && ip[1]) sum[c] += (pix[c] + pix[ip[1]]) >> 1; else sum[c] += pix[ip[0] + c]; num++; } } FORCC { /* Save to buffer */ t = pix[color]; if (c != color) t += (sum[c] - sum[color]) / num; brow[2][col][c] = CLIP(t); } } if (row > 3) /* Write buffer to image */ memcpy(image[(row - 2) * width + 2], brow[0] + 2, (width - 4) * sizeof *image); for (g = 0; g < 4; g++) brow[(g - 1) & 3] = brow[g]; } memcpy(image[(row - 2) * width + 2], brow[0] + 2, (width - 4) * sizeof *image); memcpy(image[(row - 1) * width + 2], brow[1] + 2, (width - 4) * sizeof *image); free(brow[4]); free(code[0][0]); } /* Patterned Pixel Grouping Interpolation by Alain Desbiolles */ void LibRaw::ppg_interpolate() { int dir[5] = {1, width, -1, -width, 1}; int row, col, diff[2], guess[2], c, d, i; ushort(*pix)[4]; border_interpolate(3); /* Fill in the green layer with gradients and pattern recognition: */ RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 0, 3); #ifdef LIBRAW_USE_OPENMP #pragma omp parallel for default(shared) private(guess, diff, row, col, d, c, \ i, pix) schedule(static) #endif for (row = 3; row < height - 3; row++) for (col = 3 + (FC(row, 3) & 1), c = FC(row, col); col < width - 3; col += 2) { pix = image + row * width + col; for (i = 0; i < 2; i++) { d = dir[i]; guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2 - pix[-2 * d][c] - pix[2 * d][c]; diff[i] = (ABS(pix[-2 * d][c] - pix[0][c]) + ABS(pix[2 * d][c] - pix[0][c]) + ABS(pix[-d][1] - pix[d][1])) * 3 + (ABS(pix[3 * d][1] - pix[d][1]) + ABS(pix[-3 * d][1] - pix[-d][1])) * 2; } d = dir[i = diff[0] > diff[1]]; pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]); } /* Calculate red and blue for each green pixel: */ RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 1, 3); #ifdef LIBRAW_USE_OPENMP #pragma omp parallel for default(shared) private(guess, diff, row, col, d, c, \ i, pix) schedule(static) #endif for (row = 1; row < height - 1; row++) for (col = 1 + (FC(row, 2) & 1), c = FC(row, col + 1); col < width - 1; col += 2) { pix = image + row * width + col; for (i = 0; i < 2; c = 2 - c, i++) { d = dir[i]; pix[0][c] = CLIP( (pix[-d][c] + pix[d][c] + 2 * pix[0][1] - pix[-d][1] - pix[d][1]) >> 1); } } /* Calculate blue for red pixels and vice versa: */ RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 2, 3); #ifdef LIBRAW_USE_OPENMP #pragma omp parallel for default(shared) private(guess, diff, row, col, d, c, \ i, pix) schedule(static) #endif for (row = 1; row < height - 1; row++) for (col = 1 + (FC(row, 1) & 1), c = 2 - FC(row, col); col < width - 1; col += 2) { pix = image + row * width + col; for (i = 0; i < 2; i++) { d = dir[i] + dir[i+1]; diff[i] = ABS(pix[-d][c] - pix[d][c]) + ABS(pix[-d][1] - pix[0][1]) + ABS(pix[d][1] - pix[0][1]); guess[i] = pix[-d][c] + pix[d][c] + 2 * pix[0][1] - pix[-d][1] - pix[d][1]; } if (diff[0] != diff[1]) pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1); else pix[0][c] = CLIP((guess[0] + guess[1]) >> 2); } } LibRaw-0.21.4/src/demosaic/xtrans_demosaic.cpp000066400000000000000000000427761477673233700212630ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" #define fcol(row, col) xtrans[(row + 6) % 6][(col + 6) % 6] /* Frank Markesteijn's algorithm for Fuji X-Trans sensors */ void LibRaw::xtrans_interpolate(int passes) { int cstat[4] = {0, 0, 0, 0}; int ndir; static const short orth[12] = {1, 0, 0, 1, -1, 0, 0, -1, 1, 0, 0, 1}, patt[2][16] = {{0, 1, 0, -1, 2, 0, -1, 0, 1, 1, 1, -1, 0, 0, 0, 0}, {0, 1, 0, -2, 1, 0, -2, 0, 1, 1, -2, -2, 1, -1, -1, 1}}, dir[4] = {1, LIBRAW_AHD_TILE, LIBRAW_AHD_TILE + 1, LIBRAW_AHD_TILE - 1}; short allhex[3][3][2][8]; ushort sgrow = 0, sgcol = 0; if (width < LIBRAW_AHD_TILE || height < LIBRAW_AHD_TILE) throw LIBRAW_EXCEPTION_IO_CORRUPT; // too small image /* Check against right pattern */ for (int row = 0; row < 6; row++) for (int col = 0; col < 6; col++) cstat[(unsigned)fcol(row, col)]++; if (cstat[0] < 6 || cstat[0] > 10 || cstat[1] < 16 || cstat[1] > 24 || cstat[2] < 6 || cstat[2] > 10 || cstat[3]) throw LIBRAW_EXCEPTION_IO_CORRUPT; // Init allhex table to unreasonable values for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) for (int k = 0; k < 2; k++) for (int l = 0; l < 8; l++) allhex[i][j][k][l] = 32700; cielab(0, 0); ndir = 4 << int(passes > 1); int minv = 0, maxv = 0, minh = 0, maxh = 0; /* Map a green hexagon around each non-green pixel and vice versa: */ for (int row = 0; row < 3; row++) for (int col = 0; col < 3; col++) for (int ng = 0, d = 0; d < 10; d += 2) { int g = fcol(row, col) == 1; if (fcol(row + orth[d], col + orth[d + 2]) == 1) ng = 0; else ng++; if (ng == 4) { sgrow = row; sgcol = col; } if (ng == g + 1) { int c; FORC(8) { int v = orth[d] * patt[g][c * 2] + orth[d + 1] * patt[g][c * 2 + 1]; int h = orth[d + 2] * patt[g][c * 2] + orth[d + 3] * patt[g][c * 2 + 1]; minv = MIN(v, minv); maxv = MAX(v, maxv); minh = MIN(v, minh); maxh = MAX(v, maxh); allhex[row][col][0][c ^ (g * 2 & d)] = h + v * width; allhex[row][col][1][c ^ (g * 2 & d)] = h + v * LIBRAW_AHD_TILE; } } } // Check allhex table initialization for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) for (int k = 0; k < 2; k++) for (int l = 0; l < 8; l++) if (allhex[i][j][k][l] > maxh + maxv * width + 1 || allhex[i][j][k][l] < minh + minv * width - 1) throw LIBRAW_EXCEPTION_IO_CORRUPT; int retrycount = 0; /* Set green1 and green3 to the minimum and maximum allowed values: */ for (int row = 2; row < height - 2; row++) { int col; ushort min, max; for (col = 2, max = 0u, min = 0xffffu; col < int(width) - 2; col++) { if (fcol(row, col) == 1 && (min = ~(max = 0))) continue; ushort(*pix)[4]; pix = image + row * width + col; short* hex = allhex[row % 3][col % 3][0]; if (!max) { int c; FORC(6) { int val = pix[hex[c]][1]; if (min > val) min = val; if (max < val) max = val; } } pix[0][1] = min; pix[0][3] = max; switch ((row - sgrow) % 3) { case 1: if (row < height - 3) { row++; col--; } break; case 2: if ((min = ~(max = 0)) && (col += 2) < width - 3 && row > 2) { row--; if (retrycount++ > width * height) throw LIBRAW_EXCEPTION_IO_CORRUPT; } } } } for (int row = 3; row < 9 && row < height - 3; row++) for (int col = 3; col < 9 && col < width - 3; col++) { if ((fcol(row, col)) == 1) continue; short* hex = allhex[row % 3][col % 3][0]; int c; FORC(2) { int idx3 = 3 * hex[4 + c] + row * width + col; int idx4 = -3 * hex[4 + c] + row * width + col; int maxidx = width * height; if (idx3 < 0 || idx3 >= maxidx) throw LIBRAW_EXCEPTION_IO_CORRUPT; if (idx4 < 0 || idx4 >= maxidx) throw LIBRAW_EXCEPTION_IO_CORRUPT; } } #if defined(LIBRAW_USE_OPENMP) int buffer_count = omp_get_max_threads(); #else int buffer_count = 1; #endif size_t buffer_size = LIBRAW_AHD_TILE * LIBRAW_AHD_TILE * (ndir * 11 + 6); char** buffers = malloc_omp_buffers(buffer_count, buffer_size); #if defined(LIBRAW_USE_OPENMP) # pragma omp parallel for schedule(dynamic) default(none) firstprivate(buffers, allhex, passes, sgrow, sgcol, ndir) shared(dir) #endif for (int top = 3; top < height - 19; top += LIBRAW_AHD_TILE - 16) { #if defined(LIBRAW_USE_OPENMP) char* buffer = buffers[omp_get_thread_num()]; #else char* buffer = buffers[0]; #endif ushort(*rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], (*rix)[3]; short(*lab)[LIBRAW_AHD_TILE][3], (*lix)[3]; float(*drv)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE]; char(*homo)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE]; rgb = (ushort(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3])buffer; lab = (short(*)[LIBRAW_AHD_TILE][3])( buffer + LIBRAW_AHD_TILE * LIBRAW_AHD_TILE * (ndir * 6)); drv = (float(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE])( buffer + LIBRAW_AHD_TILE * LIBRAW_AHD_TILE * (ndir * 6 + 6)); homo = (char(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE])( buffer + LIBRAW_AHD_TILE * LIBRAW_AHD_TILE * (ndir * 10 + 6)); for (int left = 3; left < width - 19; left += LIBRAW_AHD_TILE - 16) { int mrow = MIN(top + LIBRAW_AHD_TILE, height - 3); int mcol = MIN(left + LIBRAW_AHD_TILE, width - 3); for (int row = top; row < mrow; row++) for (int col = left; col < mcol; col++) memcpy(rgb[0][row - top][col - left], image[row * width + col], 6); int c; FORC3 memcpy(rgb[c + 1], rgb[0], sizeof * rgb); /* Interpolate green horizontally, vertically, and along both diagonals: */ int color[3][8]; for (int row = top; row < mrow; row++) for (int col = left; col < mcol; col++) { int f; if ((f = fcol(row, col)) == 1) continue; ushort (*pix)[4] = image + row * width + col; short* hex = allhex[row % 3][col % 3][0]; color[1][0] = 174 * (pix[hex[1]][1] + pix[hex[0]][1]) - 46 * (pix[2 * hex[1]][1] + pix[2 * hex[0]][1]); color[1][1] = 223 * pix[hex[3]][1] + pix[hex[2]][1] * 33 + 92 * (pix[0][f] - pix[-hex[2]][f]); FORC(2) color[1][2 + c] = 164 * pix[hex[4 + c]][1] + 92 * pix[-2 * hex[4 + c]][1] + 33 * (2 * pix[0][f] - pix[3 * hex[4 + c]][f] - pix[-3 * hex[4 + c]][f]); FORC4 rgb[c ^ !((row - sgrow) % 3)][row - top][col - left][1] = LIM(color[1][c] >> 8, pix[0][1], pix[0][3]); } for (int pass = 0; pass < passes; pass++) { if (pass == 1) memcpy(rgb += 4, buffer, 4 * sizeof * rgb); /* Recalculate green from interpolated values of closer pixels: */ if (pass) { for (int row = top + 2; row < mrow - 2; row++) for (int col = left + 2; col < mcol - 2; col++) { int f; if ((f = fcol(row, col)) == 1) continue; ushort(*pix)[4] = image + row * width + col; short* hex = allhex[row % 3][col % 3][1]; for (int d = 3; d < 6; d++) { rix = &rgb[(d - 2) ^ !((row - sgrow) % 3)][row - top][col - left]; int val = rix[-2 * hex[d]][1] + 2 * rix[hex[d]][1] - rix[-2 * hex[d]][f] - 2 * rix[hex[d]][f] + 3 * rix[0][f]; rix[0][1] = LIM(val / 3, pix[0][1], pix[0][3]); } } } /* Interpolate red and blue values for solitary green pixels: */ for (int row = (top - sgrow + 4) / 3 * 3 + sgrow; row < mrow - 2; row += 3) for (int col = (left - sgcol + 4) / 3 * 3 + sgcol; col < mcol - 2; col += 3) { rix = &rgb[0][row - top][col - left]; int h = fcol(row, col + 1); if (h == 1) // Incorrect pattern break; float diff[6]; memset(diff, 0, sizeof diff); for (int i = 1, d = 0; d < 6; d++, i ^= LIBRAW_AHD_TILE ^ 1, h ^= 2) { for (c = 0; c < 2; c++, h ^= 2) { int g = 2 * rix[0][1] - rix[i << c][1] - rix[-i << c][1]; color[h][d] = g + rix[i << c][h] + rix[-i << c][h]; if (d > 1) diff[d] += SQR((float)rix[i << c][1] - (float)rix[-i << c][1] - (float)rix[i << c][h] + (float)rix[-i << c][h]) + SQR((float)g); } if (d > 1 && (d & 1)) if (diff[d - 1] < diff[d]) FORC(2) color[c * 2][d] = color[c * 2][d - 1]; if (d < 2 || (d & 1)) { FORC(2) rix[0][c * 2] = CLIP(color[c * 2][d] / 2); rix += LIBRAW_AHD_TILE * LIBRAW_AHD_TILE; } } } /* Interpolate red for blue pixels and vice versa: */ for (int row = top + 3; row < mrow - 3; row++) for (int col = left + 3; col < mcol - 3; col++) { int f; if ((f = 2 - fcol(row, col)) == 1) continue; rix = &rgb[0][row - top][col - left]; c = (row - sgrow) % 3 ? LIBRAW_AHD_TILE : 1; int h = 3 * (c ^ LIBRAW_AHD_TILE ^ 1); for (int d = 0; d < 4; d++, rix += LIBRAW_AHD_TILE * LIBRAW_AHD_TILE) { int i = d > 1 || ((d ^ c) & 1) || ((ABS(rix[0][1] - rix[c][1]) + ABS(rix[0][1] - rix[-c][1])) < 2 * (ABS(rix[0][1] - rix[h][1]) + ABS(rix[0][1] - rix[-h][1]))) ? c : h; rix[0][f] = CLIP((rix[i][f] + rix[-i][f] + 2 * rix[0][1] - rix[i][1] - rix[-i][1]) / 2); } } /* Fill in red and blue for 2x2 blocks of green: */ for (int row = top + 2; row < mrow - 2; row++) if ((row - sgrow) % 3) for (int col = left + 2; col < mcol - 2; col++) if ((col - sgcol) % 3) { rix = &rgb[0][row - top][col - left]; short* hex = allhex[row % 3][col % 3][1]; for (int d = 0; d < 8; d += 2, rix += LIBRAW_AHD_TILE * LIBRAW_AHD_TILE) if (hex[d] + hex[d + 1]) { int g = 3 * rix[0][1] - 2 * rix[hex[d]][1] - rix[hex[d + 1]][1]; for (c = 0; c < 4; c += 2) rix[0][c] = CLIP( (g + 2 * rix[hex[d]][c] + rix[hex[d + 1]][c]) / 3); } else { int g = 2 * rix[0][1] - rix[hex[d]][1] - rix[hex[d + 1]][1]; for (c = 0; c < 4; c += 2) rix[0][c] = CLIP((g + rix[hex[d]][c] + rix[hex[d + 1]][c]) / 2); } } } rgb = (ushort(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3])buffer; mrow -= top; mcol -= left; /* Convert to CIELab and differentiate in all directions: */ // no effect for (int d = 0; d < ndir; d++) { for (int row = 2; row < mrow - 2; row++) for (int col = 2; col < mcol - 2; col++) cielab(rgb[d][row][col], lab[row][col]); for (int f = dir[d & 3], row = 3; row < mrow - 3; row++) for (int col = 3; col < mcol - 3; col++) { lix = &lab[row][col]; int g = 2 * lix[0][0] - lix[f][0] - lix[-f][0]; drv[d][row][col] = SQR(g) + SQR((2 * lix[0][1] - lix[f][1] - lix[-f][1] + g * 500 / 232)) + SQR((2 * lix[0][2] - lix[f][2] - lix[-f][2] - g * 500 / 580)); } } /* Build homogeneity maps from the derivatives: */ memset(homo, 0, ndir * LIBRAW_AHD_TILE * LIBRAW_AHD_TILE); for (int row = 4; row < mrow - 4; row++) for (int col = 4; col < mcol - 4; col++) { int d; float tr; for (tr = FLT_MAX, d = 0; d < ndir; d++) if (tr > drv[d][row][col]) tr = drv[d][row][col]; tr *= 8; for (int dd = 0; dd < ndir; dd++) for (int v = -1; v <= 1; v++) for (int h = -1; h <= 1; h++) if (drv[dd][row + v][col + h] <= tr) homo[dd][row][col]++; } /* Average the most homogeneous pixels for the final result: */ if (height - top < LIBRAW_AHD_TILE + 4) mrow = height - top + 2; if (width - left < LIBRAW_AHD_TILE + 4) mcol = width - left + 2; for (int row = MIN(top, 8); row < mrow - 8; row++) for (int col = MIN(left, 8); col < mcol - 8; col++) { int v; int hm[8]; for (int d = 0; d < ndir; d++) for (v = -2, hm[d] = 0; v <= 2; v++) for (int h = -2; h <= 2; h++) hm[d] += homo[d][row + v][col + h]; for (int d = 0; d < ndir - 4; d++) if (hm[d] < hm[d + 4]) hm[d] = 0; else if (hm[d] > hm[d + 4]) hm[d + 4] = 0; ushort max; int d; for (d = 1, max = hm[0]; d < ndir; d++) if (max < hm[d]) max = hm[d]; max -= max >> 3; int avg[4]; memset(avg, 0, sizeof avg); for (int dd = 0; dd < ndir; dd++) if (hm[dd] >= max) { FORC3 avg[c] += rgb[dd][row][col][c]; avg[3]++; } FORC3 image[(row + top) * width + col + left][c] = avg[c] / avg[3]; } } } #ifdef LIBRAW_USE_OPENMP #pragma omp barrier #endif free_omp_buffers(buffers, buffer_count); border_interpolate(8); } #undef fcol LibRaw-0.21.4/src/integration/000077500000000000000000000000001477673233700161135ustar00rootroot00000000000000LibRaw-0.21.4/src/integration/dngsdk_glue.cpp000066400000000000000000000306551477673233700211160ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" #if defined (USE_GPRSDK) && !defined(USE_DNGSDK) #error GPR (GoPro) SDK should be used with Adobe DNG SDK #endif #ifdef USE_DNGSDK #include "dng_read_image.h" #endif #ifdef USE_GPRSDK #include "gpr_read_image.h" #endif #ifdef USE_DNGSDK static dng_ifd* search_single_ifd(const std::vector & v, uint64 offset, int& idx, dng_stream& stream) { idx = -1; for (int i = 0; i < v.size(); i++) { if (!v[i]) continue; if (v[i]->fTileOffsetsOffset == offset) { idx = i; return v[i]; } else if (v[i]->fTileOffsetsCount == 1 && v[i]->fTileOffset[0] == offset) { idx = i; return v[i]; } else if (v[i]->fTileOffsetsCount > dng_ifd::kMaxTileInfo) { uint64 p = stream.Position(); stream.SetReadPosition(v[i]->fTileOffsetsOffset); int32 oo = stream.TagValue_uint32(v[i]->fTileOffsetsType); stream.SetReadPosition(p); if (oo == offset) { idx = i; return v[i]; } } } return NULL; } static dng_ifd* search_for_ifd(const dng_info& info, uint64 offset, ushort w, ushort h, int& ifdIndex, dng_stream& stream) { dng_ifd *ret = 0; ret = search_single_ifd(info.fIFD, offset, ifdIndex, stream); int dummy; if (!ret) ret = search_single_ifd(info.fChainedIFD, offset, dummy, stream); if (!ret) { for (int c = 0; !ret && c < info.fChainedSubIFD.size(); c++) ret = search_single_ifd(info.fChainedSubIFD[c], offset, dummy, stream); } if (ret && (ret->fImageLength == h) && ret->fImageWidth == w) return ret; ifdIndex = -1; return 0; } #endif int LibRaw::valid_for_dngsdk() { #ifndef USE_DNGSDK return 0; #else if (!imgdata.idata.dng_version) return 0; // All DNG larger than 2GB - to DNG SDK if (libraw_internal_data.internal_data.input->size() > 2147483647ULL) return 1; if (!strcasecmp(imgdata.idata.make, "Blackmagic") && (libraw_internal_data.unpacker_data.tiff_compress == 7) && (libraw_internal_data.unpacker_data.tiff_bps > 8) ) return 0; if (libraw_internal_data.unpacker_data.tiff_compress == 34892 && libraw_internal_data.unpacker_data.tiff_bps == 8 && (libraw_internal_data.unpacker_data.tiff_samples == 3 || libraw_internal_data.unpacker_data.tiff_samples == 1 || libraw_internal_data.unpacker_data.tiff_samples == 4 ) && load_raw == &LibRaw::lossy_dng_load_raw ) { if (!dnghost) return 0; dng_host *host = static_cast(dnghost); libraw_dng_stream stream(libraw_internal_data.internal_data.input); AutoPtr negative; negative.Reset(host->Make_dng_negative()); dng_info info; info.Parse(*host, stream); info.PostParse(*host); if (!info.IsValidDNG()) return 0; negative->Parse(*host, stream, info); negative->PostParse(*host, stream, info); int ifdindex = -1; dng_ifd *rawIFD = search_for_ifd(info, libraw_internal_data.unpacker_data.data_offset, imgdata.sizes.raw_width, imgdata.sizes.raw_height, ifdindex,stream); if (rawIFD && ifdindex >= 0 && ifdindex == info.fMainIndex) return 1; return 0; } #ifdef USE_GPRSDK if (load_raw == &LibRaw::vc5_dng_load_raw_placeholder) // regardless of flags or use_dngsdk value! return 1; #endif if (!imgdata.rawparams.use_dngsdk) return 0; if (load_raw == &LibRaw::lossy_dng_load_raw) // WHY?? return 0; if (is_floating_point() && (imgdata.rawparams.use_dngsdk & LIBRAW_DNG_FLOAT)) return 1; if (!imgdata.idata.filters && (imgdata.rawparams.use_dngsdk & LIBRAW_DNG_LINEAR)) return 1; if (libraw_internal_data.unpacker_data.tiff_bps == 8 && (imgdata.rawparams.use_dngsdk & LIBRAW_DNG_8BIT)) return 1; if (libraw_internal_data.unpacker_data.tiff_compress == 8 && (imgdata.rawparams.use_dngsdk & LIBRAW_DNG_DEFLATE)) return 1; if (libraw_internal_data.unpacker_data.tiff_samples == 2) return 0; // Always deny 2-samples (old fuji superccd) if (imgdata.idata.filters == 9 && (imgdata.rawparams.use_dngsdk & LIBRAW_DNG_XTRANS)) return 1; if (is_fuji_rotated()) return 0; // refuse if (imgdata.rawparams.use_dngsdk & LIBRAW_DNG_OTHER) return 1; return 0; #endif } int LibRaw::try_dngsdk() { #ifdef USE_DNGSDK if (!dnghost) return LIBRAW_UNSPECIFIED_ERROR; dng_host *host = static_cast(dnghost); try { libraw_dng_stream stream(libraw_internal_data.internal_data.input); AutoPtr negative; negative.Reset(host->Make_dng_negative()); dng_info info; info.Parse(*host, stream); info.PostParse(*host); if (!info.IsValidDNG()) { return LIBRAW_DATA_ERROR; } negative->Parse(*host, stream, info); negative->PostParse(*host, stream, info); int ifdindex; dng_ifd *rawIFD = search_for_ifd(info,libraw_internal_data.unpacker_data.data_offset,imgdata.sizes.raw_width,imgdata.sizes.raw_height,ifdindex,stream); if(!rawIFD) return LIBRAW_DATA_ERROR; AutoPtr stage2; bool stage23used = false; bool zerocopy = false; //(new dng_simple_image(rawIFD->Bounds(), rawIFD->fSamplesPerPixel, rawIFD->PixelType(), host->Allocator())); if (((libraw_internal_data.unpacker_data.tiff_compress == 34892 && libraw_internal_data.unpacker_data.tiff_bps == 8 && libraw_internal_data.unpacker_data.tiff_samples == 3 && load_raw == &LibRaw::lossy_dng_load_raw) || (imgdata.rawparams.options & (LIBRAW_RAWOPTIONS_DNG_STAGE2| LIBRAW_RAWOPTIONS_DNG_STAGE3)) || ((tiff_ifd[ifdindex].dng_levels.parsedfields & (LIBRAW_DNGFM_OPCODE2| LIBRAW_DNGFM_OPCODE3)) && (imgdata.rawparams.options & (LIBRAW_RAWOPTIONS_DNG_STAGE2_IFPRESENT | LIBRAW_RAWOPTIONS_DNG_STAGE3_IFPRESENT))) ) && ifdindex >= 0) { if (info.fMainIndex != ifdindex) info.fMainIndex = ifdindex; negative->ReadStage1Image(*host, stream, info); negative->BuildStage2Image(*host); imgdata.process_warnings |= LIBRAW_WARN_DNG_STAGE2_APPLIED; if ( (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_STAGE3) || ((tiff_ifd[ifdindex].dng_levels.parsedfields & LIBRAW_DNGFM_OPCODE3) && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_STAGE3_IFPRESENT)) ) { negative->BuildStage3Image(*host); stage2.Reset((dng_simple_image*)negative->Stage3Image()); imgdata.process_warnings |= LIBRAW_WARN_DNG_STAGE3_APPLIED; } else stage2.Reset((dng_simple_image*)negative->Stage2Image()); stage23used = true; } else { stage2.Reset(new dng_simple_image(rawIFD->Bounds(), rawIFD->fSamplesPerPixel, rawIFD->PixelType(), host->Allocator())); #ifdef USE_GPRSDK if (libraw_internal_data.unpacker_data.tiff_compress == 9) { gpr_allocator allocator; allocator.Alloc = ::malloc; allocator.Free = ::free; gpr_buffer_auto vc5_image_obj(allocator.Alloc, allocator.Free); gpr_read_image reader(&vc5_image_obj); reader.Read(*host, *rawIFD, stream, *stage2.Get(), NULL, NULL); } else #endif { dng_read_image reader; reader.Read(*host, *rawIFD, stream, *stage2.Get(), NULL, NULL); } } if (stage2->Bounds().W() != S.raw_width || stage2->Bounds().H() != S.raw_height) { if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_ALLOWSIZECHANGE) { S.raw_width = S.width = stage2->Bounds().W(); S.left_margin = 0; S.raw_height = S.height = stage2->Bounds().H(); S.top_margin = 0; } else { stage2.Release(); // It holds copy to internal dngnegative return LIBRAW_DATA_ERROR; } } if (stage23used) { if (stage2->Planes() > 1) { imgdata.idata.filters = 0; imgdata.idata.colors = stage2->Planes(); } // reset BL and whitepoint imgdata.color.black = 0; memset(imgdata.color.cblack, 0, sizeof(imgdata.color.cblack)); imgdata.color.maximum = 0xffff; } int pplanes = stage2->Planes(); int ptype = stage2->PixelType(); dng_pixel_buffer buffer; stage2->GetPixelBuffer(buffer); int pixels = stage2->Bounds().H() * stage2->Bounds().W() * pplanes; if (ptype == ttShort && !stage23used && !is_curve_linear()) { imgdata.rawdata.raw_alloc = malloc(pixels * TagTypeSize(ptype)); ushort *src = (ushort *)buffer.fData; ushort *dst = (ushort *)imgdata.rawdata.raw_alloc; for (int i = 0; i < pixels; i++) dst[i] = imgdata.color.curve[src[i]]; S.raw_pitch = S.raw_width * pplanes * TagTypeSize(ptype); } else if (ptype == ttByte) { imgdata.rawdata.raw_alloc = malloc(pixels * TagTypeSize(ttShort)); unsigned char *src = (unsigned char *)buffer.fData; ushort *dst = (ushort *)imgdata.rawdata.raw_alloc; if (is_curve_linear()) { for (int i = 0; i < pixels; i++) dst[i] = src[i]; } else { for (int i = 0; i < pixels; i++) dst[i] = imgdata.color.curve[src[i]]; } S.raw_pitch = S.raw_width * pplanes * TagTypeSize(ttShort); } else { // Alloc if ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNGSDK_ZEROCOPY) && !stage23used) { zerocopy = true; } else { imgdata.rawdata.raw_alloc = malloc(pixels * TagTypeSize(ptype)); memmove(imgdata.rawdata.raw_alloc, buffer.fData, pixels * TagTypeSize(ptype)); } S.raw_pitch = S.raw_width * pplanes * TagTypeSize(ptype); } if (stage23used) stage2.Release(); if ((ptype == ttFloat) && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT)) zerocopy = true; if (zerocopy) { switch (ptype) { case ttFloat: if (pplanes == 1) imgdata.rawdata.float_image = (float *)buffer.fData; else if (pplanes == 3) imgdata.rawdata.float3_image = (float(*)[3])buffer.fData; else if (pplanes == 4) imgdata.rawdata.float4_image = (float(*)[4])buffer.fData; break; case ttShort: if (pplanes == 1) imgdata.rawdata.raw_image = (ushort *)buffer.fData; else if (pplanes == 3) imgdata.rawdata.color3_image = (ushort(*)[3])buffer.fData; else if (pplanes == 4) imgdata.rawdata.color4_image = (ushort(*)[4])buffer.fData; break; default: /* do nothing */ break; } } else { switch (ptype) { case ttFloat: if (pplanes == 1) imgdata.rawdata.float_image = (float *)imgdata.rawdata.raw_alloc; else if (pplanes == 3) imgdata.rawdata.float3_image = (float(*)[3])imgdata.rawdata.raw_alloc; else if (pplanes == 4) imgdata.rawdata.float4_image = (float(*)[4])imgdata.rawdata.raw_alloc; break; case ttByte: case ttShort: if (pplanes == 1) imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; else if (pplanes == 3) imgdata.rawdata.color3_image = (ushort(*)[3])imgdata.rawdata.raw_alloc; else if (pplanes == 4) imgdata.rawdata.color4_image = (ushort(*)[4])imgdata.rawdata.raw_alloc; break; default: /* do nothing */ break; } } if ((ptype == ttFloat) && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT)) { convertFloatToInt(); zerocopy = false; } if (zerocopy) { dng_negative *stolen = negative.Release(); dngnegative = stolen; dng_simple_image *simage = stage2.Release(); dngimage = simage; } } catch (...) { return LIBRAW_UNSPECIFIED_ERROR; } return (dngnegative || imgdata.rawdata.raw_alloc) ? LIBRAW_SUCCESS : LIBRAW_UNSPECIFIED_ERROR; #else return LIBRAW_UNSPECIFIED_ERROR; #endif } void LibRaw::set_dng_host(void *p) { #ifdef USE_DNGSDK dnghost = p; #endif } LibRaw-0.21.4/src/integration/rawspeed_glue.cpp000066400000000000000000000157151477673233700214560ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" #ifdef USE_RAWSPEED using namespace RawSpeed; CameraMetaDataLR::CameraMetaDataLR(char *data, int sz) : CameraMetaData() { ctxt = xmlNewParserCtxt(); if (ctxt == NULL) { ThrowCME("CameraMetaData:Could not initialize context."); } xmlResetLastError(); doc = xmlCtxtReadMemory(ctxt, data, sz, "", NULL, XML_PARSE_DTDVALID); if (doc == NULL) { ThrowCME("CameraMetaData: XML Document could not be parsed successfully. " "Error was: %s", ctxt->lastError.message); } if (ctxt->valid == 0) { if (ctxt->lastError.code == 0x5e) { // ignore this error code } else { ThrowCME("CameraMetaData: XML file does not validate. DTD Error was: %s", ctxt->lastError.message); } } xmlNodePtr cur; cur = xmlDocGetRootElement(doc); if (xmlStrcmp(cur->name, (const xmlChar *)"Cameras")) { ThrowCME("CameraMetaData: XML document of the wrong type, root node is not " "cameras."); return; } cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"Camera"))) { Camera *camera = new Camera(doc, cur); addCamera(camera); // Create cameras for aliases. for (unsigned int i = 0; i < camera->aliases.size(); i++) { addCamera(new Camera(camera, i)); } } cur = cur->next; } if (doc) xmlFreeDoc(doc); doc = 0; if (ctxt) xmlFreeParserCtxt(ctxt); ctxt = 0; } CameraMetaDataLR *make_camera_metadata() { int len = 0, i; for (i = 0; i < RAWSPEED_DATA_COUNT; i++) if (_rawspeed_data_xml[i]) { len += int(strlen(_rawspeed_data_xml[i])); } char *rawspeed_xml = (char *)calloc(len + 1, sizeof(_rawspeed_data_xml[0][0])); if (!rawspeed_xml) return NULL; int offt = 0; for (i = 0; i < RAWSPEED_DATA_COUNT; i++) if (_rawspeed_data_xml[i]) { int ll = int(strlen(_rawspeed_data_xml[i])); if (offt + ll > len) break; memmove(rawspeed_xml + offt, _rawspeed_data_xml[i], ll); offt += ll; } rawspeed_xml[offt] = 0; CameraMetaDataLR *ret = NULL; try { ret = new CameraMetaDataLR(rawspeed_xml, offt); } catch (...) { // Mask all exceptions } free(rawspeed_xml); return ret; } #endif int LibRaw::set_rawspeed_camerafile(char * filename) { #ifdef USE_RAWSPEED try { CameraMetaDataLR *camerameta = new CameraMetaDataLR(filename); if (_rawspeed_camerameta) { CameraMetaDataLR *d = static_cast(_rawspeed_camerameta); delete d; } _rawspeed_camerameta = static_cast(camerameta); } catch (...) { // just return error code return -1; } #else (void)filename; #endif return 0; } #ifdef USE_RAWSPEED void LibRaw::fix_after_rawspeed(int /*bl*/) { if (load_raw == &LibRaw::lossy_dng_load_raw) C.maximum = 0xffff; else if (load_raw == &LibRaw::sony_load_raw) C.maximum = 0x3ff0; } #else void LibRaw::fix_after_rawspeed(int) {} #endif int LibRaw::try_rawspeed() { #ifdef USE_RAWSPEED int ret = LIBRAW_SUCCESS; #ifdef USE_RAWSPEED_BITS int rawspeed_ignore_errors = (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV1_IGNOREERRORS); #else int rawspeed_ignore_errors = 0; #endif if (imgdata.idata.dng_version && imgdata.idata.colors == 3 && !strcasecmp(imgdata.idata.software, "Adobe Photoshop Lightroom 6.1.1 (Windows)")) rawspeed_ignore_errors = 1; // RawSpeed Supported, INT64 spos = ID.input->tell(); void *_rawspeed_buffer = 0; try { ID.input->seek(0, SEEK_SET); INT64 _rawspeed_buffer_sz = ID.input->size() + 32; _rawspeed_buffer = malloc(_rawspeed_buffer_sz); if (!_rawspeed_buffer) throw LIBRAW_EXCEPTION_ALLOC; ID.input->read(_rawspeed_buffer, _rawspeed_buffer_sz, 1); FileMap map((uchar8 *)_rawspeed_buffer, _rawspeed_buffer_sz); RawParser t(&map); RawDecoder *d = 0; CameraMetaDataLR *meta = static_cast(_rawspeed_camerameta); d = t.getDecoder(); if (!d) throw "Unable to find decoder"; #ifdef USE_RAWSPEED_BITS if (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV1_FAILONUNKNOWN) d->failOnUnknown = TRUE; else d->failOnUnknown = FALSE; #endif d->interpolateBadPixels = FALSE; d->applyStage1DngOpcodes = FALSE; try { d->checkSupport(meta); } catch (const RawDecoderException &e) { imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_UNSUPPORTED; throw e; } _rawspeed_decoder = static_cast(d); d->decodeRaw(); d->decodeMetaData(meta); RawImage r = d->mRaw; if (r->errors.size() > 0 && !rawspeed_ignore_errors) { delete d; _rawspeed_decoder = 0; throw 1; } if (r->isCFA) { imgdata.rawdata.raw_image = (ushort *)r->getDataUncropped(0, 0); } else if (r->getCpp() == 4) { imgdata.rawdata.color4_image = (ushort(*)[4])r->getDataUncropped(0, 0); if (r->whitePoint > 0 && r->whitePoint < 65536) C.maximum = r->whitePoint; } else if (r->getCpp() == 3) { imgdata.rawdata.color3_image = (ushort(*)[3])r->getDataUncropped(0, 0); if (r->whitePoint > 0 && r->whitePoint < 65536) C.maximum = r->whitePoint; } else { delete d; _rawspeed_decoder = 0; ret = LIBRAW_UNSPECIFIED_ERROR; } if (_rawspeed_decoder) { // set sizes iPoint2D rsdim = r->getUncroppedDim(); S.raw_pitch = r->pitch; S.raw_width = rsdim.x; S.raw_height = rsdim.y; // C.maximum = r->whitePoint; fix_after_rawspeed(r->blackLevel); } free(_rawspeed_buffer); _rawspeed_buffer = 0; imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROCESSED; } catch (const RawDecoderException &RDE) { imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROBLEM; if (_rawspeed_buffer) { free(_rawspeed_buffer); _rawspeed_buffer = 0; } if (!strncmp(RDE.what(), "Decoder canceled", strlen("Decoder canceled"))) throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; ret = LIBRAW_UNSPECIFIED_ERROR; } catch (...) { // We may get here due to cancellation flag imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROBLEM; if (_rawspeed_buffer) { free(_rawspeed_buffer); _rawspeed_buffer = 0; } ret = LIBRAW_UNSPECIFIED_ERROR; } ID.input->seek(spos, SEEK_SET); return ret; #else return LIBRAW_NOT_IMPLEMENTED; #endif } LibRaw-0.21.4/src/libraw_c_api.cpp000066400000000000000000000260641477673233700167170ustar00rootroot00000000000000/* -*- C++ -*- * File: libraw_c_api.cpp * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8 , 2008 * * LibRaw C interface 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 #include #include "libraw/libraw.h" #ifdef __cplusplus #include extern "C" { #endif libraw_data_t *libraw_init(unsigned int flags) { LibRaw *ret; try { ret = new LibRaw(flags); } catch (const std::bad_alloc& ) { return NULL; } return &(ret->imgdata); } unsigned libraw_capabilities() { return LibRaw::capabilities(); } const char *libraw_version() { return LibRaw::version(); } const char *libraw_strprogress(enum LibRaw_progress p) { return LibRaw::strprogress(p); } int libraw_versionNumber() { return LibRaw::versionNumber(); } const char **libraw_cameraList() { return LibRaw::cameraList(); } int libraw_cameraCount() { return LibRaw::cameraCount(); } const char *libraw_unpack_function_name(libraw_data_t *lr) { if (!lr) return "NULL parameter passed"; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->unpack_function_name(); } void libraw_subtract_black(libraw_data_t *lr) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->subtract_black(); } int libraw_open_file(libraw_data_t *lr, const char *file) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->open_file(file); } libraw_iparams_t *libraw_get_iparams(libraw_data_t *lr) { if (!lr) return NULL; return &(lr->idata); } libraw_lensinfo_t *libraw_get_lensinfo(libraw_data_t *lr) { if (!lr) return NULL; return &(lr->lens); } libraw_imgother_t *libraw_get_imgother(libraw_data_t *lr) { if (!lr) return NULL; return &(lr->other); } #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM int libraw_open_file_ex(libraw_data_t *lr, const char *file, INT64 sz) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->open_file(file, sz); } #endif #ifdef LIBRAW_WIN32_UNICODEPATHS int libraw_open_wfile(libraw_data_t *lr, const wchar_t *file) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->open_file(file); } #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM int libraw_open_wfile_ex(libraw_data_t *lr, const wchar_t *file, INT64 sz) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->open_file(file, sz); } #endif #endif int libraw_open_buffer(libraw_data_t *lr, const void *buffer, size_t size) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->open_buffer(buffer, size); } int libraw_open_bayer(libraw_data_t *lr, unsigned char *data, unsigned datalen, ushort _raw_width, ushort _raw_height, ushort _left_margin, ushort _top_margin, ushort _right_margin, ushort _bottom_margin, unsigned char procflags, unsigned char bayer_pattern, unsigned unused_bits, unsigned otherflags, unsigned black_level) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->open_bayer(data, datalen, _raw_width, _raw_height, _left_margin, _top_margin, _right_margin, _bottom_margin, procflags, bayer_pattern, unused_bits, otherflags, black_level); } int libraw_unpack(libraw_data_t *lr) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->unpack(); } int libraw_unpack_thumb(libraw_data_t *lr) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->unpack_thumb(); } int libraw_unpack_thumb_ex(libraw_data_t *lr, int i) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->unpack_thumb_ex(i); } void libraw_recycle_datastream(libraw_data_t *lr) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->recycle_datastream(); } void libraw_recycle(libraw_data_t *lr) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->recycle(); } void libraw_close(libraw_data_t *lr) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; delete ip; } void libraw_set_exifparser_handler(libraw_data_t *lr, exif_parser_callback cb, void *data) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->set_exifparser_handler(cb, data); } void libraw_set_dataerror_handler(libraw_data_t *lr, data_callback func, void *data) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->set_dataerror_handler(func, data); } void libraw_set_progress_handler(libraw_data_t *lr, progress_callback cb, void *data) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->set_progress_handler(cb, data); } // DCRAW int libraw_adjust_sizes_info_only(libraw_data_t *lr) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->adjust_sizes_info_only(); } int libraw_dcraw_ppm_tiff_writer(libraw_data_t *lr, const char *filename) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->dcraw_ppm_tiff_writer(filename); } int libraw_dcraw_thumb_writer(libraw_data_t *lr, const char *fname) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->dcraw_thumb_writer(fname); } int libraw_dcraw_process(libraw_data_t *lr) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->dcraw_process(); } libraw_processed_image_t *libraw_dcraw_make_mem_image(libraw_data_t *lr, int *errc) { if (!lr) { if (errc) *errc = EINVAL; return NULL; } LibRaw *ip = (LibRaw *)lr->parent_class; return ip->dcraw_make_mem_image(errc); } libraw_processed_image_t *libraw_dcraw_make_mem_thumb(libraw_data_t *lr, int *errc) { if (!lr) { if (errc) *errc = EINVAL; return NULL; } LibRaw *ip = (LibRaw *)lr->parent_class; return ip->dcraw_make_mem_thumb(errc); } void libraw_dcraw_clear_mem(libraw_processed_image_t *p) { LibRaw::dcraw_clear_mem(p); } int libraw_raw2image(libraw_data_t *lr) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->raw2image(); } void libraw_free_image(libraw_data_t *lr) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->free_image(); } int libraw_get_decoder_info(libraw_data_t *lr, libraw_decoder_info_t *d) { if (!lr || !d) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->get_decoder_info(d); } int libraw_COLOR(libraw_data_t *lr, int row, int col) { if (!lr) return EINVAL; LibRaw *ip = (LibRaw *)lr->parent_class; return ip->COLOR(row, col); } /* getters/setters used by 3DLut Creator */ DllDef void libraw_set_demosaic(libraw_data_t *lr, int value) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->imgdata.params.user_qual = value; } DllDef void libraw_set_output_color(libraw_data_t *lr, int value) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->imgdata.params.output_color = value; } DllDef void libraw_set_adjust_maximum_thr(libraw_data_t *lr, float value) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->imgdata.params.adjust_maximum_thr = value; } DllDef void libraw_set_output_bps(libraw_data_t *lr, int value) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->imgdata.params.output_bps = value; } DllDef void libraw_set_output_tif(libraw_data_t *lr, int value) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->imgdata.params.output_tiff = value; } #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define LIM(x, min, max) MAX(min, MIN(x, max)) DllDef void libraw_set_user_mul(libraw_data_t *lr, int index, float val) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->imgdata.params.user_mul[LIM(index, 0, 3)] = val; } DllDef void libraw_set_gamma(libraw_data_t *lr, int index, float value) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->imgdata.params.gamm[LIM(index, 0, 5)] = value; } DllDef void libraw_set_no_auto_bright(libraw_data_t *lr, int value) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->imgdata.params.no_auto_bright = value; } DllDef void libraw_set_bright(libraw_data_t *lr, float value) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->imgdata.params.bright = value; } DllDef void libraw_set_highlight(libraw_data_t *lr, int value) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->imgdata.params.highlight = value; } DllDef void libraw_set_fbdd_noiserd(libraw_data_t *lr, int value) { if (!lr) return; LibRaw *ip = (LibRaw *)lr->parent_class; ip->imgdata.params.fbdd_noiserd = value; } DllDef int libraw_get_raw_height(libraw_data_t *lr) { if (!lr) return EINVAL; return lr->sizes.raw_height; } DllDef int libraw_get_raw_width(libraw_data_t *lr) { if (!lr) return EINVAL; return lr->sizes.raw_width; } DllDef int libraw_get_iheight(libraw_data_t *lr) { if (!lr) return EINVAL; return lr->sizes.iheight; } DllDef int libraw_get_iwidth(libraw_data_t *lr) { if (!lr) return EINVAL; return lr->sizes.iwidth; } DllDef float libraw_get_cam_mul(libraw_data_t *lr, int index) { if (!lr) return EINVAL; return lr->color.cam_mul[LIM(index, 0, 3)]; } DllDef float libraw_get_pre_mul(libraw_data_t *lr, int index) { if (!lr) return EINVAL; return lr->color.pre_mul[LIM(index, 0, 3)]; } DllDef float libraw_get_rgb_cam(libraw_data_t *lr, int index1, int index2) { if (!lr) return EINVAL; return lr->color.rgb_cam[LIM(index1, 0, 2)][LIM(index2, 0, 3)]; } DllDef int libraw_get_color_maximum(libraw_data_t *lr) { if (!lr) return EINVAL; return lr->color.maximum; } #ifdef __cplusplus } #endif LibRaw-0.21.4/src/libraw_datastream.cpp000066400000000000000000000633221477673233700177670ustar00rootroot00000000000000/* -*- C++ -*- * File: libraw_datastream.cpp * Copyright 2008-2021 LibRaw LLC (info@libraw.org) * * LibRaw C++ interface (implementation) 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). */ #ifdef _WIN32 #ifdef __MINGW32__ #define _WIN32_WINNT 0x0500 #include #endif #endif #define LIBRAW_LIBRARY_BUILD #include "libraw/libraw.h" #include "libraw/libraw_types.h" #include "libraw/libraw_datastream.h" #include #ifdef USE_JASPER #include /* Decode RED camera movies */ #else #define NO_JASPER #endif #ifdef USE_JPEG #include #include #else #define NO_JPEG #endif #ifdef USE_JPEG typedef struct { struct jpeg_source_mgr pub; /* public fields */ LibRaw_abstract_datastream *instream; /* source stream */ JOCTET *buffer; /* start of buffer */ boolean start_of_file; /* have we gotten any data yet? */ } lr_jpg_source_mgr; typedef lr_jpg_source_mgr *lr_jpg_src_ptr; #define LR_JPEG_INPUT_BUF_SIZE 16384 static void f_init_source(j_decompress_ptr cinfo) { lr_jpg_src_ptr src = (lr_jpg_src_ptr)cinfo->src; src->start_of_file = TRUE; } #ifdef ERREXIT #undef ERREXIT #endif #define ERREXIT(cinfo, code) \ ((cinfo)->err->msg_code = (code), \ (*(cinfo)->err->error_exit)((j_common_ptr)(cinfo))) static boolean lr_fill_input_buffer(j_decompress_ptr cinfo) { lr_jpg_src_ptr src = (lr_jpg_src_ptr)cinfo->src; size_t nbytes; nbytes = src->instream->read((void*)src->buffer, 1, LR_JPEG_INPUT_BUF_SIZE); if (nbytes <= 0) { if (src->start_of_file) /* Treat empty input file as fatal error */ ERREXIT(cinfo, JERR_INPUT_EMPTY); WARNMS(cinfo, JWRN_JPEG_EOF); /* Insert a fake EOI marker */ src->buffer[0] = (JOCTET)0xFF; src->buffer[1] = (JOCTET)JPEG_EOI; nbytes = 2; } src->pub.next_input_byte = src->buffer; src->pub.bytes_in_buffer = nbytes; src->start_of_file = FALSE; return TRUE; } static void lr_skip_input_data(j_decompress_ptr cinfo, long num_bytes) { struct jpeg_source_mgr *src = cinfo->src; if (num_bytes > 0) { while (num_bytes > (long)src->bytes_in_buffer) { num_bytes -= (long)src->bytes_in_buffer; (void)(*src->fill_input_buffer)(cinfo); /* note we assume that fill_input_buffer will never return FALSE, * so suspension need not be handled. */ } src->next_input_byte += (size_t)num_bytes; src->bytes_in_buffer -= (size_t)num_bytes; } } static void lr_term_source(j_decompress_ptr /*cinfo*/) {} static void lr_jpeg_src(j_decompress_ptr cinfo, LibRaw_abstract_datastream *inf) { lr_jpg_src_ptr src; if (cinfo->src == NULL) { /* first time for this JPEG object? */ cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)( (j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(lr_jpg_source_mgr)); src = (lr_jpg_src_ptr)cinfo->src; src->buffer = (JOCTET *)(*cinfo->mem->alloc_small)( (j_common_ptr)cinfo, JPOOL_PERMANENT, LR_JPEG_INPUT_BUF_SIZE * sizeof(JOCTET)); } else if (cinfo->src->init_source != f_init_source) { ERREXIT(cinfo, JERR_BUFFER_SIZE); } src = (lr_jpg_src_ptr)cinfo->src; src->pub.init_source = f_init_source; src->pub.fill_input_buffer = lr_fill_input_buffer; src->pub.skip_input_data = lr_skip_input_data; src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ src->pub.term_source = lr_term_source; src->instream = inf; src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ src->pub.next_input_byte = NULL; /* until buffer loaded */ } #endif int LibRaw_abstract_datastream::jpeg_src(void *jpegdata) { #ifdef NO_JPEG return -1; #else j_decompress_ptr cinfo = (j_decompress_ptr)jpegdata; buffering_off(); lr_jpeg_src(cinfo, this); return 0; // OK #endif } #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM // == LibRaw_file_datastream == LibRaw_file_datastream::~LibRaw_file_datastream() { if (jas_file) fclose(jas_file); } LibRaw_file_datastream::LibRaw_file_datastream(const char *fname) : filename(fname), _fsize(0) #ifdef LIBRAW_WIN32_UNICODEPATHS , wfilename() #endif , jas_file(NULL) { if (filename.size() > 0) { #ifndef LIBRAW_WIN32_CALLS struct stat st; if (!stat(filename.c_str(), &st)) _fsize = st.st_size; #else struct _stati64 st; if (!_stati64(filename.c_str(), &st)) _fsize = st.st_size; #endif #ifdef LIBRAW_USE_AUTOPTR std::auto_ptr buf(new std::filebuf()); #else std::unique_ptr buf(new std::filebuf()); #endif buf->open(filename.c_str(), std::ios_base::in | std::ios_base::binary); if (buf->is_open()) { #ifdef LIBRAW_USE_AUTOPTR f = buf; #else f = std::move(buf); #endif } } } #ifdef LIBRAW_WIN32_UNICODEPATHS LibRaw_file_datastream::LibRaw_file_datastream(const wchar_t *fname) : filename(), wfilename(fname), jas_file(NULL), _fsize(0) { if (wfilename.size() > 0) { struct _stati64 st; if (!_wstati64(wfilename.c_str(), &st)) _fsize = st.st_size; #ifdef LIBRAW_USE_AUTOPTR std::auto_ptr buf(new std::filebuf()); #else std::unique_ptr buf(new std::filebuf()); #endif buf->open(wfilename.c_str(), std::ios_base::in | std::ios_base::binary); if (buf->is_open()) { #ifdef LIBRAW_USE_AUTOPTR f = buf; #else f = std::move(buf); #endif } } } const wchar_t *LibRaw_file_datastream::wfname() { return wfilename.size() > 0 ? wfilename.c_str() : NULL; } #endif int LibRaw_file_datastream::valid() { return f.get() ? 1 : 0; } #define LR_STREAM_CHK() \ do \ { \ if (!f.get()) \ throw LIBRAW_EXCEPTION_IO_EOF; \ } while (0) int LibRaw_file_datastream::read(void *ptr, size_t size, size_t nmemb) { /* Visual Studio 2008 marks sgetn as insecure, but VS2010 does not. */ #if defined(WIN32SECURECALLS) && (_MSC_VER < 1600) LR_STREAM_CHK(); return int(f->_Sgetn_s(static_cast(ptr), nmemb * size, nmemb * size) / (size > 0 ? size : 1)); #else LR_STREAM_CHK(); return int(f->sgetn(static_cast(ptr), std::streamsize(nmemb * size)) / (size > 0 ? size : 1)); #endif } int LibRaw_file_datastream::eof() { LR_STREAM_CHK(); return f->sgetc() == EOF; } int LibRaw_file_datastream::seek(INT64 o, int whence) { LR_STREAM_CHK(); std::ios_base::seekdir dir; switch (whence) { case SEEK_SET: dir = std::ios_base::beg; break; case SEEK_CUR: dir = std::ios_base::cur; break; case SEEK_END: dir = std::ios_base::end; break; default: dir = std::ios_base::beg; } return f->pubseekoff((long)o, dir) < 0; } INT64 LibRaw_file_datastream::tell() { LR_STREAM_CHK(); return f->pubseekoff(0, std::ios_base::cur); } char *LibRaw_file_datastream::gets(char *str, int sz) { if(sz<1) return NULL; LR_STREAM_CHK(); std::istream is(f.get()); is.getline(str, sz); if (is.fail()) return 0; return str; } int LibRaw_file_datastream::scanf_one(const char *fmt, void *val) { LR_STREAM_CHK(); std::istream is(f.get()); /* HUGE ASSUMPTION: *fmt is either "%d" or "%f" */ if (strcmp(fmt, "%d") == 0) { int d; is >> d; if (is.fail()) return EOF; *(static_cast(val)) = d; } else { float f; is >> f; if (is.fail()) return EOF; *(static_cast(val)) = f; } return 1; } const char *LibRaw_file_datastream::fname() { return filename.size() > 0 ? filename.c_str() : NULL; } #undef LR_STREAM_CHK #ifdef LIBRAW_OLD_VIDEO_SUPPORT void *LibRaw_file_datastream::make_jas_stream() { #ifdef NO_JASPER return NULL; #else #ifdef LIBRAW_WIN32_UNICODEPATHS if (wfname()) { jas_file = _wfopen(wfname(), L"rb"); return jas_stream_fdopen(fileno(jas_file), "rb"); } else #endif { return jas_stream_fopen(fname(), "rb"); } #endif } #endif #endif // == LibRaw_buffer_datastream LibRaw_buffer_datastream::LibRaw_buffer_datastream(const void *buffer, size_t bsize) { buf = (unsigned char *)buffer; streampos = 0; streamsize = bsize; } LibRaw_buffer_datastream::~LibRaw_buffer_datastream() {} int LibRaw_buffer_datastream::read(void *ptr, size_t sz, size_t nmemb) { size_t to_read = sz * nmemb; if (to_read > streamsize - streampos) to_read = streamsize - streampos; if (to_read < 1) return 0; memmove(ptr, buf + streampos, to_read); streampos += to_read; return int((to_read + sz - 1) / (sz > 0 ? sz : 1)); } int LibRaw_buffer_datastream::seek(INT64 o, int whence) { switch (whence) { case SEEK_SET: if (o < 0) streampos = 0; else if (size_t(o) > streamsize) streampos = streamsize; else streampos = size_t(o); return 0; case SEEK_CUR: if (o < 0) { if (size_t(-o) >= streampos) streampos = 0; else streampos += (size_t)o; } else if (o > 0) { if (o + streampos > streamsize) streampos = streamsize; else streampos += (size_t)o; } return 0; case SEEK_END: if (o > 0) streampos = streamsize; else if (size_t(-o) > streamsize) streampos = 0; else streampos = streamsize + (size_t)o; return 0; default: return 0; } } INT64 LibRaw_buffer_datastream::tell() { return INT64(streampos); } char *LibRaw_buffer_datastream::gets(char *s, int sz) { if(sz<1) return NULL; unsigned char *psrc, *pdest, *str; str = (unsigned char *)s; psrc = buf + streampos; pdest = str; if(streampos >= streamsize) return NULL; while ((size_t(psrc - buf) < streamsize) && ((pdest - str) < (sz-1))) { *pdest = *psrc; if (*psrc == '\n') break; psrc++; pdest++; } if (size_t(psrc - buf) < streamsize) psrc++; if ((pdest - str) < sz-1) *(++pdest) = 0; else s[sz - 1] = 0; // ensure trailing zero streampos = psrc - buf; return s; } int LibRaw_buffer_datastream::scanf_one(const char *fmt, void *val) { int scanf_res; if (streampos > streamsize) return 0; #ifndef WIN32SECURECALLS scanf_res = sscanf((char *)(buf + streampos), fmt, val); #else scanf_res = sscanf_s((char *)(buf + streampos), fmt, val); #endif if (scanf_res > 0) { int xcnt = 0; while (streampos < streamsize-1) { streampos++; xcnt++; if (buf[streampos] == 0 || buf[streampos] == ' ' || buf[streampos] == '\t' || buf[streampos] == '\n' || xcnt > 24) break; } } return scanf_res; } int LibRaw_buffer_datastream::eof() { return streampos >= streamsize; } int LibRaw_buffer_datastream::valid() { return buf ? 1 : 0; } #ifdef LIBRAW_OLD_VIDEO_SUPPORT void *LibRaw_buffer_datastream::make_jas_stream() { #ifdef NO_JASPER return NULL; #else return jas_stream_memopen((char *)buf + streampos, streamsize - streampos); #endif } #endif int LibRaw_buffer_datastream::jpeg_src(void *jpegdata) { #if defined(NO_JPEG) || !defined(USE_JPEG) return -1; #else j_decompress_ptr cinfo = (j_decompress_ptr)jpegdata; jpeg_mem_src(cinfo, (unsigned char *)buf + streampos,(unsigned long)(streamsize - streampos)); return 0; #endif } // int LibRaw_buffer_datastream // == LibRaw_bigfile_datastream LibRaw_bigfile_datastream::LibRaw_bigfile_datastream(const char *fname) : filename(fname) #ifdef LIBRAW_WIN32_UNICODEPATHS , wfilename() #endif { if (filename.size() > 0) { #ifndef LIBRAW_WIN32_CALLS struct stat st; if (!stat(filename.c_str(), &st)) _fsize = st.st_size; #else struct _stati64 st; if (!_stati64(filename.c_str(), &st)) _fsize = st.st_size; #endif #ifndef WIN32SECURECALLS f = fopen(fname, "rb"); #else if (fopen_s(&f, fname, "rb")) f = 0; #endif } else { filename = std::string(); f = 0; } } #ifdef LIBRAW_WIN32_UNICODEPATHS LibRaw_bigfile_datastream::LibRaw_bigfile_datastream(const wchar_t *fname) : filename(), wfilename(fname) { if (wfilename.size() > 0) { struct _stati64 st; if (!_wstati64(wfilename.c_str(), &st)) _fsize = st.st_size; #ifndef WIN32SECURECALLS f = _wfopen(wfilename.c_str(), L"rb"); #else if (_wfopen_s(&f, fname, L"rb")) f = 0; #endif } else { wfilename = std::wstring(); f = 0; } } const wchar_t *LibRaw_bigfile_datastream::wfname() { return wfilename.size() > 0 ? wfilename.c_str() : NULL; } #endif LibRaw_bigfile_datastream::~LibRaw_bigfile_datastream() { if (f) fclose(f); } int LibRaw_bigfile_datastream::valid() { return f ? 1 : 0; } #define LR_BF_CHK() \ do \ { \ if (!f) \ throw LIBRAW_EXCEPTION_IO_EOF; \ } while (0) int LibRaw_bigfile_datastream::read(void *ptr, size_t size, size_t nmemb) { LR_BF_CHK(); return int(fread(ptr, size, nmemb, f)); } int LibRaw_bigfile_datastream::eof() { LR_BF_CHK(); return feof(f); } int LibRaw_bigfile_datastream::seek(INT64 o, int whence) { LR_BF_CHK(); #if defined(_WIN32) #ifdef WIN32SECURECALLS return _fseeki64(f, o, whence); #else return fseek(f, (long)o, whence); #endif #else return fseeko(f, o, whence); #endif } INT64 LibRaw_bigfile_datastream::tell() { LR_BF_CHK(); #if defined(_WIN32) #ifdef WIN32SECURECALLS return _ftelli64(f); #else return ftell(f); #endif #else return ftello(f); #endif } char *LibRaw_bigfile_datastream::gets(char *str, int sz) { if(sz<1) return NULL; LR_BF_CHK(); return fgets(str, sz, f); } int LibRaw_bigfile_datastream::scanf_one(const char *fmt, void *val) { LR_BF_CHK(); return #ifndef WIN32SECURECALLS fscanf(f, fmt, val) #else fscanf_s(f, fmt, val) #endif ; } const char *LibRaw_bigfile_datastream::fname() { return filename.size() > 0 ? filename.c_str() : NULL; } #ifdef LIBRAW_OLD_VIDEO_SUPPORT void *LibRaw_bigfile_datastream::make_jas_stream() { #ifdef NO_JASPER return NULL; #else return jas_stream_fdopen(fileno(f), "rb"); #endif } #endif // == LibRaw_windows_datastream #ifdef LIBRAW_WIN32_CALLS LibRaw_windows_datastream::LibRaw_windows_datastream(const TCHAR *sFile) : LibRaw_buffer_datastream(NULL, 0), hMap_(0), pView_(NULL) { #if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_APP) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) HANDLE hFile = CreateFile2(sFile, GENERIC_READ, 0, OPEN_EXISTING, 0); #else HANDLE hFile = CreateFile(sFile, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); #endif if (hFile == INVALID_HANDLE_VALUE) throw std::runtime_error("failed to open the file"); try { Open(hFile); } catch (...) { CloseHandle(hFile); throw; } CloseHandle(hFile); // windows will defer the actual closing of this handle // until the hMap_ is closed reconstruct_base(); } // ctor: construct with a file handle - caller is responsible for closing the // file handle LibRaw_windows_datastream::LibRaw_windows_datastream(HANDLE hFile) : LibRaw_buffer_datastream(NULL, 0), hMap_(0), pView_(NULL) { Open(hFile); reconstruct_base(); } // dtor: unmap and close the mapping handle LibRaw_windows_datastream::~LibRaw_windows_datastream() { if (pView_ != NULL) ::UnmapViewOfFile(pView_); if (hMap_ != 0) ::CloseHandle(hMap_); } void LibRaw_windows_datastream::Open(HANDLE hFile) { // create a file mapping handle on the file handle hMap_ = ::CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0); if (hMap_ == NULL) throw std::runtime_error("failed to create file mapping"); // now map the whole file base view if (!::GetFileSizeEx(hFile, (PLARGE_INTEGER)&cbView_)) throw std::runtime_error("failed to get the file size"); pView_ = ::MapViewOfFile(hMap_, FILE_MAP_READ, 0, 0, (size_t)cbView_); if (pView_ == NULL) throw std::runtime_error("failed to map the file"); } #endif #if defined (LIBRAW_NO_IOSTREAMS_DATASTREAM) && defined (LIBRAW_WIN32_CALLS) /* LibRaw_bigfile_buffered_datastream: copypasted from LibRaw_bigfile_datastream + extra cache on read */ #undef LR_BF_CHK #define LR_BF_CHK() \ do \ { \ if (fhandle ==0 || fhandle == INVALID_HANDLE_VALUE) \ throw LIBRAW_EXCEPTION_IO_EOF; \ } while (0) #define LIBRAW_BUFFER_ALIGN 4096 int LibRaw_bufio_params::bufsize = 16384; void LibRaw_bufio_params::set_bufsize(int bs) { if (bs > 0) bufsize = bs; } LibRaw_bigfile_buffered_datastream::LibRaw_bigfile_buffered_datastream(const char *fname) : filename(fname), _fsize(0), _fpos(0) #ifdef LIBRAW_WIN32_UNICODEPATHS , wfilename() #endif , iobuffers(), buffered(1) { if (filename.size() > 0) { std::string fn(fname); std::wstring fpath(fn.begin(), fn.end()); #if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_APP) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) if ((fhandle = CreateFile2(fpath.c_str(), GENERIC_READ, 0, OPEN_EXISTING, 0)) != INVALID_HANDLE_VALUE) #else if ((fhandle = CreateFileW(fpath.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) #endif { LARGE_INTEGER fs; if (GetFileSizeEx(fhandle, &fs)) _fsize = fs.QuadPart; } } else { filename = std::string(); fhandle = INVALID_HANDLE_VALUE; } } #ifdef LIBRAW_WIN32_UNICODEPATHS LibRaw_bigfile_buffered_datastream::LibRaw_bigfile_buffered_datastream(const wchar_t *fname) : filename(), _fsize(0), _fpos(0), wfilename(fname), iobuffers(), buffered(1) { if (wfilename.size() > 0) { #if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_APP) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) if ((fhandle = CreateFile2(wfilename.c_str(), GENERIC_READ, 0, OPEN_EXISTING, 0)) != INVALID_HANDLE_VALUE) #else if ((fhandle = CreateFileW(wfilename.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) #endif { LARGE_INTEGER fs; if (GetFileSizeEx(fhandle, &fs)) _fsize = fs.QuadPart; } } else { wfilename = std::wstring(); fhandle = INVALID_HANDLE_VALUE; } } const wchar_t *LibRaw_bigfile_buffered_datastream::wfname() { return wfilename.size() > 0 ? wfilename.c_str() : NULL; } #endif LibRaw_bigfile_buffered_datastream::~LibRaw_bigfile_buffered_datastream() { if (valid()) CloseHandle(fhandle); } int LibRaw_bigfile_buffered_datastream::valid() { return (fhandle != NULL) && (fhandle != INVALID_HANDLE_VALUE); } const char *LibRaw_bigfile_buffered_datastream::fname() { return filename.size() > 0 ? filename.c_str() : NULL; } #ifdef LIBRAW_OLD_VIDEO_SUPPORT void *LibRaw_bigfile_buffered_datastream::make_jas_stream() { #ifdef NO_JASPER return NULL; #else return NULL; #endif } #endif INT64 LibRaw_bigfile_buffered_datastream::readAt(void *ptr, size_t size, INT64 off) { LR_BF_CHK(); DWORD NumberOfBytesRead; DWORD nNumberOfBytesToRead = (DWORD)size; struct _OVERLAPPED olap; memset(&olap, 0, sizeof(olap)); olap.Offset = off & 0xffffffff; olap.OffsetHigh = off >> 32; if (ReadFile(fhandle, ptr, nNumberOfBytesToRead, &NumberOfBytesRead, &olap)) return NumberOfBytesRead; else return 0; } #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #ifdef _MSC_VER #pragma intrinsic(memcpy) #endif int LibRaw_bigfile_buffered_datastream::read(void *data, size_t size, size_t nmemb) { if (size < 1 || nmemb < 1) return 0; LR_BF_CHK(); INT64 count = size * nmemb; INT64 partbytes = 0; if (!buffered) { INT64 r = readAt(data, count, _fpos); _fpos += r; return int(r / size); } unsigned char *fBuffer = (unsigned char*)iobuffers[0].data(); while (count) { INT64 inbuffer = 0; // See if the request is totally inside buffer. if (iobuffers[0].contains(_fpos, inbuffer)) { if (inbuffer >= count) { memcpy(data, fBuffer + (unsigned)(_fpos - iobuffers[0]._bstart), count); _fpos += count; return int((count + partbytes) / size); } memcpy(data, fBuffer + (_fpos - iobuffers[0]._bstart), inbuffer); partbytes += inbuffer; count -= inbuffer; data = (void *)(((char *)data) + inbuffer); _fpos += inbuffer; } if (count > (INT64) iobuffers[0].size()) { fallback: if (_fpos + count > _fsize) count = MAX(0, _fsize - _fpos); if (count > 0) { INT64 r = readAt(data, count, _fpos); _fpos += r; return int((r + partbytes) / size); } else return 0; } if (!fillBufferAt(0, _fpos)) goto fallback; } return 0; } bool LibRaw_bigfile_buffered_datastream::fillBufferAt(int bi, INT64 off) { if (off < 0LL) return false; iobuffers[bi]._bstart = off; if (iobuffers[bi].size() >= LIBRAW_BUFFER_ALIGN * 2)// Align to a file block. iobuffers[bi]._bstart &= (INT64)~((INT64)(LIBRAW_BUFFER_ALIGN - 1)); iobuffers[bi]._bend = MIN(iobuffers[bi]._bstart + (INT64)iobuffers[bi].size(), _fsize); if (iobuffers[bi]._bend <= off) // Buffer alignment problem, fallback return false; INT64 rr = readAt(iobuffers[bi].data(), (uint32_t)(iobuffers[bi]._bend - iobuffers[bi]._bstart), iobuffers[bi]._bstart); if (rr > 0) { iobuffers[bi]._bend = iobuffers[bi]._bstart + rr; return true; } return false; } int LibRaw_bigfile_buffered_datastream::eof() { LR_BF_CHK(); return _fpos >= _fsize; } int LibRaw_bigfile_buffered_datastream::seek(INT64 o, int whence) { LR_BF_CHK(); if (whence == SEEK_SET) _fpos = o; else if (whence == SEEK_END) _fpos = o > 0 ? _fsize : _fsize + o; else if (whence == SEEK_CUR) _fpos += o; return 0; } INT64 LibRaw_bigfile_buffered_datastream::tell() { LR_BF_CHK(); return _fpos; } char *LibRaw_bigfile_buffered_datastream::gets(char *s, int sz) { if (sz < 1) return NULL; else if (sz < 2) { s[0] = 0; return s; } LR_BF_CHK(); INT64 contains; int bufindex = selectStringBuffer(sz, contains); if (bufindex < 0) return NULL; if (contains >= sz) { unsigned char *buf = iobuffers[bufindex].data() + (_fpos - iobuffers[bufindex]._bstart); int streampos = 0; int streamsize = contains; unsigned char *str = (unsigned char *)s; unsigned char *psrc, *pdest; psrc = buf + streampos; pdest = str; while ((size_t(psrc - buf) < streamsize) && ((pdest - str) < sz-1)) // sz-1: to append \0 { *pdest = *psrc; if (*psrc == '\n') break; psrc++; pdest++; } if (size_t(psrc - buf) < streamsize) psrc++; if ((pdest - str) < sz - 1) *(++pdest) = 0; else s[sz - 1] = 0; // ensure trailing zero streampos = psrc - buf; _fpos += streampos; return s; } return NULL; } int LibRaw_bigfile_buffered_datastream::selectStringBuffer(INT64 len, INT64& contains) { if (iobuffers[0].contains(_fpos, contains) && contains >= len) return 0; if (iobuffers[1].contains(_fpos, contains) && contains >= len) return 1; fillBufferAt(1, _fpos); if (iobuffers[1].contains(_fpos, contains) && contains >= len) return 1; return -1; } int LibRaw_bigfile_buffered_datastream::scanf_one(const char *fmt, void *val) { LR_BF_CHK(); INT64 contains = 0; int bufindex = selectStringBuffer(24, contains); if (bufindex < 0) return -1; if (contains >= 24) { unsigned char *bstart = iobuffers[bufindex].data() + (_fpos - iobuffers[bufindex]._bstart); int streampos = 0; int streamsize = contains; int #ifndef WIN32SECURECALLS scanf_res = sscanf((char *)(bstart), fmt, val); #else scanf_res = sscanf_s((char *)(bstart), fmt, val); #endif if (scanf_res > 0) { int xcnt = 0; while (streampos < streamsize) { streampos++; xcnt++; if (bstart[streampos] == 0 || bstart[streampos] == ' ' || bstart[streampos] == '\t' || bstart[streampos] == '\n' || xcnt > 24) break; } _fpos += streampos; return scanf_res; } } return -1; } #endif LibRaw-0.21.4/src/metadata/000077500000000000000000000000001477673233700153505ustar00rootroot00000000000000LibRaw-0.21.4/src/metadata/adobepano.cpp000066400000000000000000000110221477673233700200000ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" void LibRaw::parseAdobePanoMakernote() { uchar *PrivateMknBuf; unsigned posPrivateMknBuf; unsigned PrivateMknLength; unsigned PrivateOrder; unsigned PrivateEntries, PrivateTagID, PrivateTagType, PrivateTagCount; unsigned PrivateTagBytes; int truncated; #define CHECKSPACE(s) \ if (posPrivateMknBuf + (s) > PrivateMknLength) \ { \ free(PrivateMknBuf); \ return; \ } order = 0x4d4d; truncated = 0; PrivateMknLength = get4(); if ((PrivateMknLength > 4) && (PrivateMknLength < 10240000) && (PrivateMknBuf = (uchar *)calloc(PrivateMknLength + 1024,1))) { // 1024b for safety fread(PrivateMknBuf, PrivateMknLength, 1, ifp); PrivateOrder = sget2(PrivateMknBuf); PrivateEntries = sget2(PrivateMknBuf + 2); if ((PrivateEntries > 1000) || ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949))) { free(PrivateMknBuf); return; } posPrivateMknBuf = 4; while (PrivateEntries--) { order = 0x4d4d; CHECKSPACE(8); PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf); PrivateTagType = sget2(PrivateMknBuf + posPrivateMknBuf + 2); PrivateTagCount = sget4(PrivateMknBuf + posPrivateMknBuf + 4); posPrivateMknBuf += 8; order = PrivateOrder; if (truncated && !PrivateTagCount) continue; PrivateTagBytes = PrivateTagCount * tagtype_dataunit_bytes[(PrivateTagType <= LIBRAW_EXIFTAG_TYPE_IFD8) ? PrivateTagType : 0]; if(PrivateTagBytes > 10240000u) { free(PrivateMknBuf); return; } if (PrivateTagID == 0x0002) { posPrivateMknBuf += 2; CHECKSPACE(2); if (sget2(PrivateMknBuf + posPrivateMknBuf)) { truncated = 1; } else { posPrivateMknBuf += 2; } } else if (PrivateTagID == 0x0013) { ushort nWB, cnt, tWB; CHECKSPACE(2); nWB = sget2(PrivateMknBuf + posPrivateMknBuf); posPrivateMknBuf += 2; if (nWB > 0x100) break; for (cnt = 0; cnt < nWB; cnt++) { CHECKSPACE(2); tWB = sget2(PrivateMknBuf + posPrivateMknBuf); if (tWB < 0x100) { CHECKSPACE(4); icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2); icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 4); icWBC[tWB][1] = icWBC[tWB][3] = 0x100; } posPrivateMknBuf += 6; } } else if (PrivateTagID == 0x0027) { ushort nWB, cnt, tWB; CHECKSPACE(2); nWB = sget2(PrivateMknBuf + posPrivateMknBuf); posPrivateMknBuf += 2; if (nWB > 0x100) break; for (cnt = 0; cnt < nWB; cnt++) { CHECKSPACE(2); tWB = sget2(PrivateMknBuf + posPrivateMknBuf); if (tWB < 0x100) { CHECKSPACE(6); icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2); icWBC[tWB][1] = icWBC[tWB][3] = sget2(PrivateMknBuf + posPrivateMknBuf + 4); icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 6); } posPrivateMknBuf += 8; } } else if (PrivateTagID == 0x0121) { CHECKSPACE(4); imPana.Multishot = sget4(PrivateMknBuf + posPrivateMknBuf); posPrivateMknBuf += 4; } else { if (PrivateTagBytes > 4) posPrivateMknBuf += PrivateTagBytes; else if (!truncated) posPrivateMknBuf += 4; else { if (PrivateTagBytes <= 2) posPrivateMknBuf += 2; else posPrivateMknBuf += 4; } } } free(PrivateMknBuf); } #undef CHECKSPACE } LibRaw-0.21.4/src/metadata/canon.cpp000066400000000000000000001225341477673233700171610ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" #include "../../internal/libraw_cameraids.h" libraw_area_t LibRaw::get_CanonArea() { libraw_area_t la = {}; la.l = get2(); la.t = get2(); la.r = get2(); la.b = get2(); return la; } float LibRaw::_CanonConvertAperture(ushort in) { if ((in == (ushort)0xffe0) || (in == (ushort)0x7fff)) return 0.0f; return LibRaw::libraw_powf64l(2.f, float(in) / 64.f); } static float _CanonConvertEV(short in) { short EV, Sign, Frac; float Frac_f; EV = in; if (EV < 0) { EV = -EV; Sign = -1; } else { Sign = 1; } Frac = EV & 0x1f; EV -= Frac; // remove fraction if (Frac == 0x0c) { // convert 1/3 and 2/3 codes Frac_f = 32.0f / 3.0f; } else if (Frac == 0x14) { Frac_f = 64.0f / 3.0f; } else Frac_f = (float)Frac; return ((float)Sign * ((float)EV + Frac_f)) / 32.0f; } void LibRaw::setCanonBodyFeatures(unsigned long long id) { ilm.CamID = id; if ((id == CanonID_EOS_1D) || (id == CanonID_EOS_1D_Mark_II) || (id == CanonID_EOS_1D_Mark_II_N) || (id == CanonID_EOS_1D_Mark_III) || (id == CanonID_EOS_1D_Mark_IV)) { ilm.CameraFormat = LIBRAW_FORMAT_APSH; ilm.CameraMount = LIBRAW_MOUNT_Canon_EF; } else if ((id == CanonID_EOS_1Ds) || (id == CanonID_EOS_1Ds_Mark_II) || (id == CanonID_EOS_1Ds_Mark_III) || (id == CanonID_EOS_1D_X) || (id == CanonID_EOS_1D_X_Mark_II) || (id == CanonID_EOS_1D_X_Mark_III) || (id == CanonID_EOS_1D_C) || (id == CanonID_EOS_5D) || (id == CanonID_EOS_5D_Mark_II) || (id == CanonID_EOS_5D_Mark_III) || (id == CanonID_EOS_5D_Mark_IV) || (id == CanonID_EOS_5DS) || (id == CanonID_EOS_5DS_R) || (id == CanonID_EOS_6D) || (id == CanonID_EOS_6D_Mark_II)) { ilm.CameraFormat = LIBRAW_FORMAT_FF; ilm.CameraMount = LIBRAW_MOUNT_Canon_EF; } else if ((id == CanonID_EOS_M) || (id == CanonID_EOS_M2) || (id == CanonID_EOS_M3) || (id == CanonID_EOS_M5) || (id == CanonID_EOS_M10) || (id == CanonID_EOS_M50) || (id == CanonID_EOS_M50_Mark_II) || (id == CanonID_EOS_M6) || (id == CanonID_EOS_M6_Mark_II) || (id == CanonID_EOS_M100)) { ilm.CameraFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = LIBRAW_MOUNT_Canon_EF_M; } else if ((id == CanonID_EOS_R) || (id == CanonID_EOS_RP) || (id == CanonID_EOS_R3) || (id == CanonID_EOS_R5) || (id == CanonID_EOS_R6)) { ilm.CameraFormat = LIBRAW_FORMAT_FF; ilm.CameraMount = LIBRAW_MOUNT_Canon_RF; ilm.LensFormat = LIBRAW_FORMAT_FF; ilm.LensMount = LIBRAW_MOUNT_Canon_EF; } else if ((id == CanonID_EOS_R7) || (id == CanonID_EOS_R10)) { ilm.CameraFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = LIBRAW_MOUNT_Canon_RF; ilm.LensFormat = LIBRAW_FORMAT_APSC; ilm.LensMount = LIBRAW_MOUNT_Canon_EF; } else if ((id == CanonID_EOS_D30) || (id == CanonID_EOS_D60) || (id > 0x80000000ULL)) { ilm.CameraFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = LIBRAW_MOUNT_Canon_EF; } } int CanonCameraInfo_checkFirmwareRecordLocation (uchar *offset) { // firmware record location allows // to determine the subversion of the CameraInfo table // and to adjust offsets accordingly if ( isdigit(*offset) && isdigit(*(offset+2)) && isdigit(*(offset+4)) && (*(offset+1) == '.') && (*(offset+3) == '.') && ((*(offset+5) == 0) || isspace(*(offset+5))) ) return 1; else return 0; // error } void LibRaw::processCanonCameraInfo(unsigned long long id, uchar *CameraInfo, unsigned maxlen, unsigned type, unsigned dng_writer) { ushort iCanonLensID = 0, iCanonMaxFocal = 0, iCanonMinFocal = 0, iCanonLens = 0, iCanonCurFocal = 0, iCanonFocalType = 0, iMakernotesFlip = 0, iHTP = 0, iALO = 0; short SubVersion_offset = 0; ushort SubVersion = 0, mgck = 0; if (maxlen < 16) return; // too short mgck = sget2(CameraInfo); CameraInfo[0] = 0; CameraInfo[1] = 0; if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) { if ((maxlen == 94) || (maxlen == 138) || (maxlen == 148) || (maxlen == 156) || (maxlen == 162) || (maxlen == 167) || (maxlen == 171) || (maxlen == 264) || (maxlen > 400)) imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 3) << 2))); else if (maxlen == 72) imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 1) << 2))); else if ((maxlen == 85) || (maxlen == 93)) imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 2) << 2))); else if ((maxlen == 96) || (maxlen == 104)) imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 4) << 2))); } switch (id) { case CanonID_EOS_1D: case CanonID_EOS_1Ds: iCanonCurFocal = 0x0a; iCanonLensID = 0x0d; iCanonMinFocal = 0x0e; iCanonMaxFocal = 0x10; if (!ilm.CurFocal) ilm.CurFocal = sget2(CameraInfo + iCanonCurFocal); if (!ilm.MinFocal) ilm.MinFocal = sget2(CameraInfo + iCanonMinFocal); if (!ilm.MaxFocal) ilm.MaxFocal = sget2(CameraInfo + iCanonMaxFocal); imCommon.CameraTemperature = 0.0f; break; case CanonID_EOS_1D_Mark_II: case CanonID_EOS_1Ds_Mark_II: iCanonCurFocal = 0x09; iCanonLensID = 0x0c; iCanonMinFocal = 0x11; iCanonMaxFocal = 0x13; iCanonFocalType = 0x2d; break; case CanonID_EOS_1D_Mark_II_N: iCanonCurFocal = 0x09; iCanonLensID = 0x0c; iCanonMinFocal = 0x11; iCanonMaxFocal = 0x13; break; case CanonID_EOS_1D_Mark_III: case CanonID_EOS_1Ds_Mark_III: iCanonCurFocal = 0x1d; iMakernotesFlip = 0x30; iCanonLensID = 0x111; iCanonMinFocal = 0x113; iCanonMaxFocal = 0x115; break; case CanonID_EOS_1D_Mark_IV: if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1e8)) SubVersion = 1; else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1ed)) SubVersion = 2; // printf ("==>> CanonID_EOS_1D_Mark_IV, SubVersion: %d\n", SubVersion); iHTP = 0x07; iCanonCurFocal = 0x1e; iMakernotesFlip = 0x35; if (!SubVersion) break; else if (SubVersion < 2) SubVersion_offset += -1; iCanonLensID = 0x14f+SubVersion_offset; iCanonMinFocal = 0x151+SubVersion_offset; iCanonMaxFocal = 0x153+SubVersion_offset; break; case CanonID_EOS_1D_X: if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x271)) SubVersion = 1; else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x279)) SubVersion = 2; else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x280)) SubVersion = 3; else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x285)) SubVersion = 4; // printf ("==>> CanonID_EOS_1D_X, SubVersion: %d\n", SubVersion); if (SubVersion < 3) SubVersion_offset += -3; iCanonCurFocal = 0x23+SubVersion_offset; iMakernotesFlip = 0x7d+SubVersion_offset; if (SubVersion < 3) SubVersion_offset += -4; else if (SubVersion == 4) SubVersion_offset += 5; iCanonLensID = 0x1a7+SubVersion_offset; iCanonMinFocal = 0x1a9+SubVersion_offset; iCanonMaxFocal = 0x1ab+SubVersion_offset; break; case CanonID_EOS_5D: iMakernotesFlip = 0x27; iCanonCurFocal = 0x28; iCanonLensID = 0x0c; if (!sget2Rev(CameraInfo + iCanonLensID)) iCanonLensID = 0x97; iCanonMinFocal = 0x93; iCanonMaxFocal = 0x95; break; case CanonID_EOS_5D_Mark_II: iHTP = 0x07; iCanonCurFocal = 0x1e; iMakernotesFlip = 0x31; iALO = 0xbf; iCanonLensID = 0xe6; iCanonMinFocal = 0xe8; iCanonMaxFocal = 0xea; break; case CanonID_EOS_5D_Mark_III: if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x22c)) SubVersion = 1; else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x22d)) SubVersion = 2; else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x23c)) SubVersion = 3; else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x242)) SubVersion = 4; else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x247)) SubVersion = 5; // printf ("==>> CanonID_EOS_5D_Mark_III, SubVersion: %d\n", SubVersion); if (!SubVersion) break; else if (SubVersion < 3) SubVersion_offset += -1; iCanonCurFocal = 0x23+SubVersion_offset; if (SubVersion == 1) SubVersion_offset += -3; else if (SubVersion == 2) SubVersion_offset += -2; else if (SubVersion >= 4) SubVersion_offset += 6; iMakernotesFlip = 0x7d+SubVersion_offset; if (SubVersion < 3) SubVersion_offset += -4; else if (SubVersion > 4) SubVersion_offset += 5; iCanonLensID = 0x153+SubVersion_offset; iCanonMinFocal = 0x155+SubVersion_offset; iCanonMaxFocal = 0x157+SubVersion_offset; break; case CanonID_EOS_6D: iCanonCurFocal = 0x23; iMakernotesFlip = 0x83; iCanonLensID = 0x161; iCanonMinFocal = 0x163; iCanonMaxFocal = 0x165; break; case CanonID_EOS_7D: if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1a8)) SubVersion = 1; else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1ac)) SubVersion = 2; // printf ("==>> CanonID_EOS_7D, SubVersion: %d\n", SubVersion); iHTP = 0x07; iCanonCurFocal = 0x1e; if (!SubVersion) break; else if (SubVersion < 2) SubVersion_offset += -4; iMakernotesFlip = 0x35+SubVersion_offset; iCanonLensID = 0x112+SubVersion_offset; iCanonMinFocal = 0x114+SubVersion_offset; iCanonMaxFocal = 0x116+SubVersion_offset; break; case CanonID_EOS_40D: iCanonCurFocal = 0x1d; iMakernotesFlip = 0x30; iCanonLensID = 0xd6; iCanonMinFocal = 0xd8; iCanonMaxFocal = 0xda; iCanonLens = 0x92b; break; case CanonID_EOS_50D: iHTP = 0x07; iCanonCurFocal = 0x1e; iMakernotesFlip = 0x31; iALO = 0xbf; iCanonLensID = 0xea; iCanonMinFocal = 0xec; iCanonMaxFocal = 0xee; break; case CanonID_EOS_60D: case CanonID_EOS_1200D: iCanonCurFocal = 0x1e; if (id == CanonID_EOS_60D) iMakernotesFlip = 0x36; else iMakernotesFlip = 0x3a; iCanonLensID = 0xe8; iCanonMinFocal = 0xea; iCanonMaxFocal = 0xec; break; case CanonID_EOS_70D: iCanonCurFocal = 0x23; iMakernotesFlip = 0x84; iCanonLensID = 0x166; iCanonMinFocal = 0x168; iCanonMaxFocal = 0x16a; break; case CanonID_EOS_80D: iCanonCurFocal = 0x23; iMakernotesFlip = 0x96; iCanonLensID = 0x189; iCanonMinFocal = 0x18b; iCanonMaxFocal = 0x18d; break; case CanonID_EOS_450D: iCanonCurFocal = 0x1d; iMakernotesFlip = 0x30; iCanonLensID = 0xde; iCanonLens = 0x933; break; case CanonID_EOS_500D: iHTP = 0x07; iCanonCurFocal = 0x1e; iMakernotesFlip = 0x31; iALO = 0xbe; iCanonLensID = 0xf6; iCanonMinFocal = 0xf8; iCanonMaxFocal = 0xfa; break; case CanonID_EOS_550D: iHTP = 0x07; iCanonCurFocal = 0x1e; iMakernotesFlip = 0x35; iCanonLensID = 0xff; iCanonMinFocal = 0x101; iCanonMaxFocal = 0x103; break; case CanonID_EOS_600D: case CanonID_EOS_1100D: iHTP = 0x07; iCanonCurFocal = 0x1e; iMakernotesFlip = 0x38; iCanonLensID = 0xea; iCanonMinFocal = 0xec; iCanonMaxFocal = 0xee; break; case CanonID_EOS_650D: case CanonID_EOS_700D: iCanonCurFocal = 0x23; iMakernotesFlip = 0x7d; iCanonLensID = 0x127; iCanonMinFocal = 0x129; iCanonMaxFocal = 0x12b; break; case CanonID_EOS_750D: case CanonID_EOS_760D: iCanonCurFocal = 0x23; iMakernotesFlip = 0x96; iCanonLensID = 0x184; iCanonMinFocal = 0x186; iCanonMaxFocal = 0x188; break; case CanonID_EOS_1000D: iCanonCurFocal = 0x1d; iMakernotesFlip = 0x30; iCanonLensID = 0xe2; iCanonMinFocal = 0xe4; iCanonMaxFocal = 0xe6; iCanonLens = 0x937; break; } if (iMakernotesFlip && (CameraInfo[iMakernotesFlip] < 3)) { imCanon.MakernotesFlip = "065"[CameraInfo[iMakernotesFlip]] - '0'; // printf ("==>> iMakernotesFlip: 0x%x, flip: %d\n", iMakernotesFlip, imCanon.MakernotesFlip); } else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) && (mgck == 0xaaaa) && (dng_writer == nonDNG)) { // CameraOrientation int c, i; for (i = 2; (sget2(CameraInfo+i) != 0xbbbb) && i < (int)maxlen; i++); i+=2; while (i < int(maxlen - 5)) if ((sget4(CameraInfo+i) == 257) && ((c = CameraInfo[i+8]) < 3)) { imCanon.MakernotesFlip = "065"[c] - '0'; // printf ("==>> MakernotesFlip offset: 0x%x, flip: %d\n", i+8, imCanon.MakernotesFlip); break; } else i+=4; } if (iHTP) { imCanon.HighlightTonePriority = CameraInfo[iHTP]; if ((imCanon.HighlightTonePriority > 5) || (imCanon.HighlightTonePriority < 0)) imCanon.HighlightTonePriority = 0; if (imCanon.HighlightTonePriority) { imCommon.ExposureCalibrationShift -= float(imCanon.HighlightTonePriority); } } if (iALO) { imCanon.AutoLightingOptimizer = CameraInfo[iALO]; if ((imCanon.AutoLightingOptimizer > 3) || (imCanon.AutoLightingOptimizer < 0)) imCanon.AutoLightingOptimizer = 3; } if (iCanonFocalType) { if (iCanonFocalType >= maxlen) return; // broken; ilm.FocalType = CameraInfo[iCanonFocalType]; if (!ilm.FocalType) // zero means 'prime' here, replacing with standard '1' ilm.FocalType = LIBRAW_FT_PRIME_LENS; } if (!ilm.CurFocal && iCanonCurFocal) { if (iCanonCurFocal >= maxlen) return; // broken; ilm.CurFocal = sget2Rev(CameraInfo + iCanonCurFocal); } if (!ilm.LensID && iCanonLensID) { if (iCanonLensID >= maxlen) return; // broken; ilm.LensID = sget2Rev(CameraInfo + iCanonLensID); } if (!ilm.MinFocal && iCanonMinFocal) { if (iCanonMinFocal >= maxlen) return; // broken; ilm.MinFocal = sget2Rev(CameraInfo + iCanonMinFocal); } if (!ilm.MaxFocal && iCanonMaxFocal) { if (iCanonMaxFocal >= maxlen) return; // broken; ilm.MaxFocal = sget2Rev(CameraInfo + iCanonMaxFocal); } if (!ilm.Lens[0] && iCanonLens) { if (iCanonLens + 64 >= (int)maxlen) // broken; return; char *pl = (char *)CameraInfo + iCanonLens; if (!strncmp(pl, "EF-S", 4)) { memcpy(ilm.Lens, pl, 4); ilm.Lens[4] = ' '; memcpy(ilm.LensFeatures_pre, pl, 4); ilm.LensMount = LIBRAW_MOUNT_Canon_EF_S; ilm.LensFormat = LIBRAW_FORMAT_APSC; memcpy(ilm.Lens + 5, pl + 4, 60); } else if (!strncmp(pl, "EF-M", 4)) { memcpy(ilm.Lens, pl, 4); ilm.Lens[4] = ' '; memcpy(ilm.LensFeatures_pre, pl, 4); ilm.LensMount = LIBRAW_MOUNT_Canon_EF_M; ilm.LensFormat = LIBRAW_FORMAT_APSC; memcpy(ilm.Lens + 5, pl + 4, 60); } else if (!strncmp(pl, "EF", 2)) { memcpy(ilm.Lens, pl, 2); ilm.Lens[2] = ' '; memcpy(ilm.LensFeatures_pre, pl, 2); ilm.LensMount = LIBRAW_MOUNT_Canon_EF; ilm.LensFormat = LIBRAW_FORMAT_FF; memcpy(ilm.Lens + 3, pl + 2, 62); } else if (!strncmp(ilm.Lens, "CN-E", 4)) { memmove(ilm.Lens + 5, ilm.Lens + 4, 60); ilm.Lens[4] = ' '; memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); ilm.LensMount = LIBRAW_MOUNT_Canon_EF; ilm.LensFormat = LIBRAW_FORMAT_FF; } else if (!strncmp(pl, "TS-E", 4)) { memcpy(ilm.Lens, pl, 4); ilm.Lens[4] = ' '; memcpy(ilm.LensFeatures_pre, pl, 4); ilm.LensMount = LIBRAW_MOUNT_Canon_EF; ilm.LensFormat = LIBRAW_FORMAT_FF; memcpy(ilm.Lens + 5, pl + 4, 60); } else if (!strncmp(pl, "MP-E", 4)) { memcpy(ilm.Lens, pl, 4); ilm.Lens[4] = ' '; memcpy(ilm.LensFeatures_pre, pl, 4); ilm.LensMount = LIBRAW_MOUNT_Canon_EF; ilm.LensFormat = LIBRAW_FORMAT_FF; memcpy(ilm.Lens + 5, pl + 4, 60); } else // non-Canon lens memcpy(ilm.Lens, pl, 64); } return; } void LibRaw::Canon_CameraSettings(unsigned len) { fseek(ifp, 6, SEEK_CUR); imCanon.Quality = get2(); // 3 get2(); imgdata.shootinginfo.DriveMode = get2(); // 5 get2(); imgdata.shootinginfo.FocusMode = get2(); // 7 imCanon.RecordMode = (get2(), get2()); // 9, format fseek(ifp, 14, SEEK_CUR); imgdata.shootinginfo.MeteringMode = get2(); // 17 get2(); imgdata.shootinginfo.AFPoint = get2(); // 19 imgdata.shootinginfo.ExposureMode = get2(); // 20 get2(); ilm.LensID = get2(); // 22 ilm.MaxFocal = get2(); // 23 ilm.MinFocal = get2(); // 24 ilm.FocalUnits = get2(); // 25 if (ilm.FocalUnits > 1) { ilm.MaxFocal /= (float)ilm.FocalUnits; ilm.MinFocal /= (float)ilm.FocalUnits; } ilm.MaxAp = _CanonConvertAperture(get2()); // 26 ilm.MinAp = _CanonConvertAperture(get2()); // 27 if (len >= 36) { fseek(ifp, 12, SEEK_CUR); imgdata.shootinginfo.ImageStabilization = get2(); // 34 } else return; if (len >= 48) { fseek(ifp, 22, SEEK_CUR); imCanon.SRAWQuality = get2(); // 46 } } void LibRaw::Canon_WBpresets(int skip1, int skip2) { int c; FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][RGGB_2_RGBG(c)] = get2(); if (skip1) fseek(ifp, skip1, SEEK_CUR); FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][RGGB_2_RGBG(c)] = get2(); if (skip1) fseek(ifp, skip1, SEEK_CUR); FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Cloudy][RGGB_2_RGBG(c)] = get2(); if (skip1) fseek(ifp, skip1, SEEK_CUR); FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][RGGB_2_RGBG(c)] = get2(); if (skip1) fseek(ifp, skip1, SEEK_CUR); FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_W][RGGB_2_RGBG(c)] = get2(); if (skip2) fseek(ifp, skip2, SEEK_CUR); FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][RGGB_2_RGBG(c)] = get2(); return; } void LibRaw::Canon_WBCTpresets(short WBCTversion) { int i; float norm; if (WBCTversion == 0) { // tint, as shot R, as shot B, CСT for (i = 0; i < 15; i++) { icWBCCTC[i][2] = icWBCCTC[i][4] = 1.0f; fseek(ifp, 2, SEEK_CUR); icWBCCTC[i][1] = 1024.0f / fMAX(get2(), 1.f); icWBCCTC[i][3] = 1024.0f / fMAX(get2(), 1.f); icWBCCTC[i][0] = get2(); } } else if (WBCTversion == 1) { // as shot R, as shot B, tint, CСT for (i = 0; i < 15; i++) { icWBCCTC[i][2] = icWBCCTC[i][4] = 1.0f; icWBCCTC[i][1] = 1024.0f / fMAX(get2(), 1.f); icWBCCTC[i][3] = 1024.0f / fMAX(get2(), 1.f); fseek(ifp, 2, SEEK_CUR); icWBCCTC[i][0] = get2(); } } else if (WBCTversion == 2) { // tint, offset, as shot R, as shot B, CСT if ((unique_id == CanonID_EOS_M3) || (unique_id == CanonID_EOS_M10) || (imCanon.ColorDataSubVer == 0xfffc)) { for (i = 0; i < 15; i++) { fseek(ifp, 4, SEEK_CUR); icWBCCTC[i][2] = icWBCCTC[i][4] = 1.0f; icWBCCTC[i][1] = 1024.0f / fMAX(1.f, get2()); icWBCCTC[i][3] = 1024.0f / fMAX(1.f, get2()); icWBCCTC[i][0] = get2(); } } else if (imCanon.ColorDataSubVer == 0xfffd) { for (i = 0; i < 15; i++) { fseek(ifp, 2, SEEK_CUR); norm = (signed short)get2(); norm = 512.0f + norm / 8.0f; icWBCCTC[i][2] = icWBCCTC[i][4] = 1.0f; icWBCCTC[i][1] = (float)get2(); if (norm > 0.001f) icWBCCTC[i][1] /= norm; icWBCCTC[i][3] = (float)get2(); if (norm > 0.001f) icWBCCTC[i][3] /= norm; icWBCCTC[i][0] = get2(); } } } return; } void LibRaw::parseCanonMakernotes(unsigned tag, unsigned /*type*/, unsigned len, unsigned dng_writer) { #define AsShot_Auto_MeasuredWB(offset) \ imCanon.ColorDataSubVer = get2(); \ fseek(ifp, save1 + (offset << 1), SEEK_SET); \ FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2(); \ get2(); \ FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); \ get2(); \ FORC4 icWBC[LIBRAW_WBI_Measured][RGGB_2_RGBG(c)] = get2(); #define sRAW_WB(offset) \ fseek(ifp, save1 + (offset << 1), SEEK_SET); \ FORC4 { \ sraw_mul[RGGB_2_RGBG(c)] = get2(); \ if ((float)sraw_mul[RGGB_2_RGBG(c)] > sraw_mul_max) { \ sraw_mul_max = (float)sraw_mul[RGGB_2_RGBG(c)]; \ } \ } \ sraw_mul_max /= 1024.f; \ FORC4 sraw_mul[c] = (ushort)((float)sraw_mul[c] * sraw_mul_max); #define CR3_ColorData(offset) \ fseek(ifp, save1 + ((offset+0x0041) << 1), SEEK_SET); \ Canon_WBpresets(2, 12); \ fseek(ifp, save1 + ((offset+0x00c3) << 1), SEEK_SET); \ Canon_WBCTpresets(0); \ offsetChannelBlackLevel2 = save1 + ((offset+0x0102) << 1); \ offsetChannelBlackLevel = save1 + ((offset+0x02d1) << 1); \ offsetWhiteLevels = save1 + ((offset+0x02d5) << 1); int c; unsigned i; if (tag == 0x0001) { Canon_CameraSettings(len); } else if (tag == 0x0002) { // focal length ilm.FocalType = get2(); ilm.CurFocal = get2(); if (ilm.FocalUnits > 1) { ilm.CurFocal /= (float)ilm.FocalUnits; } } else if (tag == 0x0004) { // subdir, ShotInfo short tempAp; if (dng_writer == nonDNG) { get2(); imCanon.ISOgain[0] = get2(); imCanon.ISOgain[1] = get2(); if (imCanon.ISOgain[1] != 0x7fff) { imCommon.real_ISO = floorf(100.f * libraw_powf64l(2.f, float(imCanon.ISOgain[0]+imCanon.ISOgain[1]) / 32.f - 5.f)); if (!iso_speed || (iso_speed == 65535)) iso_speed = imCommon.real_ISO; } get4(); if (((i = get2()) != 0xffff) && !shutter) { shutter = libraw_powf64l(2.f, float((short)i) / -32.0f); } imCanon.wbi = (get2(), get2()); shot_order = (get2(), get2()); fseek(ifp, 4, SEEK_CUR); } else fseek(ifp, 24, SEEK_CUR); tempAp = get2(); if (tempAp != 0) imCommon.CameraTemperature = (float)(tempAp - 128); tempAp = get2(); if (tempAp != -1) imCommon.FlashGN = ((float)tempAp) / 32; get2(); imCommon.FlashEC = _CanonConvertEV((signed short)get2()); fseek(ifp, 8 - 32, SEEK_CUR); if ((tempAp = get2()) != 0x7fff) ilm.CurAp = _CanonConvertAperture(tempAp); if (ilm.CurAp < 0.7f) { fseek(ifp, 32, SEEK_CUR); ilm.CurAp = _CanonConvertAperture(get2()); } if (!aperture) aperture = ilm.CurAp; } else if ((tag == 0x0007) && (dng_writer == nonDNG)) { fgets(model2, 64, ifp); } else if ((tag == 0x0008) && (dng_writer == nonDNG)) { shot_order = get4(); } else if ((tag == 0x0009) && (dng_writer == nonDNG)) { fread(artist, 64, 1, ifp); } else if (tag == 0x000c) { unsigned tS = get4(); sprintf(imgdata.shootinginfo.BodySerial, "%d", tS); } else if ((tag == 0x0012) || (tag == 0x0026) || (tag == 0x003c)) { if (!imCommon.afcount) { imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; imCommon.afdata[imCommon.afcount].AFInfoData_order = order; imCommon.afdata[imCommon.afcount].AFInfoData_length = len; imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length,1); fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); imCommon.afcount = 1; } } else if ((tag == 0x0029) && (dng_writer == nonDNG)) { // PowerShot G9 int Got_AsShotWB = 0; fseek(ifp, 8, SEEK_CUR); for (unsigned linenum = 0; linenum < Canon_G9_linenums_2_StdWBi.size(); linenum++) { if (Canon_G9_linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown ) { FORC4 icWBC[Canon_G9_linenums_2_StdWBi[linenum]][GRBG_2_RGBG(c)] = get4(); if (Canon_wbi2std[imCanon.wbi] == Canon_G9_linenums_2_StdWBi[linenum]) { FORC4 cam_mul[c] = float(icWBC[Canon_G9_linenums_2_StdWBi[linenum]][c]); Got_AsShotWB = 1; } } fseek(ifp, 16, SEEK_CUR); } if (!Got_AsShotWB) FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]); } else if ((tag == 0x0081) && (dng_writer == nonDNG)) { // -1D, -1Ds data_offset = get4(); fseek(ifp, data_offset + 41, SEEK_SET); raw_height = get2() * 2; raw_width = get2(); filters = 0x61616161; } else if (tag == 0x0093) { if (!imCanon.RF_lensID) { fseek(ifp, 0x03d<<1, SEEK_CUR); imCanon.RF_lensID = get2(); } } else if (tag == 0x0095 && !ilm.Lens[0]) { // lens model tag fread(ilm.Lens, 64, 1, ifp); if (!strncmp(ilm.Lens, "EF-S", 4)) { memmove(ilm.Lens + 5, ilm.Lens + 4, 60); ilm.Lens[4] = ' '; memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); ilm.LensMount = LIBRAW_MOUNT_Canon_EF_S; ilm.LensFormat = LIBRAW_FORMAT_APSC; } else if (!strncmp(ilm.Lens, "EF-M", 4)) { memmove(ilm.Lens + 5, ilm.Lens + 4, 60); ilm.Lens[4] = ' '; memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); ilm.LensMount = LIBRAW_MOUNT_Canon_EF_M; ilm.LensFormat = LIBRAW_FORMAT_APSC; } else if (!strncmp(ilm.Lens, "EF", 2)) { memmove(ilm.Lens + 3, ilm.Lens + 2, 62); ilm.Lens[2] = ' '; memcpy(ilm.LensFeatures_pre, ilm.Lens, 2); ilm.LensMount = LIBRAW_MOUNT_Canon_EF; ilm.LensFormat = LIBRAW_FORMAT_FF; } else if (!strncmp(ilm.Lens, "CN-E", 4)) { memmove(ilm.Lens + 5, ilm.Lens + 4, 60); ilm.Lens[4] = ' '; memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); ilm.LensMount = LIBRAW_MOUNT_Canon_EF; ilm.LensFormat = LIBRAW_FORMAT_FF; } else if (!strncmp(ilm.Lens, "TS-E", 4)) { memmove(ilm.Lens + 5, ilm.Lens + 4, 60); ilm.Lens[4] = ' '; memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); ilm.LensMount = LIBRAW_MOUNT_Canon_EF; ilm.LensFormat = LIBRAW_FORMAT_FF; } else if (!strncmp(ilm.Lens, "MP-E", 4)) { memmove(ilm.Lens + 5, ilm.Lens + 4, 60); ilm.Lens[4] = ' '; memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); ilm.LensMount = LIBRAW_MOUNT_Canon_EF; ilm.LensFormat = LIBRAW_FORMAT_FF; } else if (!strncmp(ilm.Lens, "RF-S", 4)) { memmove(ilm.Lens + 5, ilm.Lens + 4, 62); ilm.Lens[4] = ' '; memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); ilm.LensMount = LIBRAW_MOUNT_Canon_RF; ilm.LensFormat = LIBRAW_FORMAT_APSC; } else if (!strncmp(ilm.Lens, "RF", 2)) { memmove(ilm.Lens + 3, ilm.Lens + 2, 62); ilm.Lens[2] = ' '; memcpy(ilm.LensFeatures_pre, ilm.Lens, 2); ilm.LensMount = LIBRAW_MOUNT_Canon_RF; ilm.LensFormat = LIBRAW_FORMAT_FF; } } else if (tag == 0x009a) { // AspectInfo i = get4(); switch (i) { case 0: case 12: /* APS-H crop */ case 13: /* APS-C crop */ imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; break; case 1: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; break; case 2: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3; break; case 7: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9; break; case 8: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_5to4; break; default: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_OTHER; break; } imgdata.sizes.raw_inset_crops[0].cwidth = get4(); imgdata.sizes.raw_inset_crops[0].cheight = get4(); imgdata.sizes.raw_inset_crops[0].cleft = get4(); imgdata.sizes.raw_inset_crops[0].ctop = get4(); } else if ((tag == 0x00a4) && (dng_writer == nonDNG)) { // -1D, -1Ds fseek(ifp, imCanon.wbi * 48, SEEK_CUR); FORC3 cam_mul[c] = get2(); } else if (tag == 0x00a9) { INT64 save1 = ftell(ifp); fseek(ifp, (0x1 << 1), SEEK_CUR); FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); Canon_WBpresets(0, 0); fseek(ifp, save1, SEEK_SET); } else if (tag == 0x00b4) { switch (get2()) { case 1: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 2: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } } else if (tag == 0x00e0) // SensorInfo { imCanon.SensorWidth = (get2(), get2()); imCanon.SensorHeight = get2(); fseek(ifp, 4, SEEK_CUR); imCanon.DefaultCropAbsolute = get_CanonArea(); imCanon.LeftOpticalBlack = get_CanonArea(); } else if (tag == 0x4001 && len > 500) { float sraw_mul_max = 0.f; int bls = 0; INT64 offsetChannelBlackLevel = 0L; INT64 offsetChannelBlackLevel2 = 0L; INT64 offsetWhiteLevels = 0L; INT64 save1 = ftell(ifp); switch (len) { case 582: imCanon.ColorDataVer = 1; // 20D, 350D fseek(ifp, save1 + (0x0019 << 1), SEEK_SET); FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2(); fseek(ifp, save1 + (0x001e << 1), SEEK_SET); FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); fseek(ifp, save1 + (0x0041 << 1), SEEK_SET); FORC4 icWBC[LIBRAW_WBI_Custom1][RGGB_2_RGBG(c)] = get2(); fseek(ifp, save1 + (0x0046 << 1), SEEK_SET); FORC4 icWBC[LIBRAW_WBI_Custom2][RGGB_2_RGBG(c)] = get2(); fseek(ifp, save1 + (0x0023 << 1), SEEK_SET); Canon_WBpresets(2, 2); fseek(ifp, save1 + (0x004b << 1), SEEK_SET); Canon_WBCTpresets(1); // ABCT offsetChannelBlackLevel = save1 + (0x00a6 << 1); break; case 653: imCanon.ColorDataVer = 2; // -1D Mark II, -1Ds Mark II fseek(ifp, save1 + (0x0018 << 1), SEEK_SET); FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); fseek(ifp, save1 + (0x0022 << 1), SEEK_SET); FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2(); fseek(ifp, save1 + (0x0090 << 1), SEEK_SET); FORC4 icWBC[LIBRAW_WBI_Custom1][RGGB_2_RGBG(c)] = get2(); fseek(ifp, save1 + (0x0095 << 1), SEEK_SET); FORC4 icWBC[LIBRAW_WBI_Custom2][RGGB_2_RGBG(c)] = get2(); fseek(ifp, save1 + (0x009a << 1), SEEK_SET); FORC4 icWBC[LIBRAW_WBI_Custom3][RGGB_2_RGBG(c)] = get2(); fseek(ifp, save1 + (0x0027 << 1), SEEK_SET); Canon_WBpresets(2, 12); fseek(ifp, save1 + (0x00a4 << 1), SEEK_SET); Canon_WBCTpresets(1); // ABCT offsetChannelBlackLevel = save1 + (0x011e << 1); break; case 796: imCanon.ColorDataVer = 3; // -1D Mark II N, 5D, 30D, 400D; ColorDataSubVer: 1 AsShot_Auto_MeasuredWB(0x003f); fseek(ifp, save1 + (0x0071 << 1), SEEK_SET); FORC4 icWBC[LIBRAW_WBI_Custom1][RGGB_2_RGBG(c)] = get2(); fseek(ifp, save1 + (0x0076 << 1), SEEK_SET); FORC4 icWBC[LIBRAW_WBI_Custom2][RGGB_2_RGBG(c)] = get2(); fseek(ifp, save1 + (0x007b << 1), SEEK_SET); FORC4 icWBC[LIBRAW_WBI_Custom3][RGGB_2_RGBG(c)] = get2(); fseek(ifp, save1 + (0x0080 << 1), SEEK_SET); FORC4 icWBC[LIBRAW_WBI_Custom][RGGB_2_RGBG(c)] = get2(); fseek(ifp, save1 + (0x004e << 1), SEEK_SET); Canon_WBpresets(2, 12); fseek(ifp, save1 + (0x0085 << 1), SEEK_SET); Canon_WBCTpresets(0); // BCAT offsetChannelBlackLevel = save1 + (0x00c4 << 1); break; case 674: // -1D Mark III; ColorDataSubVer: 2 case 692: // 40D; ColorDataSubVer: 3 case 702: // -1Ds Mark III; ColorDataSubVer: 4 case 1227: // 450D, 1000D; ColorDataSubVer: 5 case 1250: // 5D Mark II, 50D; ColorDataSubVer: 6 case 1251: // 500D; ColorDataSubVer: 7 case 1337: // -1D Mark IV, 7D; ColorDataSubVer: 7 case 1338: // 550D; ColorDataSubVer: 7 case 1346: // 1100D, 60D; ColorDataSubVer: 9 imCanon.ColorDataVer = 4; AsShot_Auto_MeasuredWB(0x003f); sRAW_WB(0x004e); fseek(ifp, save1 + (0x0053 << 1), SEEK_SET); Canon_WBpresets(2, 12); fseek(ifp, save1 + (0x00a8 << 1), SEEK_SET); Canon_WBCTpresets(0); // BCAT if ((imCanon.ColorDataSubVer == 4) || (imCanon.ColorDataSubVer == 5)) { offsetChannelBlackLevel = save1 + (0x02b4 << 1); offsetWhiteLevels = save1 + (0x02b8 << 1); } else if ((imCanon.ColorDataSubVer == 6) || (imCanon.ColorDataSubVer == 7)) { offsetChannelBlackLevel = save1 + (0x02cb << 1); offsetWhiteLevels = save1 + (0x02cf << 1); } else if (imCanon.ColorDataSubVer == 9) { offsetChannelBlackLevel = save1 + (0x02cf << 1); offsetWhiteLevels = save1 + (0x02d3 << 1); } else offsetChannelBlackLevel = save1 + (0x00e7 << 1); break; case 5120: // G10, G11, G12, G15, G16 // G1 X, G1 X Mark II, G1 X Mark III // G3 X, G5 X // G7 X, G7 X Mark II // G9 X, G9 X Mark II // S90, S95, S100, S100V, S110, S120 // SX1 IS, SX50 HS, SX60 HS // M3, M5, M6, M10, M100 imCanon.ColorDataVer = 5; imCanon.ColorDataSubVer = get2(); fseek(ifp, save1 + (0x0047 << 1), SEEK_SET); FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2(); if (imCanon.ColorDataSubVer == 0xfffc) // ColorDataSubVer: 65532 (-4) // G7 X Mark II, G9 X Mark II, G1 X Mark III // M5, M100, M6 { fseek(ifp, save1 + (0x004f << 1), SEEK_SET); FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); fseek(ifp, 8, SEEK_CUR); FORC4 icWBC[LIBRAW_WBI_Measured][RGGB_2_RGBG(c)] = get2(); fseek(ifp, 8, SEEK_CUR); FORC4 icWBC[LIBRAW_WBI_Other][RGGB_2_RGBG(c)] = get2(); fseek(ifp, 8, SEEK_CUR); Canon_WBpresets(8, 24); fseek(ifp, 168, SEEK_CUR); FORC4 icWBC[LIBRAW_WBI_FL_WW][RGGB_2_RGBG(c)] = get2(); fseek(ifp, 24, SEEK_CUR); Canon_WBCTpresets(2); // BCADT offsetChannelBlackLevel = save1 + (0x014d << 1); offsetWhiteLevels = save1 + (0x0569 << 1); } else if (imCanon.ColorDataSubVer == 0xfffd) // ColorDataSubVer: 65533 (-3) // M10, M3 // G1 X, G1 X Mark II // G3 X, G5 X, G7 X, G9 X // G10, G11, G12, G15, G16 // S90, S95, S100, S100V, S110, S120 // SX1 IS, SX50 HS, SX60 HS { fseek(ifp, save1 + (0x004c << 1), SEEK_SET); FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); get2(); FORC4 icWBC[LIBRAW_WBI_Measured][RGGB_2_RGBG(c)] = get2(); get2(); FORC4 icWBC[LIBRAW_WBI_Other][RGGB_2_RGBG(c)] = get2(); get2(); Canon_WBpresets(2, 12); fseek(ifp, save1 + (0x00ba << 1), SEEK_SET); Canon_WBCTpresets(2); // BCADT offsetChannelBlackLevel = save1 + (0x0108 << 1); } break; case 1273: // 600D; ColorDataSubVer: 10 case 1275: // 1200D; ColorDataSubVer: 10 imCanon.ColorDataVer = 6; AsShot_Auto_MeasuredWB(0x003f); sRAW_WB(0x0062); fseek(ifp, save1 + (0x0067 << 1), SEEK_SET); Canon_WBpresets(2, 12); fseek(ifp, save1 + (0x00bc << 1), SEEK_SET); Canon_WBCTpresets(0); // BCAT offsetChannelBlackLevel = save1 + (0x01df << 1); offsetWhiteLevels = save1 + (0x01e3 << 1); break; case 1312: // 5D Mark III, 650D, 700D, M; ColorDataSubVer: 10 case 1313: // 100D, 6D, 70D, EOS M2; ColorDataSubVer: 10 case 1316: // -1D C, -1D X; ColorDataSubVer: 10 case 1506: // 750D, 760D, 7D Mark II; ColorDataSubVer: 11 imCanon.ColorDataVer = 7; AsShot_Auto_MeasuredWB(0x003f); sRAW_WB(0x007b); fseek(ifp, save1 + (0x0080 << 1), SEEK_SET); Canon_WBpresets(2, 12); fseek(ifp, save1 + (0x00d5 << 1), SEEK_SET); Canon_WBCTpresets(0); // BCAT if (imCanon.ColorDataSubVer == 10) { offsetChannelBlackLevel = save1 + (0x01f8 << 1); offsetWhiteLevels = save1 + (0x01fc << 1); } else if (imCanon.ColorDataSubVer == 11) { offsetChannelBlackLevel = save1 + (0x02d8 << 1); offsetWhiteLevels = save1 + (0x02dc << 1); } break; case 1560: // 5DS, 5DS R; ColorDataSubVer: 12 case 1592: // 5D Mark IV, 80D, -1D X Mark II; ColorDataSubVer: 13 case 1353: // 1300D, 1500D, 3000D; ColorDataSubVer: 14 case 1602: // 200D, 6D Mark II, 77D, 800D; ColorDataSubVer: 15 imCanon.ColorDataVer = 8; AsShot_Auto_MeasuredWB(0x003f); sRAW_WB(0x0080); fseek(ifp, save1 + (0x0085 << 1), SEEK_SET); Canon_WBpresets(2, 12); fseek(ifp, save1 + (0x0107 << 1), SEEK_SET); Canon_WBCTpresets(0); // BCAT if (imCanon.ColorDataSubVer == 14) // 1300D, 1500D, 3000D { offsetChannelBlackLevel = save1 + (0x022c << 1); offsetWhiteLevels = save1 + (0x0230 << 1); } else { offsetChannelBlackLevel = save1 + (0x030a << 1); offsetWhiteLevels = save1 + (0x030e << 1); } break; case 1820: // M50; ColorDataSubVer: 16 case 1824: // R; ColorDataSubVer: 17 case 1816: // RP, 250D, SX70 HS; ColorDataSubVer: 18 // M6 Mark II, M200, 90D, G5 X Mark II, G7 X Mark III, 850D; ColorDataSubVer: 19 imCanon.ColorDataVer = 9; AsShot_Auto_MeasuredWB(0x0047); CR3_ColorData(0x0047); break; case 1770: // R5 CRM case 2024: // -1D X Mark III; ColorDataSubVer: 32 case 3656: // R5, R6; ColorDataSubVer: 33 imCanon.ColorDataVer = 10; AsShot_Auto_MeasuredWB(0x0055); CR3_ColorData(0x0055); break; case 3973: // R3; ColorDataSubVer: 34 case 3778: // R7, R10; ColorDataSubVer: 48 imCanon.ColorDataVer = 11; AsShot_Auto_MeasuredWB(0x0069); fseek(ifp, save1 + ((0x0069+0x0064) << 1), SEEK_SET); Canon_WBpresets(2, 12); fseek(ifp, save1 + ((0x0069+0x00c3) << 1), SEEK_SET); Canon_WBCTpresets(0); offsetChannelBlackLevel2 = save1 + ((0x0069+0x0102) << 1); offsetChannelBlackLevel = save1 + ((0x0069+0x0213) << 1); offsetWhiteLevels = save1 + ((0x0069+0x0217) << 1); break; default: imCanon.ColorDataSubVer = get2(); break; } if (offsetChannelBlackLevel) { fseek(ifp, offsetChannelBlackLevel, SEEK_SET); FORC4 bls += (imCanon.ChannelBlackLevel[RGGB_2_RGBG(c)] = get2()); imCanon.AverageBlackLevel = bls / 4; } if (offsetWhiteLevels) { if ((offsetWhiteLevels - offsetChannelBlackLevel) != 8L) fseek(ifp, offsetWhiteLevels, SEEK_SET); imCanon.NormalWhiteLevel = get2(); imCanon.SpecularWhiteLevel = get2(); FORC4 imgdata.color.linear_max[c] = imCanon.SpecularWhiteLevel; } if(!imCanon.AverageBlackLevel && offsetChannelBlackLevel2) { fseek(ifp, offsetChannelBlackLevel2, SEEK_SET); FORC4 bls += (imCanon.ChannelBlackLevel[RGGB_2_RGBG(c)] = get2()); imCanon.AverageBlackLevel = bls / 4; } fseek(ifp, save1, SEEK_SET); } else if (tag == 0x4013) { get4(); imCanon.AFMicroAdjMode = get4(); float a = float(get4()); float b = float(get4()); if (fabsf(b) > 0.001f) imCanon.AFMicroAdjValue = a / b; } else if (tag == 0x4018) { fseek(ifp, 8, SEEK_CUR); imCanon.AutoLightingOptimizer = get4(); if ((imCanon.AutoLightingOptimizer > 3) || (imCanon.AutoLightingOptimizer < 0)) imCanon.AutoLightingOptimizer = 3; imCanon.HighlightTonePriority = get4(); if ((imCanon.HighlightTonePriority > 5) || (imCanon.HighlightTonePriority < 0)) imCanon.HighlightTonePriority = 0; if (imCanon.HighlightTonePriority) { imCommon.ExposureCalibrationShift -= float(imCanon.HighlightTonePriority); } } else if ((tag == 0x4021) && (dng_writer == nonDNG) && (imCanon.multishot[0] = get4()) && (imCanon.multishot[1] = get4())) { if (len >= 4) { imCanon.multishot[2] = get4(); imCanon.multishot[3] = get4(); } FORC4 cam_mul[c] = 1024; } else if (tag == 0x4026) { fseek(ifp, 44, SEEK_CUR); imCanon.CanonLog = get4(); } #undef CR3_ColorData #undef sRAW_WB #undef AsShot_Auto_MeasuredWB } LibRaw-0.21.4/src/metadata/ciff.cpp000066400000000000000000000302771477673233700167740ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" #ifdef _MSC_VER #if _MSC_VER < 1800 /* below MSVC 2013 */ float roundf(float f) { return floorf(f + 0.5); } #endif #endif /* CIFF block 0x1030 contains an 8x8 white sample. Load this into white[][] for use in scale_colors(). */ void LibRaw::ciff_block_1030() { static const ushort key[] = {0x410, 0x45f3}; int i, bpp, row, col, vbits = 0; unsigned long bitbuf = 0; if ((get2(), get4()) != 0x80008 || !get4()) return; bpp = get2(); if (bpp != 10 && bpp != 12) return; for (i = row = 0; row < 8; row++) for (col = 0; col < 8; col++) { if (vbits < bpp) { bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]); vbits += 16; } white[row][col] = bitbuf >> (vbits -= bpp) & ~(-1 << bpp); } } /* Parse a CIFF file, better known as Canon CRW format. */ void LibRaw::parse_ciff(int offset, int length, int depth) { int nrecs, c, type, len, wbi = -1; INT64 save, tboff; ushort key[] = {0x410, 0x45f3}; ushort CanonColorInfo1_key; ushort Appendix_A = 0; INT64 WB_table_offset = 0; int UseWBfromTable_as_AsShot = 1; int Got_AsShotWB = 0; INT64 fsize = ifp->size(); if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS) throw LIBRAW_EXCEPTION_IO_CORRUPT; fseek(ifp, offset + length - 4, SEEK_SET); tboff = INT64(get4()) + offset; fseek(ifp, tboff, SEEK_SET); nrecs = get2(); if (nrecs < 1) return; if ((nrecs | depth) > 127) return; if (nrecs * 10 + offset > fsize) return; while (nrecs--) { type = get2(); len = get4(); INT64 see = offset + get4(); save = ftell(ifp); /* the following tags are not sub-tables * they contain the value in the "len" field * for such tags skip the check against filesize */ if ((type != 0x2007) && (type != 0x580b) && (type != 0x501c) && (type != 0x5029) && (type != 0x5813) && (type != 0x5814) && (type != 0x5817) && (type != 0x5834) && (type != 0x580e)) { if (see >= fsize) { // At least one byte fseek(ifp, save, SEEK_SET); continue; } fseek(ifp, see, SEEK_SET); if ((((type >> 8) + 8) | 8) == 0x38) { parse_ciff(ftell(ifp), len, depth + 1); /* Parse a sub-table */ } } if (type == 0x3004) { parse_ciff(ftell(ifp), len, depth + 1); } else if (type == 0x0810) { fread(artist, 64, 1, ifp); } else if (type == 0x080a) { fread(make, 64, 1, ifp); fseek(ifp, strbuflen(make) - 63, SEEK_CUR); fread(model, 64, 1, ifp); } else if (type == 0x080b) { stmread(imCommon.firmware, (unsigned)len, ifp); if (!strncasecmp(imCommon.firmware, "Firmware Version", 16)) memmove(imCommon.firmware, imCommon.firmware + 16, strlen(imCommon.firmware) - 15); trimSpaces(imCommon.firmware); } else if (type == 0x1810) { width = get4(); height = get4(); pixel_aspect = int_to_float(get4()); flip = get4(); } else if (type == 0x1835) { /* Get the decoder table */ tiff_compress = get4(); } else if (type == 0x2007) { thumb_offset = see; thumb_length = len; } else if (type == 0x1818) { shutter = libraw_powf64l(2.0f, -int_to_float((get4(), get4()))); ilm.CurAp = aperture = libraw_powf64l(2.0f, int_to_float(get4()) / 2); } else if (type == 0x102a) // CanonShotInfo { // iso_speed = pow (2.0, (get4(),get2())/32.0 - 4) * 50; get2(); // skip one iso_speed = libraw_powf64l(2.0f, (get2() + get2()) / 32.0f - 5.0f) * 100.0f; ilm.CurAp = aperture = _CanonConvertAperture((get2(), get2())); shutter = libraw_powf64l(2.0f, -float((short)get2()) / 32.f); imCanon.wbi = wbi = (get2(), get2()); if (wbi >= (int)Canon_wbi2std.size()) wbi = 0; fseek(ifp, 32, SEEK_CUR); if (shutter > 1e6) shutter = float(get2()) / 10.f; } else if (type == 0x102c) // CanonColorInfo2 / Appendix A: Pro90IS, G1, G2, S30, S40 { int CanonColorInfo2_type = get2(); // G1 1028, G2 272, Pro90 IS 769, S30 274, S40 273, EOS D30 276 if (CanonColorInfo2_type > 512) { /* Pro90 IS, G1 */ fseek(ifp, 118, SEEK_CUR); FORC4 cam_mul[BG2RG1_2_RGBG(c)] = get2(); } else if (CanonColorInfo2_type != 276) { /* G2, S30, S40 */ Appendix_A = 1; WB_table_offset = -14; fseek(ifp, 98, SEEK_CUR); FORC4 cam_mul[GRBG_2_RGBG(c)] = get2(); if (cam_mul[0] > 0.001f) Got_AsShotWB = 1; } } else if (type == 0x10a9) // ColorBalance: Canon D60, 10D, 300D, and clones { int bls = 0; /* int table[] = { LIBRAW_WBI_Auto, // 0 LIBRAW_WBI_Daylight, // 1 LIBRAW_WBI_Cloudy, // 2 LIBRAW_WBI_Tungsten, // 3 LIBRAW_WBI_FL_W, // 4 LIBRAW_WBI_Flash, // 5 LIBRAW_WBI_Custom, // 6, absent in Canon D60 LIBRAW_WBI_Auto, // 7, use this if camera is set to b/w JPEG LIBRAW_WBI_Shade, // 8 LIBRAW_WBI_Kelvin // 9, absent in Canon D60 }; */ int nWB = ((get2() - 2) / 8) - 1; // 2 bytes this, N recs 4*2bytes each, last rec is black level if (nWB) FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); if (nWB >= 7) Canon_WBpresets(0, 0); else FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]); if (nWB == 7) // mostly Canon EOS D60 + some fw#s for 300D; // check for 0x1668000 is unreliable { if ((wbi >= 0) && (wbi < 9) && (wbi != 6)) { FORC4 cam_mul[c] = float(icWBC[Canon_wbi2std[wbi]][c]); } else { FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]); } } else if (nWB == 9) // Canon 10D, 300D { FORC4 icWBC[LIBRAW_WBI_Custom][RGGB_2_RGBG(c)] = get2(); FORC4 icWBC[LIBRAW_WBI_Kelvin][RGGB_2_RGBG(c)] = get2(); if ((wbi >= 0) && (wbi < 10)) { FORC4 cam_mul[c] = float(icWBC[Canon_wbi2std[wbi]][c]); } else { FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]); } } FORC4 bls += (imCanon.ChannelBlackLevel[RGGB_2_RGBG(c)] = get2()); imCanon.AverageBlackLevel = bls / 4; } else if (type == 0x102d) { Canon_CameraSettings(len >> 1); } else if (type == 0x10b4) { switch (get2()) { case 1: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 2: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } } else if (type == 0x580b) { if (strcmp(model, "Canon EOS D30")) sprintf(imgdata.shootinginfo.BodySerial, "%d", len); else sprintf(imgdata.shootinginfo.BodySerial, "%0x-%05d", len >> 16, len & 0xffff); } else if (type == 0x0032) // CanonColorInfo1 { if (len == 768) { // EOS D30 ushort q; fseek(ifp, 4, SEEK_CUR); for (unsigned linenum = 0; linenum < Canon_D30_linenums_2_StdWBi.size(); linenum++) { if (Canon_D30_linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown) { FORC4 { q = get2(); icWBC[Canon_D30_linenums_2_StdWBi[linenum]][RGGB_2_RGBG(c)] = (int)(roundf(1024000.0f / (float)MAX(1, q))); } // if (Canon_wbi2std[imCanon.wbi] == *(Canon_D30_linenums_2_StdWBi + linenum)) { // FORC4 cam_mul[c] = icWBC[*(Canon_D30_linenums_2_StdWBi + linenum)][c]; // Got_AsShotWB = 1; // } } } fseek (ifp, 68-int(Canon_D30_linenums_2_StdWBi.size())*8, SEEK_CUR); FORC4 { q = get2(); cam_mul[RGGB_2_RGBG(c)] = 1024.f / float(MAX(1, q)); } if (!wbi) cam_mul[0] = -1; // use my auto white balance } else if ((cam_mul[0] <= 0.001f) || // Pro1, G3, G5, G6, S45, S50, S60, S70 Appendix_A) // G2, S30, S40 { libraw_static_table_t linenums_2_StdWBi; unsigned AsShotWB_linenum = Canon_wbi2std.size(); CanonColorInfo1_key = get2(); if ((CanonColorInfo1_key == key[0]) && (len == 2048)) { // Pro1 linenums_2_StdWBi = Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi; WB_table_offset = 8; } else if ((CanonColorInfo1_key == key[0]) && (len == 3072)) { // S60, S70, G6 linenums_2_StdWBi = Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi; WB_table_offset = 16; } else if (!CanonColorInfo1_key && (len == 2048)) { // G2, S30, S40; S45, S50, G3, G5 key[0] = key[1] = 0; linenums_2_StdWBi = Canon_KeyIsZero_Len2048_linenums_2_StdWBi; if (atof(imCommon.firmware) < 1.02f) UseWBfromTable_as_AsShot = 0; } else goto next_tag; if ((Canon_wbi2std[wbi] == LIBRAW_WBI_Auto) || (Canon_wbi2std[wbi] == LIBRAW_WBI_Unknown) || Got_AsShotWB) UseWBfromTable_as_AsShot = 0; if (UseWBfromTable_as_AsShot) { int temp_wbi; if (Canon_wbi2std[wbi] == LIBRAW_WBI_Custom) temp_wbi = LIBRAW_WBI_Daylight; else temp_wbi = wbi; for (AsShotWB_linenum = 0; AsShotWB_linenum < linenums_2_StdWBi.size(); AsShotWB_linenum++) { if (Canon_wbi2std[temp_wbi] == linenums_2_StdWBi[AsShotWB_linenum]) { break; } } } fseek (ifp, 78LL+WB_table_offset, SEEK_CUR); for (unsigned linenum = 0; linenum < linenums_2_StdWBi.size(); linenum++) { if (linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown) { FORC4 icWBC[linenums_2_StdWBi[linenum]][GRBG_2_RGBG(c)] = get2() ^ key[c & 1]; if (UseWBfromTable_as_AsShot && (AsShotWB_linenum == linenum)) { FORC4 cam_mul[c] = float(icWBC[linenums_2_StdWBi[linenum]][c]); Got_AsShotWB = 1; } } else { fseek(ifp, 8, SEEK_CUR); } } if (!Got_AsShotWB) cam_mul[0] = -1; } } else if (type == 0x1030 && wbi >= 0 && (0x18040 >> wbi & 1)) { ciff_block_1030(); // all that don't have 0x10a9 } else if (type == 0x1031) { raw_width = imCanon.SensorWidth = (get2(), get2()); raw_height = imCanon.SensorHeight = get2(); fseek(ifp, 4, SEEK_CUR); imCanon.DefaultCropAbsolute = get_CanonArea(); imCanon.LeftOpticalBlack = get_CanonArea(); } else if (type == 0x501c) { iso_speed = float(len & 0xffff); } else if (type == 0x5029) { ilm.CurFocal = float( len >> 16); ilm.FocalType = len & 0xffff; if (ilm.FocalType == LIBRAW_FT_ZOOM_LENS) { ilm.FocalUnits = 32; if (ilm.FocalUnits > 1) ilm.CurFocal /= (float)ilm.FocalUnits; } focal_len = ilm.CurFocal; } else if (type == 0x5813) { flash_used = int_to_float(len); } else if (type == 0x5814) { canon_ev = int_to_float(len); } else if (type == 0x5817) { shot_order = len; } else if (type == 0x5834) { unique_id = ((unsigned long long)len << 32) >> 32; setCanonBodyFeatures(unique_id); } else if (type == 0x580e) { timestamp = len; } else if (type == 0x180e) { timestamp = get4(); } next_tag:; #ifdef LOCALTIME if ((type | 0x4000) == 0x580e) timestamp = mktime(gmtime(×tamp)); #endif fseek(ifp, save, SEEK_SET); } } LibRaw-0.21.4/src/metadata/cr3_parser.cpp000066400000000000000000000602211477673233700201200ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" static libraw_area_t sget_CanonArea(uchar *s) { libraw_area_t la = {}; la.l = s[0] << 8 | s[1]; la.t = s[2] << 8 | s[3]; la.r = s[4] << 8 | s[5]; la.b = s[6] << 8 | s[7]; return la; } int LibRaw::selectCRXFrame(short trackNum, unsigned frameIndex) { uint32_t sample_size; uint32_t stsc_index = 0; uint32_t current_sample = 0; crx_data_header_t *hdr = &libraw_internal_data.unpacker_data.crx_header[trackNum]; if (frameIndex >= hdr->sample_count) return -1; for (int i = 0; i < hdr->chunk_count; i++) { int64_t current_offset = hdr->chunk_offsets[i]; while((stsc_index < hdr->stsc_count) && (i+1 == hdr->stsc_data[stsc_index+1].first)) stsc_index++; for (int j = 0; j < hdr->stsc_data[stsc_index].count; j++) { if (current_sample > hdr->sample_count) return -1; sample_size = hdr->sample_size > 0 ? hdr->sample_size : hdr->sample_sizes[current_sample]; if(current_sample == frameIndex) { hdr->MediaOffset = current_offset; hdr->MediaSize = sample_size; return 0; } current_offset += sample_size; current_sample++; } } return -1; } void LibRaw::selectCRXTrack() { short maxTrack = libraw_internal_data.unpacker_data.crx_track_count; if (maxTrack < 0) return; INT64 bitcounts[LIBRAW_CRXTRACKS_MAXCOUNT], maxbitcount = 0; int framecounts[LIBRAW_CRXTRACKS_MAXCOUNT], maxframecount = 0; uint32_t maxjpegbytes = 0; int framecnt = 0; int media_tracks = 0; int track_select = 0; int frame_select = 0; int err; memset(bitcounts, 0, sizeof(bitcounts)); memset(framecounts, 0, sizeof(framecounts)); // Calc max frame bitcount for max-sized RAW track(s) selection for (int i = 0; i <= maxTrack && i < LIBRAW_CRXTRACKS_MAXCOUNT; i++) { crx_data_header_t *d = &libraw_internal_data.unpacker_data.crx_header[i]; if (d->MediaType == 1) // RAW { bitcounts[i] = INT64(d->nBits) * INT64(d->f_width) * INT64(d->f_height); maxbitcount = MAX(bitcounts[i], maxbitcount); if (d->sample_count > 1) framecounts[i] = d->sample_count; } } if (maxbitcount < 8) // no raw tracks return; // Calc RAW tracks and frames for (int i = 0; i <= maxTrack && i < LIBRAW_CRXTRACKS_MAXCOUNT; i++) { if (bitcounts[i] == maxbitcount) { media_tracks++; if (framecounts[i] > 1) framecnt = MAX(framecnt, framecounts[i]); } } // If the file has only 1 media track shot_select represents frames select. // If the file has multiple media tracks shot_select represents track select. // If the file has multiple media tracks and multiple frames it is currently unsupported. if (framecnt && media_tracks > 1) return; else if (framecnt) frame_select = shot_select; else track_select = shot_select; int tracki = -1; for (int i = 0, trackcnt = 0; i <= maxTrack && i < LIBRAW_CRXTRACKS_MAXCOUNT; i++) { if (bitcounts[i] == maxbitcount) { if (trackcnt <= (int)track_select) tracki = i; trackcnt++; } } if (tracki >= 0 && tracki < LIBRAW_CRXTRACKS_MAXCOUNT /* && frame_select > 0 */) { framecnt = framecounts[tracki]; // Update to selected track frame_select = LIM(frame_select, 0, framecnt); if(frame_select > 0) if (selectCRXFrame(tracki, frame_select)) return; } else return; // No RAW track index // Frame selected: parse CTMD metadata for (int i = 0, trackcnt = 0; i <= maxTrack && i < LIBRAW_CRXTRACKS_MAXCOUNT; i++) { crx_data_header_t *d = &libraw_internal_data.unpacker_data.crx_header[i]; int fsel = LIM(frame_select, 0, d->sample_count); if (d->MediaType == 3) // CTMD metadata { /* ignore errors !*/ if (fsel) selectCRXFrame(i, fsel); parseCR3_CTMD(i); } else if (d->MediaType == 2) // JPEG { if (fsel) selectCRXFrame(i, fsel); if (d->MediaSize > maxjpegbytes) { maxjpegbytes = d->MediaSize; thumb_offset = d->MediaOffset; thumb_length = d->MediaSize; if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT) { bool do_add = true; for (int idx = 0; idx < imgdata.thumbs_list.thumbcount; idx++) if (imgdata.thumbs_list.thumblist[idx].toffset == thumb_offset) { do_add = false; break; } if (do_add) { int idx = imgdata.thumbs_list.thumbcount; imgdata.thumbs_list.thumblist[idx].tformat = LIBRAW_INTERNAL_THUMBNAIL_JPEG; imgdata.thumbs_list.thumblist[idx].toffset = thumb_offset; imgdata.thumbs_list.thumblist[idx].tlength = thumb_length; imgdata.thumbs_list.thumblist[idx].tflip = 0xffff; imgdata.thumbs_list.thumblist[idx].tmisc = (3 << 5) | 8; // 3 samples/8 bps imgdata.thumbs_list.thumblist[idx].twidth = 0; imgdata.thumbs_list.thumblist[idx].theight = 0; imgdata.thumbs_list.thumbcount++; } } } } } if (framecnt) is_raw = framecnt; else is_raw = media_tracks; if (tracki >= 0 && tracki < LIBRAW_CRXTRACKS_MAXCOUNT) { crx_data_header_t *d = &libraw_internal_data.unpacker_data.crx_header[tracki]; data_offset = d->MediaOffset; data_size = d->MediaSize; raw_width = d->f_width; raw_height = d->f_height; load_raw = &LibRaw::crxLoadRaw; tiff_bps = d->encType == 3? d->medianBits : d->nBits; switch (d->cfaLayout) { case 0: filters = 0x94949494; break; case 1: filters = 0x61616161; break; case 2: filters = 0x49494949; break; case 3: filters = 0x16161616; break; } libraw_internal_data.unpacker_data.crx_track_selected = tracki; int tiff_idx = -1; INT64 tpixels = 0; for (unsigned i = 0; i < tiff_nifds && i < LIBRAW_IFD_MAXCOUNT; i++) if (INT64(tiff_ifd[i].t_height) * INT64(tiff_ifd[i].t_height) > tpixels) { tpixels = INT64(tiff_ifd[i].t_height) * INT64(tiff_ifd[i].t_height); tiff_idx = i; } if (tiff_idx >= 0) flip = tiff_ifd[tiff_idx].t_flip; } } #define bad_hdr() \ (((order != 0x4d4d) && (order != 0x4949)) || (get2() != 0x002a) || \ (get4() != 0x00000008)) int LibRaw::parseCR3_CTMD(short trackNum) { int err = 0; short s_order = order; order = 0x4949; uint32_t relpos_inDir = 0; uint32_t relpos_inBox = 0; unsigned szItem, Tag, lTag; ushort tItem; #define track libraw_internal_data.unpacker_data.crx_header[trackNum] if (track.MediaType != 3) { err = -10; goto ctmd_fin; } while (relpos_inDir + 6 < track.MediaSize) { if (track.MediaOffset + relpos_inDir > ifp->size() - 6) // need at least 6 bytes { err = -11; goto ctmd_fin; } fseek(ifp, track.MediaOffset + relpos_inDir, SEEK_SET); szItem = get4(); tItem = get2(); if (szItem < 1 || ( (relpos_inDir + szItem) > track.MediaSize)) { err = -11; goto ctmd_fin; } if ((tItem == 7) || (tItem == 8) || (tItem == 9)) { relpos_inBox = relpos_inDir + 12L; while (relpos_inBox + 8 < relpos_inDir + szItem) { if (track.MediaOffset + relpos_inBox > ifp->size() - 8) // need at least 8 bytes { err = -11; goto ctmd_fin; } fseek(ifp, track.MediaOffset + relpos_inBox, SEEK_SET); lTag = get4(); Tag = get4(); if (lTag < 8) { err = -12; goto ctmd_fin; } else if ((relpos_inBox + lTag) > (relpos_inDir + szItem)) { err = -11; goto ctmd_fin; } if ((Tag == 0x927c) && ((tItem == 7) || (tItem == 8))) { fseek(ifp, track.MediaOffset + relpos_inBox + 8L, SEEK_SET); short q_order = order; order = get2(); if (bad_hdr()) { err = -13; goto ctmd_fin; } fseek(ifp, -8L, SEEK_CUR); libraw_internal_data.unpacker_data.CR3_CTMDtag = 1; parse_makernote(track.MediaOffset + relpos_inBox + 8, 0); libraw_internal_data.unpacker_data.CR3_CTMDtag = 0; order = q_order; } relpos_inBox += lTag; } } relpos_inDir += szItem; } ctmd_fin: order = s_order; return err; } #undef track int LibRaw::parseCR3(INT64 oAtomList, INT64 szAtomList, short &nesting, char *AtomNameStack, short &nTrack, short &TrackType) { /* Atom starts with 4 bytes for Atom size and 4 bytes containing Atom name Atom size includes the length of the header and the size of all "contained" Atoms if Atom size == 1, Atom has the extended size stored in 8 bytes located after the Atom name if Atom size == 0, it is the last top-level Atom extending to the end of the file Atom name is often a 4 symbol mnemonic, but can be a 4-byte integer */ const char UIID_Canon[17] = "\x85\xc0\xb6\x87\x82\x0f\x11\xe0\x81\x11\xf4\xce\x46\x2b\x6a\x48"; const unsigned char UIID_CanonPreview[17] = "\xea\xf4\x2b\x5e\x1c\x98\x4b\x88\xb9\xfb\xb7\xdc\x40\x6e\x4d\x16"; const unsigned char UUID_XMP[17] = "\xbe\x7a\xcf\xcb\x97\xa9\x42\xe8\x9c\x71\x99\x94\x91\xe3\xaf\xac"; /* AtomType = 0 - unknown: "unk." AtomType = 1 - container atom: "cont" AtomType = 2 - leaf atom: "leaf" AtomType = 3 - can be container, can be leaf: "both" */ short AtomType; static const struct { char AtomName[5]; short AtomType; } AtomNamesList[] = { {"dinf", 1}, {"edts", 1}, {"fiin", 1}, {"ipro", 1}, {"iprp", 1}, {"mdia", 1}, {"meco", 1}, {"mere", 1}, {"mfra", 1}, {"minf", 1}, {"moof", 1}, {"moov", 1}, {"mvex", 1}, {"paen", 1}, {"schi", 1}, {"sinf", 1}, {"skip", 1}, {"stbl", 1}, {"stsd", 1}, {"strk", 1}, {"tapt", 1}, {"traf", 1}, {"trak", 1}, {"cdsc", 2}, {"colr", 2}, {"dimg", 2}, // {"dref", 2}, {"free", 2}, {"frma", 2}, {"ftyp", 2}, {"hdlr", 2}, {"hvcC", 2}, {"iinf", 2}, {"iloc", 2}, {"infe", 2}, {"ipco", 2}, {"ipma", 2}, {"iref", 2}, {"irot", 2}, {"ispe", 2}, {"meta", 2}, {"mvhd", 2}, {"pitm", 2}, {"pixi", 2}, {"schm", 2}, {"thmb", 2}, {"tkhd", 2}, {"url ", 2}, {"urn ", 2}, {"CCTP", 1}, {"CRAW", 1}, {"JPEG", 2}, {"CDI1", 2}, {"CMP1", 2}, {"CNCV", 2}, {"CCDT", 2}, {"CTBO", 2}, {"CMT1", 2}, {"CMT2", 2}, {"CMT3", 2}, {"CMT4", 2}, {"CNOP", 2}, {"THMB", 2}, {"co64", 2}, {"mdat", 2}, {"mdhd", 2}, {"nmhd", 2}, {"stsc", 2}, {"stsz", 2}, {"stts", 2}, {"vmhd", 2}, {"dref", 3}, {"uuid", 3}, }; const char sHandlerType[5][5] = {"unk.", "soun", "vide", "hint", "meta"}; int c, err=0; ushort tL; // Atom length represented in 4 or 8 bytes char nmAtom[5]; // Atom name INT64 oAtom, szAtom; // Atom offset and Atom size INT64 oAtomContent, szAtomContent; // offset and size of Atom content INT64 lHdr; char UIID[16]; uchar CMP1[85]; uchar CDI1[60]; char HandlerType[5], MediaFormatID[5]; uint32_t relpos_inDir, relpos_inBox; unsigned szItem, Tag, lTag; ushort tItem; nmAtom[0] = MediaFormatID[0] = nmAtom[4] = MediaFormatID[4] = '\0'; strcpy(HandlerType, sHandlerType[0]); oAtom = oAtomList; nesting++; if (nesting > 31) return -14; // too deep nesting short s_order = order; while ((oAtom + 8LL) <= (oAtomList + szAtomList)) { lHdr = 0ULL; err = 0; order = 0x4d4d; fseek(ifp, oAtom, SEEK_SET); szAtom = get4(); FORC4 nmAtom[c] = AtomNameStack[nesting * 4 + c] = fgetc(ifp); AtomNameStack[(nesting + 1) * 4] = '\0'; tL = 4; AtomType = 0; for (c = 0; c < int(sizeof AtomNamesList / sizeof *AtomNamesList); c++) if (!strcmp(nmAtom, AtomNamesList[c].AtomName)) { AtomType = AtomNamesList[c].AtomType; break; } if (!AtomType) { err = 1; } if (szAtom == 0ULL) { if (nesting != 0) { err = -2; goto fin; } szAtom = szAtomList - oAtom; oAtomContent = oAtom + 8ULL; szAtomContent = szAtom - 8ULL; } else if (szAtom == 1LL) { if ((oAtom + 16LL) > (oAtomList + szAtomList)) { err = -3; goto fin; } tL = 8; szAtom = (((unsigned long long)get4()) << 32) | get4(); oAtomContent = oAtom + 16ULL; szAtomContent = szAtom - 16ULL; } else { oAtomContent = oAtom + 8ULL; szAtomContent = szAtom - 8ULL; } if (!strcmp(AtomNameStack, "uuid")) // Top level uuid { INT64 tt = ftell(ifp); lHdr = 16ULL; fread(UIID, 1, lHdr, ifp); if (!memcmp(UIID, UUID_XMP, 16) && szAtom > 24LL && szAtom < 1024000LL) { xmpdata = (char *)calloc(xmplen = unsigned(szAtom - 23),1); unsigned br = fread(xmpdata,1, szAtom - 24, ifp); xmpdata[br] = 0; } else if (!memcmp(UIID, UIID_CanonPreview, 16) && szAtom > 48LL && szAtom < 100LL * 1024000LL) { // read next 48 bytes, check for 'PRVW' unsigned char xdata[32]; fread(xdata, 32, 1, ifp); if (!memcmp(xdata + 12, "PRVW", 4)) { thumb_length = unsigned(szAtom - 56); thumb_offset = ftell(ifp); if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT) { bool do_add = true; for(int idx = 0; idx < imgdata.thumbs_list.thumbcount; idx++) if (imgdata.thumbs_list.thumblist[idx].toffset == thumb_offset) { do_add = false; break; } if (do_add) { int idx = imgdata.thumbs_list.thumbcount; imgdata.thumbs_list.thumblist[idx].tformat = LIBRAW_INTERNAL_THUMBNAIL_JPEG; imgdata.thumbs_list.thumblist[idx].toffset = thumb_offset; imgdata.thumbs_list.thumblist[idx].tlength = thumb_length; imgdata.thumbs_list.thumblist[idx].tflip = 0xffff; imgdata.thumbs_list.thumblist[idx].tmisc = (3 << 5) | 8; // 3 samples/8 bps imgdata.thumbs_list.thumblist[idx].twidth = (xdata[22] << 8) + xdata[23]; imgdata.thumbs_list.thumblist[idx].theight = (xdata[24] << 8) + xdata[25]; imgdata.thumbs_list.thumbcount++; } } } } fseek(ifp, tt, SEEK_SET); } if (!strcmp(nmAtom, "trak")) { nTrack++; TrackType = 0; if (nTrack >= LIBRAW_CRXTRACKS_MAXCOUNT) break; } if (!strcmp(AtomNameStack, "moovuuid")) { lHdr = 16ULL; fread(UIID, 1, lHdr, ifp); if (!strncmp(UIID, UIID_Canon, lHdr)) { AtomType = 1; } else fseek(ifp, -lHdr, SEEK_CUR); } else if (!strcmp(AtomNameStack, "moovuuidCCTP")) { lHdr = 12ULL; } else if (!strcmp(AtomNameStack, "moovuuidCMT1")) { short q_order = order; order = get2(); if ((tL != 4) || bad_hdr()) { err = -4; goto fin; } if (!libraw_internal_data.unpacker_data.cr3_ifd0_length) libraw_internal_data.unpacker_data.cr3_ifd0_length = unsigned(szAtomContent); parse_tiff_ifd(oAtomContent); order = q_order; } else if (!strcmp(AtomNameStack, "moovuuidTHMB") && szAtom > 24) { unsigned char xdata[16]; fread(xdata, 16, 1, ifp); INT64 xoffset = ftell(ifp); if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT) { bool do_add = true; for (int idx = 0; idx < imgdata.thumbs_list.thumbcount; idx++) if (imgdata.thumbs_list.thumblist[idx].toffset == xoffset) { do_add = false; break; } if (do_add) { int idx = imgdata.thumbs_list.thumbcount; imgdata.thumbs_list.thumblist[idx].tformat = LIBRAW_INTERNAL_THUMBNAIL_JPEG; imgdata.thumbs_list.thumblist[idx].toffset = xoffset; imgdata.thumbs_list.thumblist[idx].tlength = szAtom-24; imgdata.thumbs_list.thumblist[idx].tflip = 0xffff; imgdata.thumbs_list.thumblist[idx].tmisc = (3 << 5) | 8; // 3 samples/8 bps imgdata.thumbs_list.thumblist[idx].twidth = (xdata[4] << 8) + xdata[5]; imgdata.thumbs_list.thumblist[idx].theight = (xdata[6] << 8) + xdata[7]; imgdata.thumbs_list.thumbcount++; } } } else if (!strcmp(AtomNameStack, "moovuuidCMT2")) { short q_order = order; order = get2(); if ((tL != 4) || bad_hdr()) { err = -5; goto fin; } if (!libraw_internal_data.unpacker_data.cr3_exif_length) libraw_internal_data.unpacker_data.cr3_exif_length = unsigned(szAtomContent); parse_exif(oAtomContent); order = q_order; } else if (!strcmp(AtomNameStack, "moovuuidCMT3")) { short q_order = order; order = get2(); if ((tL != 4) || bad_hdr()) { err = -6; goto fin; } fseek(ifp, -12L, SEEK_CUR); parse_makernote(oAtomContent, 0); order = q_order; } else if (!strcmp(AtomNameStack, "moovuuidCMT4")) { short q_order = order; order = get2(); if ((tL != 4) || bad_hdr()) { err = -6; goto fin; } INT64 off = ftell(ifp); parse_gps(oAtomContent); fseek(ifp, off, SEEK_SET); parse_gps_libraw(oAtomContent); order = q_order; } else if (!strcmp(AtomNameStack, "moovtrakmdiahdlr")) { fseek(ifp, 8L, SEEK_CUR); FORC4 HandlerType[c] = fgetc(ifp); for (c = 1; c < int(sizeof sHandlerType / sizeof *sHandlerType); c++) if (!strcmp(HandlerType, sHandlerType[c])) { TrackType = c; break; } } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsd")) { if (szAtomContent >= 16) { fseek(ifp, 12L, SEEK_CUR); lHdr = 8; } else { err = -7; goto fin; } FORC4 MediaFormatID[c] = fgetc(ifp); if ((TrackType == 2) && (!strcmp(MediaFormatID, "CRAW"))) { if (szAtomContent >= 44) fseek(ifp, 24L, SEEK_CUR); else { err = -8; goto fin; } } else { AtomType = 2; // only continue for CRAW lHdr = 0; } #define current_track libraw_internal_data.unpacker_data.crx_header[nTrack] /*ImageWidth =*/ get2(); /*ImageHeight =*/ get2(); } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAW")) { lHdr = 82; } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAWCMP1")) { int read_size = szAtomContent > 85 ? 85 : szAtomContent; if (szAtomContent >= 40) fread(CMP1, 1, read_size, ifp); else { err = -7; goto fin; } if (!crxParseImageHeader(CMP1, nTrack, read_size)) current_track.MediaType = 1; } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAWCDI1")) { if (szAtomContent >= 60) { fread(CDI1, 1, 60, ifp); if (!strncmp((char *)CDI1+8, "IAD1", 4) && (sgetn(8, CDI1) == 0x38)) { // sensor area at CDI1+12, 4 16-bit values // Bayer pattern? - next 4 16-bit values imCanon.RecommendedImageArea = sget_CanonArea(CDI1+12 + 2*4*2); imCanon.LeftOpticalBlack = sget_CanonArea(CDI1+12 + 3*4*2); imCanon.UpperOpticalBlack = sget_CanonArea(CDI1+12 + 4*4*2); imCanon.ActiveArea = sget_CanonArea(CDI1+12 + 5*4*2); } } } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAWJPEG")) { current_track.MediaType = 2; } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsc")) { if (szAtomContent >= 12) { fseek(ifp, 4L, SEEK_CUR); int entries = get4(); if (entries < 1 || entries > 1000000) { err = -9; goto fin; } current_track.stsc_data = (crx_sample_to_chunk_t*) calloc(entries * sizeof(crx_sample_to_chunk_t),1); if(!current_track.stsc_data) { err = -9; goto fin; } current_track.stsc_count = entries; for(int i = 0; i < entries; i++) { current_track.stsc_data[i].first = get4(); current_track.stsc_data[i].count = get4(); current_track.stsc_data[i].id = get4(); } } } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsz")) { if (szAtomContent >= 12) { fseek(ifp, 4L, SEEK_CUR); int sample_size = get4(); int entries = get4(); current_track.sample_count = entries; // if sample size is zero sample size is fixed if (sample_size) { current_track.MediaSize = sample_size; current_track.sample_size = sample_size; } else { current_track.sample_size = 0; if (entries < 1 || entries > 1000000) { err = -10; goto fin; } current_track.sample_sizes = (int32_t*)calloc(entries * sizeof(int32_t),1); if (!current_track.sample_sizes) { err = -10; goto fin; } for (int i = 0; i < entries; i++) current_track.sample_sizes[i] = get4(); current_track.MediaSize = current_track.sample_sizes[0]; } } } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblco64")) { if (szAtomContent >= 16) { fseek(ifp, 4L, SEEK_CUR); uint32_t entries = get4(); int i; if (entries < 1 || entries > 1000000) { err = -11; goto fin; } current_track.chunk_offsets = (INT64*)calloc(entries * sizeof(int64_t),1); if(!current_track.chunk_offsets) { err = -11; goto fin; } current_track.chunk_count = entries; for (i = 0; i < entries; i++) current_track.chunk_offsets[i] = (((int64_t)get4()) << 32) | get4(); current_track.chunk_count = i; current_track.MediaOffset = current_track.chunk_offsets[0]; } } if (nTrack >= 0 && nTrack < LIBRAW_CRXTRACKS_MAXCOUNT && current_track.MediaSize && current_track.MediaOffset && ((oAtom + szAtom) >= (oAtomList + szAtomList)) && !strncmp(AtomNameStack, "moovtrakmdiaminfstbl", 20)) { if ((TrackType == 4) && (!strcmp(MediaFormatID, "CTMD"))) { current_track.MediaType = 3; } } #undef current_track if (AtomType == 1) { err = parseCR3(oAtomContent + lHdr, szAtomContent - lHdr, nesting, AtomNameStack, nTrack, TrackType); if (err) goto fin; } oAtom += szAtom; } fin: nesting--; if (nesting >= 0) AtomNameStack[nesting * 4] = '\0'; order = s_order; return err; } #undef bad_hdr void LibRaw::parseCR3_Free() { short maxTrack = libraw_internal_data.unpacker_data.crx_track_count; if (maxTrack < 0) return; for (int i = 0; i <= maxTrack && i < LIBRAW_CRXTRACKS_MAXCOUNT; i++) { crx_data_header_t *d = &libraw_internal_data.unpacker_data.crx_header[i]; if (d->stsc_data) { free(d->stsc_data); d->stsc_data = NULL; } if (d->chunk_offsets) { free(d->chunk_offsets); d->chunk_offsets = NULL; } if (d->sample_sizes) { free(d->sample_sizes); d->sample_sizes = NULL; } d->stsc_count = 0; d->sample_count = 0; d->sample_size = 0; d->chunk_count = 0; } libraw_internal_data.unpacker_data.crx_track_count = -1; } LibRaw-0.21.4/src/metadata/epson.cpp000066400000000000000000000045741477673233700172120ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" void LibRaw::parseEpsonMakernote(int base, int uptag, unsigned dng_writer) { #define isRIC imgdata.sizes.raw_inset_crops[0] unsigned entries, tag, type, len, save; short morder, sorder = order; ushort c; INT64 fsize = ifp->size(); fseek(ifp, -2, SEEK_CUR); entries = get2(); if (entries > 1000) return; morder = order; while (entries--) { order = morder; tiff_get(base, &tag, &type, &len, &save); INT64 pos = ifp->tell(); if (len > 8 && pos + len > 2 * fsize) { fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! continue; } tag |= uptag << 16; if (len > 100 * 1024 * 1024) goto next; // 100Mb tag? No! if (tag == 0x020b) { if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) isRIC.cwidth = get4(); else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) isRIC.cwidth = get2(); } else if (tag == 0x020c) { if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) isRIC.cheight = get4(); else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) isRIC.cheight = get2(); } else if (tag == 0x0400) { // sensor area ushort sdims[4] = {0, 0, 0, 0}; // left margin, top margin, width, height FORC4 sdims[c] = get2(); isRIC.cleft = (sdims[2] - sdims[0] - isRIC.cwidth) / 2; isRIC.ctop = (sdims[3] - sdims[1] - isRIC.cheight) / 2; } if (dng_writer == nonDNG) { if (tag == 0x0280) { thumb_offset = ftell(ifp); thumb_length = len; } else if (tag == 0x0401) { FORC4 cblack[RGGB_2_RGBG(c)] = get4(); } else if (tag == 0x0e80) { fseek(ifp, 48, SEEK_CUR); cam_mul[0] = get2() * 567.0 / 0x10000; cam_mul[2] = get2() * 431.0 / 0x10000; } } next: fseek(ifp, save, SEEK_SET); } order = sorder; #undef isRIC } LibRaw-0.21.4/src/metadata/exif_gps.cpp000066400000000000000000000303601477673233700176620ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" #include "../../internal/libraw_cameraids.h" void LibRaw::parse_exif_interop(int base) { unsigned entries, tag, type, len, save; char value[4] = { 0,0,0,0 }; entries = get2(); INT64 fsize = ifp->size(); while (entries--) { tiff_get(base, &tag, &type, &len, &save); INT64 savepos = ftell(ifp); if (len > 8 && savepos + len > fsize * 2) { fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! continue; } if (callbacks.exif_cb) { callbacks.exif_cb(callbacks.exifparser_data, tag | 0x40000, type, len, order, ifp, base); fseek(ifp, savepos, SEEK_SET); } switch (tag) { case 0x0001: // InteropIndex fread(value, 1, MIN(4, len), ifp); if (strncmp(value, "R98", 3) == 0 && // Canon bug, when [Canon].ColorSpace = AdobeRGB, // but [ExifIFD].ColorSpace = Uncalibrated and // [InteropIFD].InteropIndex = "R98" imgdata.color.ExifColorSpace == LIBRAW_COLORSPACE_Unknown) imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_sRGB; else if (strncmp(value, "R03", 3) == 0) imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; } fseek(ifp, save, SEEK_SET); } } void LibRaw::parse_exif(int base) { unsigned entries, tag, type, len, save, c; double expo, ape; unsigned kodak = !strncmp(make, "EASTMAN", 7) && tiff_nifds < 3; if (!libraw_internal_data.unpacker_data.exif_subdir_offset) { libraw_internal_data.unpacker_data.exif_offset = base; libraw_internal_data.unpacker_data.exif_subdir_offset = ftell(ifp); } entries = get2(); if (!strncmp(make, "Hasselblad", 10) && (tiff_nifds > 3) && (entries > 512)) return; INT64 fsize = ifp->size(); while (entries--) { tiff_get(base, &tag, &type, &len, &save); INT64 savepos = ftell(ifp); if (len > 8 && savepos + len > fsize * 2) { fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! continue; } if (callbacks.exif_cb) { callbacks.exif_cb(callbacks.exifparser_data, tag, type, len, order, ifp, base); fseek(ifp, savepos, SEEK_SET); } switch (tag) { case 0xA005: // Interoperability IFD fseek(ifp, get4() + base, SEEK_SET); parse_exif_interop(base); break; case 0xA001: // ExifIFD.ColorSpace c = get2(); if (c == 1 && imgdata.color.ExifColorSpace == LIBRAW_COLORSPACE_Unknown) imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_sRGB; else if (c == 2) imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; case 0x9400: imCommon.exifAmbientTemperature = getreal(type); if ((imCommon.CameraTemperature > -273.15f) && ((OlyID == OlyID_TG_5) || (OlyID == OlyID_TG_6)) ) imCommon.CameraTemperature += imCommon.exifAmbientTemperature; break; case 0x9401: imCommon.exifHumidity = getreal(type); break; case 0x9402: imCommon.exifPressure = getreal(type); break; case 0x9403: imCommon.exifWaterDepth = getreal(type); break; case 0x9404: imCommon.exifAcceleration = getreal(type); break; case 0x9405: imCommon.exifCameraElevationAngle = getreal(type); break; case 0xa405: // FocalLengthIn35mmFormat imgdata.lens.FocalLengthIn35mmFormat = get2(); break; case 0xa431: // BodySerialNumber stmread(imgdata.shootinginfo.BodySerial, len, ifp); break; case 0xa432: // LensInfo, 42034dec, Lens Specification per EXIF standard imgdata.lens.MinFocal = getreal(type); imgdata.lens.MaxFocal = getreal(type); imgdata.lens.MaxAp4MinFocal = getreal(type); imgdata.lens.MaxAp4MaxFocal = getreal(type); break; case 0xa435: // LensSerialNumber stmread(imgdata.lens.LensSerial, len, ifp); if (!strncmp(imgdata.lens.LensSerial, "----", 4)) imgdata.lens.LensSerial[0] = '\0'; break; case 0xa420: /* 42016, ImageUniqueID */ stmread(imgdata.color.ImageUniqueID, len, ifp); break; case 0xc65d: /* 50781, RawDataUniqueID */ imgdata.color.RawDataUniqueID[16] = 0; fread(imgdata.color.RawDataUniqueID, 1, 16, ifp); break; case 0xc630: // DNG LensInfo, Lens Specification per EXIF standard imgdata.lens.dng.MinFocal = getreal(type); imgdata.lens.dng.MaxFocal = getreal(type); imgdata.lens.dng.MaxAp4MinFocal = getreal(type); imgdata.lens.dng.MaxAp4MaxFocal = getreal(type); break; case 0xc68b: /* 50827, OriginalRawFileName */ stmread(imgdata.color.OriginalRawFileName, len, ifp); break; case 0xa433: // LensMake stmread(imgdata.lens.LensMake, len, ifp); break; case 0xa434: // LensModel stmread(imgdata.lens.Lens, len, ifp); if (!strncmp(imgdata.lens.Lens, "----", 4)) imgdata.lens.Lens[0] = '\0'; break; case 0x9205: imgdata.lens.EXIF_MaxAp = libraw_powf64l(2.0f, (getreal(type) / 2.0f)); break; case 0x829a: // 33434 shutter = getreal(type); if (tiff_nifds > 0 && tiff_nifds <= LIBRAW_IFD_MAXCOUNT) tiff_ifd[tiff_nifds - 1].t_shutter = shutter; break; case 0x829d: // 33437, FNumber aperture = getreal(type); break; case 0x8827: // 34855 iso_speed = get2(); break; case 0x8831: // 34865 if (iso_speed == 0xffff && !strncasecmp(make, "FUJI", 4)) iso_speed = getreal(type); break; case 0x8832: // 34866 if (iso_speed == 0xffff && (!strncasecmp(make, "SONY", 4) || !strncasecmp(make, "CANON", 5))) iso_speed = getreal(type); break; case 0x9003: // 36867 case 0x9004: // 36868 get_timestamp(0); break; case 0x9201: // 37377 if ((expo = -getreal(type)) < 128 && shutter == 0.) { shutter = libraw_powf64l(2.0, expo); if (tiff_nifds > 0 && tiff_nifds <= LIBRAW_IFD_MAXCOUNT) tiff_ifd[tiff_nifds - 1].t_shutter = shutter; } break; case 0x9202: // 37378 ApertureValue if ((fabs(ape = getreal(type)) < 256.0) && (!aperture)) aperture = libraw_powf64l(2.0, ape / 2); break; case 0x9209: // 37385 flash_used = getreal(type); break; case 0x920a: // 37386 focal_len = getreal(type); break; case 0x927c: // 37500 #ifndef USE_6BY9RPI if (((make[0] == '\0') && !strncmp(model, "ov5647", 6)) || (!strncmp(make, "RaspberryPi", 11) && (!strncmp(model, "RP_OV5647", 9) || !strncmp(model, "RP_imx219", 9)))) #else if (((make[0] == '\0') && !strncmp(model, "ov5647", 6)) || (!strncmp(make, "RaspberryPi", 11) && (!strncmp(model, "RP_", 3) || !strncmp(model,"imx477",6)))) #endif { char mn_text[512]; char *pos; char ccms[512]; ushort l; float num; fgets(mn_text, MIN(len, 511), ifp); mn_text[511] = 0; pos = strstr(mn_text, "ev="); if (pos) imCommon.ExposureCalibrationShift = atof(pos + 3); pos = strstr(mn_text, "gain_r="); if (pos) cam_mul[0] = atof(pos + 7); pos = strstr(mn_text, "gain_b="); if (pos) cam_mul[2] = atof(pos + 7); if ((cam_mul[0] > 0.001f) && (cam_mul[2] > 0.001f)) cam_mul[1] = cam_mul[3] = 1.0f; else cam_mul[0] = cam_mul[2] = 0.0f; pos = strstr(mn_text, "ccm="); if (pos) { pos += 4; char *pos2 = strstr(pos, " "); if (pos2) { l = pos2 - pos; memcpy(ccms, pos, l); ccms[l] = '\0'; #ifdef LIBRAW_WIN32_CALLS // Win32 strtok is already thread-safe pos = strtok(ccms, ","); #else char *last = 0; pos = strtok_r(ccms, ",", &last); #endif if (pos) { for (l = 0; l < 3; l++) // skip last row { num = 0.0; for (c = 0; c < 3; c++) { cmatrix[l][c] = (float)atoi(pos); num += cmatrix[c][l]; #ifdef LIBRAW_WIN32_CALLS pos = strtok(NULL, ","); #else pos = strtok_r(NULL, ",", &last); #endif if (!pos) goto end; // broken } if (num > 0.01) FORC3 cmatrix[l][c] = cmatrix[l][c] / num; } } } } end:; } else if (!strncmp(make, "SONY", 4) && (!strncmp(model, "DSC-V3", 6) || !strncmp(model, "DSC-F828", 8))) { parseSonySRF(len); break; } else if ((len == 1) && !strncmp(make, "NIKON", 5)) { c = get4(); if (c) fseek(ifp, c, SEEK_SET); is_NikonTransfer = 1; } parse_makernote(base, 0); break; case 0xa002: // 40962 if (kodak) raw_width = get4(); break; case 0xa003: // 40963 if (kodak) raw_height = get4(); break; case 0xa302: // 41730 if (get4() == 0x20002) for (exif_cfa = c = 0; c < 8; c += 2) exif_cfa |= fgetc(ifp) * 0x01010101U << c; } fseek(ifp, save, SEEK_SET); } } void LibRaw::parse_gps_libraw(int base) { unsigned entries, tag, type, len, save, c; entries = get2(); if (entries > 40) return; if (entries > 0) imgdata.other.parsed_gps.gpsparsed = 1; INT64 fsize = ifp->size(); while (entries--) { tiff_get(base, &tag, &type, &len, &save); if (len > 1024) { fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! continue; // no GPS tags are 1k or larger } INT64 savepos = ftell(ifp); if (len > 8 && savepos + len > fsize * 2) { fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! continue; } if (callbacks.exif_cb) { callbacks.exif_cb(callbacks.exifparser_data, tag | 0x50000, type, len, order, ifp, base); fseek(ifp, savepos, SEEK_SET); } switch (tag) { case 0x0001: imgdata.other.parsed_gps.latref = getc(ifp); break; case 0x0003: imgdata.other.parsed_gps.longref = getc(ifp); break; case 0x0005: imgdata.other.parsed_gps.altref = getc(ifp); break; case 0x0002: if (len == 3) FORC(3) imgdata.other.parsed_gps.latitude[c] = getreal(type); break; case 0x0004: if (len == 3) FORC(3) imgdata.other.parsed_gps.longitude[c] = getreal(type); break; case 0x0007: if (len == 3) FORC(3) imgdata.other.parsed_gps.gpstimestamp[c] = getreal(type); break; case 0x0006: imgdata.other.parsed_gps.altitude = getreal(type); break; case 0x0009: imgdata.other.parsed_gps.gpsstatus = getc(ifp); break; } fseek(ifp, save, SEEK_SET); } } void LibRaw::parse_gps(int base) { unsigned entries, tag, type, len, save, c; entries = get2(); if (entries > 40) return; while (entries--) { tiff_get(base, &tag, &type, &len, &save); if (len > 1024) { fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! continue; // no GPS tags are 1k or larger } switch (tag) { case 0x0001: case 0x0003: case 0x0005: gpsdata[29 + tag / 2] = getc(ifp); break; case 0x0002: case 0x0004: case 0x0007: FORC(6) gpsdata[tag / 3 * 6 + c] = get4(); break; case 0x0006: FORC(2) gpsdata[18 + c] = get4(); break; case 0x0012: // 18 case 0x001d: // 29 fgets((char *)(gpsdata + 14 + tag / 3), MIN(len, 12), ifp); } fseek(ifp, save, SEEK_SET); } } LibRaw-0.21.4/src/metadata/fuji.cpp000066400000000000000000001372041477673233700170200ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" int LibRaw::guess_RAFDataGeneration (uchar *RAFData_start) // returns offset to first valid width/height pair { /* RAFDataGeneration codes, values are 4 bytes, little endian RAFData gen. 0: no RAFData DBP for GX680 / DX-2000 E550, E900, (F500 / F505?) F550, F600 / F605, F700, F770 / F775, F800, F810, F900 HS10 HS11, HS20 / HS22, HS30 / HS33 / HS35, HS50 S1, SL1000, S100, S200 / S205, S20Pro, S2Pro, S3Pro, S5Pro S5000, S5100 / S5500, S5200 / S5600, S6000 / S6500, S7000, S9000 / S9500, S9100 / S9600 RAFData gen. 1, offset to WH pair (offsetWH_inRAFData) = 0: - number in bytes 0..1 is less than 10000 - contains WH pair, recommended image size WH pair, 16 bytes unknown, 2*13 values (for crops, scales?) X100, X-Pro1, X-S1, X10, XF1 RAFData gen. 2, offset to WH pair = 4: - bytes 0..1 contain a number greater than 10000; bytes 2..3 contain zero; version is in bytes 0..1, possibly big endian - contains WH pair, recommended image size WH pair, 16 bytes unknown, 2*13 values X-E1 RAFData gen. 3, offset to WH pair = 4: - bytes 0..1 contain zero; bytes 2..3 contain version; - contains a table of 3+2*13 values; first 3 values look like WHW X-A1, X-A2, X-E2, X-M1 X-T1, X-T10 X100S, X100T X20, X30, X70, XQ1, XQ2 RAFData gen. 4, offset to WH pair = 8: - same conditions as for RAFData gen. 3, but also adds WRTS in bytes 4..7 - contains a table of 3+2*13 values; first 3 values look like WHW - H in WHW group has a different meaning if the shot is taken in crop 2 mode GFX 100, GFX 100S, GFX 50R, GFX 50S, GFX 50S II X-E2S, X-E3, X-H1, X-S10 X-T2, X-T3, X-T4, X-T20, X-T30 X-Pro2, X-Pro3 X100F, X100V RAFData gen. set to 4096: - RAFData length is exactly 4096 X-A3, X-A5, X-A7, X-A10, X-A20 X-T100, X-T200, XF10 */ int offsetWH_inRAFData=0; /* clang warns about not initialized value */ ushort b01 = sget2(RAFData_start); // bytes 0..1 ushort b23 = sget2(RAFData_start+2); // bytes 2..3 int is_WRTS = (sget4(RAFData_start + 4) == 0x53545257); // STRW if (b01 && !b23 && (b01<10000)) { imFuji.RAFDataGeneration = 1; offsetWH_inRAFData = 0; } else if ((b01>10000) && !b23) { imFuji.RAFDataGeneration = 2; imFuji.RAFDataVersion = b01; offsetWH_inRAFData = 4; } else if (!b01) { if (!is_WRTS) { imFuji.RAFDataGeneration = 3; offsetWH_inRAFData = 4; } else { imFuji.RAFDataGeneration = 4; offsetWH_inRAFData = 8; } imFuji.RAFDataVersion = b23; } // printf ("RAFDataVersion: 0x%04x, RAFDataGeneration: %d\n", // imFuji.RAFDataVersion, imFuji.RAFDataGeneration); return offsetWH_inRAFData; } void LibRaw::parseAdobeRAFMakernote() { uchar *PrivateMknBuf; unsigned posPrivateMknBuf=0; /* clang warns about not inited value */ unsigned PrivateMknLength; unsigned PrivateOrder; unsigned ifd_start, ifd_len; unsigned PrivateEntries, PrivateTagID; unsigned PrivateTagBytes; int FujiShotSelect; unsigned wb_section_offset = 0; int posWB; int c; #define CHECKSPACE_ABS3(s1, s2, s3) \ if (INT64(s1) + INT64(s2) + INT64(s3) > INT64(PrivateMknLength)) \ { \ free(PrivateMknBuf); \ return; \ } #define CHECKSPACE_ABS2(s1,s2) \ if (INT64(s1) + INT64(s2) > INT64(PrivateMknLength)) \ { \ free(PrivateMknBuf); \ return; \ } #define CHECKSPACE(s) \ if (INT64(posPrivateMknBuf) + INT64(s) > INT64(PrivateMknLength)) \ { \ free(PrivateMknBuf); \ return; \ } #define isWB(posWB) \ sget2(posWB) != 0 && sget2(posWB + 2) != 0 && sget2(posWB + 4) != 0 && \ sget2(posWB + 6) != 0 && sget2(posWB + 8) != 0 && \ sget2(posWB + 10) != 0 && sget2(posWB) != 0xff && \ sget2(posWB + 2) != 0xff && sget2(posWB + 4) != 0xff && \ sget2(posWB + 6) != 0xff && sget2(posWB + 8) != 0xff && \ sget2(posWB + 10) != 0xff && sget2(posWB) == sget2(posWB + 6) && \ sget2(posWB) < sget2(posWB + 2) && sget2(posWB) < sget2(posWB + 4) && \ sget2(posWB) < sget2(posWB + 8) && sget2(posWB) < sget2(posWB + 10) #define get_average_WB(wb_index) \ CHECKSPACE(8); \ FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = \ sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1)); \ if ((PrivateTagBytes == 16) && average_WBData) { \ CHECKSPACE(16); \ FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = \ (icWBC[wb_index][GRGB_2_RGBG(c)] + \ sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1)+8)) /2; \ } \ if (use_WBcorr_coeffs) { \ icWBC[wb_index][0] *= wbR_corr; \ icWBC[wb_index][2] *= wbB_corr; \ } ushort use_WBcorr_coeffs = 0; double wbR_corr = 1.0; double wbB_corr = 1.0; if (strstr(model, "S2Pro") || strstr(model, "S20Pro") || strstr(model, "F700") || strstr(model, "S5000") || strstr(model, "S7000") ) { use_WBcorr_coeffs = 1; wbR_corr = 10.0 / 17.0 / 0.652941; wbB_corr = 2.0 /3.0 / (3.0 / 4.0 + 1.0 / 300.0); } else if (strstr(model, "DBP") || strstr(model, "DX-2000")) { use_WBcorr_coeffs = 1; wbR_corr = 0.7632653061; wbB_corr = 0.8591549296; } FujiShotSelect = LIM(shot_select, 0, 1); int average_WBData = 1; order = 0x4d4d; PrivateMknLength = get4(); // At least 0x36 bytes because of memcpy(imFuji.RAFVersion, PrivateMknBuf + 0x32, 4); if ((PrivateMknLength >= 0x36) && (PrivateMknLength < 10240000) && (PrivateMknBuf = (uchar *)malloc(PrivateMknLength + 1024))) // 1024b for safety { fread(PrivateMknBuf, PrivateMknLength, 1, ifp); memcpy(imFuji.SerialSignature, PrivateMknBuf + 6, 0x0c); imFuji.SerialSignature[0x0c] = 0; memcpy(imFuji.SensorID, imFuji.SerialSignature + 0x06, 0x04); imFuji.SensorID[0x04] = 0; c = 11; while (isdigit(imFuji.SerialSignature[c]) && (c>0)) c--; ilm.CamID = unique_id = (unsigned long long)atoi(imFuji.SerialSignature+c+1); memcpy(model, PrivateMknBuf + 0x12, 0x20); model[0x20] = 0; memcpy(imFuji.RAFVersion, PrivateMknBuf + 0x32, 4); imFuji.RAFVersion[4] = 0; PrivateOrder = sget2(PrivateMknBuf); unsigned s, l; s = ifd_start = sget4(PrivateMknBuf +2)+6; CHECKSPACE(INT64(ifd_start)+4LL); l = ifd_len = sget4(PrivateMknBuf +ifd_start); CHECKSPACE_ABS3(ifd_start, ifd_len, 4); if (!sget4(PrivateMknBuf+ifd_start+ifd_len+4)) FujiShotSelect = 0; if ((FujiShotSelect == 1) && (PrivateMknLength > ifd_len*2)) { ifd_start += (ifd_len+4); CHECKSPACE_ABS2(ifd_start, 4); ifd_len = sget4(PrivateMknBuf +ifd_start); if ((ifd_start+ifd_len) > PrivateMknLength) { ifd_start = s; ifd_len = l; FujiShotSelect = 0; } } else FujiShotSelect = 0; CHECKSPACE_ABS3(ifd_start, 4, 4); PrivateEntries = sget4(PrivateMknBuf + ifd_start + 4); if ((PrivateEntries > 1000) || ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949))) { free(PrivateMknBuf); return; } posPrivateMknBuf = (ifd_start+8); /* * because Adobe DNG converter strips or misplaces 0xfnnn tags, * for now, Auto WB is missing for the following cameras: * - F550EXR / F600EXR / F770EXR / F800EXR / F900EXR * - HS10 / HS11 / HS20EXR / HS30EXR / HS33EXR / HS35EXR / HS50EXR * - S1 / SL1000 **/ while (PrivateEntries--) { order = 0x4d4d; CHECKSPACE(4); PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf); PrivateTagBytes = sget2(PrivateMknBuf + posPrivateMknBuf + 2); posPrivateMknBuf += 4; order = PrivateOrder; if (PrivateTagID == 0x2000) { get_average_WB(LIBRAW_WBI_Auto); } else if (PrivateTagID == 0x2100) { get_average_WB(LIBRAW_WBI_FineWeather); } else if (PrivateTagID == 0x2200) { get_average_WB(LIBRAW_WBI_Shade); } else if (PrivateTagID == 0x2300) { get_average_WB(LIBRAW_WBI_FL_D); } else if (PrivateTagID == 0x2301) { get_average_WB(LIBRAW_WBI_FL_N); } else if (PrivateTagID == 0x2302) { get_average_WB(LIBRAW_WBI_FL_W); } else if (PrivateTagID == 0x2310) { get_average_WB(LIBRAW_WBI_FL_WW); } else if (PrivateTagID == 0x2311) { get_average_WB(LIBRAW_WBI_FL_L); } else if (PrivateTagID == 0x2400) { get_average_WB(LIBRAW_WBI_Tungsten); } else if (PrivateTagID == 0x2410) { get_average_WB(LIBRAW_WBI_Flash); } else if (PrivateTagID == 0x2f00) { CHECKSPACE(4); int nWBs = MIN(sget4(PrivateMknBuf + posPrivateMknBuf), 6); posWB = posPrivateMknBuf + 4; for (int wb_ind = LIBRAW_WBI_Custom1; wb_ind < LIBRAW_WBI_Custom1+nWBs; wb_ind++) { CHECKSPACE_ABS2(posWB, 8); FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = sget2(PrivateMknBuf + posWB + (c << 1)); if ((PrivateTagBytes >= unsigned(4+16*nWBs)) && average_WBData) { posWB += 8; CHECKSPACE_ABS2(posWB, 8); FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = (icWBC[wb_ind][GRGB_2_RGBG(c)] + sget2(PrivateMknBuf + posWB + (c << 1))) /2; } if (use_WBcorr_coeffs) { icWBC[wb_ind][0] *= wbR_corr; icWBC[wb_ind][2] *= wbB_corr; } posWB += 8; } } else if (PrivateTagID == 0x2ff0) { get_average_WB(LIBRAW_WBI_AsShot); FORC4 cam_mul[c] = icWBC[LIBRAW_WBI_AsShot][c]; } else if ((PrivateTagID == 0x4000) && ((PrivateTagBytes == 8) || (PrivateTagBytes == 16))) { imFuji.BlackLevel[0] = PrivateTagBytes / 2; CHECKSPACE(10); FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c)+1] = sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1)); if (imFuji.BlackLevel[0] == 8) { CHECKSPACE(18); FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c) + 5] = sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1) + 8); } } else if (PrivateTagID == 0x9650) { CHECKSPACE(4); short a = (short)sget2(PrivateMknBuf + posPrivateMknBuf); float b = fMAX(1.0f, sget2(PrivateMknBuf + posPrivateMknBuf + 2)); imFuji.ExpoMidPointShift = a / b; imCommon.ExposureCalibrationShift += imFuji.ExpoMidPointShift; } else if ((PrivateTagID == 0xc000) && (PrivateTagBytes > 3) && (PrivateTagBytes < 10240000)) { order = 0x4949; if (PrivateTagBytes != 4096) // not one of Fuji X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10 { int is34 = 0; CHECKSPACE(8); guess_RAFDataGeneration (PrivateMknBuf + posPrivateMknBuf); // printf ("RAFDataVersion: 0x%04x, RAFDataGeneration: %d\n", // imFuji.RAFDataVersion, imFuji.RAFDataGeneration); for (posWB = 0; posWB < (int)PrivateTagBytes - 16; posWB++) { CHECKSPACE_ABS2(posWB, 12); if ((!memcmp(PrivateMknBuf + posWB, "TSNERDTS", 8) && (sget2(PrivateMknBuf + posWB + 10) > 125))) { posWB += 10; icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] = sget2(PrivateMknBuf + posWB); icWBC[LIBRAW_WBI_Auto][0] = sget2(PrivateMknBuf + posWB + 2); icWBC[LIBRAW_WBI_Auto][2] = sget2(PrivateMknBuf + posWB + 4); break; } } if ((imFuji.RAFDataVersion == 0x0260) || // X-Pro3, GFX 100S (imFuji.RAFDataVersion == 0x0261) || // X100V, GFX 50S II (imFuji.RAFDataVersion == 0x0262) || // X-T4 (imFuji.RAFDataVersion == 0x0264) || // X-S10 (imFuji.RAFDataVersion == 0x0265) || // X-E4 (imFuji.RAFDataVersion == 0x0266) || // X-T30 II !strcmp(model, "X-Pro3") || !strcmp(model, "GFX 100S") || !strcmp(model, "GFX100S") || !strcmp(model, "GFX 50S II") || !strcmp(model, "GFX50S II") || !strcmp(model, "X100V") || !strcmp(model, "X-T4") || !strcmp(model, "X-E4") || !strcmp(model, "X-T30 II") || !strcmp(model, "X-S10")) is34 = 1; if (imFuji.RAFDataVersion == 0x4500) // X-E1, RAFData gen. 3 { wb_section_offset = 0x13ac; } else if (imFuji.RAFDataVersion == 0x0146 || // X20 imFuji.RAFDataVersion == 0x0149 || // X100S imFuji.RAFDataVersion == 0x0249) // X100S { wb_section_offset = 0x1410; } else if (imFuji.RAFDataVersion == 0x014d || // X-M1 imFuji.RAFDataVersion == 0x014e) // X-A1, X-A2 { wb_section_offset = 0x1474; } else if (imFuji.RAFDataVersion == 0x014f || // X-E2 imFuji.RAFDataVersion == 0x024f || // X-E2 imFuji.RAFDataVersion == 0x025d || // X-H1 imFuji.RAFDataVersion == 0x035d) // X-H1 { wb_section_offset = 0x1480; } else if (imFuji.RAFDataVersion == 0x0150) // XQ1, XQ2 { wb_section_offset = 0x1414; } else if (imFuji.RAFDataVersion == 0x0151 || // X-T1 w/diff. fws imFuji.RAFDataVersion == 0x0251 || imFuji.RAFDataVersion == 0x0351 || imFuji.RAFDataVersion == 0x0451 || imFuji.RAFDataVersion == 0x0551) { wb_section_offset = 0x14b0; } else if (imFuji.RAFDataVersion == 0x0152 || // X30 imFuji.RAFDataVersion == 0x0153) // X100T { wb_section_offset = 0x1444; } else if (imFuji.RAFDataVersion == 0x0154) // X-T10 { wb_section_offset = 0x1824; } else if (imFuji.RAFDataVersion == 0x0155) // X70 { wb_section_offset = 0x17b4; } else if (imFuji.RAFDataVersion == 0x0255 || // X-Pro2 imFuji.RAFDataVersion == 0x0455) { wb_section_offset = 0x135c; } else if (imFuji.RAFDataVersion == 0x0258 || // X-T2 imFuji.RAFDataVersion == 0x025b) // X-T20 { wb_section_offset = 0x13dc; } else if (imFuji.RAFDataVersion == 0x0259) // X100F { wb_section_offset = 0x1370; } else if (imFuji.RAFDataVersion == 0x025a || // GFX 50S imFuji.RAFDataVersion == 0x045a) { wb_section_offset = 0x1424; } else if (imFuji.RAFDataVersion == 0x025c) // X-E3 { wb_section_offset = 0x141c; } else if (imFuji.RAFDataVersion == 0x025e) // X-T3 { wb_section_offset = 0x2014; } else if (imFuji.RAFDataVersion == 0x025f) // X-T30, GFX 50R, GFX 100 (? RAFDataVersion 0x045f) { if (!strcmp(model, "X-T30")) { CHECKSPACE(0x20b8 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20b8)) wb_section_offset = 0x20b8; else { CHECKSPACE(0x20c8 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20c8)) wb_section_offset = 0x20c8; } } else if (!strcmp(model, "GFX 50R")) wb_section_offset = 0x1424; else if (!strcmp(model, "GFX 100")) wb_section_offset = 0x20e4; } else if (imFuji.RAFDataVersion == 0x0260) // X-Pro3, GFX 100S { if (!strcmp(model, "X-Pro3")) wb_section_offset = 0x20e8; else if (!strcmp(model, "GFX 100S") || !strcmp(model, "GFX100S")) wb_section_offset = 0x2108; } else if (imFuji.RAFDataVersion == 0x0261) // X100V, GFX 50S II { if (!strcmp(model, "X100V")) wb_section_offset = 0x2078; else if (!strcmp(model, "GFX 50S II") || !strcmp(model, "GFX50S II")) wb_section_offset = 0x214c; } else if (imFuji.RAFDataVersion == 0x0262) // X-T4 { wb_section_offset = 0x21c8; } else if (imFuji.RAFDataVersion == 0x0264) // X-S10 { wb_section_offset = 0x21de; } else if ((imFuji.RAFDataVersion == 0x0265) || // X-E4 (imFuji.RAFDataVersion == 0x0266)) // X-T30 II { wb_section_offset = 0x21cc; } else if (imFuji.RAFDataVersion == 0x0355) // X-E2S { wb_section_offset = 0x1840; } /* try for unknown RAF Data versions */ else if (!strcmp(model, "X-Pro2")) { CHECKSPACE(0x135c + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x135c)) wb_section_offset = 0x135c; } else if (!strcmp(model, "X100F")) { CHECKSPACE(0x1370 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1370)) wb_section_offset = 0x1370; } else if (!strcmp(model, "X-E1")) { CHECKSPACE(0x13ac + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13ac)) wb_section_offset = 0x13ac; } else if (!strcmp(model, "X-T2") || !strcmp(model, "X-T20")) { CHECKSPACE(0x13dc + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13dc)) wb_section_offset = 0x13dc; } else if (!strcmp(model, "X20") || !strcmp(model, "X100S")) { CHECKSPACE(0x1410 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1410)) wb_section_offset = 0x1410; } else if (!strcmp(model, "XQ1") || !strcmp(model, "XQ2")) { CHECKSPACE(0x1414+ 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1414)) wb_section_offset = 0x1414; } else if (!strcmp(model, "X-E3")) { CHECKSPACE(0x141c + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x141c)) wb_section_offset = 0x141c; } else if (!strcmp(model, "GFX 50S") || !strcmp(model, "GFX 50R")) { CHECKSPACE(0x1424 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1424)) wb_section_offset = 0x1424; } else if (!strcmp(model, "GFX 50S II") || !strcmp(model, "GFX50S II")) { CHECKSPACE(0x214c + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x214c)) wb_section_offset = 0x214c; } else if (!strcmp(model, "X30") || !strcmp(model, "X100T")) { CHECKSPACE(0x1444 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1444)) wb_section_offset = 0x1444; } else if (!strcmp(model, "X-M1") || !strcmp(model, "X-A1") || !strcmp(model, "X-A2")) { CHECKSPACE(0x1474 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1474)) wb_section_offset = 0x1474; } else if (!strcmp(model, "X-E2") || !strcmp(model, "X-H1")) { CHECKSPACE(0x1480 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1480)) wb_section_offset = 0x1480; } else if (!strcmp(model, "X-T1")) { CHECKSPACE(0x14b0 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x14b0)) wb_section_offset = 0x14b0; } else if (!strcmp(model, "X70")) { CHECKSPACE(0x17b4 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x17b4)) wb_section_offset = 0x17b4; } else if (!strcmp(model, "X-T10")) { CHECKSPACE(0x1824 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1824)) wb_section_offset = 0x1824; } else if (!strcmp(model, "X-E2S")) { CHECKSPACE(0x1840 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1840)) wb_section_offset = 0x1840; } else if (!strcmp(model, "X-T3")) { CHECKSPACE(0x2014 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x2014)) wb_section_offset = 0x2014; } else if (!strcmp(model, "X100V")) { CHECKSPACE(0x2078 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x2078)) wb_section_offset = 0x2078; } else if (!strcmp(model, "X-T30")) { CHECKSPACE(0x20b8 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20b8)) wb_section_offset = 0x20b8; else { CHECKSPACE(0x20c8 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20c8)) wb_section_offset = 0x20c8; } } else if (!strcmp(model, "GFX 100")) { CHECKSPACE(0x20e4 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20e4)) wb_section_offset = 0x20e4; } else if (!strcmp(model, "X-Pro3")) { CHECKSPACE(0x20e8 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20e8)) wb_section_offset = 0x20e8; } else if (!strcmp(model, "GFX100S") || !strcmp(model, "GFX 100S")) { CHECKSPACE(0x2108 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x2108)) wb_section_offset = 0x2108; } else if (!strcmp(model, "X-T4")) { CHECKSPACE(0x21c8 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x21c8)) wb_section_offset = 0x21c8; } else if ((!strcmp(model, "X-E4")) || (!strcmp(model, "X-T30 II"))) { CHECKSPACE(0x21cc + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x21cc)) wb_section_offset = 0x21cc; } else if (!strcmp(model, "X-S10")) { CHECKSPACE(0x21de + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x21de)) wb_section_offset = 0x21de; } /* no RAF Data version for the models below */ else if (!strcmp(model, "FinePix X100")) // X100 0 0x19f0 0x19e8 { if (!strcmp(imFuji.RAFVersion, "0069")) wb_section_offset = 0x19e8; else if (!strcmp(imFuji.RAFVersion, "0100") || !strcmp(imFuji.RAFVersion, "0110")) wb_section_offset = 0x19f0; else { CHECKSPACE(0x19e8 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x19e8)) wb_section_offset = 0x19e8; else { CHECKSPACE(0x19f0 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x19f0)) wb_section_offset = 0x19f0; } } } else if (!strcmp(model, "X-Pro1")) // X-Pro1 0 0x13a4 { if (!strcmp(imFuji.RAFVersion, "0100") || !strcmp(imFuji.RAFVersion, "0101") || !strcmp(imFuji.RAFVersion, "0204")) wb_section_offset = 0x13a4; else { CHECKSPACE(0x13a4 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13a4)) wb_section_offset = 0x13a4; } } else if (!strcmp(model, "XF1")) // XF1 0 0x138c { if (!strcmp(imFuji.RAFVersion, "0100")) wb_section_offset = 0x138c; else { CHECKSPACE(0x138c + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x138c)) wb_section_offset = 0x138c; } } else if (!strcmp(model, "X-S1")) // X-S1 0 0x1284 { if (!strcmp(imFuji.RAFVersion, "0100")) wb_section_offset = 0x1284; else { CHECKSPACE(0x1284 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1284)) wb_section_offset = 0x1284; } } else if (!strcmp(model, "X10")) // X10 0 0x1280 0x12d4 { if (!strcmp(imFuji.RAFVersion, "0100") || !strcmp(imFuji.RAFVersion, "0102")) wb_section_offset = 0x1280; else if (!strcmp(imFuji.RAFVersion, "0103")) wb_section_offset = 0x12d4; else { CHECKSPACE(0x1280 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1280)) wb_section_offset = 0x1280; else { CHECKSPACE(0x12d4 + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x12d4)) wb_section_offset = 0x12d4; } } } else if (!strcmp(model, "XF1")) // XF1 0 0x138c { if (!strcmp(imFuji.RAFVersion, "0100")) wb_section_offset = 0x138c; else { CHECKSPACE(0x138c + 12); if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x138c)) wb_section_offset = 0x138c; } } if (wb_section_offset) { CHECKSPACE(INT64(wb_section_offset) + 12LL); } if (wb_section_offset && isWB(PrivateMknBuf + posPrivateMknBuf + wb_section_offset)) { if (!imFuji.RAFDataVersion) { posWB = posPrivateMknBuf + wb_section_offset - 6; CHECKSPACE_ABS2(posWB, 6); icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] = sget2(PrivateMknBuf + posWB); icWBC[LIBRAW_WBI_Auto][0] = sget2(PrivateMknBuf + posWB + 2); icWBC[LIBRAW_WBI_Auto][2] = sget2(PrivateMknBuf + posWB + 4); } posWB = posPrivateMknBuf + wb_section_offset; for (int wb_ind = 0; wb_ind < (int)Fuji_wb_list1.size(); posWB += 6, wb_ind++) { CHECKSPACE_ABS2(posWB, 6); icWBC[Fuji_wb_list1[wb_ind]][1] = icWBC[Fuji_wb_list1[wb_ind]][3] = sget2(PrivateMknBuf + posWB); icWBC[Fuji_wb_list1[wb_ind]][0] = sget2(PrivateMknBuf + posWB + 2); icWBC[Fuji_wb_list1[wb_ind]][2] = sget2(PrivateMknBuf + posWB + 4); } int found = 0; if (is34) posWB += 0x30; posWB += 0xc0; CHECKSPACE_ABS2(posWB, 2); ushort Gval = sget2(PrivateMknBuf + posWB); for (int posEndCCTsection = posWB; posEndCCTsection < (posWB + 30); posEndCCTsection += 6) { CHECKSPACE_ABS2(posEndCCTsection, 2); if (sget2(PrivateMknBuf + posEndCCTsection) != Gval) { if (is34) wb_section_offset = posEndCCTsection - 34*3*2; // 34 records, 3 2-byte values in a record else wb_section_offset = posEndCCTsection - 31*3*2; // 31 records, 3 2-byte values in a record found = 1; break; } } if (found) { for (int iCCT = 0; iCCT < 31; iCCT++) { CHECKSPACE_ABS2(wb_section_offset, iCCT*6+6); icWBCCTC[iCCT][0] = FujiCCT_K[iCCT]; icWBCCTC[iCCT][1] = sget2(PrivateMknBuf + wb_section_offset + iCCT * 6 + 2); icWBCCTC[iCCT][2] = icWBCCTC[iCCT][4] = sget2(PrivateMknBuf + wb_section_offset + iCCT * 6); icWBCCTC[iCCT][3] = sget2(PrivateMknBuf + wb_section_offset + iCCT * 6 + 4); } } } } else // process 4K raf data { int wb[4]; int nWB, tWB, pWB; int iCCT = 0; imFuji.RAFDataGeneration = 4096; // X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10 posWB = posPrivateMknBuf + 0x200; for (int wb_ind = 0; wb_ind < 42; wb_ind++) { CHECKSPACE_ABS2(posWB, 24); nWB = sget4(PrivateMknBuf + posWB); posWB += 4; tWB = sget4(PrivateMknBuf + posWB); posWB += 4; wb[0] = sget4(PrivateMknBuf + posWB) << 1; posWB += 4; wb[1] = sget4(PrivateMknBuf + posWB); posWB += 4; wb[3] = sget4(PrivateMknBuf + posWB); posWB += 4; wb[2] = sget4(PrivateMknBuf + posWB) << 1; posWB += 4; if (tWB && (iCCT < 64)) { icWBCCTC[iCCT][0] = tWB; FORC4 icWBCCTC[iCCT][c + 1] = wb[c]; iCCT++; } if (nWB != 0x46) { for (pWB = 1; pWB < (int)Fuji_wb_list2.size(); pWB += 2) { if (Fuji_wb_list2[pWB] == nWB) { FORC4 icWBC[Fuji_wb_list2[pWB - 1]][c] = wb[c]; break; } } } } } } posPrivateMknBuf += PrivateTagBytes; } free(PrivateMknBuf); } #undef get_average_WB #undef CHECKSPACE #undef CHECKSPACE_ABS2 #undef CHECKSPACE_ABS3 } void LibRaw::parseFujiMakernotes(unsigned tag, unsigned type, unsigned len, unsigned /*dng_writer*/) { if (tag == 0x0010) { char FujiSerial[sizeof(imgdata.shootinginfo.InternalBodySerial)]; char *words[4] = { 0,0,0,0 }; char yy[2], mm[3], dd[3], ystr[16], ynum[16]; int year, nwords, ynum_len; unsigned c; memset(FujiSerial, 0, sizeof(imgdata.shootinginfo.InternalBodySerial)); ifp->read(FujiSerial, MIN(len,sizeof(FujiSerial)), 1); nwords = getwords(FujiSerial, words, 4, sizeof(imgdata.shootinginfo.InternalBodySerial)); for (int i = 0; i < nwords; i++) { if (!words[i]) break; // probably damaged input mm[2] = dd[2] = 0; if (strnlen(words[i], sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) < 18) { if (i == 0) { strncpy(imgdata.shootinginfo.InternalBodySerial, words[0], sizeof(imgdata.shootinginfo.InternalBodySerial) - 1); } else { char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)]; snprintf(tbuf, sizeof(tbuf)-1, "%s %s", imgdata.shootinginfo.InternalBodySerial, words[i]); strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf, sizeof(imgdata.shootinginfo.InternalBodySerial) - 1); } } else { strncpy( dd, words[i] + strnlen(words[i], sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - 14, 2); strncpy( mm, words[i] + strnlen(words[i], sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - 16, 2); strncpy( yy, words[i] + strnlen(words[i], sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - 18, 2); year = (yy[0] - '0') * 10 + (yy[1] - '0'); if (year < 70) year += 2000; else year += 1900; ynum_len = MIN( int(sizeof(ynum) - 1), (int)strnlen(words[i], sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - 18); strncpy(ynum, words[i], ynum_len); ynum[ynum_len] = 0; for (int j = 0; ynum[j] && ynum[j + 1] && sscanf(ynum + j, "%2x", &c); j += 2) ystr[j / 2] = c; ynum_len /= 2; ystr[ynum_len + 1] = 0; strcpy(model2, ystr); if (i == 0) { char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)]; if (nwords == 1) { snprintf( tbuf, sizeof(tbuf), "%s %d:%s:%s %s", ystr, year, mm, dd, words[0] + strnlen(words[0], sizeof(imgdata.shootinginfo.InternalBodySerial)-1)-12); } else { snprintf( tbuf, sizeof(tbuf), "%s %d:%s:%s %s", ystr, year, mm, dd, words[0] + strnlen(words[0], sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - 12); } strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf, sizeof(imgdata.shootinginfo.InternalBodySerial) - 1); } else { char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)]; snprintf( tbuf, sizeof(tbuf), "%s %s %d:%s:%s %s", imgdata.shootinginfo.InternalBodySerial, ystr, year, mm, dd, words[i] + strnlen(words[i], sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - 12); strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf, sizeof(imgdata.shootinginfo.InternalBodySerial) - 1); } } } } else switch (tag) { case 0x1002: imFuji.WB_Preset = get2(); break; case 0x1011: imCommon.FlashEC = getreal(type); break; case 0x1020: imFuji.Macro = get2(); break; case 0x1021: imFuji.FocusMode = imgdata.shootinginfo.FocusMode = get2(); break; case 0x1022: imFuji.AFMode = get2(); break; case 0x1023: imFuji.FocusPixel[0] = get2(); imFuji.FocusPixel[1] = get2(); break; case 0x102b: imFuji.PrioritySettings = get2(); break; case 0x102d: imFuji.FocusSettings = get4(); break; case 0x102e: imFuji.AF_C_Settings = get4(); break; case 0x1034: imFuji.ExrMode = get2(); break; case 0x104d: FujiCropMode = get2(); // odd: one of raw dimensions here can be lost break; case 0x1050: imFuji.ShutterType = get2(); break; case 0x1100: imFuji.AutoBracketing = get2(); // AutoBracketing = 6 for pixel shift mode break; case 0x1101: imFuji.SequenceNumber = get2(); break; case 0x1103: imgdata.shootinginfo.DriveMode = get2(); imFuji.DriveMode = imgdata.shootinginfo.DriveMode & 0xff; break; case 0x1105: imFuji.SeriesLength = get2(); break; case 0x1106: imFuji.PixelShiftOffset[0] = getreal(type); imFuji.PixelShiftOffset[1] = getreal(type); break; case 0x1301: imFuji.FocusWarning = get2(); break; case 0x1400: imFuji.DynamicRange = get2(); break; case 0x1401: imFuji.FilmMode = get2(); break; case 0x1402: imFuji.DynamicRangeSetting = get2(); break; case 0x1403: imFuji.DevelopmentDynamicRange = get2(); break; case 0x1404: ilm.MinFocal = getreal(type); break; case 0x1405: ilm.MaxFocal = getreal(type); break; case 0x1406: ilm.MaxAp4MinFocal = getreal(type); break; case 0x1407: ilm.MaxAp4MaxFocal = getreal(type); break; case 0x140b: imFuji.AutoDynamicRange = get2(); break; case 0x1422: imFuji.ImageStabilization[0] = get2(); imFuji.ImageStabilization[1] = get2(); imFuji.ImageStabilization[2] = get2(); imgdata.shootinginfo.ImageStabilization = (imFuji.ImageStabilization[0] << 9) + imFuji.ImageStabilization[1]; break; case 0x1438: imFuji.ImageCount = get2(); break; case 0x1431: imFuji.Rating = get4(); break; case 0x1443: imFuji.DRangePriority = get2(); break; case 0x1444: imFuji.DRangePriorityAuto = get2(); break; case 0x1445: imFuji.DRangePriorityFixed = get2(); break; } return; } void LibRaw::parse_fuji_thumbnail(int offset) { uchar xmpmarker[] = "http://ns.adobe.com/xap/1.0/"; uchar buf[sizeof(xmpmarker)+1]; int xmpsz = sizeof(xmpmarker); // we do not INT64 pos = ftell(ifp); fseek(ifp, offset, SEEK_SET); ushort s_order = order; order = 0x4a4a; // JPEG is always in MM order if (get2() == 0xFFD8) { while (1) { ushort tag = get2(); if (tag != 0xFFE1 && tag != 0xFFE2) // allow APP1/APP2 only break; INT64 tpos = ftell(ifp); int len = get2(); if (len > xmpsz + 2) { if ((fread(buf, 1, xmpsz, ifp) == xmpsz) && !memcmp(buf, xmpmarker, xmpsz)) // got it { xmplen = len - xmpsz - 2; xmpdata = (char*) calloc(xmplen+1,1); unsigned br = fread(xmpdata, 1, xmplen, ifp); xmpdata[br] = 0; break; } } fseek(ifp, tpos + len, SEEK_SET); } } order = s_order; fseek(ifp, pos, SEEK_SET); } void LibRaw::parse_fuji(int offset) { unsigned entries, tag, len, save, c; #define get_average_WB(wb_index) \ FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = get2(); \ if ((len == 16) && average_WBData) { \ FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = \ (icWBC[wb_index][GRGB_2_RGBG(c)] + get2())/2; \ } \ if (use_WBcorr_coeffs) { \ icWBC[wb_index][0] *= wbR_corr; \ icWBC[wb_index][2] *= wbB_corr; \ } ushort raw_inset_present = 0; ushort use_WBcorr_coeffs = 0; double wbR_corr = 1.0; double wbB_corr = 1.0; ilm.CamID = unique_id; int average_WBData = 1; fseek(ifp, offset, SEEK_SET); entries = get4(); if (entries > 255) return; imgdata.process_warnings |= LIBRAW_WARN_PARSEFUJI_PROCESSED; if (strstr(model, "S2Pro") || strstr(model, "S20Pro") || strstr(model, "F700") || strstr(model, "S5000") || strstr(model, "S7000") ) { use_WBcorr_coeffs = 1; wbR_corr = 10.0 / 17.0 / 0.652941; wbB_corr = 2.0 /3.0 / (3.0 / 4.0 + 1.0 / 300.0); } else if (strstr(model, "DBP") || strstr(model, "DX-2000")) { use_WBcorr_coeffs = 1; wbR_corr = 0.7632653061; wbB_corr = 0.8591549296; } while (entries--) { tag = get2(); len = get2(); save = ftell(ifp); if (tag == 0x0100) // RawImageFullSize { raw_height = get2(); raw_width = get2(); raw_inset_present = 1; } else if ((tag == 0x0110) && raw_inset_present) // RawImageCropTopLeft { imgdata.sizes.raw_inset_crops[0].ctop = get2(); imgdata.sizes.raw_inset_crops[0].cleft = get2(); } else if ((tag == 0x0111) && raw_inset_present) // RawImageCroppedSize { imgdata.sizes.raw_inset_crops[0].cheight = get2(); imgdata.sizes.raw_inset_crops[0].cwidth = get2(); } else if ((tag == 0x0115) && raw_inset_present) // RawImageAspectRatio { int a = get2(); int b = get2(); if (a * b == 6) imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; else if (a * b == 12) imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3; else if (a * b == 144) imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9; else if (a * b == 1) imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; } else if (tag == 0x0121) // RawImageSize { height = get2(); if ((width = get2()) == 4284) width += 3; } else if (tag == 0x0130) // FujiLayout, { fuji_layout = fgetc(ifp) >> 7; fuji_width = !(fgetc(ifp) & 8); } else if (tag == 0x0131) // XTransLayout { filters = 9; char *xtrans_abs_alias = &xtrans_abs[0][0]; FORC(36) { int q = fgetc(ifp); xtrans_abs_alias[35 - c] = MAX(0, MIN(q, 2)); /* & 3;*/ } } else if (tag == 0x2ff0) // WB_GRGBLevels { get_average_WB(LIBRAW_WBI_AsShot); FORC4 cam_mul[c] = icWBC[LIBRAW_WBI_AsShot][c]; } else if ((tag == 0x4000) && ((len == 8) || (len == 16))) { imFuji.BlackLevel[0] = len / 2; FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c)+1] = get2(); if (imFuji.BlackLevel[0] == 8) FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c)+5] = get2(); if (imFuji.BlackLevel[0] == 4) FORC4 cblack[c] = imFuji.BlackLevel[c+1]; else if (imFuji.BlackLevel[0] == 8) FORC4 cblack[c] = (imFuji.BlackLevel[c+1]+imFuji.BlackLevel[c+5]) /2; } else if (tag == 0x9200) // RelativeExposure { int s1 = get2(); int s2 = get2(); if ((s1 == s2) || !s1) imFuji.BrightnessCompensation = 0.0f; else if ((s1*4) == s2) imFuji.BrightnessCompensation = 2.0f; else if ((s1*16) == s2) imFuji.BrightnessCompensation = 4.0f; else imFuji.BrightnessCompensation = log(double(s2)/double(s1))/log(2.0); } else if (tag == 0x9650) // RawExposureBias { short a = (short)get2(); float b = fMAX(1.0f, get2()); imFuji.ExpoMidPointShift = a / b; imCommon.ExposureCalibrationShift += imFuji.ExpoMidPointShift; } else if (tag == 0x2000) // WB_GRGBLevelsAuto { get_average_WB(LIBRAW_WBI_Auto); } else if (tag == 0x2100) // WB_GRGBLevelsDaylight { get_average_WB(LIBRAW_WBI_FineWeather); } else if (tag == 0x2200) // WB_GRGBLevelsCloudy { get_average_WB(LIBRAW_WBI_Shade); } else if (tag == 0x2300) // WB_GRGBLevelsDaylightFluor { get_average_WB(LIBRAW_WBI_FL_D); } else if (tag == 0x2301) // WB_GRGBLevelsDayWhiteFluor { get_average_WB(LIBRAW_WBI_FL_N); } else if (tag == 0x2302) // WB_GRGBLevelsWhiteFluorescent { get_average_WB(LIBRAW_WBI_FL_W); } else if (tag == 0x2310) // WB_GRGBLevelsWarmWhiteFluor { get_average_WB(LIBRAW_WBI_FL_WW); } else if (tag == 0x2311) // WB_GRGBLevelsLivingRoomWarmWhiteFluor { get_average_WB(LIBRAW_WBI_FL_L); } else if (tag == 0x2400) // WB_GRGBLevelsTungsten { get_average_WB(LIBRAW_WBI_Tungsten); } else if (tag == 0x2410) { get_average_WB(LIBRAW_WBI_Flash); } else if (tag == 0x2f00) // WB_GRGBLevels { int nWBs = get4(); nWBs = MIN(nWBs, 6); for (int wb_ind = LIBRAW_WBI_Custom1; wb_ind < LIBRAW_WBI_Custom1+nWBs; wb_ind++) { FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = get2(); if ((len >= unsigned(4+16*nWBs)) && average_WBData) { FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = (icWBC[wb_ind][GRGB_2_RGBG(c)] +get2()) /2; } if (use_WBcorr_coeffs) { icWBC[LIBRAW_WBI_Custom1 + wb_ind][0] *= wbR_corr; icWBC[LIBRAW_WBI_Custom1 + wb_ind][2] *= wbB_corr; } } } else if (tag == 0xc000) // RAFData { int offsetWH_inRAFData; unsigned save_order = order; order = 0x4949; if (len > 20000) { uchar RAFDataHeader[16]; libraw_internal_data.unpacker_data.posRAFData = save; libraw_internal_data.unpacker_data.lenRAFData = (len >> 1); fread(RAFDataHeader, sizeof RAFDataHeader, 1, ifp); offsetWH_inRAFData = guess_RAFDataGeneration(RAFDataHeader); fseek(ifp, offsetWH_inRAFData-int(sizeof RAFDataHeader), SEEK_CUR); for (int i=0; i< (int)((sizeof imFuji.RAFData_ImageSizeTable) / (sizeof imFuji.RAFData_ImageSizeTable[0])); i++) { imFuji.RAFData_ImageSizeTable[i] = get4(); } // if ((width > raw_width) // || (raw_inset_present && (width < imgdata.sizes.raw_inset_crops[0].cwidth)) // ) // width = raw_width; // if ((height > raw_height) // || (raw_inset_present && (height < imgdata.sizes.raw_inset_crops[0].cheight)) // ) // height = raw_height; // } else if (len == 4096) // X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10 { // Ill.A aligned to CCT 2850 int wb[4]; int nWB, tWB; int iCCT = 0; imFuji.RAFDataGeneration = 4096; fseek(ifp, save + 0x200, SEEK_SET); for (int wb_ind = 0; wb_ind < 42; wb_ind++) { nWB = get4(); tWB = get4(); wb[0] = get4() << 1; wb[1] = get4(); wb[3] = get4(); wb[2] = get4() << 1; if (tWB && (iCCT < 64)) { icWBCCTC[iCCT][0] = tWB; FORC4 icWBCCTC[iCCT][c + 1] = wb[c]; iCCT++; } if (nWB != 70) { for (int pWB = 1; pWB < (int)Fuji_wb_list2.size(); pWB += 2) { if (Fuji_wb_list2[pWB] == nWB) { FORC4 icWBC[Fuji_wb_list2[pWB - 1]][c] = wb[c]; break; } } } } } order = save_order; } fseek(ifp, save + len, SEEK_SET); } if (!imFuji.RAFDataGeneration) { height <<= fuji_layout; width >>= fuji_layout; } #undef get_average_WB } LibRaw-0.21.4/src/metadata/hasselblad_model.cpp000066400000000000000000000473021477673233700213440ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" #include "../../internal/libraw_cameraids.h" static const struct { const int idx; const char *FormatName; } HassyRawFormat[] = { { LIBRAW_HF_Unknown, "Unknown"}, { LIBRAW_HF_3FR, "-3FR"}, { LIBRAW_HF_FFF, "-FFF"}, { LIBRAW_HF_Imacon, "Imacon"}, { LIBRAW_HF_HasselbladDNG, "hDNG"}, { LIBRAW_HF_AdobeDNG, "aDNG"}, { LIBRAW_HF_AdobeDNG_fromPhocusDNG, "a(hDNG)"}, }; const char* LibRaw::HassyRawFormat_idx2HR(unsigned idx) // HR means "human-readable" { for (int i = 0; i < int(sizeof HassyRawFormat / sizeof *HassyRawFormat); i++) if((unsigned)HassyRawFormat[i].idx == idx) return HassyRawFormat[i].FormatName; return 0; } void LibRaw::process_Hassy_Lens (int LensMount) { // long long unsigned id = // mount*100000000ULL + series*10000000ULL + // focal1*10000ULL + focal2*10 + version; char *ps; int c; char *q = strchr(imgdata.lens.Lens, ' '); if(!q) return ; c = atoi(q+1); if (!c) return; if (LensMount == LIBRAW_MOUNT_Hasselblad_H) { if (imgdata.lens.Lens[2] == ' ') // HC lens ilm.LensID = LensMount*100000000ULL + 10000000ULL; else // HCD lens ilm.LensID = LensMount*100000000ULL + 20000000ULL; ilm.LensFormat = LIBRAW_FORMAT_645; } else if (LensMount == LIBRAW_MOUNT_Hasselblad_XCD) { ilm.LensFormat = LIBRAW_FORMAT_CROP645; ilm.LensID = LensMount*100000000ULL; } else return; ilm.LensMount = LensMount; ilm.LensID += c*10000ULL; if ((ps=strchr(imgdata.lens.Lens, '-'))) { ilm.FocalType = LIBRAW_FT_ZOOM_LENS; ilm.LensID += atoi(ps+1)*10ULL; } else { ilm.FocalType = LIBRAW_FT_PRIME_LENS; ilm.LensID += c*10ULL; } if (strstr(imgdata.lens.Lens, "III")) ilm.LensID += 3ULL; else if (strstr(imgdata.lens.Lens, "II")) ilm.LensID += 2ULL; } void LibRaw::parseHassyModel() { static const char *Hasselblad_Ctrl[] = { // manually selectable options only "ELD", "ELX", "Winder CW", "CW", "Pinhole", "Flash Sync", "SWC", "200 (Mod)", "200", "500 Mech.", "500", "H Series", "H-Series", "H1", "H2", "Black Box", "LENSCONTROL S", "LENSCTRL S", "Generic", }; static const char *Hasselblad_SensorEnclosures[] = { "CFH", "CFV", "CFV", "CFII", "CF", "Ixpress", }; char tmp_model[64]; const char *ps; char *eos; int c; int nPix = raw_width*raw_height; int add_MP_toName = 1; int norm_model_isSet = 0; if (model[0] == ' ') memmove(model, model+1, MIN(sizeof(model)-1,strlen(model))); imHassy.HostBody[0] = 0; if ((ps = strrchr(model, '/'))) strcpy(imHassy.HostBody, ps+1); else if ((ps = strrchr(imgdata.color.LocalizedCameraModel, '/'))) strcpy(imHassy.HostBody, ps+1); else if ((ps = strrchr(imgdata.color.UniqueCameraModel, '/'))) strcpy(imHassy.HostBody, ps+1); else if ((ps = strrchr(imHassy.SensorUnitConnector, '/'))) strcpy(imHassy.HostBody, ps+1); if (imHassy.HostBody[0]) { if ((eos = strrchr(imHassy.HostBody, '-'))) *eos = 0; } if (!imHassy.format) { if (dng_version) { if (!strncmp(software, "Adobe", 5)) { if (!imgdata.color.OriginalRawFileName[0] || !imgdata.color.LocalizedCameraModel[0] || !strcasestr(imgdata.color.UniqueCameraModel, "coated")) imHassy.format = LIBRAW_HF_AdobeDNG_fromPhocusDNG; else imHassy.format = LIBRAW_HF_AdobeDNG; } else imHassy.format = LIBRAW_HF_HasselbladDNG; } else if ((imHassy.nIFD_CM[0] != -1) && (imHassy.nIFD_CM[1] == -1) && !imHassy.mnColorMatrix[0][0]) { imHassy.format = LIBRAW_HF_3FR; } else imHassy.format = LIBRAW_HF_FFF; } if (imHassy.SensorUnitConnector[0]) { char buf[64]; if (!strncmp(imHassy.SensorUnitConnector, "Hasselblad ", 11)) memmove(imHassy.SensorUnitConnector, imHassy.SensorUnitConnector+11, 64-11); strcpy(buf, imHassy.SensorUnitConnector); if ((eos = strrchr(buf, '/'))) { *eos = 0; if ((eos = strrchr(buf, ' '))) { *eos = 0; strcpy (imHassy.SensorUnitConnector, buf); } } } if (imHassy.format == LIBRAW_HF_AdobeDNG) { // Adobe DNG, use LocalizedCameraModel imgdata.color.LocalizedCameraModel[63] = 0; // make sure it's 0-terminated if ((ps = strrchr(imgdata.color.LocalizedCameraModel, '-'))) c = ps-imgdata.color.LocalizedCameraModel; else c = int(strlen(imgdata.color.LocalizedCameraModel)); int cc = MIN(c, (int)sizeof(tmp_model)-1); memcpy(tmp_model, imgdata.color.LocalizedCameraModel,cc); tmp_model[cc] = 0; if (strcasestr(imgdata.color.UniqueCameraModel, "coated")) { strncpy(normalized_model, imgdata.color.UniqueCameraModel,sizeof(imgdata.color.UniqueCameraModel)-1); normalized_model[sizeof(imgdata.color.UniqueCameraModel) - 1] = 0; norm_model_isSet = 1; } if (!strncmp(normalized_model, "Hasselblad ", 11)) memmove(normalized_model, normalized_model+11, 64-11); } else { if ((ps = strrchr(imgdata.color.UniqueCameraModel, '/'))) { c = ps-imgdata.color.UniqueCameraModel; } else c = int(strlen(imgdata.color.UniqueCameraModel)); int cc = MIN(c, (int)sizeof(tmp_model)-1); memcpy(tmp_model, imgdata.color.UniqueCameraModel,cc); tmp_model[cc] = 0; } if (!strncasecmp(tmp_model, "Hasselblad ", 11)) memmove(tmp_model, tmp_model+11, 64-11); strncpy(imHassy.CaptureSequenceInitiator, model,31); imHassy.CaptureSequenceInitiator[31] = 0; if ((eos = strrchr(imHassy.CaptureSequenceInitiator, '/'))) { *eos = 0; } // check if model tag contains manual CaptureSequenceInitiator info: FORC(int(sizeof Hasselblad_Ctrl / sizeof *Hasselblad_Ctrl)) { if (strcasestr(model, Hasselblad_Ctrl[c])) { // yes, fill 'model' with sensor unit data strncpy(model, tmp_model,63); model[63] = 0; break; } } if (!imHassy.HostBody[0]) { ps = strchr(model, '-'); if (ps) { // check if model contains both host body and sensor version, resolution, MS info strncpy(imHassy.SensorUnit, model,63); memcpy(imHassy.HostBody, model, ps-model); imHassy.HostBody[ps-model] = 0; if (!strncmp(ps-2, "II-", 3)) ps -=2; strncpy(imHassy.Sensor, ps,7); imHassy.Sensor[7] = 0; add_MP_toName = 0; } else { // model contains host body only strncpy(imHassy.HostBody, model,63); imHassy.HostBody[63] = 0; // fill 'model' with sensor unit data strncpy(model, tmp_model,63); model[63] = 0; } } if (strstr(model, "503CWD")) { strncpy(imHassy.HostBody, model,63); imHassy.HostBody[63] = 0; ilm.CameraFormat = LIBRAW_FORMAT_66; ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_V; if (model[6] == 'I' && model[7] == 'I') strcpy(model, "CFVII"); else strcpy(model, "CFV"); } else if (strstr(model, "Hasselblad") && (model[10] != ' ')) { strcpy(model, "CFV"); ilm.CameraMount = LIBRAW_MOUNT_DigitalBack; } else { FORC(int(sizeof Hasselblad_SensorEnclosures / sizeof *Hasselblad_SensorEnclosures)) { if (strcasestr(model, Hasselblad_SensorEnclosures[c])) { if (add_MP_toName) strcpy(model, Hasselblad_SensorEnclosures[c]); ilm.CameraMount = LIBRAW_MOUNT_DigitalBack; break; } } } #define cpynorm(str) \ if (!norm_model_isSet) { \ strcpy(normalized_model, str); \ norm_model_isSet = 1; \ } if ((imHassy.SensorCode == 4) && (imHassy.CoatingCode < 2)) { strcpy(imHassy.Sensor, "-16"); cpynorm("16-Uncoated"); } else if ((imHassy.SensorCode == 6) && (imHassy.CoatingCode < 2)) { strcpy(imHassy.Sensor, "-22"); cpynorm("22-Uncoated"); } else if ((imHassy.SensorCode == 8) && (imHassy.CoatingCode == 1)) { strcpy(imHassy.Sensor, "-31"); cpynorm("31-Uncoated"); } else if ((imHassy.SensorCode == 9) && (imHassy.CoatingCode < 2)) { strcpy(imHassy.Sensor, "-39"); cpynorm("39-Uncoated"); } else if ((imHassy.SensorCode == 9) && (imHassy.CoatingCode == 4)) { strcpy(imHassy.Sensor, "-39"); strcpy(model, "H3DII"); add_MP_toName = 1; cpynorm("39-Coated"); } else if ((imHassy.SensorCode == 13) && (imHassy.CoatingCode == 4)) { strcpy(imHassy.Sensor, "-40"); cpynorm("40-Coated"); } else if ((imHassy.SensorCode == 13) && (imHassy.CoatingCode == 5)) { strcpy(imHassy.Sensor, "-40"); cpynorm("40-Coated5"); } else if ((imHassy.SensorCode == 11) && (imHassy.CoatingCode == 4)) { if (!strncmp(model, "H3D", 3)) strcpy(model, "H3DII-50"); else strcpy(imHassy.Sensor, "-50"); cpynorm("50-Coated"); } else if ((imHassy.SensorCode == 11) && (imHassy.CoatingCode == 5)) { strcpy(imHassy.Sensor, "-50"); cpynorm("50-Coated5"); } else if ((imHassy.SensorCode == 15) && (imHassy.CoatingCode == 5)) { strcpy(imHassy.Sensor, "-50c"); cpynorm("50-15-Coated5"); if (!strncmp(imHassy.CaptureSequenceInitiator, "CFV II 50C", 10)) { imHassy.SensorSubCode = 2; add_MP_toName = 0; strcat(imHassy.Sensor, " II"); strcpy(model, "CFV II 50C"); strcat(normalized_model, "-II"); } else if (!strncmp(imHassy.CaptureSequenceInitiator, "X1D", 3)) { imHassy.SensorSubCode = 2; add_MP_toName = 0; strcat(imHassy.Sensor, " II"); if (!strncasecmp(imHassy.CaptureSequenceInitiator, "X1D II 50C", 10)) { strcpy(model, "X1D II 50C"); strcat(normalized_model, "-II"); } else { strcpy(model, "X1D-50c"); } } } else if ((imHassy.SensorCode == 12) && (imHassy.CoatingCode == 4)) { strcpy(imHassy.Sensor, "-60"); cpynorm("60-Coated"); } else if ((imHassy.SensorCode == 17) && (imHassy.CoatingCode == 5)) { strcpy(imHassy.Sensor, "-100c"); cpynorm("100-17-Coated5"); } else if ((raw_width == 4090) || // V96C ((raw_width == 4096) && (raw_height == 4096)) || ((raw_width == 4088) && (raw_height == 4088)) || // Adobe crop ((raw_width == 4080) && (raw_height == 4080))) { // Phocus crop strcpy(imHassy.Sensor, "-16"); cpynorm("16-Uncoated"); if (!imHassy.SensorCode) imHassy.SensorCode = 4; } else if ((raw_width == 5568) && (raw_height == 3648)) { strcpy(imHassy.Sensor, "-20c"); } else if (((raw_width == 4096) && (raw_height == 5456)) || ((raw_width == 4088) && (raw_height == 5448)) || // Adobe crop ((raw_width == 4080) && (raw_height == 5440))) { // Phocus crop strcpy(imHassy.Sensor, "-22"); cpynorm("22-Uncoated"); if (!imHassy.SensorCode) imHassy.SensorCode = 6; } else if (((raw_width == 6542) && (raw_height == 4916)) || ((raw_width == 6504) && (raw_height == 4880)) || // Adobe crop ((raw_width == 6496) && (raw_height == 4872))) { // Phocus crop strcpy(imHassy.Sensor, "-31"); cpynorm("31-Uncoated"); if (!imHassy.SensorCode) imHassy.SensorCode = 8; } else if (((raw_width == 7262) && (raw_height == 5456)) || // ((raw_width == 7224) && (raw_height == 5420)) || // Adobe crop ((raw_width == 7216) && (raw_height == 5412)) || // Phocus crop ((raw_width == 7212) && (raw_height == 5412)) || // CF-39, CFV-39, possibly v.II; Phocus crop // uncropped, when the exact size is unknown, should be: // - greater or equal to the smallest Phocus crop for the current size // - smaller than the smallest Phocus crop for the next size ((nPix >= 7212*5412) && (nPix < 7304*5478))) { strcpy(imHassy.Sensor, "-39"); if (!imHassy.SensorCode) imHassy.SensorCode = 9; if (!strncmp(model, "H3D", 3)) { if (((imHassy.format == LIBRAW_HF_Imacon) || strstr(imgdata.color.UniqueCameraModel, "H3D-39") || strstr(imgdata.color.LocalizedCameraModel, "H3D-39") || strstr(model, "H3D-39")) && !strstr(imgdata.color.UniqueCameraModel, "II") && !strstr(imgdata.color.LocalizedCameraModel, "II") && !strstr(model, "II")) { strcpy(model, "H3D-39"); add_MP_toName = 0; cpynorm("39-Uncoated"); } else { strcpy(model, "H3DII-39"); add_MP_toName = 0; cpynorm("39-Coated"); if (!imHassy.CoatingCode) imHassy.CoatingCode = 4; } } else cpynorm("39-Uncoated"); } else if (((raw_width == 7410) && (raw_height == 5586)) || // (H4D-40, H5D-40) ((raw_width == 7312) && (raw_height == 5486)) || // Adobe crop ((raw_width == 7304) && (raw_height == 5478))) { // Phocus crop strcpy(imHassy.Sensor, "-40"); if (!strncmp(model, "H4D", 3)) { cpynorm("40-Coated"); if (!imHassy.SensorCode) imHassy.SensorCode = 13; if (!imHassy.CoatingCode) imHassy.CoatingCode = 4; } else { cpynorm("40-Coated5"); if (!imHassy.SensorCode) imHassy.SensorCode = 13; if (!imHassy.CoatingCode) imHassy.CoatingCode = 5; } } else if (((raw_width == 8282) && (raw_height == 6240)) || // (CFV-50, H3DII-50, H5D-50) ((raw_width == 8184) && (raw_height == 6140)) || // Adobe crop ((raw_width == 8176) && (raw_height == 6132))) { // Phocus crop strcpy(imHassy.Sensor, "-50"); if (!strncmp(model, "H5D", 3)) { cpynorm("50-Coated5"); if (!imHassy.SensorCode) imHassy.SensorCode = 11; if (!imHassy.CoatingCode) imHassy.CoatingCode = 5; } else { cpynorm("50-Coated"); // CFV-50, H3DII-50, if (!strncmp(model, "H3D", 3)) { strcpy(model, "H3DII-50"); if (!imHassy.SensorCode) imHassy.SensorCode = 11; if (!imHassy.CoatingCode) imHassy.CoatingCode = 4; add_MP_toName = 0; } } } else if (((raw_width == 8374) && (raw_height == 6304)) || // (H5D-50c) ((raw_width == 8384) && (raw_height == 6304)) || // (X1D-50c, "X1D II 50C", "CFV II 50C") ((raw_width == 8280) && (raw_height == 6208)) || // Adobe crop ((raw_width == 8272) && (raw_height == 6200))) { // Phocus crop cpynorm("50-15-Coated5"); if (!imHassy.SensorCode) imHassy.SensorCode = 15; if (!imHassy.CoatingCode) imHassy.CoatingCode = 5; strcpy(imHassy.Sensor, "-50c"); if ((raw_width == 8384) || !strncmp(imHassy.CaptureSequenceInitiator, "X1D", 3) || !strncmp(imHassy.CaptureSequenceInitiator, "CFV II", 6)) { imHassy.SensorSubCode = 2; add_MP_toName = 0; strcat(imHassy.Sensor, " II"); if (strstr(imHassy.CaptureSequenceInitiator, " II ")) { strcat(normalized_model, "-II"); if (!strncasecmp(imHassy.CaptureSequenceInitiator, "X1D II 50C", 10)) { strcpy(model, "X1D II 50C"); } else if (!strncasecmp(imHassy.CaptureSequenceInitiator, "CFV II 50C", 10)) { strcpy(model, "CFV II 50C"); } } else { strcpy(model, "X1D-50c"); } } } else if (((raw_width == 9044) && (raw_height == 6732)) || ((raw_width == 8964) && (raw_height == 6716)) || // Adobe crop ((raw_width == 8956) && (raw_height == 6708))) { // Phocus crop strcpy(imHassy.Sensor, "-60"); cpynorm("60-Coated"); if (!imHassy.SensorCode) imHassy.SensorCode = 12; if (!imHassy.CoatingCode) imHassy.CoatingCode = 4; } else if (((raw_width == 10320) && (raw_height == 7752)) || // Phocus crop, A5D-80 ((nPix >= 10320*7752) && (nPix < 10520*8000))) { strcpy(imHassy.Sensor, "-80"); cpynorm("80-Coated"); } else if (((raw_width == 12000) && (raw_height == 8816)) || ((raw_width == 11608) && (raw_height == 8708)) || // Adobe crop ((raw_width == 11600) && (raw_height == 8700))) { // Phocus crop strcpy(imHassy.Sensor, "-100c"); cpynorm("100-17-Coated5"); if (!imHassy.SensorCode) imHassy.SensorCode = 17; if (!imHassy.CoatingCode) imHassy.CoatingCode = 5; } if (raw_width == 4090) strcpy(model, "V96C"); if ( (raw_width == 4090) || ((raw_width == 4096) && (raw_height == 4096)) || ((raw_width == 5568) && (raw_height == 3648)) || ((raw_width == 4096) && (raw_height == 5456)) || ((raw_width == 6542) && (raw_height == 4916)) || ((raw_width == 7262) && (raw_height == 5456)) || ((raw_width == 7410) && (raw_height == 5586)) || ((raw_width == 8282) && (raw_height == 6240)) || ((raw_width == 8374) && (raw_height == 6304)) || ((raw_width == 8384) && (raw_height == 6304)) || ((raw_width == 9044) && (raw_height == 6732)) || ((raw_width == 10320) && (raw_height == 7752)) || ((raw_width == 12000) && (raw_height == 8816)) ) imHassy.uncropped = 1; if (model[0] && add_MP_toName) strcat(model, imHassy.Sensor); if (imHassy.Sensor[0] == '-') memmove(imHassy.Sensor, imHassy.Sensor+1, strlen(imHassy.Sensor)); if (dng_version && (imHassy.SensorCode == 13) && (imHassy.CoatingCode == 4)) { c = LIBRAW_HF_AdobeDNG; } else if ((imHassy.format == LIBRAW_HF_HasselbladDNG) || (imHassy.format == LIBRAW_HF_AdobeDNG_fromPhocusDNG)) { c = LIBRAW_HF_FFF; } else if (imHassy.format == LIBRAW_HF_Imacon) { c = LIBRAW_HF_3FR; } else { c = imHassy.format; } ps = HassyRawFormat_idx2HR(c); if ((c == LIBRAW_HF_3FR) || (c == LIBRAW_HF_FFF)) strcat(normalized_model, ps); if (((imHassy.CaptureSequenceInitiator[0] == 'H') && (imHassy.CaptureSequenceInitiator[1] != 'a')) || ((imHassy.CaptureSequenceInitiator[0] == 'A') && isdigit(imHassy.CaptureSequenceInitiator[1]))) { ilm.CameraFormat = LIBRAW_FORMAT_645; ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H; if (imgdata.lens.Lens[0] == 'H') process_Hassy_Lens(LIBRAW_MOUNT_Hasselblad_H); } else if (((imHassy.CaptureSequenceInitiator[0] == 'X') && isdigit(imHassy.CaptureSequenceInitiator[1])) || !strncmp(imHassy.HostBody, "907", 3)) { ilm.CameraFormat = LIBRAW_FORMAT_CROP645; ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_XCD; if (imgdata.lens.Lens[0] == 'H') { process_Hassy_Lens(LIBRAW_MOUNT_Hasselblad_H); strcpy(ilm.Adapter, "XH"); } else { if (imgdata.lens.Lens[0] == 'X') { process_Hassy_Lens(LIBRAW_MOUNT_Hasselblad_XCD); } else if (!imgdata.lens.Lens[0] && (aperture > 1.0f) && (focal_len > 10.0f)) { ilm.LensID = focal_len; if (ilm.LensID == 35) { ilm.FocalType = LIBRAW_FT_ZOOM_LENS; ilm.LensID = LIBRAW_MOUNT_Hasselblad_XCD*100000000ULL + 35*10000ULL + 75*10; } else { ilm.FocalType = LIBRAW_FT_PRIME_LENS; ilm.LensID = LIBRAW_MOUNT_Hasselblad_XCD*100000000ULL + ilm.LensID*10000ULL + ilm.LensID*10; } } } } if (normalized_model[0] && !CM_found) CM_found = adobe_coeff(maker_index, normalized_model); } LibRaw-0.21.4/src/metadata/identify.cpp000066400000000000000000003102271477673233700176740ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" #include "../../internal/libraw_cameraids.h" // clang-format on static const struct { const int CorpId; const char *CorpName; } CorpTable[] = { {LIBRAW_CAMERAMAKER_Agfa, "AgfaPhoto"}, {LIBRAW_CAMERAMAKER_Apple, "Apple"}, {LIBRAW_CAMERAMAKER_Broadcom, "Broadcom"}, {LIBRAW_CAMERAMAKER_Canon, "Canon"}, {LIBRAW_CAMERAMAKER_Casio, "Casio"}, {LIBRAW_CAMERAMAKER_CINE, "CINE"}, {LIBRAW_CAMERAMAKER_Epson, "Epson"}, {LIBRAW_CAMERAMAKER_Fujifilm, "Fujifilm"}, {LIBRAW_CAMERAMAKER_Mamiya, "Mamiya"}, {LIBRAW_CAMERAMAKER_Motorola, "Motorola"}, {LIBRAW_CAMERAMAKER_Kodak, "Kodak"}, {LIBRAW_CAMERAMAKER_Konica, "Konica"}, {LIBRAW_CAMERAMAKER_Minolta, "Minolta"}, {LIBRAW_CAMERAMAKER_Leica, "Leica"}, {LIBRAW_CAMERAMAKER_Nikon, "Nikon"}, {LIBRAW_CAMERAMAKER_Nokia, "Nokia"}, {LIBRAW_CAMERAMAKER_Olympus, "Olympus"}, {LIBRAW_CAMERAMAKER_OmDigital, "OM Digital"}, {LIBRAW_CAMERAMAKER_Ricoh, "Ricoh"}, {LIBRAW_CAMERAMAKER_Pentax, "Pentax"}, {LIBRAW_CAMERAMAKER_PhaseOne, "Phase One"}, {LIBRAW_CAMERAMAKER_PhaseOne, "PhaseOne"}, {LIBRAW_CAMERAMAKER_Samsung, "Samsung"}, {LIBRAW_CAMERAMAKER_Sigma, "Sigma"}, {LIBRAW_CAMERAMAKER_Sinar, "Sinar"}, {LIBRAW_CAMERAMAKER_Sony, "Sony"}, {LIBRAW_CAMERAMAKER_YI, "YI"}, // add corp. names below {LIBRAW_CAMERAMAKER_Alcatel, "Alcatel"}, {LIBRAW_CAMERAMAKER_Aptina, "Aptina"}, {LIBRAW_CAMERAMAKER_AVT, "AVT"}, {LIBRAW_CAMERAMAKER_Baumer, "Baumer"}, {LIBRAW_CAMERAMAKER_Clauss, "Clauss"}, {LIBRAW_CAMERAMAKER_Contax, "Contax"}, {LIBRAW_CAMERAMAKER_Creative, "Creative"}, {LIBRAW_CAMERAMAKER_DJI, "DJI"}, {LIBRAW_CAMERAMAKER_Foculus, "Foculus"}, {LIBRAW_CAMERAMAKER_Generic, "Generic"}, {LIBRAW_CAMERAMAKER_Gione, "Gione"}, {LIBRAW_CAMERAMAKER_GITUP, "GITUP"}, {LIBRAW_CAMERAMAKER_Hasselblad, "Hasselblad"}, {LIBRAW_CAMERAMAKER_HTC, "HTC"}, {LIBRAW_CAMERAMAKER_I_Mobile, "I_Mobile"}, {LIBRAW_CAMERAMAKER_Imacon, "Imacon"}, {LIBRAW_CAMERAMAKER_ISG, "ISG"}, {LIBRAW_CAMERAMAKER_JK_Imaging, "JK Imaging"}, // Kodak {LIBRAW_CAMERAMAKER_Leaf, "Leaf"}, {LIBRAW_CAMERAMAKER_Lenovo, "Lenovo"}, {LIBRAW_CAMERAMAKER_LG, "LG"}, {LIBRAW_CAMERAMAKER_Logitech, "Logitech"}, {LIBRAW_CAMERAMAKER_Matrix, "Matrix"}, {LIBRAW_CAMERAMAKER_Meizu, "Meizu"}, {LIBRAW_CAMERAMAKER_Micron, "Micron"}, {LIBRAW_CAMERAMAKER_NGM, "NGM"}, {LIBRAW_CAMERAMAKER_OmniVison, "OmniVison"}, {LIBRAW_CAMERAMAKER_Panasonic, "Panasonic"}, {LIBRAW_CAMERAMAKER_Photron, "Photron"}, {LIBRAW_CAMERAMAKER_Pixelink, "Pixelink"}, {LIBRAW_CAMERAMAKER_Polaroid, "Polaroid"}, {LIBRAW_CAMERAMAKER_Rollei, "Rollei"}, {LIBRAW_CAMERAMAKER_RoverShot, "RoverShot"}, {LIBRAW_CAMERAMAKER_SMaL, "SMaL"}, {LIBRAW_CAMERAMAKER_ST_Micro, "ST Micro"}, {LIBRAW_CAMERAMAKER_THL, "THL"}, {LIBRAW_CAMERAMAKER_Xiaomi, "Xiaomi"}, {LIBRAW_CAMERAMAKER_XIAOYI, "Xiayi"}, {LIBRAW_CAMERAMAKER_Yuneec, "Yuneec"}, {LIBRAW_CAMERAMAKER_DXO, "DxO"}, {LIBRAW_CAMERAMAKER_RED, "Red"}, {LIBRAW_CAMERAMAKER_PhotoControl, "Photo Control"}, {LIBRAW_CAMERAMAKER_Google, "Google"}, {LIBRAW_CAMERAMAKER_GoPro, "GoPro"}, {LIBRAW_CAMERAMAKER_Parrot, "Parrot"}, {LIBRAW_CAMERAMAKER_Zeiss, "Zeiss"}, {LIBRAW_CAMERAMAKER_OnePlus, "OnePlus"}, {LIBRAW_CAMERAMAKER_VIVO, "Vivo"}, {LIBRAW_CAMERAMAKER_HMD_Global, "HMD Global"}, {LIBRAW_CAMERAMAKER_HUAWEI, "Huawei"}, {LIBRAW_CAMERAMAKER_RaspberryPi, "RaspberryPi"}, }; // clang-format on int LibRaw::setMakeFromIndex(unsigned makei) { if (makei <= LIBRAW_CAMERAMAKER_Unknown || makei >= LIBRAW_CAMERAMAKER_TheLastOne) return 0; for (int i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++) if ((unsigned)CorpTable[i].CorpId == makei) { strcpy(normalized_make, CorpTable[i].CorpName); maker_index = makei; return 1; } return 0; } const char *LibRaw::cameramakeridx2maker(unsigned maker) { for (int i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++) if((unsigned)CorpTable[i].CorpId == maker) return CorpTable[i].CorpName; return 0; } #ifdef LIBRAW_OLD_VIDEO_SUPPORT void LibRaw::fixupArri() { struct alist_t { const char *a_model; const char *a_software; ushort a_width,a_height; int a_black; unsigned a_filters; float a_aspect; } alist[] = { {"ALEXA65", "Alexa65 XT", 6560 ,3100, 256,0x49494949,1.f}, {"ALEXALF", "Alexa LF Plus W", 3840 ,2160, 256,0x49494949,1.0f }, {"ALEXALF", "Alexa LF Plus W", 4448 ,1856, 256,0x49494949,0.75f }, {"ALEXALF", "Alexa LF Plus W", 4448 ,3096, 256,0x49494949,1.f }, {"ALEXA", "Alexa Plus 4:3 SXT", 2880 ,1620, 256,0x61616161,.75f}, {"ALEXA", "Alexa Plus 4:3 SXT", 3168 ,1782, 256,0x61616161,0.75f}, {"ALEXA", "Alexa Plus 4:3 SXT", 3424 ,2202, 256,0x61616161,1.f}, {"ALEXA", "Alexa Plus 4:3 SXT", 2592 ,2160, 256,0x61616161,1.12f}, {"ALEXA", "Alexa Plus 4:3 XT", 2592 ,2160, 256,0x61616161,1.12f}, {"ALEXA", "Alexa Plus 4:3 XT", 2880 ,2160, 256,0x61616161,1.f}, {"ALEXA", "Alexa Plus 4:3 XT", 2880 ,1620, 256,0x61616161,0.75f}, {"ALEXA", "Alexa Plus 4:3 XT", 3424 ,2202, 256,0x61616161,1.f}, }; for(int i = 0; i < int(sizeof(alist)/sizeof(alist[0])); i++) if(!strncasecmp(model,alist[i].a_model,strlen(alist[i].a_model)) && software && !strncasecmp(software,alist[i].a_software,strlen(alist[i].a_software)) && width == alist[i].a_width && height == alist[i].a_height) { filters = alist[i].a_filters; black = alist[i].a_black; pixel_aspect = alist[i].a_aspect; strcpy(model,software); software[0]=0; return; } } #endif /* Identify which camera created this file, and set global variables accordingly. */ void LibRaw::identify() { // clang-format off static const ushort canon[][11] = { // raw_width, raw_height, left_margin, top_margin, // width_decrement, height_decrement, // mask01, mask03, mask11, mask13, // CFA_filters. { 1944, 1416, 0, 0, 48, 0 }, // 00 "PowerShot Pro90 IS" { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 }, // 01 "PowerShot S30", "PowerShot G1" { 2224, 1456, 48, 6, 0, 2 }, // 02 "EOS D30" { 2376, 1728, 12, 6, 52, 2 }, // 03 "PowerShot G2", "PowerShot S40", "PowerShot G3", "PowerShot S45" { 2672, 1968, 12, 6, 44, 2 }, // 04 "PowerShot G5", "PowerShot S50", "PowerShot S60" { 3152, 2068, 64, 12, 0, 0, 16 }, // 05 "EOS D60", "EOS 10D", "EOS 300D" { 3160, 2344, 44, 12, 4, 4 }, // 06 "PowerShot G6", "PowerShot S70" { 3344, 2484, 4, 6, 52, 6 }, // 07 "PowerShot Pro1" { 3516, 2328, 42, 14, 0, 0 }, // 08 "EOS 350D" { 3596, 2360, 74, 12, 0, 0 }, // 09 "EOS-1D Mark II", "EOS 20D", "EOS-1D Mark II N", "EOS 30D" { 3744, 2784, 52, 12, 8, 12 }, // 10 "PowerShot G11", "PowerShot S90", "PowerShot G12", "PowerShot S95" { 3944, 2622, 30, 18, 6, 2 }, // 11 "EOS 40D" { 3948, 2622, 42, 18, 0, 2 }, // 12 "EOS 400D", "EOS 1000D" { 3984, 2622, 76, 20, 0, 2, 14 }, // 13 "EOS-1D Mark III" { 4032, 2656, 112, 44, 10, 0 }, // 14 APS-C crop mode: "EOS 6D Mark II"??, "EOS RP" { 4104, 3048, 48, 12, 24, 12 }, // 15 "PowerShot G9" { 4116, 2178, 4, 2, 0, 0 }, // 16 ?? { 4152, 2772, 192, 12, 0, 0 }, // 17 "PowerShot SX1 IS" { 4160, 3124, 104, 11, 8, 65 }, // 18 "PowerShot S100 (new)", "PowerShot S100V", "PowerShot G15", "PowerShot S110 (new)" { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 }, // 19 "PowerShot SX50 HS" { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 }, // 20 "PowerShot G16", "PowerShot S120" { 4312, 2876, 22, 18, 0, 2 }, // 21 "EOS 450D" { 4352, 2850, 144, 46, 0, 0 }, // 22 APS-C crop mode: "EOS R" { 4352, 2874, 62, 18, 0, 0 }, // 23 "EOS 1100D" { 4476, 2954, 90, 34, 0, 0 }, // 24 "EOS 5D" { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 }, // 25 "PowerShot G10" { 4480, 3366, 80, 50, 0, 0 }, // 26 "PowerShot G1 X Mark II" { 4496, 3366, 80, 50, 12, 0 }, // 27 "PowerShot G1 X" { 4768, 3516, 96, 16, 0, 0, 0, 16 }, // 28 "PowerShot SX60 HS" { 4832, 3204, 62, 26, 0, 0 }, // 29 "EOS 500D" { 4832, 3228, 62, 51, 0, 0 }, // 30 "EOS 50D" { 5108, 3349, 98, 13, 0, 0 }, // 31 "EOS-1Ds Mark II" { 5120, 3318, 142, 45, 62, 0 }, // 32 "EOS-1D Mark IV" { 5280, 3528, 72, 52, 0, 0 }, // 33 "EOS M10", "EOS 650D", "EOS 700D", "EOS M", "EOS 100D", "EOS M2" { 5344, 3516, 142, 51, 0, 0 }, // 34 "EOS 550D", "EOS 600D", "EOS 60D", "EOS 1200D", "EOS 1300D", "EOS 3000D" { 5344, 3584, 126, 100, 0, 2 }, // 35 "EOS-1D X", "EOS-1D C" { 5344, 3950, 98, 18, 0, 0, 0, 24, 0, 0 }, // 36 "PowerShot SX70 HS" { 5360, 3516, 158, 51, 0, 0 }, // 37 "EOS 7D" { 5568, 3708, 72, 38, 0, 0 }, // 38; "EOS 7D Mark II", "EOS 6D", "EOS 70D", "EOS-1D X MARK II" { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 }, // 39 "PowerShot G7 X", "PowerShot G3 X", "PowerShot G9 X", "PowerShot G5 X", "PowerShot G7 X Mark II", "PowerShot G9 X Mark II" { 5712, 3774, 62, 20, 10, 2 }, // 40 "EOS-1Ds Mark III" { 5792, 3804, 158, 51, 0, 0 }, // 41 "EOS 5D Mark II" { 5920, 3950, 122, 80, 2, 0 }, // 42 "EOS 5D Mark III" { 6096, 4051, 76, 35, 0, 0 }, // 43 "EOS 1500D" { 6096, 4056, 72, 34, 0, 0 }, // 44 "EOS M3", "EOS 760D", "EOS 750D" { 6288, 4056, 264, 36, 0, 0 }, // 45 "EOS M5", "EOS M100", "EOS M6", "PowerShot G1 X Mark III", "EOS 80D", "EOS 800D", "EOS 77D", "EOS 200D", "EOS 250D", "EOS M50" { 6384, 4224, 120, 44, 0, 0 }, // 46 "EOS 6D Mark II", "EOS RP" { 6880, 4544, 136, 42, 0, 0 }, // 47 "EOS 5D Mark IV" { 6888, 4546, 146, 48, 0, 0 }, // 48 "EOS R" { 7128, 4732, 144, 72, 0, 0 }, // 49 "EOS M6 II", "EOS 90D" { 8896, 5920, 160, 64, 0, 0 }, // 50 "EOS 5DS", "EOS 5DS R" { 6192, 4152, 160, 120, 0, 0}, // EOS R3 { 6192, 4060, 168, 52, 24, 8, 16,48,32,0,} // EOS R10 }; static const libraw_custom_camera_t const_table[] = { { 786432, 1024, 768, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-080C" }, { 1447680, 1392, 1040, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-145C" }, { 1920000, 1600, 1200, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-201C" }, { 5067304, 2588, 1958, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-510C" }, { 5067316, 2588, 1958, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-510C", 12 }, { 10134608, 2588, 1958, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-510C" }, { 10134620, 2588, 1958, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-510C", 12 }, { 16157136, 3272, 2469, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-810C" }, { 3995136, 1632, 1224, 0, 0, 0, 0, 8, 0x61, 0, 1, "AgfaPhoto", "DC-833m" }, { 15980544, 3264, 2448, 0, 0, 0, 0, 8, 0x61, 0, 1, "AgfaPhoto", "DC-833m" }, { 9631728, 2532, 1902, 0, 0, 0, 0, 96, 0x61, 0, 0, "Alcatel", "5035D" }, { 31850496, 4608, 3456, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "GIT2 4:3" }, { 23887872, 4608, 2592, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "GIT2 16:9" }, { 32257024, 4624, 3488, 8, 2, 16, 2, 0, 0x94, 0, 0, "GITUP", "GIT2P 4:3" }, { 24192768, 4624, 2616, 8, 2, 16, 2, 0, 0x94, 0, 0, "GITUP", "GIT2P 16:9" }, { 18016000, 4000, 2252, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "G3DUO 16:9" }, // {24000000, 4000, 3000, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", // "G3DUO 4:3"}, // Conflict w/ Samsung WB550 // Android Raw dumps id start // File Size in bytes Horizontal Res Vertical Flag then bayer order eg // 0x16 bbgr 0x94 rggb { 1540857, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "Samsung", "S3" }, { 2658304, 1212, 1096, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3FrontMipi" }, { 2842624, 1296, 1096, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3FrontQCOM" }, { 2969600, 1976, 1200, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "MI3wMipi" }, { 3170304, 1976, 1200, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "MI3wQCOM" }, { 3763584, 1584, 1184, 0, 0, 0, 0, 96, 0x61, 0, 0, "I_Mobile", "I_StyleQ6" }, { 5107712, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "UltraPixel1" }, { 5382640, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "UltraPixel2" }, { 5664912, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" }, { 5664912, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" }, { 5364240, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" }, { 6299648, 2592, 1944, 0, 0, 0, 0, 1, 0x16, 0, 0, "OmniVisi", "OV5648" }, { 6721536, 2592, 1944, 0, 0, 0, 0, 0, 0x16, 0, 0, "OmniVisi", "OV56482" }, { 6746112, 2592, 1944, 0, 0, 0, 0, 0, 0x16, 0, 0, "HTC", "OneSV" }, { 9631728, 2532, 1902, 0, 0, 0, 0, 96, 0x61, 0, 0, "Sony", "5mp" }, { 9830400, 2560, 1920, 0, 0, 0, 0, 96, 0x61, 0, 0, "NGM", "ForwardArt" }, { 10186752, 3264, 2448, 0, 0, 0, 0, 1, 0x94, 0, 0, "Sony", "IMX219-mipi 8mp" }, { 10223360, 2608, 1944, 0, 0, 0, 0, 96, 0x16, 0, 0, "Sony", "IMX" }, { 10782464, 3282, 2448, 0, 0, 0, 0, 0, 0x16, 0, 0, "HTC", "MyTouch4GSlide" }, { 10788864, 3282, 2448, 0, 0, 0, 0, 0, 0x16, 0, 0, "Xperia", "L" }, { 15967488, 3264, 2446, 0, 0, 0, 0, 96, 0x16, 0, 0, "OmniVison", "OV8850" }, { 16224256, 4208, 3082, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3MipiL" }, { 16424960, 4208, 3120, 0, 0, 0, 0, 1, 0x16, 0, 0, "IMX135", "MipiL" }, { 17326080, 4164, 3120, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3LQCom" }, { 17522688, 4212, 3120, 0, 0, 0, 0, 0, 0x16, 0, 0, "Sony", "IMX135-QCOM" }, { 19906560, 4608, 3456, 0, 0, 0, 0, 1, 0x16, 0, 0, "Gione", "E7mipi" }, { 19976192, 5312, 2988, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G4" }, { 20389888, 4632, 3480, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "RedmiNote3Pro" }, { 20500480, 4656, 3496, 0, 0, 0, 0, 1, 0x94, 0, 0, "Sony", "IMX298-mipi 16mp" }, { 21233664, 4608, 3456, 0, 0, 0, 0, 1, 0x16, 0, 0, "Gione", "E7qcom" }, { 26023936, 4192, 3104, 0, 0, 0, 0, 96, 0x94, 0, 0, "THL", "5000" }, { 26257920, 4208, 3120, 0, 0, 0, 0, 96, 0x94, 0, 0, "Sony", "IMX214" }, { 26357760, 4224, 3120, 0, 0, 0, 0, 96, 0x61, 0, 0, "OV", "13860" }, { 41312256, 5248, 3936, 0, 0, 0, 0, 96, 0x61, 0, 0, "Meizu", "MX4" }, { 42923008, 5344, 4016, 0, 0, 0, 0, 96, 0x61, 0, 0, "Sony", "IMX230" }, // Android Raw dumps id end { 20137344, 3664, 2748, 0, 0, 0, 0, 0x40, 0x49, 0, 0, "Aptina", "MT9J003", 0xffff }, { 2868726, 1384, 1036, 0, 0, 0, 0, 64, 0x49, 0, 8, "Baumer", "TXG14", 1078 }, { 6553440, 2664, 1968, 4, 4, 44, 4, 40, 0x94, 0, 2, "Canon", "PowerShot A460" }, // chdk hack { 9243240, 3152, 2346, 12, 7, 44, 13, 40, 0x49, 0, 2, "Canon", "PowerShot A470" }, // chdk hack { 6653280, 2672, 1992, 10, 6, 42, 2, 40, 0x94, 0, 2, "Canon", "PowerShot A530" }, // chdk hack { 6573120, 2672, 1968, 12, 8, 44, 0, 40, 0x94, 0, 2, "Canon", "PowerShot A610" }, // chdk hack { 9219600, 3152, 2340, 36, 12, 4, 0, 40, 0x94, 0, 2, "Canon", "PowerShot A620" }, // chdk hack { 10383120, 3344, 2484, 12, 6, 44, 6, 40, 0x94, 0, 2, "Canon", "PowerShot A630" }, // chdk hack { 12945240, 3736, 2772, 12, 6, 52, 6, 40, 0x94, 0, 2, "Canon", "PowerShot A640" }, // chdk hack { 15636240, 4104, 3048, 48, 12, 24, 12, 40, 0x94, 0, 2, "Canon", "PowerShot A650 IS" }, // chdk hack { 10341600, 3336, 2480, 6, 5, 32, 3, 40, 0x94, 0, 2, "Canon", "PowerShot A720 IS" }, // chdk hack { 24724224, 4704, 3504, 8, 16, 56, 8, 40, 0x49, 0, 2, "Canon", "PowerShot A3300 IS" }, // chdk hack { 18763488, 4104, 3048, 10, 22, 82, 22, 8, 0x49, 0, 0, "Canon", "PowerShot D10" }, // ? chdk hack ? { 19493760, 4160, 3124, 104, 12, 8, 66, 40, 0x49, 0, 2, "Canon", "PowerShot S100" }, // chdk hack CRW { 7710960, 2888, 2136, 44, 8, 4, 0, 40, 0x94, 0, 2, "Canon", "PowerShot S3 IS" }, // chdk hack { 5298000, 2400, 1766, 12, 12, 44, 2, 40, 0x94, 0, 2, "Canon", "PowerShot SD300" }, // chdk hack { 18653760, 4080, 3048, 24, 12, 24, 12, 40, 0x94, 0, 2, "Canon", "PowerShot SX20 IS" }, // chdk hack { 21936096, 4464, 3276, 25, 10, 73, 12, 40, 0x16, 0, 2, "Canon", "PowerShot SX30 IS" }, // chdk hack { 19167840, 4176, 3060, 96, 16, 8, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX40 HS" }, // chdk hack CR2 { 15467760, 3720, 2772, 6, 12, 30, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX110 IS" }, // chdk hack { 15534576, 3728, 2778, 12, 9, 44, 9, 40, 0x94, 0, 2, "Canon", "PowerShot SX120 IS" }, // chdk hack { 19131120, 4168, 3060, 92, 16, 4, 1, 40, 0x94, 0, 2, "Canon", "PowerShot SX220 HS" }, // chdk hack { 31663200, 5344, 3950, 96, 18, 0, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX710 HS" }, // chdk hack { 30858240, 5248, 3920, 8, 16, 56, 16, 40, 0x94, 0, 2, "Canon", "IXUS 160" }, // chdk hack { 1976352, 1632, 1211, 0, 2, 0, 1, 0, 0x94, 0, 1, "Casio", "QV-2000UX" }, { 3217760, 2080, 1547, 0, 0, 10, 1, 0, 0x94, 0, 1, "Casio", "QV-3*00EX" }, { 6218368, 2585, 1924, 0, 0, 9, 0, 0, 0x94, 0, 1, "Casio", "QV-5700" }, { 7816704, 2867, 2181, 0, 0, 34, 36, 0, 0x16, 0, 1, "Casio", "EX-Z60" }, { 2937856, 1621, 1208, 0, 0, 1, 0, 0, 0x94, 7, 13, "Casio", "EX-S20" }, { 4948608, 2090, 1578, 0, 0, 32, 34, 0, 0x94, 7, 1, "Casio", "EX-S100" }, { 6054400, 2346, 1720, 2, 0, 32, 0, 0, 0x94, 7, 1, "Casio", "QV-R41" }, { 7426656, 2568, 1928, 0, 0, 0, 0, 0, 0x94, 0, 1, "Casio", "EX-P505" }, { 7530816, 2602, 1929, 0, 0, 22, 0, 0, 0x94, 7, 1, "Casio", "QV-R51" }, { 7542528, 2602, 1932, 0, 0, 32, 0, 0, 0x94, 7, 1, "Casio", "EX-Z50" }, { 7562048, 2602, 1937, 0, 0, 25, 0, 0, 0x16, 7, 1, "Casio", "EX-Z500" }, { 7753344, 2602, 1986, 0, 0, 32, 26, 0, 0x94, 7, 1, "Casio", "EX-Z55" }, { 9313536, 2858, 2172, 0, 0, 14, 30, 0, 0x94, 7, 1, "Casio", "EX-P600" }, { 10834368, 3114, 2319, 0, 0, 27, 0, 0, 0x94, 0, 1, "Casio", "EX-Z750" }, { 10843712, 3114, 2321, 0, 0, 25, 0, 0, 0x94, 0, 1, "Casio", "EX-Z75" }, { 10979200, 3114, 2350, 0, 0, 32, 32, 0, 0x94, 7, 1, "Casio", "EX-P700" }, { 12310144, 3285, 2498, 0, 0, 6, 30, 0, 0x94, 0, 1, "Casio", "EX-Z850" }, { 12489984, 3328, 2502, 0, 0, 47, 35, 0, 0x94, 0, 1, "Casio", "EX-Z8" }, { 15499264, 3754, 2752, 0, 0, 82, 0, 0, 0x94, 0, 1, "Casio", "EX-Z1050" }, { 18702336, 4096, 3044, 0, 0, 24, 0, 80, 0x94, 7, 1, "Casio", "EX-ZR100" }, { 7684000, 2260, 1700, 0, 0, 0, 0, 13, 0x94, 0, 1, "Casio", "QV-4000" }, { 787456, 1024, 769, 0, 1, 0, 0, 0, 0x49, 0, 0, "Creative", "PC-CAM 600" }, { 28829184, 4384, 3288, 0, 0, 0, 0, 36, 0x61, 0, 0, "DJI" }, { 15151104, 4608, 3288, 0, 0, 0, 0, 0, 0x94, 0, 0, "Matrix" }, { 3840000, 1600, 1200, 0, 0, 0, 0, 65, 0x49, 0, 0, "Foculus", "531C" }, { 307200, 640, 480, 0, 0, 0, 0, 0, 0x94, 0, 0, "Generic" }, { 62464, 256, 244, 1, 1, 6, 1, 0, 0x8d, 0, 0, "Kodak", "DC20" }, { 124928, 512, 244, 1, 1, 10, 1, 0, 0x8d, 0, 0, "Kodak", "DC20" }, { 1652736, 1536, 1076, 0, 52, 0, 0, 0, 0x61, 0, 0, "Kodak", "DCS200" }, { 4159302, 2338, 1779, 1, 33, 1, 2, 0, 0x94, 0, 0, "Kodak", "C330" }, { 4162462, 2338, 1779, 1, 33, 1, 2, 0, 0x94, 0, 0, "Kodak", "C330", 3160 }, { 2247168, 1232, 912, 0, 0, 16, 0, 0, 0x00, 0, 0, "Kodak", "C330" }, { 3370752, 1232, 912, 0, 0, 16, 0, 0, 0x00, 0, 0, "Kodak", "C330" }, { 6163328, 2864, 2152, 0, 0, 0, 0, 0, 0x94, 0, 0, "Kodak", "C603" }, { 6166488, 2864, 2152, 0, 0, 0, 0, 0, 0x94, 0, 0, "Kodak", "C603", 3160 }, { 460800, 640, 480, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "C603" }, { 9116448, 2848, 2134, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "C603" }, { 12241200, 4040, 3030, 2, 0, 0, 13, 0, 0x49, 0, 0, "Kodak", "12MP" }, { 12272756, 4040, 3030, 2, 0, 0, 13, 0, 0x49, 0, 0, "Kodak", "12MP", 31556 }, { 18000000, 4000, 3000, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "12MP" }, { 614400, 640, 480, 0, 3, 0, 0, 64, 0x94, 0, 0, "Kodak", "KAI-0340" }, { 15360000, 3200, 2400, 0, 0, 0, 0, 96, 0x16, 0, 0, "Lenovo", "A820" }, { 3884928, 1608, 1207, 0, 0, 0, 0, 96, 0x16, 0, 0, "Micron", "2010", 3212 }, { 1138688, 1534, 986, 0, 0, 0, 0, 0, 0x61, 0, 0, "Minolta", "RD175", 513 }, { 1581060, 1305, 969, 0, 0, 18, 6, 6, 0x1e, 4, 1, "Nikon", "E900" }, // "diag raw" hack { 2465792, 1638, 1204, 0, 0, 22, 1, 6, 0x4b, 5, 1, "Nikon", "E950" }, // "diag raw" hack; possibly also Nikon E700, E800, E775; // Olympus C-2020Z { 2940928, 1616, 1213, 0, 0, 0, 7, 30, 0x94, 0, 1, "Nikon", "E2100" }, // "diag raw" hack; also Nikon E2500 { 4771840, 2064, 1541, 0, 0, 0, 1, 6, 0xe1, 0, 1, "Nikon", "E990" }, // "diag raw" hack; possibly also Nikon E880, E885, E995; // Olympus C-3030Z { 4775936, 2064, 1542, 0, 0, 0, 0, 30, 0x94, 0, 1, "Nikon", "E3700" }, // "diag raw" hack; Nikon E3100, E3200, E3500; // Pentax "Optio 33WR"; possibly also Olympus C-740UZ { 5865472, 2288, 1709, 0, 0, 0, 1, 6, 0xb4, 0, 1, "Nikon", "E4500" }, // "diag raw" hack; possibly also Olympus C-4040Z { 5869568, 2288, 1710, 0, 0, 0, 0, 6, 0x16, 0, 1, "Nikon", "E4300" }, // "diag raw" hack; also Minolta "DiMAGE Z2" { 7438336, 2576, 1925, 0, 0, 0, 1, 6, 0xb4, 0, 1, "Nikon", "E5000" }, // also Nikon E5700 { 8998912, 2832, 2118, 0, 0, 0, 0, 30, 0x94, 7, 1, "Nikon", "COOLPIX S6" }, // "diag raw" hack { 5939200, 2304, 1718, 0, 0, 0, 0, 30, 0x16, 0, 0, "Olympus", "C-770UZ" }, // possibly also Olympus C-4100Z, C-765UZ { 3178560, 2064, 1540, 0, 0, 0, 0, 0, 0x94, 0, 1, "Pentax", "Optio S V1.01" }, { 4841984, 2090, 1544, 0, 0, 22, 0, 0, 0x94, 7, 1, "Pentax", "Optio S" }, { 6114240, 2346, 1737, 0, 0, 22, 0, 0, 0x94, 7, 1, "Pentax", "Optio S4" }, { 10702848, 3072, 2322, 0, 0, 0, 21, 30, 0x94, 0, 1, "Pentax", "Optio 750Z" }, { 4147200, 1920, 1080, 0, 0, 0, 0, 0, 0x49, 0, 0, "Photron", "BC2-HD" }, { 4151666, 1920, 1080, 0, 0, 0, 0, 0, 0x49, 0, 0, "Photron", "BC2-HD", 8 }, { 13248000, 2208, 3000, 0, 0, 0, 0, 13, 0x61, 0, 0, "Pixelink", "A782" }, { 6291456, 2048, 1536, 0, 0, 0, 0, 96, 0x61, 0, 0, "RoverShot", "3320AF" }, { 311696, 644, 484, 0, 0, 0, 0, 0, 0x16, 0, 8, "ST Micro", "STV680 VGA" }, { 16098048, 3288, 2448, 0, 0, 24, 0, 9, 0x94, 0, 1, "Samsung", "S85" }, // hack { 16215552, 3312, 2448, 0, 0, 48, 0, 9, 0x94, 0, 1, "Samsung", "S85" }, // hack { 20487168, 3648, 2808, 0, 0, 0, 0, 13, 0x94, 5, 1, "Samsung", "WB550" }, { 24000000, 4000, 3000, 0, 0, 0, 0, 13, 0x94, 5, 1, "Samsung", "WB550" }, { 12582980, 3072, 2048, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 23; same res. as Leaf Volare & Cantare { 33292868, 4080, 4080, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 44 { 44390468, 4080, 5440, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 54 { 1409024, 1376, 1024, 0, 0, 1, 0, 0, 0x49, 0, 0, "Sony", "XCD-SX910CR" }, { 2818048, 1376, 1024, 0, 0, 1, 0, 97, 0x49, 0, 0, "Sony", "XCD-SX910CR" }, }; libraw_custom_camera_t table[64 + sizeof(const_table) / sizeof(const_table[0])]; // clang-format on char head[64] = {0}, *cp; int hlen, fsize, flen, zero_fsize = 1, i, c; INT64 fsize64; struct jhead jh; unsigned camera_count = parse_custom_cameras(64, table, imgdata.rawparams.custom_camera_strings); for (int q = 0; q < int(sizeof(const_table) / sizeof(const_table[0])); q++) memmove(&table[q + camera_count], &const_table[q], sizeof(const_table[0])); camera_count += sizeof(const_table) / sizeof(const_table[0]); tiff_flip = flip = filters = UINT_MAX; /* unknown */ raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; maximum = height = width = top_margin = left_margin = 0; cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0; iso_speed = shutter = aperture = focal_len = 0; unique_id = 0ULL; tiff_nifds = 0; is_NikonTransfer = 0; is_Olympus = 0; OlympusDNG_SubDirOffsetValid = 0; is_Sony = 0; is_pana_raw = 0; maker_index = LIBRAW_CAMERAMAKER_Unknown; FujiCropMode = 0; is_PentaxRicohMakernotes = 0; normalized_model[0] = 0; normalized_make[0] = 0; CM_found = 0; memset(tiff_ifd, 0, sizeof tiff_ifd); libraw_internal_data.unpacker_data.crx_track_selected = -1; libraw_internal_data.unpacker_data.crx_track_count = -1; libraw_internal_data.unpacker_data.CR3_CTMDtag = 0; imHassy.nIFD_CM[0] = imHassy.nIFD_CM[1] = -1; imKodak.ISOCalibrationGain = 1.0f; imCommon.CameraTemperature = imCommon.SensorTemperature = imCommon.SensorTemperature2 = imCommon.LensTemperature = imCommon.AmbientTemperature = imCommon.BatteryTemperature = imCommon.exifAmbientTemperature = -1000.0f; libraw_internal_data.unpacker_data.ifd0_offset = -1LL; imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_Unknown; for (i = 0; i < LIBRAW_IFD_MAXCOUNT; i++) { tiff_ifd[i].dng_color[0].illuminant = tiff_ifd[i].dng_color[1].illuminant = 0xffff; for (int q = 0; q < 4; q++) tiff_ifd[i].dng_levels.analogbalance[q] = 1.0f; } memset(gpsdata, 0, sizeof gpsdata); memset(cblack, 0, sizeof cblack); memset(white, 0, sizeof white); memset(mask, 0, sizeof mask); thumb_offset = thumb_length = thumb_width = thumb_height = 0; load_raw = 0; thumb_format = LIBRAW_INTERNAL_THUMBNAIL_JPEG; // default to JPEG data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0; kodak_cbpp = zero_after_ff = dng_version = load_flags = 0; timestamp = shot_order = tiff_samples = black = is_foveon = 0; mix_green = profile_length = data_error = zero_is_bad = 0; pixel_aspect = is_raw = raw_color = 1; tile_width = tile_length = 0; metadata_blocks = 0; for (i = 0; i < 4; i++) { cam_mul[i] = i == 1; pre_mul[i] = i < 3; FORC3 cmatrix[c][i] = 0; FORC3 rgb_cam[c][i] = c == i; } colors = 3; for (i = 0; i < 0x10000; i++) curve[i] = i; order = get2(); hlen = get4(); fseek(ifp, 0, SEEK_SET); if (fread(head, 1, 64, ifp) < 64) throw LIBRAW_EXCEPTION_IO_CORRUPT; libraw_internal_data.unpacker_data.lenRAFData = libraw_internal_data.unpacker_data.posRAFData = 0; fseek(ifp, 0, SEEK_END); fsize64 = ftell(ifp); if(fsize64 > LIBRAW_MAX_NONDNG_RAW_FILE_SIZE && fsize64 > LIBRAW_MAX_DNG_RAW_FILE_SIZE) throw LIBRAW_EXCEPTION_TOOBIG; flen = fsize = ftell(ifp); if ((cp = (char *)memmem(head, 32, (char *)"MMMM", 4)) || (cp = (char *)memmem(head, 32, (char *)"IIII", 4))) { parse_phase_one(cp - head); if (cp - head && parse_tiff(0)) apply_tiff(); } else if (order == 0x4949 || order == 0x4d4d) { if (!memcmp(head + 6, "HEAPCCDR", 8)) { data_offset = hlen; parse_ciff(hlen, flen - hlen, 0); load_raw = &LibRaw::canon_load_raw; } else if (parse_tiff(0)) apply_tiff(); } else if (!memcmp(head, "\xff\xd8\xff\xe1", 4) && !memcmp(head + 6, "Exif", 4)) { fseek(ifp, 4, SEEK_SET); data_offset = 4 + get2(); fseek(ifp, data_offset, SEEK_SET); if (fgetc(ifp) != 0xff) parse_tiff(12); thumb_offset = 0; } else if (!memcmp(head + 25, "ARECOYK", 7)) // 'KYOCERA' right-to-left { strcpy(make, "Contax"); strcpy(model, "N Digital"); parse_kyocera(); } else if (!strcmp(head, "PXN")) { strcpy(make, "Logitech"); strcpy(model, "Fotoman Pixtura"); } else if (!strcmp(head, "qktk")) { strcpy(make, "Apple"); strcpy(model, "QuickTake 100"); load_raw = &LibRaw::quicktake_100_load_raw; } else if (!strcmp(head, "qktn")) { strcpy(make, "Apple"); strcpy(model, "QuickTake 150"); load_raw = &LibRaw::kodak_radc_load_raw; } else if (!memcmp(head, "FUJIFILM", 8)) { memcpy(imFuji.SerialSignature, head + 0x10, 0x0c); imFuji.SerialSignature[0x0c] = 0; memcpy(imFuji.SensorID, imFuji.SerialSignature + 0x06, 0x04); imFuji.SensorID[0x04] = 0; strncpy(model, head + 0x1c, 0x20); model[0x20] = 0; c = 11; while (imFuji.SerialSignature[c] > 0 && isdigit(imFuji.SerialSignature[c]) && (c>0)) c--; if(c < 11) unique_id = (unsigned long long)atoi(imFuji.SerialSignature+c+1); memcpy(imFuji.RAFVersion, head + 0x3c, 4); imFuji.RAFVersion[4] = 0; fseek(ifp, 84, SEEK_SET); thumb_offset = get4(); thumb_length = get4(); fseek(ifp, 92, SEEK_SET); parse_fuji(get4()); if (thumb_offset > 120) { fseek(ifp, 120, SEEK_SET); is_raw += (i = get4()) ? 1 : 0; if (is_raw == 2 && shot_select) parse_fuji(i); } load_raw = &LibRaw::unpacked_load_raw; fseek(ifp, 100 + 28 * (shot_select > 0), SEEK_SET); parse_tiff(data_offset = get4()); parse_tiff(thumb_offset + 12); parse_fuji_thumbnail(thumb_offset); apply_tiff(); } else if (!memcmp(head, "RIFF", 4)) { fseek(ifp, 0, SEEK_SET); parse_riff(100); } else if (!memcmp(head + 4, "ftypqt ", 9)) { fseek(ifp, 0, SEEK_SET); parse_qt(fsize); is_raw = 0; } else if (!memcmp(head, "\0\001\0\001\0@", 6)) { fseek(ifp, 6, SEEK_SET); fread(make, 1, 8, ifp); fread(model, 1, 8, ifp); fread(model2, 1, 16, ifp); data_offset = get2(); get2(); raw_width = get2(); raw_height = get2(); load_raw = &LibRaw::nokia_load_raw; filters = 0x61616161; } else if (!memcmp(head, "NOKIARAW", 8)) { strcpy(make, "NOKIA"); order = 0x4949; fseek(ifp, 300, SEEK_SET); data_offset = get4(); i = get4(); // bytes count width = get2(); height = get2(); // Data integrity check if (width < 1 || width > 16000 || height < 1 || height > 16000 || i < (width * height) || i > (2 * width * height)) throw LIBRAW_EXCEPTION_IO_CORRUPT; switch (tiff_bps = i * 8 / (width * height)) { case 8: load_raw = &LibRaw::eight_bit_load_raw; break; case 10: load_raw = &LibRaw::nokia_load_raw; break; case 0: throw LIBRAW_EXCEPTION_IO_CORRUPT; break; } raw_height = height + (top_margin = i / (width * tiff_bps / 8) - height); mask[0][3] = 1; filters = 0x61616161; } #ifdef LIBRAW_OLD_VIDEO_SUPPORT else if (!memcmp(head, "ARRI", 4)) { order = 0x4949; fseek(ifp, 20, SEEK_SET); width = get4(); height = get4(); strcpy(make, "ARRI"); fseek(ifp, 668, SEEK_SET); fread(model, 1, 64, ifp); model[63] = 0; fseek(ifp, 760, SEEK_SET); fread(software, 1, 64, ifp); if((unsigned char)software[0] == 0xff) software[0] = 0; software[63] = 0; data_offset = 4096; load_raw = &LibRaw::packed_load_raw; load_flags = 88; filters = 0x61616161; fixupArri(); } else if (!memcmp(head, "XPDS", 4)) { order = 0x4949; fseek(ifp, 0x800, SEEK_SET); fread(make, 1, 41, ifp); raw_height = get2(); raw_width = get2(); fseek(ifp, 56, SEEK_CUR); fread(model, 1, 30, ifp); data_offset = 0x10000; load_raw = &LibRaw::canon_rmf_load_raw; gamma_curve(0, 12.25, 1, 1023); } else if (!memcmp(head + 4, "RED1", 4)) { strcpy(make, "Red"); strcpy(model, "One"); parse_redcine(); load_raw = &LibRaw::redcine_load_raw; gamma_curve(1 / 2.4, 12.92, 1, 4095); filters = 0x49494949; } #endif else if (!memcmp(head, "DSC-Image", 9)) parse_rollei(); else if (!memcmp(head, "PWAD", 4)) parse_sinar_ia(); else if (!memcmp(head, "\0MRM", 4)) parse_minolta(0); else if (!memcmp(head, "FOVb", 4)) { parse_x3f(); /* Does nothing if USE_X3FTOOLS is not defined */ } else if (!memcmp(head, "CI", 2)) parse_cine(); #ifdef USE_6BY9RPI else if (!memcmp(head, "BRCM", 4)) { fseek(ifp, 0, SEEK_SET); strcpy(make, "RaspberryPi"); strcpy(model, "Pi"); parse_raspberrypi(); } #endif else if (!memcmp(head + 4, "ftypcrx ", 8)) { int err; unsigned long long szAtomList; short nesting = -1; short nTrack = -1; short TrackType; char AtomNameStack[129]; strcpy(make, "Canon"); szAtomList = ifp->size(); err = parseCR3(0ULL, szAtomList, nesting, AtomNameStack, nTrack, TrackType); libraw_internal_data.unpacker_data.crx_track_count = nTrack; if ((err == 0 || err == -14) && nTrack >= 0) // no error, or too deep nesting selectCRXTrack(); } if (dng_version) { if (fsize64 > LIBRAW_MAX_DNG_RAW_FILE_SIZE) throw LIBRAW_EXCEPTION_TOOBIG; } else { if (fsize64 > LIBRAW_MAX_NONDNG_RAW_FILE_SIZE) throw LIBRAW_EXCEPTION_TOOBIG; } if (make[0] == 0) for (zero_fsize = i = 0; i < (int)camera_count; i++) if (fsize == (int)table[i].fsize) { strcpy(make, table[i].t_make); strcpy(model, table[i].t_model); flip = table[i].flags >> 2; zero_is_bad = table[i].flags & 2; data_offset = table[i].offset == 0xffff ? 0 : table[i].offset; raw_width = table[i].rw; raw_height = table[i].rh; left_margin = table[i].lm; top_margin = table[i].tm; width = raw_width - left_margin - table[i].rm; height = raw_height - top_margin - table[i].bm; filters = 0x1010101U * table[i].cf; colors = 4 - !((filters & filters >> 1) & 0x5555); load_flags = table[i].lf & 0xff; if (table[i].lf & 0x100) /* Monochrome sensor dump */ { colors = 1; filters = 0; } switch (tiff_bps = (fsize - data_offset) * 8 / (raw_width * raw_height)) { case 6: load_raw = &LibRaw::minolta_rd175_load_raw; ilm.CameraMount = LIBRAW_MOUNT_Minolta_A; break; case 8: load_raw = &LibRaw::eight_bit_load_raw; break; case 10: if ((fsize - data_offset) / raw_height * 3 >= raw_width * 4) { load_raw = &LibRaw::android_loose_load_raw; break; } else if (load_flags & 1) { load_raw = &LibRaw::android_tight_load_raw; break; } case 12: load_flags |= 128; load_raw = &LibRaw::packed_load_raw; break; case 16: order = 0x4949 | 0x404 * (load_flags & 1); tiff_bps -= load_flags >> 4; tiff_bps -= load_flags = load_flags >> 1 & 7; load_raw = table[i].offset == 0xffff ? &LibRaw::unpacked_load_raw_reversed : &LibRaw::unpacked_load_raw; } maximum = (1 << tiff_bps) - (1 << table[i].max); break; } if (zero_fsize) fsize = 0; if (make[0] == 0 && fsize64 < 25000000LL) parse_smal(0, flen); if (make[0] == 0) { parse_jpeg(0); #ifdef USE_6BY9RPI if (!(strncmp(model, "ov", 2) && strncmp(model, "RP_", 3) && strncmp(model, "imx477", 6))) { //Assume that this isn't a raw unless the header can be found is_raw = 0; if (!strncasecmp(model, "RP_testc",8) || !strncasecmp(model, "imx477", 6) // from PyDNG || !strncasecmp(model, "RP_imx477",9)) { const long offsets[] = { //IMX477 offsets 3375104, //2028x1080 12bit 4751360, //2028x1520 12bit 18711040, //4056x3040 12bit 1015808, //1012x760 10bit -1 //Marker for end of table }; int offset_idx; for (offset_idx=0; offsets[offset_idx]!=-1; offset_idx++) { if(!fseek (ifp, -offsets[offset_idx], SEEK_END) && fread (head, 1, 32, ifp) && !strncmp(head,"BRCM", 4)) { fseek(ifp, -32, SEEK_CUR); strcpy (make, "RaspberryPi"); strcpy(model, "RP_imx477"); // Force single model black = (offset_idx == 3) ? 64 : 256; parse_raspberrypi(); break; } } } else if (!strncasecmp(model, "RP_imx", 6)) { const long offsets[] = { //IMX219 offsets 10270208, //8MPix 3280x2464 2678784, //1920x1080 2628608, //1640x1232 1963008, //1640x922 1233920, //1280x720 445440, //640x480 -1 //Marker for end of table }; int offset_idx; for (offset_idx = 0; offsets[offset_idx] != -1; offset_idx++) { if (!fseek(ifp, -offsets[offset_idx], SEEK_END) && fread(head, 1, 32, ifp) && !strncmp(head, "BRCM", 4)) { fseek(ifp, -32, SEEK_CUR); strcpy(make, "RaspberryPi"); black = 66; parse_raspberrypi(); break; } } } else if (!strncasecmp(model, "RP_OV", 5) || !strncasecmp(model, "ov5647", 6)) { const long offsets[] = { 6404096, //5MPix 2592x1944 2717696, //1920x1080 1625600, //1296x972 1233920, //1296x730 445440, //640x480 -1 //Marker for end of table }; int offset_idx; for (offset_idx = 0; offsets[offset_idx] != -1; offset_idx++) { if (!fseek(ifp, -offsets[offset_idx], SEEK_END) && fread(head, 1, 32, ifp) && !strncmp(head, "BRCM", 4)) { fseek(ifp, -32, SEEK_CUR); strcpy(make, "RaspberryPi"); strcpy(model, "ov5647"); // Force single model width = raw_width; //Defaults raw_width = 2611; filters = 0x16161616; black = 16; parse_raspberrypi(); break; } } } }// else is_raw = 0; #else fseek(ifp, 0, SEEK_END); int sz = ftell(ifp); if (!strncmp(model, "RP_imx219", 9) && sz >= 0x9cb600 && !fseek(ifp, -0x9cb600, SEEK_END) && fread(head, 1, 0x20, ifp) && !strncmp(head, "BRCM", 4)) { strcpy(make, "Broadcom"); strcpy(model, "RPi IMX219"); if (raw_height > raw_width) flip = 5; data_offset = ftell(ifp) + 0x8000 - 0x20; parse_broadcom(); black = 66; maximum = 0x3ff; load_raw = &LibRaw::broadcom_load_raw; thumb_offset = 0; thumb_length = sz - 0x9cb600 - 1; } else if (!(strncmp(model, "ov5647", 6) && strncmp(model, "RP_OV5647", 9)) && sz >= 0x61b800 && !fseek(ifp, -0x61b800, SEEK_END) && fread(head, 1, 0x20, ifp) && !strncmp(head, "BRCM", 4)) { strcpy(make, "Broadcom"); if (!strncmp(model, "ov5647", 6)) strcpy(model, "RPi OV5647 v.1"); else strcpy(model, "RPi OV5647 v.2"); if (raw_height > raw_width) flip = 5; data_offset = ftell(ifp) + 0x8000 - 0x20; parse_broadcom(); black = 16; maximum = 0x3ff; load_raw = &LibRaw::broadcom_load_raw; thumb_offset = 0; thumb_length = sz - 0x61b800 - 1; } else is_raw = 0; #endif } // make sure strings are terminated desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0; for (i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++) { if (strcasestr(make, CorpTable[i].CorpName)) { /* Simplify company names */ maker_index = CorpTable[i].CorpId; break; } } if (makeIs(LIBRAW_CAMERAMAKER_HMD_Global) && !strncasecmp(model, "Nokia", 5)) { maker_index = LIBRAW_CAMERAMAKER_Nokia; } else if (makeIs(LIBRAW_CAMERAMAKER_JK_Imaging) && !strncasecmp(model, "Kodak", 5)) { maker_index = LIBRAW_CAMERAMAKER_Kodak; } else if (makeIs(LIBRAW_CAMERAMAKER_Ricoh) && !strncasecmp(model, "PENTAX", 6)) { maker_index = LIBRAW_CAMERAMAKER_Pentax; } for (i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++) { if (maker_index == (unsigned)CorpTable[i].CorpId) { strcpy(make, CorpTable[i].CorpName); break; } } if ((makeIs(LIBRAW_CAMERAMAKER_Kodak) || makeIs(LIBRAW_CAMERAMAKER_Leica)) && ((cp = strcasestr(model, " DIGITAL CAMERA")) || (cp = strstr(model, "FILE VERSION")))) { *cp = 0; } remove_trailing_spaces(make, sizeof(make)); remove_trailing_spaces(model, sizeof(model)); i = int(strbuflen(make)); /* Remove make from model */ if (!strncasecmp(model, make, i) && model[i++] == ' ') memmove(model, model + i, 64 - i); if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && !strncmp(model, "FinePix", 7)) { memmove(model, model + 7, strlen(model) - 6); if (model[0] == ' ') { memmove(model, model + 1, strlen(model)); } } else if ((makeIs(LIBRAW_CAMERAMAKER_Kodak) || makeIs(LIBRAW_CAMERAMAKER_Konica)) && !strncmp(model, "Digital Camera ", 15)) { memmove(model, model + 15, strlen(model) - 14); } desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0; if (!is_raw) goto notraw; if (!height) height = raw_height; if (!width) width = raw_width; identify_finetune_pentax(); if (dng_version) { if (filters == UINT_MAX) filters = 0; if (!filters) colors = tiff_samples; switch (tiff_compress) { case 0: // Compression not set, assuming uncompressed case 1: // Uncompressed float: decoder set in apply_tiff for valid files; not set for non-valid with sampleformat==3 if ((load_raw != &LibRaw::uncompressed_fp_dng_load_raw) && (tiff_sampleformat != 3)) load_raw = &LibRaw::packed_dng_load_raw; break; case 7: load_raw = &LibRaw::lossless_dng_load_raw; break; case 8: if (tiff_sampleformat == 3 && tiff_bps > 8 && (tiff_bps % 8 == 0) && tiff_bps <= 32) load_raw = &LibRaw::deflate_dng_load_raw; else if((tiff_sampleformat == 0 || tiff_sampleformat == 1) && tiff_bps>=8 && tiff_bps <=16) load_raw = &LibRaw::deflate_dng_load_raw; break; #ifdef USE_GPRSDK case 9: load_raw = &LibRaw::vc5_dng_load_raw_placeholder; break; #endif case 34892: load_raw = &LibRaw::lossy_dng_load_raw; break; default: load_raw = 0; } GetNormalizedModel(); if (makeIs(LIBRAW_CAMERAMAKER_Leica)) { if (!strcmp(model, "SL2")) height -= 3; if (!strncasecmp(model, "Q2 MONO",7)) height -= 18; } else if (makeIs(LIBRAW_CAMERAMAKER_Olympus) && (OlyID == OlyID_STYLUS_1) && // don't use normalized_model below, it is 'Stylus 1' (strchr(model+6, 's') || strchr(model+6, 'S'))) { width -= 16; } goto dng_skip; } if (makeIs(LIBRAW_CAMERAMAKER_Canon) && !fsize && tiff_bps != 15) { bool fromtable = false; if (!load_raw) load_raw = &LibRaw::lossless_jpeg_load_raw; for (i = 0; i < int(sizeof canon / sizeof *canon); i++) if (raw_width == canon[i][0] && raw_height == canon[i][1]) { width = raw_width - (left_margin = canon[i][2]); height = raw_height - (top_margin = canon[i][3]); width -= canon[i][4]; height -= canon[i][5]; mask[0][1] = canon[i][6]; mask[0][3] = -canon[i][7]; mask[1][1] = canon[i][8]; mask[1][3] = -canon[i][9]; if (canon[i][10]) filters = canon[i][10] * 0x01010101U; fromtable = true; } if ((unique_id | 0x20000ULL) == 0x2720000ULL) // "PowerShot G11", "PowerShot S90": 0x2700000, 0x2720000 // possibly "PowerShot SX120 IS" (if not chdk hack?): 0x2710000 { left_margin = 8; top_margin = 16; } if(!fromtable && imCanon.AverageBlackLevel) // not known, but metadata known { FORC4 cblack[c] = imCanon.ChannelBlackLevel[c]; black = cblack[4] = cblack[5] = 0; // Prevent automatic BL calculation mask[0][3] = 1; mask[0][1] = 2; if ((imCanon.SensorWidth == raw_width) && (imCanon.SensorHeight == raw_height)) { left_margin = (imCanon.DefaultCropAbsolute.l+1) & 0xfffe; // round to 2 width = imCanon.DefaultCropAbsolute.r - left_margin; top_margin = (imCanon.DefaultCropAbsolute.t +1) & 0xfffe; height = imCanon.DefaultCropAbsolute.b - top_margin; } } } identify_finetune_by_filesize(fsize); if (!strcmp(model, "KAI-0340") && find_green(16, 16, 3840, 5120) < 25) { height = 480; top_margin = filters = 0; strcpy(model, "C603"); } GetNormalizedModel(); identify_finetune_dcr(head, fsize, flen); /* Early reject for damaged images */ if (!load_raw || height < 22 || width < 22 || (tiff_bps > 16 && (load_raw != &LibRaw::deflate_dng_load_raw && load_raw != &LibRaw::uncompressed_fp_dng_load_raw)) || tiff_samples > 4 || colors > 4 || colors < 1 /* alloc in unpack() may be fooled by size adjust */ || ((int)width + (int)left_margin > 65535) || ((int)height + (int)top_margin > 65535)) { is_raw = 0; RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY, 1, 2); return; } if (!model[0]) { sprintf(model, "%dx%d", width, height); strcpy(normalized_model, model); } if (!(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_ZEROFILTERS_FOR_MONOCHROMETIFFS) && (filters == UINT_MAX)) // Default dcraw behaviour filters = 0x94949494; else if (filters == UINT_MAX) { if (tiff_nifds > 0 && tiff_samples == 1) { colors = 1; filters = 0; } else filters = 0x94949494; } if (thumb_offset && !thumb_height) { fseek(ifp, thumb_offset, SEEK_SET); if (ljpeg_start(&jh, 1)) { thumb_width = jh.wide; thumb_height = jh.high; } } dng_skip: if (dng_version) identify_process_dng_fields(); /* Early reject for damaged images again (after dng fields processing) */ if (!load_raw || height < 22 || width < 22 || (tiff_bps > 16 && (load_raw != &LibRaw::deflate_dng_load_raw && load_raw != &LibRaw::uncompressed_fp_dng_load_raw )) || ((load_raw == &LibRaw::deflate_dng_load_raw || load_raw == &LibRaw::uncompressed_fp_dng_load_raw) && (tiff_bps < 16 || tiff_bps > 32 || (tiff_bps % 8)) ) ||tiff_samples > 4 || colors > 4 || colors < 1) { is_raw = 0; RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY, 1, 2); return; } { // Check cam_mul range int cmul_ok = 1; FORCC if (cam_mul[c] <= 0.001f) cmul_ok = 0; ; if (cmul_ok) { double cmin = cam_mul[0], cmax; double cnorm[4]; FORCC cmin = MIN(cmin, cam_mul[c]); FORCC cnorm[c] = cam_mul[c] / cmin; cmax = cmin = cnorm[0]; FORCC { cmin = MIN(cmin, cnorm[c]); cmax = MIN(cmax, cnorm[c]); } if (cmin <= 0.01f || cmax > 100.f) cmul_ok = false; } if (!cmul_ok) { if (cam_mul[0] > 0) cam_mul[0] = 0; cam_mul[3] = 0; } } if ((use_camera_matrix & (((use_camera_wb || dng_version)?1:0) | 0x2)) && cmatrix[0][0] > 0.125) { memcpy(rgb_cam, cmatrix, sizeof cmatrix); raw_color = 0; } if (raw_color && !CM_found) CM_found = adobe_coeff(maker_index, normalized_model); else if ((imgdata.color.cam_xyz[0][0] < 0.01) && !CM_found) CM_found = adobe_coeff(maker_index, normalized_model, 1); if (load_raw == &LibRaw::kodak_radc_load_raw) if ((raw_color) && !CM_found) CM_found = adobe_coeff(LIBRAW_CAMERAMAKER_Apple, "Quicktake"); if ((maker_index != LIBRAW_CAMERAMAKER_Unknown) && normalized_model[0]) SetStandardIlluminants (maker_index, normalized_model); // Clear erroneous fuji_width if not set through parse_fuji or for DNG if (fuji_width && !dng_version && !(imgdata.process_warnings & LIBRAW_WARN_PARSEFUJI_PROCESSED)) fuji_width = 0; if (fuji_width) { fuji_width = width >> int(!fuji_layout); filters = fuji_width & 1 ? 0x94949494 : 0x49494949; width = (height >> fuji_layout) + fuji_width; height = width - 1; pixel_aspect = 1; // Prevent incorrect-sized fuji-rotated files if (INT64(width)*INT64(height) > INT64(raw_width) * INT64(raw_height) * 8LL) is_raw = 0; } else { if (raw_height < height) raw_height = height; if (raw_width < width) raw_width = width; } if (!tiff_bps) tiff_bps = 12; if (!maximum) { maximum = (1 << tiff_bps) - 1; if (maximum < 0x10000 && curve[maximum] > 0 && load_raw == &LibRaw::sony_arw2_load_raw) maximum = curve[maximum]; } if (maximum > 0xffff) maximum = 0xffff; if (!load_raw || height < 22 || width < 22 || (tiff_bps > 16 && (load_raw != &LibRaw::deflate_dng_load_raw && load_raw != &LibRaw::uncompressed_fp_dng_load_raw)) || tiff_samples > 6 || colors > 4) is_raw = 0; if (raw_width < 22 || raw_width > 64000 || raw_height < 22 || pixel_aspect < 0.1 || pixel_aspect > 10. || raw_height > 64000) is_raw = 0; if(raw_width <= left_margin || raw_height <= top_margin) is_raw = 0; if (dng_version && (tiff_samples < 1 || tiff_samples > 4)) is_raw = 0; // we do not handle DNGs with more than 4 values per pixel #ifdef LIBRAW_OLD_VIDEO_SUPPORT #ifdef NO_JASPER if (load_raw == &LibRaw::redcine_load_raw) { is_raw = 0; imgdata.process_warnings |= LIBRAW_WARN_NO_JASPER; } #endif #endif #ifdef NO_JPEG if (load_raw == &LibRaw::kodak_jpeg_load_raw || load_raw == &LibRaw::lossy_dng_load_raw) { is_raw = 0; imgdata.process_warnings |= LIBRAW_WARN_NO_JPEGLIB; } #endif if (!cdesc[0]) strcpy(cdesc, colors == 3 ? "RGBG" : "GMCY"); if (!raw_height) raw_height = height; if (!raw_width) raw_width = width; if (filters > 999 && colors == 3) filters |= ((filters >> 2 & 0x22222222) | (filters << 2 & 0x88888888)) & filters << 1; notraw: if (flip == (int)UINT_MAX) flip = tiff_flip; if (flip == (int)UINT_MAX) flip = 0; // Convert from degrees to bit-field if needed if (flip > 89 || flip < -89) { switch ((flip + 3600) % 360) { case 270: flip = 5; break; case 180: flip = 3; break; case 90: flip = 6; break; } } if (pana_bpp) imgdata.color.raw_bps = pana_bpp; else if ((load_raw == &LibRaw::phase_one_load_raw) || (load_raw == &LibRaw::phase_one_load_raw_s) || (load_raw == &LibRaw::phase_one_load_raw_c)) imgdata.color.raw_bps = ph1.format; else imgdata.color.raw_bps = tiff_bps; RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY, 1, 2); } void LibRaw::identify_process_dng_fields() { if (!dng_version) return; // Cleanup inset_crops if set by makernotes parser imgdata.sizes.raw_inset_crops[0].cleft = imgdata.sizes.raw_inset_crops[0].ctop = imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[1].ctop = 0xffff; imgdata.sizes.raw_inset_crops[0].cwidth = imgdata.sizes.raw_inset_crops[0].cheight = imgdata.sizes.raw_inset_crops[1].cwidth = imgdata.sizes.raw_inset_crops[1].cheight = 0; int c; { /* copy DNG data from per-IFD field to color.dng */ int iifd = find_ifd_by_offset(data_offset); int pifd = find_ifd_by_offset(thumb_offset); #define IFDCOLORINDEX(ifd, subset, bit) \ (tiff_ifd[ifd].dng_color[subset].parsedfields & bit) \ ? ifd \ : ((tiff_ifd[0].dng_color[subset].parsedfields & bit) ? 0 : -1) #define IFDLEVELINDEX(ifd, bit) \ (tiff_ifd[ifd].dng_levels.parsedfields & bit) \ ? ifd \ : ((tiff_ifd[0].dng_levels.parsedfields & bit) ? 0 : -1) #define COPYARR(to, from) memmove(&to, &from, sizeof(from)) if (iifd < (int)tiff_nifds && iifd >= 0) { int sidx; // Per field, not per structure if (!(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DONT_CHECK_DNG_ILLUMINANT)) { int illidx[2], cmidx[2], calidx[2], abidx; for (int i = 0; i < 2; i++) { illidx[i] = IFDCOLORINDEX(iifd, i, LIBRAW_DNGFM_ILLUMINANT); cmidx[i] = IFDCOLORINDEX(iifd, i, LIBRAW_DNGFM_COLORMATRIX); calidx[i] = IFDCOLORINDEX(iifd, i, LIBRAW_DNGFM_CALIBRATION); } abidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_ANALOGBALANCE); // Data found, all in same ifd, illuminants are inited if (illidx[0] >= 0 && illidx[0] < (int)tiff_nifds && illidx[0] == illidx[1] && illidx[0] == cmidx[0] && illidx[0] == cmidx[1] && tiff_ifd[illidx[0]].dng_color[0].illuminant > 0 && tiff_ifd[illidx[0]].dng_color[1].illuminant > 0) { sidx = illidx[0]; // => selected IFD double cc[4][4], cm[4][3], cam_xyz[4][3]; // CM -> Color Matrix // CC -> Camera calibration for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) cc[j][i] = i == j; int colidx = -1; // IS D65 here? for (int i = 0; i < 2; i++) { if (tiff_ifd[sidx].dng_color[i].illuminant == LIBRAW_WBI_D65) { colidx = i; break; } } // Other daylight-type ill if (colidx < 0) for (int i = 0; i < 2; i++) { int ill = tiff_ifd[sidx].dng_color[i].illuminant; if (ill == LIBRAW_WBI_Daylight || ill == LIBRAW_WBI_D55 || ill == LIBRAW_WBI_D75 || ill == LIBRAW_WBI_D50 || ill == LIBRAW_WBI_Flash) { colidx = i; break; } } if (colidx >= 0) // Selected { // Init camera matrix from DNG FORCC for (int j = 0; j < 3; j++) cm[c][j] = tiff_ifd[sidx].dng_color[colidx].colormatrix[c][j]; if (calidx[colidx] == sidx) { for (int i = 0; i < colors && i < 4; i++) FORCC cc[i][c] = tiff_ifd[sidx].dng_color[colidx].calibration[i][c]; } if (abidx == sidx) for (int i = 0; i < colors && i < 4; i++) FORCC cc[i][c] *= tiff_ifd[sidx].dng_levels.analogbalance[i]; int j; FORCC for (int i = 0; i < 3; i++) for (cam_xyz[c][i] = j = 0; j < colors && j < 4; j++) cam_xyz[c][i] += cc[c][j] * cm[j][i]; // add AsShotXY later * xyz[i]; cam_xyz_coeff(cmatrix, cam_xyz); } } } bool noFujiDNGCrop = makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && (!strcmp(normalized_model, "S3Pro") || !strcmp(normalized_model, "S5Pro") || !strcmp(normalized_model, "S2Pro")); if (!noFujiDNGCrop) // Promote DNG Crops to raw_inset_crops { sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_CROPORIGIN); int sidx2 = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_CROPSIZE); if (sidx >= 0 && sidx == sidx2 && tiff_ifd[sidx].dng_levels.default_crop[2] > 0 && tiff_ifd[sidx].dng_levels.default_crop[3] > 0) { int lm = tiff_ifd[sidx].dng_levels.default_crop[0]; int tm = tiff_ifd[sidx].dng_levels.default_crop[1]; int ww = tiff_ifd[sidx].dng_levels.default_crop[2]; int hh = tiff_ifd[sidx].dng_levels.default_crop[3]; if ((lm + ww < int(raw_width) + int(left_margin)) && (tm + hh < int(raw_height) + int(top_margin))) // Crop data is correct { imgdata.sizes.raw_inset_crops[0].cleft = left_margin + lm; imgdata.sizes.raw_inset_crops[0].cwidth = ww; imgdata.sizes.raw_inset_crops[0].ctop = top_margin + tm; imgdata.sizes.raw_inset_crops[0].cheight = hh; int sidx3 = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_USERCROP); if (sidx3 >= 0 && sidx3 == sidx) // No need to check values range, it is checked at parse { int dt = int(imgdata.sizes.raw_inset_crops[0].cheight * tiff_ifd[sidx].dng_levels.user_crop[0]); int dl = int(imgdata.sizes.raw_inset_crops[0].cwidth * tiff_ifd[sidx].dng_levels.user_crop[1]); int db = int(imgdata.sizes.raw_inset_crops[0].cheight * tiff_ifd[sidx].dng_levels.user_crop[2]); int dr = int(imgdata.sizes.raw_inset_crops[0].cwidth * tiff_ifd[sidx].dng_levels.user_crop[3]); int dh = db - dt; int dw = dr - dl; if (dh > 0 && dw > 0 && dh < imgdata.sizes.raw_inset_crops[0].cheight // No need to repeat crop for 0,0,1,1 && dw < imgdata.sizes.raw_inset_crops[0].cwidth) { imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft + dl; imgdata.sizes.raw_inset_crops[1].cwidth = dw; imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop + dt; imgdata.sizes.raw_inset_crops[1].cheight = dh; } } } } } if (!(imgdata.color.dng_color[0].parsedfields & LIBRAW_DNGFM_FORWARDMATRIX)) // Not set already (Leica makernotes) { sidx = IFDCOLORINDEX(iifd, 0, LIBRAW_DNGFM_FORWARDMATRIX); if (sidx >= 0) COPYARR(imgdata.color.dng_color[0].forwardmatrix, tiff_ifd[sidx].dng_color[0].forwardmatrix); } if (!(imgdata.color.dng_color[1].parsedfields & LIBRAW_DNGFM_FORWARDMATRIX)) // Not set already (Leica makernotes) { sidx = IFDCOLORINDEX(iifd, 1, LIBRAW_DNGFM_FORWARDMATRIX); if (sidx >= 0) COPYARR(imgdata.color.dng_color[1].forwardmatrix, tiff_ifd[sidx].dng_color[1].forwardmatrix); } for (int ss = 0; ss < 2; ss++) { sidx = IFDCOLORINDEX(iifd, ss, LIBRAW_DNGFM_COLORMATRIX); if (sidx >= 0) COPYARR(imgdata.color.dng_color[ss].colormatrix, tiff_ifd[sidx].dng_color[ss].colormatrix); sidx = IFDCOLORINDEX(iifd, ss, LIBRAW_DNGFM_CALIBRATION); if (sidx >= 0) COPYARR(imgdata.color.dng_color[ss].calibration, tiff_ifd[sidx].dng_color[ss].calibration); sidx = IFDCOLORINDEX(iifd, ss, LIBRAW_DNGFM_ILLUMINANT); if (sidx >= 0) imgdata.color.dng_color[ss].illuminant = tiff_ifd[sidx].dng_color[ss].illuminant; } // Levels sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_ANALOGBALANCE); if (sidx >= 0) COPYARR(imgdata.color.dng_levels.analogbalance, tiff_ifd[sidx].dng_levels.analogbalance); sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_BASELINEEXPOSURE); if (sidx >= 0) imgdata.color.dng_levels.baseline_exposure = tiff_ifd[sidx].dng_levels.baseline_exposure; sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_WHITE); if (sidx >= 0 && tiff_ifd[sidx].dng_levels.dng_whitelevel[0]) COPYARR(imgdata.color.dng_levels.dng_whitelevel, tiff_ifd[sidx].dng_levels.dng_whitelevel); else if (tiff_ifd[iifd].sample_format <= 2 && tiff_ifd[iifd].bps > 0 && tiff_ifd[iifd].bps < 32) FORC4 imgdata.color.dng_levels.dng_whitelevel[c] = (1 << tiff_ifd[iifd].bps) - 1; sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_ASSHOTNEUTRAL); if (sidx >= 0) { COPYARR(imgdata.color.dng_levels.asshotneutral, tiff_ifd[sidx].dng_levels.asshotneutral); if (imgdata.color.dng_levels.asshotneutral[0]) { cam_mul[3] = 0; FORCC if (fabs(imgdata.color.dng_levels.asshotneutral[c]) > 0.0001) cam_mul[c] = 1 / imgdata.color.dng_levels.asshotneutral[c]; } } sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_BLACK); if (sidx >= 0) { imgdata.color.dng_levels.dng_fblack = tiff_ifd[sidx].dng_levels.dng_fblack; imgdata.color.dng_levels.dng_black = tiff_ifd[sidx].dng_levels.dng_black; COPYARR(imgdata.color.dng_levels.dng_cblack, tiff_ifd[sidx].dng_levels.dng_cblack); COPYARR(imgdata.color.dng_levels.dng_fcblack, tiff_ifd[sidx].dng_levels.dng_fcblack); } if (pifd >= 0) { sidx = IFDLEVELINDEX(pifd, LIBRAW_DNGFM_PREVIEWCS); if (sidx >= 0) imgdata.color.dng_levels.preview_colorspace = tiff_ifd[sidx].dng_levels.preview_colorspace; } sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_OPCODE2); if (sidx >= 0) meta_offset = tiff_ifd[sidx].opcode2_offset; sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_LINTABLE); INT64 linoff = -1; int linlen = 0; if (sidx >= 0) { linoff = tiff_ifd[sidx].lineartable_offset; linlen = tiff_ifd[sidx].lineartable_len; } if (linoff >= 0 && linlen > 0) { INT64 pos = ftell(ifp); fseek(ifp, linoff, SEEK_SET); linear_table(linlen); fseek(ifp, pos, SEEK_SET); } // Need to add curve too } /* Copy DNG black level to LibRaw's */ if (load_raw == &LibRaw::lossy_dng_load_raw) { maximum = 0xffff; FORC4 imgdata.color.linear_max[c] = imgdata.color.dng_levels.dng_whitelevel[c] = 0xffff; } else { maximum = imgdata.color.dng_levels.dng_whitelevel[0]; } black = imgdata.color.dng_levels.dng_black; if (tiff_samples == 2 && !imgdata.color.dng_levels.dng_cblack[2] && !imgdata.color.dng_levels.dng_cblack[3] && (imgdata.color.dng_levels.dng_cblack[4] == 1) && (imgdata.color.dng_levels.dng_cblack[5] == 1) && (imgdata.color.dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1] == tiff_samples) ) { black = imgdata.color.dng_levels.dng_cblack[shot_select]; imgdata.color.dng_levels.dng_cblack[0] = imgdata.color.dng_levels.dng_cblack[1] = 0; imgdata.color.dng_levels.dng_cblack[4] = imgdata.color.dng_levels.dng_cblack[5] = 0; imgdata.color.dng_levels.dng_fcblack[0] = imgdata.color.dng_levels.dng_fcblack[1] = 0.0f; imgdata.color.dng_levels.dng_fcblack[4] = imgdata.color.dng_levels.dng_fcblack[5] = 0.0f; } else if (tiff_samples == 2 && imgdata.color.dng_levels.dng_cblack[4] * imgdata.color.dng_levels.dng_cblack[5] * tiff_samples == imgdata.color.dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1]) { unsigned ff = filters; if (filters > 999 && colors == 3) filters |= ((filters >> 2 & 0x22222222) | (filters << 2 & 0x88888888)) & filters << 1; /* Special case, Fuji SuperCCD dng */ int csum[4] = { 0,0,0,0 }, ccount[4] = { 0,0,0,0 }; int i = 6 + shot_select; for (unsigned row = 0; row < imgdata.color.dng_levels.dng_cblack[4]; row++) for (unsigned col = 0; col < imgdata.color.dng_levels.dng_cblack[5]; col++) { csum[FC(row, col)] += imgdata.color.dng_levels.dng_cblack[i]; ccount[FC(row, col)]++; i += tiff_samples; } for (int q = 0; q < 4; q++) if (ccount[q]) imgdata.color.dng_levels.dng_cblack[q] += csum[q] / ccount[q]; imgdata.color.dng_levels.dng_cblack[4] = imgdata.color.dng_levels.dng_cblack[5] = 0; filters = ff; } else if (tiff_samples > 2 && tiff_samples <= 4 && imgdata.color.dng_levels.dng_cblack[4] * imgdata.color.dng_levels.dng_cblack[5] * tiff_samples == imgdata.color.dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1]) { /* Special case, per_channel blacks in RepeatDim, average for per-channel */ int csum[4] = { 0,0,0,0 }, ccount[4] = { 0,0,0,0 }; int i = 6; for (unsigned row = 0; row < imgdata.color.dng_levels.dng_cblack[4]; row++) for (unsigned col = 0; col < imgdata.color.dng_levels.dng_cblack[5]; col++) for (unsigned q = 0; q < tiff_samples && q < 4; q++) { csum[q] += imgdata.color.dng_levels.dng_cblack[i]; ccount[q]++; i++; } for (int q = 0; q < 4; q++) if (ccount[q]) imgdata.color.dng_levels.dng_cblack[q] += csum[q] / ccount[q]; imgdata.color.dng_levels.dng_cblack[4] = imgdata.color.dng_levels.dng_cblack[5] = 0; } memmove(cblack, imgdata.color.dng_levels.dng_cblack, sizeof(cblack)); if (iifd < (int)tiff_nifds && iifd >= 0) { int sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_LINEARRESPONSELIMIT); if (sidx >= 0) { imgdata.color.dng_levels.LinearResponseLimit = tiff_ifd[sidx].dng_levels.LinearResponseLimit; if (imgdata.color.dng_levels.LinearResponseLimit > 0.1 && imgdata.color.dng_levels.LinearResponseLimit <= 1.0) { // And approx promote it to linear_max: int bl4 = 0, bl64 = 0; for (int chan = 0; chan < colors && chan < 4; chan++) bl4 += cblack[chan]; bl4 /= LIM(colors, 1, 4); if (cblack[4] * cblack[5] > 0) { unsigned cnt = 0; for (unsigned q = 0; q < 4096 && q < cblack[4] * cblack[5]; q++) { bl64 += cblack[q + 6]; cnt++; } bl64 /= LIM(cnt, 1, 4096); } int rblack = black + bl4 + bl64; for (int chan = 0; chan < colors && chan < 4; chan++) imgdata.color.linear_max[chan] = (maximum - rblack) * imgdata.color.dng_levels.LinearResponseLimit + rblack; if (imgdata.color.linear_max[1] && !imgdata.color.linear_max[3]) imgdata.color.linear_max[3] = imgdata.color.linear_max[1]; } } } } } void LibRaw::identify_finetune_pentax() { if (dng_version && data_offset) { for(int i = 0; i < (int)tiff_nifds; i++) if (tiff_ifd[i].offset == data_offset) { if (tiff_ifd[i].phint == 34892) return; // Linear DNG made from Pentax source break; } } if (makeIs(LIBRAW_CAMERAMAKER_Pentax) || makeIs(LIBRAW_CAMERAMAKER_Samsung)) { if (height == 2624 && width == 3936) // Pentax K10D, Samsung GX10; { height = 2616; width = 3896; } if (height == 3136 && width == 4864) // Pentax K20D, Samsung GX20; { height = 3124; width = 4688; filters = 0x16161616; } } if (makeIs(LIBRAW_CAMERAMAKER_Pentax)) { if ((width == 4352) && ((unique_id == PentaxID_K_r) || (unique_id == PentaxID_K_x))) { width = 4309; filters = 0x16161616; } if ((width >= 4960) && ((unique_id == PentaxID_K_5) || (unique_id == PentaxID_K_5_II) || (unique_id == PentaxID_K_5_II_s))) { left_margin = 10; width = 4950; filters = 0x16161616; } if ((width == 6080) && (unique_id == PentaxID_K_70)) { height = 4016; top_margin = 32; width = 6020; left_margin = 60; } if ((width == 4736) && (unique_id == PentaxID_K_7)) { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; } if ((width == 6080) && (unique_id == PentaxID_K_3_II)) { left_margin = 4; width = 6040; } if ((width == 6304) && (unique_id == PentaxID_K_3_III)) // From DNG ActiveArea { left_margin = 26; width = 6224; top_margin = 34; height = 4160; } if ((width == 6112) && (unique_id == PentaxID_KP)) { // From DNG, maybe too strict left_margin = 54; top_margin = 28; width = 6028; height = raw_height - top_margin; } if ((width == 6080) && (unique_id == PentaxID_K_3)) { left_margin = 4; width = 6040; } if ((width == 7424) && (unique_id == PentaxID_645D)) { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29; left_margin = 48; } } else if (makeIs(LIBRAW_CAMERAMAKER_Ricoh) && (height == 3014) && (width == 4096)) // Ricoh GX200 width = 4014; } void LibRaw::identify_finetune_by_filesize(int fsize) { if (fsize == 4771840) { // hack Nikon 3mpix: E880, E885, E990, E995; // Olympus C-3030Z if (!timestamp && nikon_e995()) strcpy(model, "E995"); } else if (fsize == 2940928) { // hack Nikon 2mpix: E2100, E2500 if (!timestamp && !nikon_e2100()) strcpy(model, "E2500"); } else if (fsize == 4775936) { // hack Nikon 3mpix: E3100, E3200, E3500, E3700; // Pentax "Optio 33WR"; // Olympus C-740UZ if (!timestamp) nikon_3700(); } else if (fsize == 5869568) { // hack Nikon 4mpix: E4300; // hack Minolta "DiMAGE Z2" if (!timestamp && minolta_z2()) { maker_index = LIBRAW_CAMERAMAKER_Minolta; strcpy(make, "Minolta"); strcpy(model, "DiMAGE Z2"); } } } void LibRaw::identify_finetune_dcr(char head[64], int fsize, int flen) { static const short pana[][6] = { // raw_width, raw_height, left_margin, top_margin, width_increment, // height_increment {3130, 1743, 4, 0, -6, 0}, /* 00 */ {3130, 2055, 4, 0, -6, 0}, /* 01 */ {3130, 2319, 4, 0, -6, 0}, /* 02 DMC-FZ8 */ {3170, 2103, 18, 0, -42, 20}, /* 03 */ {3170, 2367, 18, 13, -42, -21}, /* 04 */ {3177, 2367, 0, 0, -1, 0}, /* 05 DMC-L1 */ {3304, 2458, 0, 0, -1, 0}, /* 06 DMC-FZ30 */ {3330, 2463, 9, 0, -5, 0}, /* 07 DMC-FZ18 */ {3330, 2479, 9, 0, -17, 4}, /* 08 */ {3370, 1899, 15, 0, -44, 20}, /* 09 */ {3370, 2235, 15, 0, -44, 20}, /* 10 */ {3370, 2511, 15, 10, -44, -21}, /* 11 */ {3690, 2751, 3, 0, -8, -3}, /* 12 DMC-FZ50 */ {3710, 2751, 0, 0, -3, 0}, /* 13 DMC-L10 */ {3724, 2450, 0, 0, 0, -2}, /* 14 */ {3770, 2487, 17, 0, -44, 19}, /* 15 */ {3770, 2799, 17, 15, -44, -19}, /* 16 */ {3880, 2170, 6, 0, -6, 0}, /* 17 DMC-LX1 */ {4060, 3018, 0, 0, 0, -2}, /* 18 DMC-FZ35, DMC-FZ38 */ {4290, 2391, 3, 0, -8, -1}, /* 19 DMC-LX2 */ {4330, 2439, 17, 15, -44, -19}, /* 20 "D-LUX 3" */ {4508, 2962, 0, 0, -3, -4}, /* 21 */ {4508, 3330, 0, 0, -3, -6}, /* 22 */ {10480, 7794, 0, 0, -2, 0}, /* 23: G9 in high-res */ }; int i,c; struct jhead jh; if (makeIs(LIBRAW_CAMERAMAKER_Canon) && ( !tiff_flip || unique_id == CanonID_EOS_40D) && !(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CANON_IGNORE_MAKERNOTES_ROTATION) && imCanon.MakernotesFlip) { tiff_flip = imCanon.MakernotesFlip; } else if (makeIs(LIBRAW_CAMERAMAKER_Nikon)) { if (!load_raw) load_raw = &LibRaw::packed_load_raw; if (model[0] == 'E') // Nikon E8800, E8700, E8400, E5700, E5400, E5000, // others are diag hacks? load_flags |= !data_offset << 2 | 2; } /* Set parameters based on camera name (for non-DNG files). */ /* Always 512 for arw2_load_raw */ else if (makeIs(LIBRAW_CAMERAMAKER_Sony) && (raw_width > 3888) && !black && !cblack[0]) { black = (load_raw == &LibRaw::sony_arw2_load_raw) ? 512 : (128 << (tiff_bps - 12)); } if (is_foveon) { if (height * 2 < width) pixel_aspect = 0.5; if (height > width) pixel_aspect = 2; filters = 0; } else if (makeIs(LIBRAW_CAMERAMAKER_Pentax)) { if ((unique_id == PentaxID_K_1) || (unique_id == PentaxID_K_1_Mark_II)) { top_margin = 18; height = raw_height - top_margin; if (raw_width == 7392) { left_margin = 6; width = 7376; } } else if (unique_id == PentaxID_Optio_S_V101) { // (fsize == 3178560) cam_mul[0] *= 4; cam_mul[2] *= 4; } else if (unique_id == PentaxID_Optio_33WR) { // (fsize == 4775936) flip = 1; filters = 0x16161616; } else if (unique_id == PentaxID_staristD) { load_raw = &LibRaw::unpacked_load_raw; /* data_error = -1; */ /* No way to know why data_error was raised in dcraw.c, looks not needed esp. for unpacked_load_raw */ } else if (unique_id == PentaxID_staristDS) { height -= 2; } } else if (makeIs(LIBRAW_CAMERAMAKER_Canon)) { if (tiff_bps == 15) { // Canon sRAW if (width == 3344) width = 3272; else if (width == 3872) width = 3866; if (height > width) { SWAP(height, width); SWAP(raw_height, raw_width); } if (width == 7200 && height == 3888) { // Canon EOS 5DS (R); raw_width = width = 6480; raw_height = height = 4320; } filters = 0; tiff_samples = colors = 3; load_raw = &LibRaw::canon_sraw_load_raw; } if (!strcmp(normalized_model, "PowerShot 600")) { height = 613; width = 854; raw_width = 896; colors = 4; filters = 0xe1e4e1e4; load_raw = &LibRaw::canon_600_load_raw; } else if (!strcmp(normalized_model, "PowerShot A5") || !strcmp(normalized_model, "PowerShot A5 Zoom")) { height = 773; width = 960; raw_width = 992; pixel_aspect = 256 / 235.0; filters = 0x1e4e1e4e; goto canon_a5; } else if (!strcmp(normalized_model, "PowerShot A50")) { height = 968; width = 1290; raw_width = 1320; filters = 0x1b4e4b1e; goto canon_a5; } else if (!strcmp(normalized_model, "PowerShot Pro70")) { height = 1024; width = 1552; filters = 0x1e4b4e1b; canon_a5: colors = 4; tiff_bps = 10; load_raw = &LibRaw::packed_load_raw; load_flags = 40; } else if (!strcmp(normalized_model, "PowerShot Pro90 IS") || !strcmp(normalized_model, "PowerShot G1")) { colors = 4; filters = 0xb4b4b4b4; } else if (!strcmp(normalized_model, "PowerShot A610")) { // chdk hack if (canon_s2is()) { strcpy(model + 10, "S2 IS"); strcpy(normalized_model + 10, "S2 IS"); } } else if (!strcmp(normalized_model, "PowerShot SX220 HS")) { // chdk hack mask[1][3] = -4; top_margin = 16; left_margin = 92; } else if (!strcmp(normalized_model, "PowerShot S120")) { // chdk hack raw_width = 4192; raw_height = 3062; width = 4022; height = 3016; mask[0][0] = top_margin = 31; mask[0][2] = top_margin + height; left_margin = 120; mask[0][1] = 23; mask[0][3] = 72; } else if (!strcmp(normalized_model, "PowerShot G16")) { mask[0][0] = 0; mask[0][2] = 80; mask[0][1] = 0; mask[0][3] = 16; top_margin = 29; left_margin = 120; width = raw_width - left_margin - 48; height = raw_height - top_margin - 14; } else if (!strcmp(normalized_model, "PowerShot SX50 HS")) { top_margin = 17; } } else if (makeIs(LIBRAW_CAMERAMAKER_Nikon)) { if (!strcmp(model, "D1")) { imgdata.other.analogbalance[0] = cam_mul[0]; imgdata.other.analogbalance[2] = cam_mul[2]; imgdata.other.analogbalance[1] = imgdata.other.analogbalance[3] = cam_mul[1]; cam_mul[0] = cam_mul[1] = cam_mul[2] = 1.0f; } else if (!strcmp(model, "D1X")) { width -= 4; pixel_aspect = 0.5; } else if (!strcmp(model, "D40X") || !strcmp(model, "D60") || !strcmp(model, "D80") || !strcmp(model, "D3000")) { height -= 3; width -= 4; } else if (!strcmp(model, "D3") || !strcmp(model, "D3S") || !strcmp(model, "D700")) { width -= 4; left_margin = 2; } else if (!strcmp(model, "D3100")) { width -= 28; left_margin = 6; } else if (!strcmp(model, "D5000") || !strcmp(model, "D90")) { width -= 42; } else if (!strcmp(model, "D5100") || !strcmp(model, "D7000") || !strcmp(model, "COOLPIX A")) { width -= 44; } else if (!strcmp(model, "D3200") || !strcmp(model, "D600") || !strcmp(model, "D610") || !strncmp(model, "D800", 4)) // Nikons: D800, D800E { width -= 46; } else if (!strcmp(model, "D4") || !strcmp(model, "Df")) { width -= 52; left_margin = 2; } else if (!strcmp(model, "D500")) { // Empty - to avoid width-1 below } else if (!strncmp(model, "D40", 3) || !strncmp(model, "D50", 3) || !strncmp(model, "D70", 3)) { width--; } else if (!strcmp(model, "D100")) { if (load_flags) // compressed NEF raw_width = (width += 3) + 3; } else if (!strcmp(model, "D200")) { left_margin = 1; width -= 4; filters = 0x94949494; } else if (!strncmp(model, "D2H", 3)) // Nikons: D2H, D2Hs { left_margin = 6; width -= 14; } else if (!strncmp(model, "D2X", 3)) // Nikons: D2X, D2Xs { if (width == 3264) // in-camera Hi-speed crop: On width -= 32; else width -= 8; } else if (!strncmp(model, "D300", 4)) // Nikons: D300, D300s { width -= 32; } else if (raw_width == 4032) // Nikon "COOLPIX P7700", "COOLPIX P7800", // "COOLPIX P330", "COOLPIX P340" { if (!strcmp(normalized_model, "COOLPIX P7700")) { maximum = 65504; load_flags = 0; } else if (!strcmp(normalized_model, "COOLPIX P7800")) { maximum = 65504; load_flags = 0; } else if (!strcmp(model, "COOLPIX P340")) { load_flags = 0; } } else if (!strncmp(model, "COOLPIX P", 9) && raw_width != 4032) // Nikon "COOLPIX P1000", "COOLPIX P6000", // "COOLPIX P7000", "COOLPIX P7100" { load_flags = 24; filters = 0x94949494; /* the following 'if' is most probably obsolete, because we now read black * level from metadata */ if ((model[9] == '7') && /* P7000, P7100 */ ((iso_speed >= 400) || (iso_speed == 0)) && !strstr(software, "V1.2")) /* v. 1.2 seen for P7000 only */ black = 255; } else if (!strncmp(model, "COOLPIX B700", 12)) { load_flags = 24; } else if (!strncmp(model, "1 ", 2)) // Nikons: "1 AW1", "1 J1", "1 J2", "1 J3", "1 J4", // "1 J5", "1 S1", "1 S2", "1 V1", "1 V2", "1 V3" { height -= 2; } else if (fsize == 1581060) // hack Nikon 1mpix: E900 { simple_coeff(3); pre_mul[0] = 1.2085f; pre_mul[1] = 1.0943f; pre_mul[3] = 1.1103f; } else if ((fsize == 4771840) && // hack Nikon 3mpix: E880, E885, E990 strcmp(model, "E995")) // but not E995 { filters = 0xb4b4b4b4; simple_coeff(3); pre_mul[0] = 1.196f; pre_mul[1] = 1.246f; pre_mul[2] = 1.018f; } else if ((fsize == 4775936) && // hack Nikon 3mpix: E3100, E3200, E3500 (atoi(model + 1) < 3700)) // but not E3700; { filters = 0x49494949; } else if (fsize == 5869568) // hack Nikon 4mpix: E4300; { load_flags = 6; } else if (!strcmp(model, "E2500")) { height -= 2; load_flags = 6; colors = 4; filters = 0x4b4b4b4b; } } else if (makeIs(LIBRAW_CAMERAMAKER_Olympus)) { if (OlyID == OlyID_C_740UZ) { // (fsize == 4775936) i = find_green(12, 32, 1188864, 3576832); c = find_green(12, 32, 2383920, 2387016); if (abs(i) < abs(c)) { SWAP(i, c); load_flags = 24; } if (i < 0) filters = 0x61616161; } else if (OlyID == OlyID_C_770UZ) { height = 1718; width = 2304; filters = 0x16161616; load_raw = &LibRaw::packed_load_raw; load_flags = 30; } else { height += height & 1; if (exif_cfa) filters = exif_cfa; if (width == 4100) // Olympus E-PL2, E-PL1, E-P2, E-P1, E-620, E-600, E-5, E-30; width -= 4; if (width == 4080) // Olympus E-PM1, E-PL3, E-P3; width -= 24; if (width == 10400) // Olympus PEN-F, E-M1-II, E-M1-III, E-M1X, OM-1 width -= 12; if (width == 8200) // E-M1-III in 50Mp mode, E-M1X width -= 30; if (width == 8180) // OM-1 in 50Mp width -= 10; if (width == 9280) { // Olympus E-M5 Mark II; width -= 6; height -= 6; } if (load_raw == &LibRaw::unpacked_load_raw) { load_flags = 4; if (imOly.ValidBits == 10) load_flags += 2; } tiff_bps = imOly.ValidBits; if ((OlyID == OlyID_E_300) || (OlyID == OlyID_E_500)) { width -= 20; if (load_raw == &LibRaw::unpacked_load_raw) { maximum = 0xfc3; memset(cblack, 0, sizeof cblack); } } else if (OlyID == OlyID_STYLUS_1) { width -= 16; maximum = 0xfff; } else if (OlyID == OlyID_E_330) { width -= 30; if (load_raw == &LibRaw::unpacked_load_raw) maximum = 0xf79; } else if (OlyID == OlyID_SP_550UZ) { thumb_length = flen - (thumb_offset = 0xa39800); thumb_height = 480; thumb_width = 640; } else if (OlyID == OlyID_TG_4) { width -= 16; } else if ((OlyID == OlyID_TG_5) || (OlyID == OlyID_TG_6)) { width -= 26; } } } else if (makeIs(LIBRAW_CAMERAMAKER_RoverShot) && (fsize == 6291456)) { // RoverShot 3320AF fseek(ifp, 0x300000, SEEK_SET); if ((order = guess_byte_order(0x10000)) == 0x4d4d) { height -= (top_margin = 16); width -= (left_margin = 28); maximum = 0xf5c0; strcpy(make, "ISG"); maker_index = LIBRAW_CAMERAMAKER_ISG; model[0] = 0; } } else if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm)) { if (!imFuji.RAFDataGeneration && (raw_width == 2944)) // S2Pro { height = 2144; width = 2880; flip = 6; } else if (load_raw != &LibRaw::packed_load_raw && strncmp(model, "X-", 2) && filters >= 1000) // Bayer and not an X-model maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00; if (!FujiCropMode && imFuji.RAFDataGeneration && (imFuji.RAFDataGeneration != 4096)) { width = imFuji.RAFData_ImageSizeTable[0]; height = imFuji.RAFData_ImageSizeTable[1]; } else if (FujiCropMode == 1) // FF crop on GFX { width = raw_width; height = raw_height; } // Do we need set height = raw_height for CropMode == 2 for all cameras?? else if (FujiCropMode == 4) // electronic shutter, high speed mode (1.25x crop) { height = raw_height; } top_margin = (raw_height >= height) ? (raw_height - height) >> 2 << 1 : 0; left_margin = (raw_width >= width) ? (raw_width - width) >> 2 << 1 : 0; if (imFuji.RAFDataGeneration && (imFuji.RAFDataGeneration != 4096)) { switch (raw_width) { case 2944: // X-S1, X10, XF1 filters = 0x16161616; break; case 4096: // X20, X30, XQ1, XQ2 case 5120: // X-Pro1, X-E1, X-A1, X-A2, X-M1 case 6048: // lossless compressed X100F, X-T2, X-T20, X-Pro2, X-H1, X-E3 case 6160: // uncompressed (unpacked) X100F, X-T2, X-T20, X-Pro2, X-H1, X-E3 left_margin = 0; break; case 4992: // X-E2S, X-E2, X-T10, X-T1, X100S, X100T, X70 left_margin = 4; break; case 6336: // X-H2S top_margin = 6; left_margin = 0; width = 6264; height = 4176; break; case 6384: // X-T3, X-T4, X100V, X-S10, X-T30, X-Pro3 top_margin = 0; switch (FujiCropMode) { case 0: // no crop left_margin = 0; top_margin = 6; width = 6246; height = 4170; break; case 2: // sports finder mode left_margin = 624; width = 5004; height = raw_height; break; case 4: // electronic shutter, high speed mode (1.25x crop) left_margin = 624; width = 5004; break; } break; case 6912: // GFX 50S, GFX 50R; FF crop case 9216: // GFX 50S, GFX 50R; no crop left_margin = 0; top_margin = 0; break; case 8472: // GFX 50S II left_margin = 0; top_margin = 0; width = raw_width - 192; break; case 9696: // GFX 100; FF crop case 11808: // GFX 100; no crop left_margin = 0; width = raw_width - 146; height = raw_height - (top_margin = 2); if (tiff_bps == 16) maximum = 0xffff; default: /* insert model name-based width/height/margins/etc. assignments */ break; } } else if (!imFuji.RAFDataGeneration) { switch (raw_width) { case 2304: // S5100 height -= (top_margin = 6); break; case 3328: // F550EXR, F600EXR, F770EXR, F800EXR, F900EXR, // HS20EXR, HS30EXR, HS33EXR, HS50EXR if ((width = raw_width - 66)) left_margin = 34; if (imgdata.sizes.raw_inset_crops[0].cleft == 8) // HS50EXR, F900EXR { left_margin = 0; width += 2; filters = 0x16161616; } break; case 3664: // "HS10 HS11" filters = 0x16161616; break; case 5504: // DBP for GX680 aka DX-2000 // 7712 2752 -> 5504 3856 // width = 688; // height = 30848; // raw_width = 688; // raw_height = 30848; left_margin = 32; // imgdata.sizes.raw_inset_crops[0].cleft top_margin = 8; width = raw_width - 2*left_margin; height = raw_height - 2*top_margin; load_raw = &LibRaw::unpacked_load_raw_FujiDBP; // maximum = 0x0fff; filters = 0x16161616; load_flags = 0; flip = 6; break; default: /* insert model name-based width/height/margins/etc. assignments */ break; } } if (fuji_layout) raw_width *= is_raw; if (filters == 9) FORC(36) ((char *)xtrans)[c] = xtrans_abs[(c / 6 + top_margin) % 6][(c + left_margin) % 6]; } else if (makeIs(LIBRAW_CAMERAMAKER_Konica)) { if (!strcmp(model, "KD-400Z")) { height = 1711; // 1712 width = 2312; raw_width = 2336; goto konica_400z; } else if (!strcmp(model, "KD-510Z")) { goto konica_510z; } } else if (makeIs(LIBRAW_CAMERAMAKER_Minolta)) { if (fsize == 5869568) { // hack "DiMAGE Z2" load_flags = 30; } if (imSony.prd_StorageMethod == LIBRAW_MINOLTA_UNPACKED) { load_raw = &LibRaw::unpacked_load_raw; } else if (imSony.prd_StorageMethod == LIBRAW_MINOLTA_PACKED) { load_raw = &LibRaw::packed_load_raw; } else if (!load_raw && (maximum = 0xfff)) { load_raw = &LibRaw::unpacked_load_raw; } if (imSony.prd_BayerPattern == LIBRAW_MINOLTA_G2BRG1) { filters = 0x49494949; } else if (imSony.prd_BayerPattern == LIBRAW_MINOLTA_RGGB) { filters = 0x94949494; } if (imSony.prd_Active_bps && imSony.prd_Total_bps) { tiff_bps = imSony.prd_Active_bps; } if (!strncmp(model, "DiMAGE G", 8)) // hack "DiMAGE G400", "DiMAGE G500", // "DiMAGE G530", "DiMAGE G600" { if (model[8] == '4') // DiMAGE G400 { height = 1716; width = 2304; } else if (model[8] == '5') // DiMAGE G500 / G530 { konica_510z: height = 1956; width = 2607; raw_width = 2624; } else if (model[8] == '6') // DiMAGE G600 { height = 2136; width = 2848; } data_offset += 14; filters = 0x61616161; konica_400z: load_raw = &LibRaw::unpacked_load_raw; maximum = 0x3df; order = 0x4d4d; } } else if (makeIs(LIBRAW_CAMERAMAKER_Samsung)) { if (raw_width == 4704) // Samsung NX100, NX10, NX11, { height -= top_margin = 8; width -= 2 * (left_margin = 8); load_flags = 32; } else if (!strcmp(model, "NX3000")) // Samsung NX3000; raw_width: 5600 { top_margin = 38; left_margin = 92; width = 5456; height = 3634; filters = 0x61616161; colors = 3; } else if (raw_height == 3714) // Samsung NX2000, NX300M, NX300, NX30, // "NX U" (aka: // "EK-GN100", "EK-GN110", "EK-GN120", // "EK-KN120", "Galaxy NX") { height -= top_margin = 18; left_margin = raw_width - (width = 5536); if (raw_width != 5600) left_margin = top_margin = 0; filters = 0x61616161; colors = 3; } else if (raw_width == 5632) // Samsung NX1000, NX200, NX20, NX210 { order = 0x4949; height = 3694; top_margin = 2; width = 5574 - (left_margin = 32 + tiff_bps); if (tiff_bps == 12) load_flags = 80; } else if (raw_width == 5664) // Samsung "NX mini" { height -= top_margin = 17; left_margin = 96; width = 5544; filters = 0x49494949; } else if (raw_width == 6496) // Samsung NX1, NX500 { filters = 0x61616161; if (!black && !cblack[0] && !cblack[1] && !cblack[2] && !cblack[3]) black = 1 << (tiff_bps - 7); } else if (!strcmp(normalized_model, "EX1")) // Samsung EX1; raw_width: 3688 { order = 0x4949; height -= 20; top_margin = 2; if ((width -= 6) > 3682) { height -= 10; width -= 46; top_margin = 8; } } else if (!strcmp(normalized_model, "WB2000")) // Samsung WB2000; raw_width: 3728 { order = 0x4949; height -= 3; top_margin = 2; if ((width -= 10) > 3718) { height -= 28; width -= 56; top_margin = 8; } } else if (!strcmp(model, "WB550")) // Samsung WB550; raw_width: 4000 { order = 0x4949; } else if (!strcmp(model, "EX2F")) // Samsung EX2F; raw_width: 4176 { height = 3030; width = 4040; top_margin = 15; left_margin = 24; order = 0x4949; filters = 0x49494949; load_raw = &LibRaw::unpacked_load_raw; } } else if (makeIs(LIBRAW_CAMERAMAKER_ST_Micro) && !strcmp(model, "STV680 VGA")) { black = 16; } else if (!strcmp(model, "N95")) { height = raw_height - (top_margin = 2); } else if (!strcmp(model, "640x480")) { gamma_curve(0.45, 4.5, 1, 255); } else if (makeIs(LIBRAW_CAMERAMAKER_Hasselblad)) { if (load_raw == &LibRaw::lossless_jpeg_load_raw) load_raw = &LibRaw::hasselblad_load_raw; if ((imHassy.SensorCode == 4) && !strncmp(model, "V96C", 4)) { // Hasselblad V96C strcpy(model, "V96C"); strcpy(normalized_model, model); height -= (top_margin = 6); width -= (left_margin = 3) + 7; filters = 0x61616161; } else if ((imHassy.SensorCode == 9) && imHassy.uncropped) { // various Hasselblad '-39' height = 5444; width = 7248; top_margin = 4; left_margin = 7; filters = 0x61616161; } else if ((imHassy.SensorCode == 13) && imHassy.uncropped) { // Hasselblad H4D-40, H5D-40 height -= 84; width -= 82; top_margin = 4; left_margin = 41; filters = 0x61616161; } else if ((imHassy.SensorCode == 11) && imHassy.uncropped) { // Hasselblad H5D-50 height -= 84; width -= 82; top_margin = 4; left_margin = 41; filters = 0x61616161; } else if ((imHassy.SensorCode == 15) && !imHassy.SensorSubCode && // Hasselblad H5D-50c imHassy.uncropped) { left_margin = 52; top_margin = 100; width = 8272; height = 6200; black = 256; } else if ((imHassy.SensorCode == 15) && (imHassy.SensorSubCode == 2) && // various Hasselblad X1D cameras imHassy.uncropped) { top_margin = 96; height -= 96; left_margin = 48; width -= 106; maximum = 0xffff; tiff_bps = 16; } else if ((imHassy.SensorCode == 12) && imHassy.uncropped) { // Hasselblad H4D-60 if (black > 500) { // (imHassy.format == LIBRAW_HF_FFF) top_margin = 12; left_margin = 44; width = 8956; height = 6708; memset(cblack, 0, sizeof(cblack)); black = 512; } else { // (imHassy.format == LIBRAW_HF_3FR) top_margin = 8; left_margin = 40; width = 8964; height = 6716; black += load_flags = 256; maximum = 0x8101; } } else if ((imHassy.SensorCode == 17) && imHassy.uncropped) { // Hasselblad H6D-100c, A6D-100c left_margin = 64; width = 11608; top_margin = 108; height = raw_height - top_margin; } if (tiff_samples > 1) { is_raw = tiff_samples + 1; if (!shot_select && !half_size) filters = 0; } } else if (makeIs(LIBRAW_CAMERAMAKER_Sinar)) { if (!load_raw) load_raw = &LibRaw::unpacked_load_raw; if (is_raw > 1 && !shot_select) filters = 0; maximum = 0x3fff; } if (load_raw == &LibRaw::sinar_4shot_load_raw) { if (is_raw > 1 && !shot_select) filters = 0; } else if (makeIs(LIBRAW_CAMERAMAKER_Leaf)) { maximum = 0x3fff; fseek(ifp, data_offset, SEEK_SET); if (ljpeg_start(&jh, 1) && jh.bits == 15) maximum = 0x1fff; if (tiff_samples > 1) filters = 0; if (tiff_samples > 1 || tile_length < raw_height) { load_raw = &LibRaw::leaf_hdr_load_raw; raw_width = tile_width; } if ((width | height) == 2048) { if (tiff_samples == 1) { filters = 1; strcpy(cdesc, "RBTG"); strcpy(model, "CatchLight"); strcpy(normalized_model, model); top_margin = 8; left_margin = 18; height = 2032; width = 2016; } else { strcpy(model, "DCB2"); strcpy(normalized_model, model); top_margin = 10; left_margin = 16; height = 2028; width = 2022; } } else if (width + height == 3144 + 2060) { if (!model[0]) { strcpy(model, "Cantare"); strcpy(normalized_model, model); } if (width > height) { top_margin = 6; left_margin = 32; height = 2048; width = 3072; filters = 0x61616161; } else { left_margin = 6; top_margin = 32; width = 2048; height = 3072; filters = 0x16161616; } if (!cam_mul[0] || model[0] == 'V') filters = 0; else is_raw = tiff_samples; } else if (width == 2116) // Leaf "Valeo 6" { strcpy(model, "Valeo 6"); strcpy(normalized_model, model); height -= 2 * (top_margin = 30); width -= 2 * (left_margin = 55); filters = 0x49494949; } else if (width == 3171) // Leaf "Valeo 6" { strcpy(model, "Valeo 6"); strcpy(normalized_model, model); height -= 2 * (top_margin = 24); width -= 2 * (left_margin = 24); filters = 0x16161616; } } else if (makeIs(LIBRAW_CAMERAMAKER_Panasonic)) { if (raw_width > 0 && ((flen - data_offset) / (raw_width * 8 / 7) == raw_height)) load_raw = &LibRaw::panasonic_load_raw; if (!load_raw) { load_raw = &LibRaw::unpacked_load_raw; load_flags = 4; } zero_is_bad = 1; if ((height += 12) > raw_height) height = raw_height; for (i = 0; i < int(sizeof pana / sizeof *pana); i++) if (raw_width == pana[i][0] && raw_height == pana[i][1]) { left_margin = pana[i][2]; top_margin = pana[i][3]; width += pana[i][4]; height += pana[i][5]; } if (!tiff_bps && pana_bpp >= 12 && pana_bpp <= 14) tiff_bps = pana_bpp; if (!strcmp(model, "DC-LX100M2") && raw_height == 3568 && raw_width == 4816 && filters == 3) filters = 4; filters = 0x01010101U * (uchar) "\x94\x61\x49\x16"[((filters - 1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3]; } else if (makeIs(LIBRAW_CAMERAMAKER_Contax) && !strcmp(model, "N Digital")) { height = 2047; width = 3072; filters = 0x61616161; data_offset = 0x1a00; load_raw = &LibRaw::packed_load_raw; } else if (makeIs(LIBRAW_CAMERAMAKER_Sony)) { if (!strcmp(model, "DSC-F828")) { // Sony DSC-F828 width = 3288; left_margin = 5; mask[1][3] = -17; data_offset = 862144; load_raw = &LibRaw::sony_load_raw; filters = 0x9c9c9c9c; colors = 4; strcpy(cdesc, "RGBE"); } else if (!strcmp(model, "DSC-V3")) { // Sony DSC-V3 width = 3109; left_margin = 59; mask[0][1] = 9; data_offset = 787392; load_raw = &LibRaw::sony_load_raw; } else if (raw_width == 3984) { // Sony DSC-R1; width = 3925; order = 0x4d4d; } else if (raw_width == 4288) { // Sony ILCE-7S, ILCE-7SM2, ILCE-7SM3, DSLR-A700, DSLR-A500; width -= 32; } else if (raw_width == 4600) { // Sony DSLR-A290, DSLR-A350, DSLR-A380; if (!strcmp(model, "DSLR-A350")) height -= 4; black = 0; } else if (raw_width == 4928) { // Sony DSLR-A580, NEX-C3, SLT-A35, DSC-HX99, SLT-A55, // NEX-5N, SLT-A37, SLT-A57, NEX-F3, NEX-6, NEX-5R, NEX-3N, NEX-5T; if (height < 3280) width -= 8; } else if (raw_width == 5504) { // Sony ILCE-3000, SLT-A58, DSC-RX100M3, ILCE-QX1, // DSC-RX10M4, DSC-RX100M6, DSC-RX100, DSC-RX100M2, DSC-RX10, // ILCE-5000, DSC-RX100M4, DSC-RX10M2, DSC-RX10M3, // DSC-RX100M5, DSC-RX100M5A; width -= height > 3664 ? 8 : 32; } else if (raw_width == 6048) { // Sony SLT-A65, DSC-RX1, SLT-A77, DSC-RX1, ILCA-77M2, // ILCE-7M3, NEX-7, SLT-A99, ILCE-7, DSC-RX1R, ILCE-6000, // ILCE-5100, ILCE-7M2, ILCA-68, ILCE-6300, ILCE-9, // ILCE-6500, ILCE-6400; width -= 24; if (strstr(normalized_model, "RX1") || strstr(normalized_model, "A99")) width -= 6; } else if (raw_width == 7392) { // Sony ILCE-7R; width -= 30; } else if (raw_width == 8000) { // Sony ILCE-7RM2, ILCE-7RM2, ILCE-7RM3, DSC-RX1RM2, ILCA-99M2; width -= 32; } else if (raw_width == 9600) { // Sony ILCE-7RM4 width -= 32; } else if(unique_id == SonyID_ILCE_1) { if (raw_width == 8704 && raw_height == 6144) // ILCE-1 FF@Compressed { width = 8660; height = 5784; } else if (raw_width == 8672) // FF uncompressed/lossy { width -= 12; } else if (raw_width == 6144 && raw_height == 4096) // APSC/Lossless { width = 5636; height = 3768; } else if (raw_width == 5664) // APS-C/Uncompressed or lossy { width -= 28; } } else if (unique_id == SonyID_ILCE_7M4) { if (raw_width == 7168 && raw_height == 5120) // ILCE-1 FF@Compressed { width = 7028; height = 4688; } else if (raw_width == 7040) // FF uncompressed/lossy { width -= 12; } /* FIXME: need APS-C samples, both losslesscompressed and uncompressed or lossy */ } else if (!strcmp(model, "DSLR-A100")) { if (width == 3880) { height--; width = ++raw_width; } else { height -= 4; width -= 4; order = 0x4d4d; load_flags = 2; } filters = 0x61616161; } } else if (!strcmp(model, "PIXL")) { height -= top_margin = 4; width -= left_margin = 32; gamma_curve(0, 7, 1, 255); } else if (makeIs(LIBRAW_CAMERAMAKER_Kodak)) { if (!strncasecmp(model, "EasyShare", 9)) { data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000; load_raw = &LibRaw::packed_load_raw; } else if (!strcmp(model, "C603") || !strcmp(model, "C330") || !strcmp(model, "12MP")) { order = 0x4949; if (filters && data_offset) { fseek(ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET); read_shorts(curve, 256); } else gamma_curve(0, 3.875, 1, 255); load_raw = filters ? &LibRaw::eight_bit_load_raw : strcmp(model, "C330") ? &LibRaw::kodak_c603_load_raw : &LibRaw::kodak_c330_load_raw; load_flags = tiff_bps > 16; tiff_bps = 8; } else { if (!strncmp(model, "NC2000", 6) || !strncmp(model, "EOSDCS", 6) || !strncmp(model, "DCS4", 4)) { width -= 4; left_margin = 2; } else if (!strcmp(model, "DCS660M")) { black = 214; } else if (!strcmp(model, "EOS D2000C")) { filters = 0x61616161; if (!black) black = curve[200]; } if (filters == UINT_MAX) filters = 0x61616161; if (!strcmp(model + 4, "20X")) strcpy(cdesc, "MYCY"); if (!strcmp(model, "DC25")) { data_offset = 15424; } if (!strncmp(model, "DC2", 3)) { raw_height = 2 + (height = 242); if (!strncmp(model, "DC290", 5)) iso_speed = 100; if (!strncmp(model, "DC280", 5)) iso_speed = 70; if (flen < 100000) { raw_width = 256; width = 249; pixel_aspect = (4.0 * height) / (3.0 * width); } else { raw_width = 512; width = 501; pixel_aspect = (493.0 * height) / (373.0 * width); } top_margin = left_margin = 1; colors = 4; filters = 0x8d8d8d8d; simple_coeff(1); pre_mul[1] = 1.179f; pre_mul[2] = 1.209f; pre_mul[3] = 1.036f; load_raw = &LibRaw::eight_bit_load_raw; } else if (!strcmp(model, "DC40")) { height = 512; width = 768; data_offset = 1152; load_raw = &LibRaw::kodak_radc_load_raw; tiff_bps = 12; FORC4 cam_mul[c] = 1.0f; } else if (!strcmp(model, "DC50")) { height = 512; width = 768; iso_speed = 84; data_offset = 19712; load_raw = &LibRaw::kodak_radc_load_raw; FORC4 cam_mul[c] = 1.0f; } else if (!strcmp(model, "DC120")) { raw_height = height = 976; raw_width = width = 848; iso_speed = 160; pixel_aspect = height / 0.75 / width; load_raw = tiff_compress == 7 ? &LibRaw::kodak_jpeg_load_raw : &LibRaw::kodak_dc120_load_raw; } else if (!strcmp(model, "DCS200")) { thumb_height = 128; thumb_width = 192; thumb_offset = 6144; thumb_misc = 360; iso_speed = 140; thumb_format = LIBRAW_INTERNAL_THUMBNAIL_LAYER; black = 17; } } } else if (makeIs(LIBRAW_CAMERAMAKER_Logitech) && !strcmp(model, "Fotoman Pixtura")) { height = 512; width = 768; data_offset = 3632; load_raw = &LibRaw::kodak_radc_load_raw; filters = 0x61616161; simple_coeff(2); } else if (makeIs(LIBRAW_CAMERAMAKER_Apple) && !strncmp(model, "QuickTake", 9)) { if (head[5]) { strcpy(model + 10, "200"); strcpy(normalized_model, model); } fseek(ifp, 544, SEEK_SET); height = get2(); width = get2(); data_offset = (get4(), get2()) == 30 ? 738 : 736; if (height > width) { SWAP(height, width); fseek(ifp, data_offset - 6, SEEK_SET); flip = ~get2() & 3 ? 5 : 6; } filters = 0x61616161; } else if (makeIs(LIBRAW_CAMERAMAKER_Rollei) && !load_raw) { switch (raw_width) { case 1316: // Rollei d530flex height = 1030; width = 1300; top_margin = 1; left_margin = 6; break; case 2568: height = 1960; width = 2560; top_margin = 2; left_margin = 8; } filters = 0x16161616; load_raw = &LibRaw::rollei_load_raw; } else if (!strcmp(model, "GRAS-50S5C")) { height = 2048; width = 2440; load_raw = &LibRaw::unpacked_load_raw; data_offset = 0; filters = 0x49494949; order = 0x4949; maximum = 0xfffC; } else if (!strcmp(model, "BB-500CL")) { height = 2058; width = 2448; load_raw = &LibRaw::unpacked_load_raw; data_offset = 0; filters = 0x94949494; order = 0x4949; maximum = 0x3fff; } else if (!strcmp(model, "BB-500GE")) { height = 2058; width = 2456; load_raw = &LibRaw::unpacked_load_raw; data_offset = 0; filters = 0x94949494; order = 0x4949; maximum = 0x3fff; } else if (!strcmp(model, "SVS625CL")) { height = 2050; width = 2448; load_raw = &LibRaw::unpacked_load_raw; data_offset = 0; filters = 0x94949494; order = 0x4949; maximum = 0x0fff; } } LibRaw-0.21.4/src/metadata/identify_tools.cpp000066400000000000000000000067361477673233700211230ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" short LibRaw::guess_byte_order(int words) { uchar test[4][2]; int t = 2, msb; double diff, sum[2] = {0, 0}; fread(test[0], 2, 2, ifp); for (words -= 2; words--;) { fread(test[t], 2, 1, ifp); for (msb = 0; msb < 2; msb++) { diff = (test[t ^ 2][msb] << 8 | test[t ^ 2][!msb]) - (test[t][msb] << 8 | test[t][!msb]); sum[msb] += diff * diff; } t = (t + 1) & 3; } return sum[0] < sum[1] ? 0x4d4d : 0x4949; } float LibRaw::find_green(int bps, int bite, int off0, int off1) { UINT64 bitbuf = 0; int vbits, col, i, c; ushort img[2][2064]; double sum[] = {0, 0}; if (width > 2064) return 0.f; // too wide FORC(2) { fseek(ifp, c ? off1 : off0, SEEK_SET); for (vbits = col = 0; col < width; col++) { for (vbits -= bps; vbits < 0; vbits += bite) { bitbuf <<= bite; for (i = 0; i < bite; i += 8) bitbuf |= (unsigned)(fgetc(ifp) << i); } img[c][col] = bitbuf << (64 - bps - vbits) >> (64 - bps); } } FORC(width - 1) { sum[c & 1] += ABS(img[0][c] - img[1][c + 1]); sum[~c & 1] += ABS(img[1][c] - img[0][c + 1]); } if (sum[0] >= 1.0 && sum[1] >= 1.0) return 100 * log(sum[0] / sum[1]); else return 0.f; } void LibRaw::trimSpaces(char *s) { char *p = s; int l = int(strlen(p)); if (!l) return; while (isspace(p[l - 1])) p[--l] = 0; /* trim trailing spaces */ while (*p && isspace(*p)) ++p, --l; /* trim leading spaces */ memmove(s, p, l + 1); } void LibRaw::remove_trailing_spaces(char *string, size_t len) { if (len < 1) return; // not needed, b/c sizeof of make/model is 64 string[len - 1] = 0; if (len < 3) return; // also not needed len = strnlen(string, len - 1); for (int i = int(len) - 1; i >= 0; i--) { if (isspace((unsigned char)string[i])) string[i] = 0; else break; } } void LibRaw::remove_caseSubstr(char *string, char *subStr) // replace a substring with an equal length of spaces { char *found; while ((found = strcasestr(string,subStr))) { if (!found) return; int fill_len = int(strlen(subStr)); int p = found - string; for (int i=p; i 0x1fff) && (romm_camScale[1] > 0x1fff) && (romm_camScale[2] > 0x1fff)) { FORC3 for (j = 0; j < 3; j++)((float *)romm_camIllum)[c * 3 + j] = ((float)romm_camTemp[c * 3 + j]) / ((float)romm_camScale[c]); return 1; } } return 0; } /* Thanks to Alexey Danilchenko for wb as-shot parsing code */ void LibRaw::parse_kodak_ifd(int base) { unsigned entries, tag, type, len, save; int c, wbi = -1; static const int wbtag_kdc[] = { LIBRAW_WBI_Auto, // 64037 / 0xfa25 LIBRAW_WBI_Fluorescent, // 64040 / 0xfa28 LIBRAW_WBI_Tungsten, // 64039 / 0xfa27 LIBRAW_WBI_Daylight, // 64041 / 0xfa29 -1, -1, LIBRAW_WBI_Shade // 64042 / 0xfa2a }; static const int wbtag_dcr[] = { LIBRAW_WBI_Daylight, // 2120 / 0x0848 LIBRAW_WBI_Tungsten, // 2121 / 0x0849 LIBRAW_WBI_Fluorescent, // 2122 / 0x084a LIBRAW_WBI_Flash, // 2123 / 0x084b LIBRAW_WBI_Custom, // 2124 / 0x084c LIBRAW_WBI_Auto // 2125 / 0x084d }; // int a_blck = 0; entries = get2(); if (entries > 1024) return; INT64 fsize = ifp->size(); while (entries--) { tiff_get(base, &tag, &type, &len, &save); INT64 savepos = ftell(ifp); if (len > 8 && len + savepos > 2 * fsize) { fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! continue; } if (callbacks.exif_cb) { callbacks.exif_cb(callbacks.exifparser_data, tag | 0x20000, type, len, order, ifp, base); fseek(ifp, savepos, SEEK_SET); } if (tag == 0x03eb) // 1003 imgdata.sizes.raw_inset_crops[0].cleft = get2(); else if (tag == 0x03ec) // 1004 imgdata.sizes.raw_inset_crops[0].ctop = get2(); else if (tag == 0x03ed) // 1005 imgdata.sizes.raw_inset_crops[0].cwidth = get2(); else if (tag == 0x03ee) // 1006 imgdata.sizes.raw_inset_crops[0].cheight = get2(); else if (tag == 0x03ef) // 1007 { if (!strcmp(model, "EOS D2000C")) black = get2(); else imKodak.BlackLevelTop = get2(); } else if (tag == 0x03f0) // 1008 { if (!strcmp(model, "EOS D2000C")) { if (black) // already set by tag 1007 (0x03ef) black = (black + get2()) / 2; else black = get2(); } else imKodak.BlackLevelBottom = get2(); } else if (tag == 0x03f1) { // 1009 Kodak TextualInfo if (len > 0) { char kti[1024]; char *pkti; int nsym = MIN(len, 1023); fread(kti, 1, nsym, ifp); kti[nsym] = 0; #ifdef LIBRAW_WIN32_CALLS pkti = strtok(kti, "\x0a"); #else char *last = 0; pkti = strtok_r(kti, "\x0a", &last); #endif while (pkti != NULL) { c = 12; if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Camera body:", c))) { while ((pkti[c] == ' ') && (c < (int)strlen(pkti))) { c++; } strcpy(ilm.body, pkti + c); } c = 5; if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Lens:", c))) { ilm.CurFocal = atoi(pkti + c); } c = 9; if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Aperture:", c))) { while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti))) { c++; } ilm.CurAp = atof(pkti + c); } c = 10; if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "ISO Speed:", c))) { iso_speed = atoi(pkti + c); } c = 13; if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Focal Length:", c))) { ilm.CurFocal = atoi(pkti + c); } c = 13; if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Max Aperture:", c))) { while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti))) { c++; } ilm.MaxAp4CurFocal = atof(pkti + c); } c = 13; if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Min Aperture:", c))) { while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti))) { c++; } ilm.MinAp4CurFocal = atof(pkti + c); } #ifdef LIBRAW_WIN32_CALLS pkti = strtok(NULL, "\x0a"); #else pkti = strtok_r(NULL, "\x0a", &last); #endif } } } else if (tag == 0x03f3) // 1011 imCommon.FlashEC = getreal(type); else if (tag == 0x03fc) // 1020 { wbi = getint(type); if ((wbi >= 0) && (wbi < 6) && (wbi != -2)) wbi = wbtag_dcr[wbi]; } else if (tag == 0x03fd && len == 72) // 1021 { /* WB set in software */ fseek(ifp, 40, SEEK_CUR); FORC3 cam_mul[c] = 2048.0 / fMAX(1.0f, get2()); wbi = -2; } else if ((tag == 0x0406) && (len == 1)) // 1030 imCommon.CameraTemperature = getreal(type); else if ((tag == 0x0413) && (len == 1)) // 1043 imCommon.SensorTemperature = getreal(type); else if (tag == 0x0848) // 2120 Kodak_DCR_WBtags(LIBRAW_WBI_Daylight, type, wbi); else if (tag == 0x0849) // 2121 Kodak_DCR_WBtags(LIBRAW_WBI_Tungsten, type, wbi); else if (tag == 0x084a) // 2122 Kodak_DCR_WBtags(LIBRAW_WBI_Fluorescent, type, wbi); else if (tag == 0x084b) // 2123 Kodak_DCR_WBtags(LIBRAW_WBI_Flash, type, wbi); else if (tag == 0x084c) // 2124 Kodak_DCR_WBtags(LIBRAW_WBI_Custom, type, wbi); else if (tag == 0x084d) // 2125 { if (wbi == -1) wbi = LIBRAW_WBI_Auto; Kodak_DCR_WBtags(LIBRAW_WBI_Auto, type, wbi); } else if (tag == 0x089f) // 2207 imKodak.ISOCalibrationGain = getreal(type); else if (tag == 0x0903) // 2307 imKodak.AnalogISO = iso_speed = getreal(type); else if (tag == 0x090d) // 2317 linear_table(len); else if (tag == 0x09ce) // 2510 stmread(imgdata.shootinginfo.InternalBodySerial, len, ifp); else if (tag == 0x0e92) // 3730 { imKodak.val018percent = get2(); imgdata.color.linear_max[0] = imgdata.color.linear_max[1] = imgdata.color.linear_max[2] = imgdata.color.linear_max[3] = (int)(((float)imKodak.val018percent) / 18.0f * 170.0f); } else if (tag == 0x0e93) // 3731 imgdata.color.linear_max[0] = imgdata.color.linear_max[1] = imgdata.color.linear_max[2] = imgdata.color.linear_max[3] = imKodak.val170percent = get2(); else if (tag == 0x0e94) // 3732 imKodak.val100percent = get2(); /* else if (tag == 0x1784) // 6020 iso_speed = getint(type); */ else if (tag == 0xfa00) // 64000 stmread(imgdata.shootinginfo.BodySerial, len, ifp); else if (tag == 0xfa0d) // 64013 { wbi = fgetc(ifp); if ((wbi >= 0) && (wbi < 7)) wbi = wbtag_kdc[wbi]; } else if (tag == 0xfa13) // 64019 width = getint(type); else if (tag == 0xfa14) // 64020 height = (getint(type) + 1) & -2; /* height = getint(type); else if (tag == 0xfa16) // 64022 raw_width = get2(); else if (tag == 0xfa17) // 64023 raw_height = get2(); */ else if (tag == 0xfa18) // 64024 { imKodak.offset_left = getint(LIBRAW_EXIFTAG_TYPE_SSHORT); if (type != LIBRAW_EXIFTAG_TYPE_SSHORT) imKodak.offset_left += 1; } else if (tag == 0xfa19) // 64025 { imKodak.offset_top = getint(LIBRAW_EXIFTAG_TYPE_SSHORT); if (type != LIBRAW_EXIFTAG_TYPE_SSHORT) imKodak.offset_top += 1; } else if (tag == 0xfa25) // 64037 Kodak_KDC_WBtags(LIBRAW_WBI_Auto, wbi); else if (tag == 0xfa27) // 64039 Kodak_KDC_WBtags(LIBRAW_WBI_Tungsten, wbi); else if (tag == 0xfa28) // 64040 Kodak_KDC_WBtags(LIBRAW_WBI_Fluorescent, wbi); else if (tag == 0xfa29) // 64041 Kodak_KDC_WBtags(LIBRAW_WBI_Daylight, wbi); else if (tag == 0xfa2a) // 64042 Kodak_KDC_WBtags(LIBRAW_WBI_Shade, wbi); else if (tag == 0xfa31) // 64049 imgdata.sizes.raw_inset_crops[0].cwidth = get2(); else if (tag == 0xfa32) // 64050 imgdata.sizes.raw_inset_crops[0].cheight = get2(); else if (tag == 0xfa3e) // 64062 imgdata.sizes.raw_inset_crops[0].cleft = get2(); else if (tag == 0xfa3f) // 64063 imgdata.sizes.raw_inset_crops[0].ctop = get2(); else if (((tag == 0x07e4) || (tag == 0xfb01)) && (len == 9)) // 2020 or 64257 { if (KodakIllumMatrix(type, (float *)imKodak.romm_camDaylight)) { romm_coeff(imKodak.romm_camDaylight); } } else if (((tag == 0x07e5) || (tag == 0xfb02)) && (len == 9)) // 2021 or 64258 KodakIllumMatrix(type, (float *)imKodak.romm_camTungsten); else if (((tag == 0x07e6) || (tag == 0xfb03)) && (len == 9)) // 2022 or 64259 KodakIllumMatrix(type, (float *)imKodak.romm_camFluorescent); else if (((tag == 0x07e7) || (tag == 0xfb04)) && (len == 9)) // 2023 or 64260 KodakIllumMatrix(type, (float *)imKodak.romm_camFlash); else if (((tag == 0x07e8) || (tag == 0xfb05)) && (len == 9)) // 2024 or 64261 KodakIllumMatrix(type, (float *)imKodak.romm_camCustom); else if (((tag == 0x07e9) || (tag == 0xfb06)) && (len == 9)) // 2025 or 64262 KodakIllumMatrix(type, (float *)imKodak.romm_camAuto); fseek(ifp, save, SEEK_SET); } } LibRaw-0.21.4/src/metadata/leica.cpp000066400000000000000000000247621477673233700171440ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" void LibRaw::setLeicaBodyFeatures(int LeicaMakernoteSignature) { if (LeicaMakernoteSignature == -3) // M8 { ilm.CameraFormat = LIBRAW_FORMAT_APSH; ilm.CameraMount = LIBRAW_MOUNT_Leica_M; } else if (LeicaMakernoteSignature == -2) // DMR { ilm.CameraFormat = LIBRAW_FORMAT_Leica_DMR; if ((model[0] == 'R') || (model[6] == 'R')) ilm.CameraMount = LIBRAW_MOUNT_Leica_R; } else if (LeicaMakernoteSignature == 0) // "DIGILUX 2" { ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.FocalType = LIBRAW_FT_ZOOM_LENS; } else if ((LeicaMakernoteSignature == 0x0100) || // X1 (LeicaMakernoteSignature == 0x0500) || // X2, "X-E (Typ 102)" (LeicaMakernoteSignature == 0x0700) || // "X (Typ 113)" (LeicaMakernoteSignature == 0x1000)) // "X-U (Typ 113)" { ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.FocalType = LIBRAW_FT_PRIME_LENS; } else if (LeicaMakernoteSignature == 0x0400) // "X VARIO (Typ 107)" { ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.FocalType = LIBRAW_FT_ZOOM_LENS; } else if ((LeicaMakernoteSignature == 0x0200) || // M10, M10-D, M10-R, "S (Typ 007)", M11 (LeicaMakernoteSignature == 0x02ff) || // "M (Typ 240)", "M (Typ 262)", "M-D (Typ 262)", // "M Monochrom (Typ 246)", "S (Typ 006)", "S-E (Typ 006)", S2, S3 (LeicaMakernoteSignature == 0x0300)) // M9, "M9 Monochrom", "M Monochrom", M-E { if ((model[0] == 'M') || (model[6] == 'M')) { ilm.CameraFormat = LIBRAW_FORMAT_FF; ilm.CameraMount = LIBRAW_MOUNT_Leica_M; } else if ((model[0] == 'S') || (model[6] == 'S')) { ilm.CameraFormat = LIBRAW_FORMAT_LeicaS; ilm.CameraMount = LIBRAW_MOUNT_Leica_S; } } else if ((LeicaMakernoteSignature == 0x0600) || // "T (Typ 701)", TL (LeicaMakernoteSignature == 0x0900) || // SL2, "SL2-S", "SL (Typ 601)", CL, Q2, "Q2 MONO" (LeicaMakernoteSignature == 0x1a00)) // TL2 { if ((model[0] == 'S') || (model[6] == 'S')) { ilm.CameraFormat = LIBRAW_FORMAT_FF; ilm.CameraMount = LIBRAW_MOUNT_LPS_L; } else if ((model[0] == 'T') || (model[6] == 'T') || (model[0] == 'C') || (model[6] == 'C')) { ilm.CameraFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = LIBRAW_MOUNT_LPS_L; } else if (((model[0] == 'Q') || (model[6] == 'Q')) && ((model[1] == '2') || (model[7] == '2'))) { ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_FF; ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.FocalType = LIBRAW_FT_PRIME_LENS; } } else if (LeicaMakernoteSignature == 0x0800) // "Q (Typ 116)" { ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_FF; ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.FocalType = LIBRAW_FT_PRIME_LENS; } } void LibRaw::parseLeicaLensID() { ilm.LensID = get4(); if (ilm.LensID) { ilm.LensID = ((ilm.LensID >> 2) << 8) | (ilm.LensID & 0x3); if ((ilm.LensID > 0x00ff) && (ilm.LensID < 0x3b00)) { ilm.LensMount = ilm.CameraMount; ilm.LensFormat = LIBRAW_FORMAT_FF; } } } int LibRaw::parseLeicaLensName(unsigned len) { #define plln ilm.Lens if (!len) { strcpy(plln, "N/A"); return 0; } stmread(plln, len, ifp); if ((plln[0] == ' ') || !strncasecmp(plln, "not ", 4) || !strncmp(plln, "---", 3) || !strncmp(plln, "***", 3)) { strcpy(plln, "N/A"); return 0; } else return 1; #undef plln } int LibRaw::parseLeicaInternalBodySerial(unsigned len) { #define plibs imgdata.shootinginfo.InternalBodySerial if (!len) { strcpy(plibs, "N/A"); return 0; } stmread(plibs, len, ifp); if (!strncmp(plibs, "000000000000", 12)) { plibs[0] = '0'; plibs[1] = '\0'; return 1; } if (strnlen(plibs, len) == 13) { for (int i = 3; i < 13; i++) { if (!isdigit(plibs[i])) goto non_std; } memcpy(plibs + 15, plibs + 9, 4); memcpy(plibs + 12, plibs + 7, 2); memcpy(plibs + 9, plibs + 5, 2); memcpy(plibs + 6, plibs + 3, 2); plibs[3] = plibs[14] = ' '; plibs[8] = plibs[11] = '/'; if (((short)(plibs[3] - '0') * 10 + (short)(plibs[4] - '0')) < 70) { memcpy(plibs + 4, "20", 2); } else { memcpy(plibs + 4, "19", 2); } return 2; } non_std: #undef plibs return 1; } void LibRaw::parseLeicaMakernote(int base, int uptag, unsigned MakernoteTagType) { int c; uchar ci, cj; unsigned entries, tag, type, len, save; short morder, sorder = order; char buf[10]; int LeicaMakernoteSignature = -1; INT64 fsize = ifp->size(); fread(buf, 1, 10, ifp); if (strncmp(buf, "LEICA", 5)) { fseek(ifp, -10, SEEK_CUR); if (uptag == 0x3400) LeicaMakernoteSignature = 0x3400; else LeicaMakernoteSignature = -2; // DMR } else { fseek(ifp, -2, SEEK_CUR); LeicaMakernoteSignature = ((uchar)buf[6] << 8) | (uchar)buf[7]; // printf ("LeicaMakernoteSignature 0x%04x\n", LeicaMakernoteSignature); if (!LeicaMakernoteSignature && (!strncmp(model, "M8", 2) || !strncmp(model + 6, "M8", 2))) LeicaMakernoteSignature = -3; if ((LeicaMakernoteSignature != 0x0000) && (LeicaMakernoteSignature != 0x0200) && (LeicaMakernoteSignature != 0x0800) && (LeicaMakernoteSignature != 0x0900) && (LeicaMakernoteSignature != 0x02ff)) base = ftell(ifp) - 8; } setLeicaBodyFeatures(LeicaMakernoteSignature); entries = get2(); if (entries > 1000) return; morder = order; while (entries--) { order = morder; tiff_get(base, &tag, &type, &len, &save); INT64 pos = ifp->tell(); if (len > 8 && pos + len > 2 * fsize) { fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! continue; } tag |= uptag << 16; if (len > 100 * 1024 * 1024) goto next; // 100Mb tag? No! if (LeicaMakernoteSignature == -3) // M8 { if (tag == 0x0310) { parseLeicaLensID(); } else if ((tag == 0x0313) && (fabs(ilm.CurAp) < 0.17f)) { ilm.CurAp = getreal(type); if (ilm.CurAp > 126.3) { ilm.CurAp = 0.0f; } else if (fabs(aperture) < 0.17f) aperture = ilm.CurAp; } else if (tag == 0x0320) { imCommon.CameraTemperature = getreal(type); } } else if (LeicaMakernoteSignature == -2) // DMR { if (tag == 0x000d) { FORC3 cam_mul[c] = get2(); cam_mul[3] = cam_mul[1]; } } else if (LeicaMakernoteSignature == 0) // "DIGILUX 2" { if (tag == 0x0007) { imgdata.shootinginfo.FocusMode = get2(); } else if (tag == 0x001a) { imgdata.shootinginfo.ImageStabilization = get2(); } } else if ((LeicaMakernoteSignature == 0x0100) || // X1 (LeicaMakernoteSignature == 0x0400) || // "X VARIO" (LeicaMakernoteSignature == 0x0500) || // X2, "X-E (Typ 102)" (LeicaMakernoteSignature == 0x0700) || // "X (Typ 113)" (LeicaMakernoteSignature == 0x1000)) // "X-U (Typ 113)" { if (tag == 0x040d) { ci = fgetc(ifp); cj = fgetc(ifp); imgdata.shootinginfo.ExposureMode = ((ushort)ci << 8) | cj; } } else if ((LeicaMakernoteSignature == 0x0600) || // TL, "T (Typ 701)" (LeicaMakernoteSignature == 0x1a00)) // TL2 { if (tag == 0x040d) { ci = fgetc(ifp); cj = fgetc(ifp); imgdata.shootinginfo.ExposureMode = ((ushort)ci << 8) | cj; } else if (tag == 0x0303) { parseLeicaLensName(len); } } else if (LeicaMakernoteSignature == 0x0200) // M10, M10-D, M10-R, "S (Typ 007)", M11 { if ((tag == 0x035a) && (fabs(ilm.CurAp) < 0.17f)) { ilm.CurAp = get4() / 1000.0f; if (ilm.CurAp > 126.3) { ilm.CurAp = 0.0f; } else if (fabs(aperture) < 0.17f) aperture = ilm.CurAp; } } else if (LeicaMakernoteSignature == 0x02ff) // "M (Typ 240)", "M (Typ 262)", "M-D (Typ 262)" // "M Monochrom (Typ 246)" // "S (Typ 006)", "S-E (Typ 006)", S2, S3 { if (tag == 0x0303) { if (parseLeicaLensName(len)) { ilm.LensMount = ilm.CameraMount; ilm.LensFormat = ilm.CameraFormat; } } } else if (LeicaMakernoteSignature == 0x0300) // M9, "M9 Monochrom", "M Monochrom", M-E { if (tag == 0x3400) { parseLeicaMakernote(base, 0x3400, MakernoteTagType); } } else if ((LeicaMakernoteSignature == 0x0800) || // "Q (Typ 116)" (LeicaMakernoteSignature == 0x0900)) // SL2, "SL2-S", "SL (Typ 601)", // CL, Q2, "Q2 MONO" { if ((tag == 0x0304) && (len == 1) && ((c = fgetc(ifp)) != 0) && (ilm.CameraMount == LIBRAW_MOUNT_LPS_L)) { strcpy(ilm.Adapter, "M-Adapter L"); ilm.LensMount = LIBRAW_MOUNT_Leica_M; ilm.LensFormat = LIBRAW_FORMAT_FF; if (c != 0xff) ilm.LensID = c * 256; } else if (tag == 0x0500) { parseLeicaInternalBodySerial(len); } } else if (LeicaMakernoteSignature == 0x3400) // tag 0x3400 in M9, "M9 Monochrom", "M Monochrom" { if (tag == 0x34003402) { imCommon.CameraTemperature = getreal(type); } else if (tag == 0x34003405) { parseLeicaLensID(); } else if ((tag == 0x34003406) && (fabs(ilm.CurAp) < 0.17f)) { ilm.CurAp = getreal(type); if (ilm.CurAp > 126.3) { ilm.CurAp = 0.0f; } else if (fabs(aperture) < 0.17f) aperture = ilm.CurAp; } } next: fseek(ifp, save, SEEK_SET); } order = sorder; } LibRaw-0.21.4/src/metadata/makernotes.cpp000066400000000000000000000526611477673233700202360ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" void LibRaw::parseSigmaMakernote (int base, int /*uptag*/, unsigned /*dng_writer*/) { unsigned wb_table1 [] = { LIBRAW_WBI_Auto, LIBRAW_WBI_Daylight, LIBRAW_WBI_Shade, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Tungsten, LIBRAW_WBI_Fluorescent, LIBRAW_WBI_Flash, LIBRAW_WBI_Custom, LIBRAW_WBI_Custom1, LIBRAW_WBI_Custom2 }; unsigned entries, tag, type, len, save; unsigned i; entries = get2(); if (entries > 1000) return; while (entries--) { tiff_get(base, &tag, &type, &len, &save); if (tag == 0x0027) { ilm.LensID = get2(); } else if (tag == 0x002a) { ilm.MinFocal = getreal(type); ilm.MaxFocal = getreal(type); } else if (tag == 0x002b) { ilm.MaxAp4MinFocal = getreal(type); ilm.MaxAp4MaxFocal = getreal(type); } else if (tag == 0x0120) { const unsigned tblsz = (sizeof wb_table1 / sizeof wb_table1[0]); if ((len >= tblsz) && (len%3 == 0) && len/3 <= tblsz) { for (i=0; i<(len/3); i++) { icWBC[wb_table1[i]][0] = (int)(getreal(type)*10000.0); icWBC[wb_table1[i]][1] = icWBC[wb_table1[i]][3] = (int)(getreal(type)*10000.0); icWBC[wb_table1[i]][2] = (int)(getreal(type)*10000.0); } } } fseek(ifp, save, SEEK_SET); } return; } void LibRaw::parse_makernote_0xc634(int base, int uptag, unsigned dng_writer) { if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS) throw LIBRAW_EXCEPTION_IO_CORRUPT; if (!strncmp(make, "NIKON", 5)) { parseNikonMakernote(base, uptag, AdobeDNG); return; } else if (!strncasecmp(make, "LEICA", 5)) { parseLeicaMakernote(base, uptag, is_0xc634); return; } short morder, sorder = order; char buf[10]; INT64 fsize = ifp->size(); fread(buf, 1, 10, ifp); if (!strcmp(buf, "EPSON")) { parseEpsonMakernote(base, uptag, AdobeDNG); return; } else if (!strcmp(buf, "SIGMA")) { parseSigmaMakernote(base, uptag, AdobeDNG); return; } unsigned entries, tag, type, len, save, c; uchar *CanonCameraInfo = NULL; unsigned lenCanonCameraInfo = 0; unsigned typeCanonCameraInfo = 0; uchar *table_buf_0x0116; ushort table_buf_0x0116_len = 0; uchar *table_buf_0x2010; ushort table_buf_0x2010_len = 0; uchar *table_buf_0x9050; ushort table_buf_0x9050_len = 0; uchar *table_buf_0x9400; ushort table_buf_0x9400_len = 0; uchar *table_buf_0x9402; ushort table_buf_0x9402_len = 0; uchar *table_buf_0x9403; ushort table_buf_0x9403_len = 0; uchar *table_buf_0x9406; ushort table_buf_0x9406_len = 0; uchar *table_buf_0x940c; ushort table_buf_0x940c_len = 0; uchar *table_buf_0x940e; ushort table_buf_0x940e_len = 0; if (!strcmp(buf, "OLYMPUS") || !strcmp(buf, "PENTAX ") || !strncmp(buf,"OM SYS",6)|| (!strncmp(make, "SAMSUNG", 7) && (dng_writer == CameraDNG))) { base = ftell(ifp) - 10; fseek(ifp, -2, SEEK_CUR); order = get2(); if (buf[0] == 'O') get2(); else if (buf[0] == 'P') is_PentaxRicohMakernotes = 1; } else if (is_PentaxRicohMakernotes && (dng_writer == CameraDNG)) { base = ftell(ifp) - 10; fseek(ifp, -4, SEEK_CUR); order = get2(); } else if (!strncmp(buf, "SONY", 4) || !strcmp(buf, "Panasonic")) { order = 0x4949; fseek(ifp, 2, SEEK_CUR); } else if (!strncmp(buf, "FUJIFILM", 8)) { base = ftell(ifp) - 10; order = 0x4949; fseek(ifp, 2, SEEK_CUR); } else if (!strcmp(buf, "OLYMP") || !strcmp(buf, "Ricoh")) { fseek(ifp, -2, SEEK_CUR); } else if (!strcmp(buf, "AOC") || !strcmp(buf, "QVC")) { fseek(ifp, -4, SEEK_CUR); } else { fseek(ifp, -10, SEEK_CUR); if ((!strncmp(make, "SAMSUNG", 7) && (dng_writer == AdobeDNG))) base = ftell(ifp); } entries = get2(); if (entries > 1000) return; if (!strncasecmp(make, "SONY", 4) || !strncasecmp(make, "Konica", 6) || !strncasecmp(make, "Minolta", 7) || (!strncasecmp(make, "Hasselblad", 10) && (!strncasecmp(model, "Stellar", 7) || !strncasecmp(model, "Lunar", 5) || !strncasecmp(model, "Lusso", 5) || !strncasecmp(model, "HV", 2)))) is_Sony = 1; if (!is_Olympus && (!strncmp(make, "OLYMPUS", 7) || !strncmp(make, "OM Digi", 7) || (!strncasecmp(make, "CLAUSS", 6) && !strncasecmp(model, "piX 5oo", 7)))) { is_Olympus = 1; OlympusDNG_SubDirOffsetValid = strncmp(model, "E-300", 5) && strncmp(model, "E-330", 5) && strncmp(model, "E-400", 5) && strncmp(model, "E-500", 5) && strncmp(model, "E-1", 3); } morder = order; while (entries--) { order = morder; tiff_get(base, &tag, &type, &len, &save); INT64 pos = ifp->tell(); if (len > 8 && pos + len > 2 * fsize) { fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! continue; } tag |= uptag << 16; if (len > 100 * 1024 * 1024) goto next; // 100Mb tag? No! if (!strncmp(make, "Canon", 5)) { if (tag == 0x000d && len < 256000) { // camera info if (!tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) { CanonCameraInfo = (uchar *)calloc(MAX(16, len),1); fread(CanonCameraInfo, len, 1, ifp); } else { CanonCameraInfo = (uchar *)calloc(MAX(16, len * 4),1); fread(CanonCameraInfo, len, 4, ifp); } lenCanonCameraInfo = len; typeCanonCameraInfo = type; } else if (tag == 0x0010) // Canon ModelID { unique_id = get4(); setCanonBodyFeatures(unique_id); if (lenCanonCameraInfo) { processCanonCameraInfo(unique_id, CanonCameraInfo, lenCanonCameraInfo, typeCanonCameraInfo, AdobeDNG); free(CanonCameraInfo); CanonCameraInfo = 0; lenCanonCameraInfo = 0; } } else parseCanonMakernotes(tag, type, len, AdobeDNG); } else if (!strncmp(make, "FUJI", 4)) { parseFujiMakernotes(tag, type, len, AdobeDNG); } else if (!strncasecmp(make, "Hasselblad", 10) && !is_Sony) { if (tag == 0x0011) { imHassy.SensorCode = getint(type); } else if ((tag == 0x0015) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII)) { stmread (imHassy.SensorUnitConnector, len, ifp); for (int i=0; i<(int)len; i++) { if(!isalnum(imHassy.SensorUnitConnector[i]) && (imHassy.SensorUnitConnector[i]!=' ') && (imHassy.SensorUnitConnector[i]!='/') && (imHassy.SensorUnitConnector[i]!='-')) { imHassy.SensorUnitConnector[0] = 0; break; } } } else if (tag == 0x0016) { imHassy.CoatingCode = getint(type); } else if ((tag == 0x002a) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL) && (len == 12) && imHassy.SensorUnitConnector[0]) { FORC4 for (int i = 0; i < 3; i++) imHassy.mnColorMatrix[c][i] = getreal(type); } else if ((tag == 0x0031) && imHassy.SensorUnitConnector[0]) { imHassy.RecommendedCrop[0] = getint(type); imHassy.RecommendedCrop[1] = getint(type); } } else if (is_Olympus) { if ((tag == 0x2010) || (tag == 0x2020) || (tag == 0x2030) || (tag == 0x2031) || (tag == 0x2040) || (tag == 0x2050) || (tag == 0x3000)) { fseek(ifp, save - 4, SEEK_SET); fseek(ifp, base + get4(), SEEK_SET); parse_makernote_0xc634(base, tag, dng_writer); } if (!OlympusDNG_SubDirOffsetValid && ((len > 4) || ((tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) || tagtypeIs(LIBRAW_EXIFTAG_TYPE_SSHORT)) && (len > 2)) || ((tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) || tagtypeIs(LIBRAW_EXIFTAG_TYPE_SLONG)) && (len > 1)) || tagtypeIs(LIBRAW_EXIFTAG_TYPE_RATIONAL) || (type > LIBRAW_EXIFTAG_TYPE_SLONG))) { goto skip_Oly_broken_tags; } else { parseOlympusMakernotes(base, tag, type, len, AdobeDNG); } skip_Oly_broken_tags:; } else if (!strncmp(make, "PENTAX", 6) || !strncmp(model, "PENTAX", 6) || is_PentaxRicohMakernotes) { parsePentaxMakernotes(base, tag, type, len, dng_writer); } else if (!strncmp(make, "SAMSUNG", 7)) { if (dng_writer == AdobeDNG) parseSamsungMakernotes(base, tag, type, len, dng_writer); else parsePentaxMakernotes(base, tag, type, len, dng_writer); } else if (is_Sony) { parseSonyMakernotes( base, tag, type, len, AdobeDNG, table_buf_0x0116, table_buf_0x0116_len, table_buf_0x2010, table_buf_0x2010_len, table_buf_0x9050, table_buf_0x9050_len, table_buf_0x9400, table_buf_0x9400_len, table_buf_0x9402, table_buf_0x9402_len, table_buf_0x9403, table_buf_0x9403_len, table_buf_0x9406, table_buf_0x9406_len, table_buf_0x940c, table_buf_0x940c_len, table_buf_0x940e, table_buf_0x940e_len); } next: fseek(ifp, save, SEEK_SET); } order = sorder; } void LibRaw::parse_makernote(int base, int uptag) { if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS) throw LIBRAW_EXCEPTION_IO_CORRUPT; if (!strncmp(make, "NIKON", 5)) { parseNikonMakernote(base, uptag, nonDNG); return; } else if (!strncasecmp(make, "LEICA", 5)) { parseLeicaMakernote(base, uptag, is_0x927c); return; } if (!strncmp(make, "Nokia", 5)) return; char buf[10]; char another_buf[128]; fseek(ifp, -12, SEEK_CUR); fread (another_buf, 1, 12, ifp); if (!strncmp(another_buf, "SONY", 4) || !strncmp(another_buf, "VHAB", 4)) { // Sony branded as Hasselblad is_Sony = 1; } fread(buf, 1, 10, ifp); if (!strncmp(buf, "KDK", 3) || /* these aren't TIFF tables */ !strncmp(buf, "VER", 3) || !strncmp(buf, "IIII", 4) || !strncmp(buf, "MMMM", 4)) return; if (!strcmp(buf, "EPSON")) { parseEpsonMakernote(base, uptag, nonDNG); return; } else if (!strcmp(buf, "SIGMA")) { parseSigmaMakernote(base, uptag, CameraDNG); return; } unsigned entries, tag, type, len, save, c; unsigned i, wb[4] = {0, 0, 0, 0}; short morder, sorder = order; uchar *CanonCameraInfo = 0;; unsigned lenCanonCameraInfo = 0; unsigned typeCanonCameraInfo = 0; imCanon.wbi = 0; uchar *table_buf_0x0116; ushort table_buf_0x0116_len = 0; uchar *table_buf_0x2010; ushort table_buf_0x2010_len = 0; uchar *table_buf_0x9050; ushort table_buf_0x9050_len = 0; uchar *table_buf_0x9400; ushort table_buf_0x9400_len = 0; uchar *table_buf_0x9402; ushort table_buf_0x9402_len = 0; uchar *table_buf_0x9403; ushort table_buf_0x9403_len = 0; uchar *table_buf_0x9406; ushort table_buf_0x9406_len = 0; uchar *table_buf_0x940c; ushort table_buf_0x940c_len = 0; uchar *table_buf_0x940e; ushort table_buf_0x940e_len = 0; INT64 fsize = ifp->size(); /* The MakerNote might have its own TIFF header (possibly with its own byte-order!), or it might just be a table. */ if (!strncmp(buf, "KC", 2) || /* Konica KD-400Z, KD-510Z */ !strncmp(buf, "MLY", 3)) /* Minolta DiMAGE G series */ { order = 0x4d4d; while ((i = ftell(ifp)) < data_offset && i < 16384) { wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3]; if (feof(ifp)) break; wb[3] = get2(); if (wb[1] == 256 && wb[3] == 256 && wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640) FORC4 cam_mul[c] = wb[c]; } goto quit; } if (!strcmp(buf, "OLYMPUS") || !strncmp(buf, "OM SYS",6) || !strcmp(buf, "PENTAX ")) { base = ftell(ifp) - 10; fseek(ifp, -2, SEEK_CUR); if (buf[1] == 'M') get4(); order = get2(); if (buf[0] == 'O') get2(); } else if (!strncmp(buf, "SONY", 4) || // DSLR-A100 !strcmp(buf, "Panasonic")) { if (buf[0] == 'S') is_Sony = 1; goto nf; } else if (!strncmp(buf, "FUJIFILM", 8)) { base = ftell(ifp) - 10; nf: order = 0x4949; fseek(ifp, 2, SEEK_CUR); } else if (!strcmp (buf, "OLYMP") || !strncmp(buf, "LEICA", 5) || !strcmp (buf, "Ricoh")) { fseek(ifp, -2, SEEK_CUR); } else if (!strcmp(buf, "AOC") || // Pentax, tribute to Asahi Optical Co. !strcmp(buf, "QVC")) // Casio, from "QV-Camera" { fseek(ifp, -4, SEEK_CUR); } else if (!strncmp(buf, "CMT3", 4)) { order = sget2((uchar *)(buf + 4)); fseek(ifp, 2L, SEEK_CUR); } else if (libraw_internal_data.unpacker_data.CR3_CTMDtag) { order = sget2((uchar *)buf); fseek(ifp, -2L, SEEK_CUR); } else { fseek(ifp, -10, SEEK_CUR); if (!strncmp(make, "SAMSUNG", 7)) base = ftell(ifp); } if (!is_Olympus && (!strncasecmp(make, "Olympus", 7) || !strncmp(make, "OM Digi", 7) || (!strncasecmp(make, "CLAUSS", 6) && !strncasecmp(model, "piX 5oo", 7)))) { is_Olympus = 1; } if (!is_Sony && (!strncasecmp(make, "SONY", 4) || !strncasecmp(make, "Konica", 6) || !strncasecmp(make, "Minolta", 7) || (!strncasecmp(make, "Hasselblad", 10) && (!strncasecmp(model, "Stellar", 7) || !strncasecmp(model, "Lunar", 5) || !strncasecmp(model, "Lusso", 5) || !strncasecmp(model, "HV", 2))))) { is_Sony = 1; } if (strcasestr(make, "Kodak") && (sget2((uchar *)buf) > 1) && // check number of entries (sget2((uchar *)buf) < 128) && (sget2((uchar *)(buf + 4)) > 0) && // check type (sget2((uchar *)(buf + 4)) < 13) && (sget4((uchar *)(buf + 6)) < 256) // check count ) imKodak.MakerNoteKodak8a = 1; // Kodak P712 / P850 / P880 entries = get2(); if (entries > 1000) return; morder = order; while (entries--) { order = morder; tiff_get(base, &tag, &type, &len, &save); tag |= uptag << 16; INT64 _pos = ftell(ifp); if (len > 100 * 1024 * 1024) goto next; // 100Mb tag? No! if (len > 8 && _pos + len > 2 * fsize) { fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! continue; } if (imKodak.MakerNoteKodak8a) { if ((tag == 0xff00) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) && (len == 1)) { INT64 _pos1 = get4(); if ((_pos1 < fsize) && (_pos1 > 0)) { fseek(ifp, _pos1, SEEK_SET); parse_makernote(base, tag); } } else if (tag == 0xff00f90b) { imKodak.clipBlack = get2(); } else if (tag == 0xff00f90c) { imKodak.clipWhite = imgdata.color.linear_max[0] = imgdata.color.linear_max[1] = imgdata.color.linear_max[2] = imgdata.color.linear_max[3] = get2(); } } else if (!strncmp(make, "Canon", 5)) { if (tag == 0x000d && len < 256000) // camera info { if (!tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) { CanonCameraInfo = (uchar *)calloc(MAX(16, len),1); fread(CanonCameraInfo, len, 1, ifp); } else { CanonCameraInfo = (uchar *)calloc(MAX(16, len * 4),1); fread(CanonCameraInfo, len, 4, ifp); } lenCanonCameraInfo = len; typeCanonCameraInfo = type; } else if (tag == 0x0010) // Canon ModelID { unique_id = get4(); setCanonBodyFeatures(unique_id); if (lenCanonCameraInfo) { processCanonCameraInfo(unique_id, CanonCameraInfo, lenCanonCameraInfo, typeCanonCameraInfo, nonDNG); if(CanonCameraInfo) free(CanonCameraInfo); CanonCameraInfo = 0; lenCanonCameraInfo = 0; } } else parseCanonMakernotes(tag, type, len, nonDNG); } else if (!strncmp(make, "FUJI", 4)) parseFujiMakernotes(tag, type, len, nonDNG); else if (!strncasecmp(model, "Hasselblad X1D", 14) || !strncasecmp(model, "Hasselblad H6D", 14) || !strncasecmp(model, "Hasselblad A6D", 14)) { if (tag == 0x0045) { imHassy.BaseISO = get4(); } else if (tag == 0x0046) { imHassy.Gain = getreal(type); } } else if (!strncmp(make, "PENTAX", 6) || !strncmp(make, "RICOH", 5) || !strncmp(model, "PENTAX", 6)) { if (!strncmp(model, "GR", 2) || !strncmp(model, "GXR", 3)) { parseRicohMakernotes(base, tag, type, len, CameraDNG); } else { parsePentaxMakernotes(base, tag, type, len, nonDNG); } } else if (!strncmp(make, "SAMSUNG", 7)) { if (!dng_version) parseSamsungMakernotes(base, tag, type, len, nonDNG); else parsePentaxMakernotes(base, tag, type, len, CameraDNG); } else if (is_Sony) { if ((tag == 0xb028) && (len == 1) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) // DSLR-A100 { if ((c = get4())) { fseek(ifp, c, SEEK_SET); parse_makernote(base, tag); } } else { parseSonyMakernotes( base, tag, type, len, nonDNG, table_buf_0x0116, table_buf_0x0116_len, table_buf_0x2010, table_buf_0x2010_len, table_buf_0x9050, table_buf_0x9050_len, table_buf_0x9400, table_buf_0x9400_len, table_buf_0x9402, table_buf_0x9402_len, table_buf_0x9403, table_buf_0x9403_len, table_buf_0x9406, table_buf_0x9406_len, table_buf_0x940c, table_buf_0x940c_len, table_buf_0x940e, table_buf_0x940e_len); } } fseek(ifp, _pos, SEEK_SET); if (!strncasecmp(make, "Hasselblad", 10) && !is_Sony) { if (tag == 0x0011) imHassy.SensorCode = getint(type); else if (tag == 0x0016) imHassy.CoatingCode = getint(type); else if ((tag == 0x002a) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL) && (len == 12)) { FORC4 for (int ii = 0; ii < 3; ii++) imHassy.mnColorMatrix[c][ii] = getreal(type); } else if (tag == 0x0031) { imHassy.RecommendedCrop[0] = getint(type); imHassy.RecommendedCrop[1] = getint(type); } } if ((tag == 0x0004 || tag == 0x0114) && !strncmp(make, "KONICA", 6)) { fseek(ifp, tag == 0x0004 ? 140 : 160, SEEK_CUR); switch (get2()) { case 72: flip = 0; break; case 76: flip = 6; break; case 82: flip = 5; break; } } if (is_Olympus) { INT64 _pos2 = ftell(ifp); if ((tag == 0x2010) || (tag == 0x2020) || (tag == 0x2030) || (tag == 0x2031) || (tag == 0x2040) || (tag == 0x2050) || (tag == 0x3000)) { if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary)) { parse_makernote(base, tag); } else if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_ifd) || tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_int32u)) { fseek(ifp, base + get4(), SEEK_SET); parse_makernote(base, tag); } } else { parseOlympusMakernotes(base, tag, type, len, nonDNG); } fseek(ifp, _pos2, SEEK_SET); } if ((tag == 0x0015) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII) && is_raw) { // Hasselblad stmread (imHassy.SensorUnitConnector, len, ifp); } if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) && ((tag == 0x0081) || // Minolta (tag == 0x0100))) // Olympus { thumb_offset = ftell(ifp); thumb_length = len; } if ((tag == 0x0088) && // Minolta, possibly Olympus too tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) && (thumb_offset = get4())) thumb_offset += base; if ((tag == 0x0089) && // Minolta, possibly Olympus too tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) thumb_length = get4(); if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) && // Nikon ((tag == 0x008c) || (tag == 0x0096))) { meta_offset = ftell(ifp); } if ((tag == 0x00a1) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) && strncasecmp(make, "Samsung", 7)) { order = 0x4949; fseek(ifp, 140, SEEK_CUR); FORC3 cam_mul[c] = get4(); } if (tag == 0xb001 && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) // Sony ModelID { unique_id = get2(); } if (tag == 0x0200 && len == 3) // Olympus shot_order = (get4(), get4()); if (tag == 0x0f00 && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED)) { if (len == 614) fseek(ifp, 176, SEEK_CUR); else if (len == 734 || len == 1502) // Kodak, Minolta, Olympus fseek(ifp, 148, SEEK_CUR); else goto next; goto get2_256; } if (tag == 0x2011 && len == 2) // Casio { get2_256: order = 0x4d4d; cam_mul[0] = get2() / 256.0; cam_mul[2] = get2() / 256.0; } next: fseek(ifp, save, SEEK_SET); } quit: order = sorder; } LibRaw-0.21.4/src/metadata/mediumformat.cpp000066400000000000000000000344161477673233700205550ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" void LibRaw::parse_phase_one(int base) { unsigned entries, tag, type, len, data, i, c; INT64 save; float romm_cam[3][3]; char *cp; memset(&ph1, 0, sizeof ph1); fseek(ifp, base, SEEK_SET); order = get4() & 0xffff; if (get4() >> 8 != 0x526177) return; /* "Raw" */ unsigned offset = get4(); if (offset == 0xbad0bad) return; fseek(ifp, offset + base, SEEK_SET); entries = get4(); if (entries > 8192) return; // too much?? get4(); while (entries--) { tag = get4(); type = get4(); len = get4(); if (feof(ifp)) break; data = get4(); save = ftell(ifp); bool do_seek = (tag < 0x0108 || tag > 0x0110); // to make it single rule, not copy-paste if(do_seek) fseek(ifp, base + data, SEEK_SET); switch (tag) { case 0x0100: flip = "0653"[data & 3] - '0'; break; case 0x0102: stmread(imgdata.shootinginfo.BodySerial, len, ifp); if ((imgdata.shootinginfo.BodySerial[0] == 0x4c) && (imgdata.shootinginfo.BodySerial[1] == 0x49)) { unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[2] & 0x3f)) - 0x41; } else { unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[1] & 0x3f)) - 0x41; } setPhaseOneFeatures(unique_id); break; case 0x0106: for (i = 0; i < 9; i++) imgdata.color.P1_color[0].romm_cam[i] = ((float *)romm_cam)[i] = (float)getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); romm_coeff(romm_cam); break; case 0x0107: FORC3 cam_mul[c] = (float)getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); break; case 0x0108: raw_width = data; break; case 0x0109: raw_height = data; break; case 0x010a: left_margin = data; break; case 0x010b: top_margin = data; break; case 0x010c: width = data; break; case 0x010d: height = data; break; case 0x010e: ph1.format = data; break; case 0x010f: data_offset = data + base; data_size = len; break; case 0x0110: meta_offset = data + base; meta_length = len; break; case 0x0112: ph1.key_off = int(save - 4); break; case 0x0203: stmread(imPhaseOne.Software, len, ifp); case 0x0204: stmread(imPhaseOne.SystemType, len, ifp); case 0x0210: ph1.tag_210 = int_to_float(data); imCommon.SensorTemperature = ph1.tag_210; break; case 0x0211: imCommon.SensorTemperature2 = int_to_float(data); break; case 0x021a: ph1.tag_21a = data; break; case 0x021c: strip_offset = data + base; break; case 0x021d: ph1.t_black = data; break; case 0x0222: ph1.split_col = data; break; case 0x0223: ph1.black_col = data + base; break; case 0x0224: ph1.split_row = data; break; case 0x0225: ph1.black_row = data + base; break; case 0x0226: for (i = 0; i < 9; i++) imgdata.color.P1_color[1].romm_cam[i] = (float)getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); break; case 0x0301: model[63] = 0; fread(imPhaseOne.FirmwareString, 1, 255, ifp); imPhaseOne.FirmwareString[255] = 0; memcpy(model, imPhaseOne.FirmwareString, 63); model[63] = 0; if ((cp = strstr(model, " camera"))) *cp = 0; else if ((cp = strchr(model, ','))) *cp = 0; /* minus and the letter after it are not always present if present, last letter means: C : Contax 645AF H : Hasselblad H1 / H2 M : Mamiya V : Hasselblad 555ELD / 553ELX / 503CW / 501CM; not included below because of adapter conflicts (Mamiya RZ body) if not present, Phase One 645 AF, Mamiya 645AFD Series, or anything */ strcpy(imPhaseOne.SystemModel, model); if ((cp = strchr(model, '-'))) { if (cp[1] == 'C') { strcpy(ilm.body, "Contax 645AF"); ilm.CameraMount = LIBRAW_MOUNT_Contax645; ilm.CameraFormat = LIBRAW_FORMAT_645; } else if (cp[1] == 'M') { strcpy(ilm.body, "Mamiya 645"); ilm.CameraMount = LIBRAW_MOUNT_Mamiya645; ilm.CameraFormat = LIBRAW_FORMAT_645; } else if (cp[1] == 'H') { strcpy(ilm.body, "Hasselblad H1/H2"); ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H; ilm.CameraFormat = LIBRAW_FORMAT_645; } *cp = 0; } case 0x0401: if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) ilm.CurAp = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f)); else ilm.CurAp = libraw_powf64l(2.0f, float(getreal(type) / 2.0f)); break; case 0x0403: if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) ilm.CurFocal = int_to_float(data); else ilm.CurFocal = (float)getreal(type); break; case 0x0410: stmread(ilm.body, len, ifp); if (((unsigned char)ilm.body[0]) == 0xff) ilm.body[0] = 0; break; case 0x0412: stmread(ilm.Lens, len, ifp); if (((unsigned char)ilm.Lens[0]) == 0xff) ilm.Lens[0] = 0; break; case 0x0414: if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) { ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f)); } else { ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, float(getreal(type) / 2.0f)); } break; case 0x0415: if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) { ilm.MinAp4CurFocal = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f)); } else { ilm.MinAp4CurFocal = libraw_powf64l(2.0f, float(getreal(type) / 2.0f)); } break; case 0x0416: if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) { ilm.MinFocal = int_to_float(data); } else { ilm.MinFocal = (float)getreal(type); } if (ilm.MinFocal > 1000.0f) { ilm.MinFocal = 0.0f; } break; case 0x0417: if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) { ilm.MaxFocal = int_to_float(data); } else { ilm.MaxFocal = (float)getreal(type); } break; } if (do_seek) fseek(ifp, save, SEEK_SET); } if (!ilm.body[0] && !imgdata.shootinginfo.BodySerial[0]) { fseek(ifp, meta_offset, SEEK_SET); order = get2(); fseek(ifp, 6, SEEK_CUR); fseek(ifp, meta_offset + get4(), SEEK_SET); entries = get4(); if (entries > 8192) return; // too much?? get4(); while (entries--) { tag = get4(); len = get4(); if (feof(ifp)) break; data = get4(); save = ftell(ifp); fseek(ifp, meta_offset + data, SEEK_SET); if (tag == 0x0407) { stmread(imgdata.shootinginfo.BodySerial, len, ifp); if ((imgdata.shootinginfo.BodySerial[0] == 0x4c) && (imgdata.shootinginfo.BodySerial[1] == 0x49)) { unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[2] & 0x3f)) - 0x41; } else { unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[1] & 0x3f)) - 0x41; } setPhaseOneFeatures(unique_id); } fseek(ifp, save, SEEK_SET); } } if ((ilm.MaxAp4CurFocal > 0.7f) && (ilm.MinAp4CurFocal > 0.7f)) { float MinAp4CurFocal = MAX(ilm.MaxAp4CurFocal,ilm.MinAp4CurFocal); ilm.MaxAp4CurFocal = MIN(ilm.MaxAp4CurFocal,ilm.MinAp4CurFocal); ilm.MinAp4CurFocal = MinAp4CurFocal; } if (ph1.format == 6) load_raw = &LibRaw::phase_one_load_raw_s; else load_raw = ph1.format < 3 ? &LibRaw::phase_one_load_raw : &LibRaw::phase_one_load_raw_c; maximum = 0xffff; // Always scaled to 16bit? strcpy(make, "Phase One"); if (model[0]) return; switch (raw_height) { case 2060: strcpy(model, "LightPhase"); break; case 2682: strcpy(model, "H 10"); break; case 4128: strcpy(model, "H 20"); break; case 5488: strcpy(model, "H 25"); break; } } void LibRaw::parse_mos(INT64 offset) { char data[40]; int i, c, neut[4], planes = 0, frot = 0; INT64 from; unsigned skip; static const char *mod[] = { /* DM22, DM28, DM40, DM56 are somewhere here too */ "", // 0 "DCB2", // 1 "Volare", // 2 "Cantare", // 3 "CMost", // 4 "Valeo 6", // 5 "Valeo 11", // 6 "Valeo 22", // 7 "Valeo 11p", // 8 "Valeo 17", // 9 "", // 10 "Aptus 17", // 11 "Aptus 22", // 12 "Aptus 75", // 13 "Aptus 65", // 14 "Aptus 54S", // 15 "Aptus 65S", // 16 "Aptus 75S", // 17 "AFi 5", // 18 "AFi 6", // 19 "AFi 7", // 20 "AFi-II 7", // 21 "Aptus-II 7", // 22 (same CMs as Mamiya DM33) "", // 23 "Aptus-II 6", // 24 (same CMs as Mamiya DM28) "AFi-II 10", // 25 "", // 26 "Aptus-II 10", // 27 (same CMs as Mamiya DM56) "Aptus-II 5", // 28 (same CMs as Mamiya DM22) "", // 29 "DM33", // 30, make is Mamiya "", // 31 "", // 32 "Aptus-II 10R", // 33 "Aptus-II 8", // 34 (same CMs as Mamiya DM40) "", // 35 "Aptus-II 12", // 36 "", // 37 "AFi-II 12" // 38 }; float romm_cam[3][3]; fseek(ifp, offset, SEEK_SET); while (!feof(ifp)) { if (get4() != 0x504b5453) break; get4(); fread(data, 1, 40, ifp); skip = get4(); from = ftell(ifp); if (!strcmp(data, "CameraObj_camera_type")) { stmread(ilm.body, (unsigned)skip, ifp); if (ilm.body[0]) { if (!strncmp(ilm.body, "Mamiya R", 8)) { ilm.CameraMount = LIBRAW_MOUNT_Mamiya67; ilm.CameraFormat = LIBRAW_FORMAT_67; } else if (!strncmp(ilm.body, "Hasselblad 5", 12)) { ilm.CameraFormat = LIBRAW_FORMAT_66; ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_V; } else if (!strncmp(ilm.body, "Hasselblad H", 12)) { ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H; ilm.CameraFormat = LIBRAW_FORMAT_645; } else if (!strncmp(ilm.body, "Mamiya 6", 8) || !strncmp(ilm.body, "Phase One 6", 11)) { ilm.CameraMount = LIBRAW_MOUNT_Mamiya645; ilm.CameraFormat = LIBRAW_FORMAT_645; } else if (!strncmp(ilm.body, "Large F", 7)) { ilm.CameraMount = LIBRAW_MOUNT_LF; ilm.CameraFormat = LIBRAW_FORMAT_LF; } else if (!strncmp(model, "Leaf AFi", 8)) { ilm.CameraMount = LIBRAW_MOUNT_Rollei_bayonet; ilm.CameraFormat = LIBRAW_FORMAT_66; } } } if (!strcmp(data, "back_serial_number")) { char buffer[sizeof(imgdata.shootinginfo.BodySerial)]; char *words[4] = {0, 0, 0, 0}; stmread(buffer, (unsigned)skip, ifp); /*nwords = */ getwords(buffer, words, 4, sizeof(imgdata.shootinginfo.BodySerial)); if(words[0]) strcpy(imgdata.shootinginfo.BodySerial, words[0]); } if (!strcmp(data, "CaptProf_serial_number")) { char buffer[sizeof(imgdata.shootinginfo.InternalBodySerial)]; char *words[4] = {0, 0, 0, 0}; stmread(buffer, (unsigned)skip, ifp); getwords(buffer, words, 4, sizeof(imgdata.shootinginfo.InternalBodySerial)); if(words[0]) strcpy(imgdata.shootinginfo.InternalBodySerial, words[0]); } if (!strcmp(data, "JPEG_preview_data")) { thumb_offset = from; thumb_length = skip; } if (!strcmp(data, "icc_camera_profile")) { profile_offset = from; profile_length = skip; } if (!strcmp(data, "ShootObj_back_type")) { fscanf(ifp, "%d", &i); if ((unsigned)i < sizeof mod / sizeof(*mod)) { strcpy(model, mod[i]); if (!strncmp(model, "AFi", 3)) { ilm.CameraMount = LIBRAW_MOUNT_Rollei_bayonet; ilm.CameraFormat = LIBRAW_FORMAT_66; } ilm.CamID = i; } } if (!strcmp(data, "icc_camera_to_tone_matrix")) { for (i = 0; i < 9; i++) ((float *)romm_cam)[i] = int_to_float(get4()); romm_coeff(romm_cam); } if (!strcmp(data, "CaptProf_color_matrix")) { for (i = 0; i < 9; i++) fscanf(ifp, "%f", (float *)romm_cam + i); romm_coeff(romm_cam); } if (!strcmp(data, "CaptProf_number_of_planes")) fscanf(ifp, "%d", &planes); if (!strcmp(data, "CaptProf_raw_data_rotation")) fscanf(ifp, "%d", &flip); if (!strcmp(data, "CaptProf_mosaic_pattern")) FORC4 { fscanf(ifp, "%d", &i); if (i == 1) frot = c ^ (c >> 1); // 0123 -> 0132 } if (!strcmp(data, "ImgProf_rotation_angle")) { fscanf(ifp, "%d", &i); flip = i - flip; } if (!strcmp(data, "NeutObj_neutrals") && !cam_mul[0]) { FORC4 fscanf(ifp, "%d", neut + c); FORC3 if (neut[c + 1]) cam_mul[c] = (float)neut[0] / neut[c + 1]; } if (!strcmp(data, "Rows_data")) load_flags = get4(); parse_mos(from); fseek(ifp, skip + from, SEEK_SET); } if (planes) filters = (planes == 1) * 0x01010101U * (uchar) "\x94\x61\x16\x49"[(flip / 90 + frot) & 3]; } LibRaw-0.21.4/src/metadata/minolta.cpp000066400000000000000000000076511477673233700175300ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" void LibRaw::parse_minolta(int base) { int tag, len, offset, high = 0, wide = 0, i, c; short sorder = order; INT64 save; fseek(ifp, base, SEEK_SET); if (fgetc(ifp) || fgetc(ifp) - 'M' || fgetc(ifp) - 'R') return; order = fgetc(ifp) * 0x101; offset = base + get4() + 8; INT64 fsize = ifp->size(); if (offset > fsize - 8) // At least 8 bytes for tag/len offset = fsize - 8; while ((save = ftell(ifp)) < offset) { for (tag = i = 0; i < 4; i++) tag = tag << 8 | fgetc(ifp); len = get4(); if (len < 0) return; // just ignore wrong len?? or raise bad file exception? if ((INT64)len + save + 8LL > fsize) return; // just ignore out of file metadata, stop parse switch (tag) { case 0x505244: /* PRD */ fseek(ifp, 8, SEEK_CUR); high = get2(); wide = get2(); imSony.prd_ImageHeight = get2(); imSony.prd_ImageWidth = get2(); imSony.prd_Total_bps = (ushort)fgetc(ifp); imSony.prd_Active_bps = (ushort)fgetc(ifp); imSony.prd_StorageMethod = (ushort)fgetc(ifp); fseek(ifp, 4L, SEEK_CUR); imSony.prd_BayerPattern = (ushort)fgetc(ifp); break; case 0x524946: /* RIF */ fseek(ifp, 8, SEEK_CUR); icWBC[LIBRAW_WBI_Tungsten][0] = get2(); icWBC[LIBRAW_WBI_Tungsten][2] = get2(); icWBC[LIBRAW_WBI_Daylight][0] = get2(); icWBC[LIBRAW_WBI_Daylight][2] = get2(); icWBC[LIBRAW_WBI_Cloudy][0] = get2(); icWBC[LIBRAW_WBI_Cloudy][2] = get2(); icWBC[LIBRAW_WBI_FL_W][0] = get2(); icWBC[LIBRAW_WBI_FL_W][2] = get2(); icWBC[LIBRAW_WBI_Flash][0] = get2(); icWBC[LIBRAW_WBI_Flash][2] = get2(); icWBC[LIBRAW_WBI_Custom][0] = get2(); icWBC[LIBRAW_WBI_Custom][2] = get2(); icWBC[LIBRAW_WBI_Tungsten][1] = icWBC[LIBRAW_WBI_Tungsten][3] = icWBC[LIBRAW_WBI_Daylight][1] = icWBC[LIBRAW_WBI_Daylight][3] = icWBC[LIBRAW_WBI_Cloudy][1] = icWBC[LIBRAW_WBI_Cloudy][3] = icWBC[LIBRAW_WBI_FL_W][1] = icWBC[LIBRAW_WBI_FL_W][3] = icWBC[LIBRAW_WBI_Flash][1] = icWBC[LIBRAW_WBI_Flash][3] = icWBC[LIBRAW_WBI_Custom][1] = icWBC[LIBRAW_WBI_Custom][3] = 0x100; if (!strncasecmp(model, "DSLR-A100", 9)) { icWBC[LIBRAW_WBI_Shade][0] = get2(); icWBC[LIBRAW_WBI_Shade][2] = get2(); icWBC[LIBRAW_WBI_FL_D][0] = get2(); icWBC[LIBRAW_WBI_FL_D][2] = get2(); icWBC[LIBRAW_WBI_FL_N][0] = get2(); icWBC[LIBRAW_WBI_FL_N][2] = get2(); icWBC[LIBRAW_WBI_FL_WW][0] = get2(); icWBC[LIBRAW_WBI_FL_WW][2] = get2(); icWBC[LIBRAW_WBI_Shade][1] = icWBC[LIBRAW_WBI_Shade][3] = icWBC[LIBRAW_WBI_FL_D][1] = icWBC[LIBRAW_WBI_FL_D][3] = icWBC[LIBRAW_WBI_FL_N][1] = icWBC[LIBRAW_WBI_FL_N][3] = icWBC[LIBRAW_WBI_FL_WW][1] = icWBC[LIBRAW_WBI_FL_WW][3] = 0x0100; } break; case 0x574247: /* WBG */ get4(); if (imSony.prd_BayerPattern == LIBRAW_MINOLTA_G2BRG1) FORC4 cam_mul[G2BRG1_2_RGBG(c)] = get2(); else FORC4 cam_mul[RGGB_2_RGBG(c)] = get2(); break; case 0x545457: /* TTW */ parse_tiff(ftell(ifp)); data_offset = offset; } fseek(ifp, save + len + 8, SEEK_SET); } raw_height = high; raw_width = wide; order = sorder; } LibRaw-0.21.4/src/metadata/misc_parsers.cpp000066400000000000000000000406001477673233700205460ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" /* Returns 1 for a Coolpix 2100, 0 for anything else. */ int LibRaw::nikon_e2100() { uchar t[12]; int i; fseek(ifp, 0, SEEK_SET); for (i = 0; i < 1024; i++) { fread(t, 1, 12, ifp); if (((t[2] & t[4] & t[7] & t[9]) >> 4 & t[1] & t[6] & t[8] & t[11] & 3) != 3) return 0; } return 1; } void LibRaw::nikon_3700() { int bits, i; uchar dp[24]; static const struct { int bits; char t_make[12], t_model[15]; int t_maker_idx; } table[] = {{0x00, "Pentax", "Optio 33WR", LIBRAW_CAMERAMAKER_Pentax}, {0x03, "Nikon", "E3200", LIBRAW_CAMERAMAKER_Nikon}, {0x32, "Nikon", "E3700", LIBRAW_CAMERAMAKER_Nikon}, {0x33, "Olympus", "C-740UZ", LIBRAW_CAMERAMAKER_Olympus}}; fseek(ifp, 3072, SEEK_SET); fread(dp, 1, 24, ifp); bits = (dp[8] & 3) << 4 | (dp[20] & 3); for (i = 0; i < int(sizeof table / sizeof *table); i++) if (bits == table[i].bits) { strcpy(make, table[i].t_make); maker_index = table[i].t_maker_idx; strcpy(model, table[i].t_model); } } /* Separates a Minolta DiMAGE Z2 from a Nikon E4300. */ int LibRaw::minolta_z2() { int i, nz; char tail[424]; fseek(ifp, -int(sizeof tail), SEEK_END); fread(tail, 1, sizeof tail, ifp); for (nz = i = 0; i < int(sizeof tail); i++) if (tail[i]) nz++; return nz > 20; } int LibRaw::canon_s2is() { unsigned row; for (row = 0; row < 100; row++) { fseek(ifp, row * 3340 + 3284, SEEK_SET); if (getc(ifp) > 15) return 1; } return 0; } #ifdef LIBRAW_OLD_VIDEO_SUPPORT void LibRaw::parse_redcine() { unsigned i, len, rdvo; order = 0x4d4d; is_raw = 0; fseek(ifp, 52, SEEK_SET); width = get4(); height = get4(); fseek(ifp, 0, SEEK_END); fseek(ifp, -(i = ftello(ifp) & 511), SEEK_CUR); if (get4() != i || get4() != 0x52454f42) { fseek(ifp, 0, SEEK_SET); while ((len = get4()) != (unsigned)EOF) { if (get4() == 0x52454456) if (is_raw++ == shot_select) data_offset = ftello(ifp) - 8; fseek(ifp, len - 8, SEEK_CUR); } } else { rdvo = get4(); fseek(ifp, 12, SEEK_CUR); is_raw = get4(); fseeko(ifp, rdvo + 8 + shot_select * 4, SEEK_SET); data_offset = get4(); } } #endif void LibRaw::parse_cine() { unsigned off_head, off_setup, off_image, i, temp; order = 0x4949; fseek(ifp, 4, SEEK_SET); is_raw = get2() == 2; fseek(ifp, 14, SEEK_CUR); is_raw *= get4(); off_head = get4(); off_setup = get4(); off_image = get4(); timestamp = get4(); if ((i = get4())) timestamp = i; fseek(ifp, off_head + 4, SEEK_SET); raw_width = get4(); raw_height = get4(); switch (get2(), get2()) { case 8: load_raw = &LibRaw::eight_bit_load_raw; break; case 16: load_raw = &LibRaw::unpacked_load_raw; } fseek(ifp, off_setup + 792, SEEK_SET); strcpy(make, "CINE"); sprintf(model, "%d", get4()); fseek(ifp, 12, SEEK_CUR); switch ((i = get4()) & 0xffffff) { case 3: filters = 0x94949494; break; case 4: filters = 0x49494949; break; default: is_raw = 0; } fseek(ifp, 72, SEEK_CUR); switch ((get4() + 3600) % 360) { case 270: flip = 4; break; case 180: flip = 1; break; case 90: flip = 7; break; case 0: flip = 2; } cam_mul[0] = getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); cam_mul[2] = getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); temp = get4(); maximum = ~((~0u) << LIM(temp, 1, 31)); fseek(ifp, 668, SEEK_CUR); shutter = get4() / 1000000000.0; fseek(ifp, off_image, SEEK_SET); if (shot_select < is_raw) fseek(ifp, shot_select * 8, SEEK_CUR); data_offset = (INT64)get4() + 8; data_offset += (INT64)get4() << 32; } void LibRaw::parse_qt(int end) { unsigned save, size; char tag[4]; order = 0x4d4d; while (ftell(ifp) + 7 < end) { save = ftell(ifp); if ((size = get4()) < 8) return; if ((int)size < 0) return; // 2+GB is too much if (save + size < save) return; // 32bit overflow fread(tag, 4, 1, ifp); if (!memcmp(tag, "moov", 4) || !memcmp(tag, "udta", 4) || !memcmp(tag, "CNTH", 4)) parse_qt(save + size); if (!memcmp(tag, "CNDA", 4)) parse_jpeg(ftell(ifp)); fseek(ifp, save + size, SEEK_SET); } } void LibRaw::parse_smal(int offset, int fsize) { int ver; fseek(ifp, offset + 2, SEEK_SET); order = 0x4949; ver = fgetc(ifp); if (ver == 6) fseek(ifp, 5, SEEK_CUR); if (get4() != (unsigned)fsize) return; if (ver > 6) data_offset = get4(); raw_height = height = get2(); raw_width = width = get2(); strcpy(make, "SMaL"); sprintf(model, "v%d %dx%d", ver, width, height); if (ver == 6) load_raw = &LibRaw::smal_v6_load_raw; if (ver == 9) load_raw = &LibRaw::smal_v9_load_raw; } void LibRaw::parse_riff(int maxdepth) { unsigned i, size, end; char tag[4], date[64], month[64]; static const char mon[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; struct tm t; if (maxdepth < 1) throw LIBRAW_EXCEPTION_IO_CORRUPT; order = 0x4949; fread(tag, 4, 1, ifp); size = get4(); end = ftell(ifp) + size; if (!memcmp(tag, "RIFF", 4) || !memcmp(tag, "LIST", 4)) { int maxloop = 1000; get4(); while (ftell(ifp) + 7 < end && !feof(ifp) && maxloop--) parse_riff(maxdepth-1); } else if (!memcmp(tag, "nctg", 4)) { while (ftell(ifp) + 7 < end) { if (feof(ifp)) break; i = get2(); size = get2(); if ((i + 1) >> 1 == 10 && size == 20) get_timestamp(0); else fseek(ifp, size, SEEK_CUR); } } else if (!memcmp(tag, "IDIT", 4) && size < 64) { fread(date, 64, 1, ifp); date[size] = 0; memset(&t, 0, sizeof t); if (sscanf(date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) { for (i = 0; i < 12 && strcasecmp(mon[i], month); i++) ; t.tm_mon = i; t.tm_year -= 1900; if (mktime(&t) > 0) timestamp = mktime(&t); } } else fseek(ifp, size, SEEK_CUR); } void LibRaw::parse_rollei() { char line[128], *val; struct tm t; fseek(ifp, 0, SEEK_SET); memset(&t, 0, sizeof t); do { line[0] = 0; if (!fgets(line, 128, ifp)) break; line[127] = 0; if(!line[0]) break; // zero-length if ((val = strchr(line, '='))) *val++ = 0; else val = line + strbuflen(line); if (!strcmp(line, "DAT")) sscanf(val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year); if (!strcmp(line, "TIM")) sscanf(val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec); if (!strcmp(line, "HDR")) thumb_offset = atoi(val); if (!strcmp(line, "X ")) raw_width = atoi(val); if (!strcmp(line, "Y ")) raw_height = atoi(val); if (!strcmp(line, "TX ")) thumb_width = atoi(val); if (!strcmp(line, "TY ")) thumb_height = atoi(val); if (!strcmp(line, "APT")) aperture = atof(val); if (!strcmp(line, "SPE")) shutter = atof(val); if (!strcmp(line, "FOCLEN")) focal_len = atof(val); if (!strcmp(line, "BLKOFS")) black = atoi(val) +1; if (!strcmp(line, "ORI")) switch (atoi(val)) { case 1: flip = 6; break; case 2: flip = 3; break; case 3: flip = 5; break; } if (!strcmp(line, "CUTRECT")) { sscanf(val, "%hu %hu %hu %hu", &imgdata.sizes.raw_inset_crops[0].cleft, &imgdata.sizes.raw_inset_crops[0].ctop, &imgdata.sizes.raw_inset_crops[0].cwidth, &imgdata.sizes.raw_inset_crops[0].cheight); } } while (strncmp(line, "EOHD", 4)); data_offset = thumb_offset + thumb_width * thumb_height * 2; t.tm_year -= 1900; t.tm_mon -= 1; if (mktime(&t) > 0) timestamp = mktime(&t); strcpy(make, "Rollei"); strcpy(model, "d530flex"); thumb_format = LIBRAW_INTERNAL_THUMBNAIL_ROLLEI; } void LibRaw::parse_sinar_ia() { int entries, off; char str[8], *cp; order = 0x4949; fseek(ifp, 4, SEEK_SET); entries = get4(); if (entries < 1 || entries > 8192) return; fseek(ifp, get4(), SEEK_SET); while (entries--) { off = get4(); get4(); fread(str, 8, 1, ifp); str[7] = 0; // Ensure end of string if (!strcmp(str, "META")) meta_offset = off; if (!strcmp(str, "THUMB")) thumb_offset = off; if (!strcmp(str, "RAW0")) data_offset = off; } fseek(ifp, meta_offset + 20, SEEK_SET); fread(make, 64, 1, ifp); make[63] = 0; if ((cp = strchr(make, ' '))) { strcpy(model, cp + 1); *cp = 0; } raw_width = get2(); raw_height = get2(); load_raw = &LibRaw::unpacked_load_raw; thumb_width = (get4(), get2()); thumb_height = get2(); thumb_format = LIBRAW_INTERNAL_THUMBNAIL_PPM; maximum = 0x3fff; } void LibRaw::parse_kyocera() { int c; static const ushort table[13] = {25, 32, 40, 50, 64, 80, 100, 125, 160, 200, 250, 320, 400}; fseek(ifp, 33, SEEK_SET); get_timestamp(1); fseek(ifp, 52, SEEK_SET); c = get4(); if ((c > 6) && (c < 20)) iso_speed = table[c - 7]; shutter = libraw_powf64l(2.0f, (((float)get4()) / 8.0f)) / 16000.0f; FORC4 cam_mul[RGGB_2_RGBG(c)] = get4(); fseek(ifp, 88, SEEK_SET); aperture = libraw_powf64l(2.0f, ((float)get4()) / 16.0f); fseek(ifp, 112, SEEK_SET); focal_len = get4(); fseek(ifp, 104, SEEK_SET); ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, ((float)get4()) / 16.0f); fseek(ifp, 124, SEEK_SET); stmread(ilm.Lens, 32, ifp); ilm.CameraMount = LIBRAW_MOUNT_Contax_N; ilm.CameraFormat = LIBRAW_FORMAT_FF; if (ilm.Lens[0]) { ilm.LensMount = LIBRAW_MOUNT_Contax_N; ilm.LensFormat = LIBRAW_FORMAT_FF; } } int LibRaw::parse_jpeg(int offset) { int len, save, hlen, mark; fseek(ifp, offset, SEEK_SET); if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0; while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) { order = 0x4d4d; len = get2() - 2; save = ftell(ifp); if (mark == 0xc0 || mark == 0xc3 || mark == 0xc9) { fgetc(ifp); raw_height = get2(); raw_width = get2(); } order = get2(); hlen = get4(); if (get4() == 0x48454150 && (save + hlen) >= 0 && (save + hlen) <= ifp->size()) /* "HEAP" */ { parse_ciff(save + hlen, len - hlen, 0); } if (parse_tiff(save + 6)) apply_tiff(); fseek(ifp, save + len, SEEK_SET); } return 1; } void LibRaw::parse_thumb_note(int base, unsigned toff, unsigned tlen) { unsigned entries, tag, type, len, save; entries = get2(); while (entries--) { tiff_get(base, &tag, &type, &len, &save); if (tag == toff) thumb_offset = get4() + base; if (tag == tlen) thumb_length = get4(); fseek(ifp, save, SEEK_SET); } } void LibRaw::parse_broadcom() { /* This structure is at offset 0xb0 from the 'BRCM' ident. */ struct { uint8_t umode[32]; uint16_t uwidth; uint16_t uheight; uint16_t padding_right; uint16_t padding_down; uint32_t unknown_block[6]; uint16_t transform; uint16_t format; uint8_t bayer_order; uint8_t bayer_format; } header; header.bayer_order = 0; fseek(ifp, 0xb0 - 0x20, SEEK_CUR); fread(&header, 1, sizeof(header), ifp); raw_stride = ((((((header.uwidth + header.padding_right) * 5) + 3) >> 2) + 0x1f) & (~0x1f)); raw_width = width = header.uwidth; raw_height = height = header.uheight; filters = 0x16161616; /* default Bayer order is 2, BGGR */ switch (header.bayer_order) { case 0: /* RGGB */ filters = 0x94949494; break; case 1: /* GBRG */ filters = 0x49494949; break; case 3: /* GRBG */ filters = 0x61616161; break; } } /* Returns 1 for a Coolpix 995, 0 for anything else. */ int LibRaw::nikon_e995() { int i, histo[256]; const uchar often[] = {0x00, 0x55, 0xaa, 0xff}; memset(histo, 0, sizeof histo); fseek(ifp, -2000, SEEK_END); for (i = 0; i < 2000; i++) histo[fgetc(ifp)]++; for (i = 0; i < 4; i++) if (histo[often[i]] < 200) return 0; return 1; } /* Since the TIFF DateTime string has no timezone information, assume that the camera's clock was set to Universal Time. */ void LibRaw::get_timestamp(int reversed) { struct tm t; char str[20]; int i; str[19] = 0; if (reversed) for (i = 19; i--;) str[i] = fgetc(ifp); else fread(str, 19, 1, ifp); memset(&t, 0, sizeof t); if (sscanf(str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6) return; t.tm_year -= 1900; t.tm_mon -= 1; t.tm_isdst = -1; if (mktime(&t) > 0) timestamp = mktime(&t); } #ifdef USE_6BY9RPI void LibRaw::parse_raspberrypi() { //This structure is at offset 0xB0 from the 'BRCM' ident. struct brcm_raw_header { uint8_t name[32]; uint16_t h_width; uint16_t h_height; uint16_t padding_right; uint16_t padding_down; uint32_t dummy[6]; uint16_t transform; uint16_t format; uint8_t bayer_order; uint8_t bayer_format; }; //Values taken from https://github.com/raspberrypi/userland/blob/master/interface/vctypes/vc_image_types.h #define BRCM_FORMAT_BAYER 33 #define BRCM_BAYER_RAW8 2 #define BRCM_BAYER_RAW10 3 #define BRCM_BAYER_RAW12 4 #define BRCM_BAYER_RAW14 5 #define BRCM_BAYER_RAW16 6 struct brcm_raw_header header; uint8_t brcm_tag[4]; if (ftell(ifp) > 22LL) // 22 bytes is minimum jpeg size { thumb_length = ftell(ifp); thumb_offset = 0; thumb_width = thumb_height = 0; load_flags |= 0x4000; // flag: we have JPEG from beginning to meta_offset } // Sanity check that the caller has found a BRCM header if (!fread(brcm_tag, 1, sizeof(brcm_tag), ifp) || memcmp(brcm_tag, "BRCM", sizeof(brcm_tag))) return; width = raw_width; data_offset = ftell(ifp) + 0x8000 - sizeof(brcm_tag); if (!fseek(ifp, 0xB0 - int(sizeof(brcm_tag)), SEEK_CUR) && fread(&header, 1, sizeof(header), ifp)) { switch (header.bayer_order) { case 0: //RGGB filters = 0x94949494; break; case 1: //GBRG filters = 0x49494949; break; default: case 2: //BGGR filters = 0x16161616; break; case 3: //GRBG filters = 0x61616161; break; } if (header.format == BRCM_FORMAT_BAYER) { switch (header.bayer_format) { case BRCM_BAYER_RAW8: load_raw = &LibRaw::rpi_load_raw8; //1 pixel per byte raw_stride = ((header.h_width + header.padding_right) + 31)&(~31); width = header.h_width; raw_height = height = header.h_height; is_raw = 1; order = 0x4d4d; break; case BRCM_BAYER_RAW10: load_raw = &LibRaw::nokia_load_raw; //4 pixels per 5 bytes raw_stride = (((((header.h_width + header.padding_right) * 5) + 3) >> 2) + 31)&(~31); width = header.h_width; raw_height = height = header.h_height; is_raw = 1; order = 0x4d4d; break; case BRCM_BAYER_RAW12: load_raw = &LibRaw::rpi_load_raw12; //2 pixels per 3 bytes raw_stride = (((((header.h_width + header.padding_right) * 3) + 1) >> 1) + 31)&(~31); width = header.h_width; raw_height = height = header.h_height; is_raw = 1; order = 0x4d4d; break; case BRCM_BAYER_RAW14: load_raw = &LibRaw::rpi_load_raw14; //4 pixels per 7 bytes raw_stride = (((((header.h_width + header.padding_right) * 7) + 3) >> 2) + 31)&(~31); width = header.h_width; raw_height = height = header.h_height; is_raw = 1; order = 0x4d4d; break; case BRCM_BAYER_RAW16: load_raw = &LibRaw::rpi_load_raw16; //1 pixel per 2 bytes raw_stride = (((header.h_width + header.padding_right) << 1) + 31)&(~31); width = header.h_width; raw_height = height = header.h_height; is_raw = 1; order = 0x4d4d; break; default: break; } } } } #endif LibRaw-0.21.4/src/metadata/nikon.cpp000066400000000000000000001023311477673233700171720ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" // void hexDump(char *title, void *addr, int len); unsigned sget4_order (short _order, uchar *s); double sget_fixed32u (short _order, uchar *s); double AngleConversion_a (short _order, uchar *s); double AngleConversion (short _order, uchar *s); static const uchar xlat[2][256] = { {0xc1, 0xbf, 0x6d, 0x0d, 0x59, 0xc5, 0x13, 0x9d, 0x83, 0x61, 0x6b, 0x4f, 0xc7, 0x7f, 0x3d, 0x3d, 0x53, 0x59, 0xe3, 0xc7, 0xe9, 0x2f, 0x95, 0xa7, 0x95, 0x1f, 0xdf, 0x7f, 0x2b, 0x29, 0xc7, 0x0d, 0xdf, 0x07, 0xef, 0x71, 0x89, 0x3d, 0x13, 0x3d, 0x3b, 0x13, 0xfb, 0x0d, 0x89, 0xc1, 0x65, 0x1f, 0xb3, 0x0d, 0x6b, 0x29, 0xe3, 0xfb, 0xef, 0xa3, 0x6b, 0x47, 0x7f, 0x95, 0x35, 0xa7, 0x47, 0x4f, 0xc7, 0xf1, 0x59, 0x95, 0x35, 0x11, 0x29, 0x61, 0xf1, 0x3d, 0xb3, 0x2b, 0x0d, 0x43, 0x89, 0xc1, 0x9d, 0x9d, 0x89, 0x65, 0xf1, 0xe9, 0xdf, 0xbf, 0x3d, 0x7f, 0x53, 0x97, 0xe5, 0xe9, 0x95, 0x17, 0x1d, 0x3d, 0x8b, 0xfb, 0xc7, 0xe3, 0x67, 0xa7, 0x07, 0xf1, 0x71, 0xa7, 0x53, 0xb5, 0x29, 0x89, 0xe5, 0x2b, 0xa7, 0x17, 0x29, 0xe9, 0x4f, 0xc5, 0x65, 0x6d, 0x6b, 0xef, 0x0d, 0x89, 0x49, 0x2f, 0xb3, 0x43, 0x53, 0x65, 0x1d, 0x49, 0xa3, 0x13, 0x89, 0x59, 0xef, 0x6b, 0xef, 0x65, 0x1d, 0x0b, 0x59, 0x13, 0xe3, 0x4f, 0x9d, 0xb3, 0x29, 0x43, 0x2b, 0x07, 0x1d, 0x95, 0x59, 0x59, 0x47, 0xfb, 0xe5, 0xe9, 0x61, 0x47, 0x2f, 0x35, 0x7f, 0x17, 0x7f, 0xef, 0x7f, 0x95, 0x95, 0x71, 0xd3, 0xa3, 0x0b, 0x71, 0xa3, 0xad, 0x0b, 0x3b, 0xb5, 0xfb, 0xa3, 0xbf, 0x4f, 0x83, 0x1d, 0xad, 0xe9, 0x2f, 0x71, 0x65, 0xa3, 0xe5, 0x07, 0x35, 0x3d, 0x0d, 0xb5, 0xe9, 0xe5, 0x47, 0x3b, 0x9d, 0xef, 0x35, 0xa3, 0xbf, 0xb3, 0xdf, 0x53, 0xd3, 0x97, 0x53, 0x49, 0x71, 0x07, 0x35, 0x61, 0x71, 0x2f, 0x43, 0x2f, 0x11, 0xdf, 0x17, 0x97, 0xfb, 0x95, 0x3b, 0x7f, 0x6b, 0xd3, 0x25, 0xbf, 0xad, 0xc7, 0xc5, 0xc5, 0xb5, 0x8b, 0xef, 0x2f, 0xd3, 0x07, 0x6b, 0x25, 0x49, 0x95, 0x25, 0x49, 0x6d, 0x71, 0xc7}, {0xa7, 0xbc, 0xc9, 0xad, 0x91, 0xdf, 0x85, 0xe5, 0xd4, 0x78, 0xd5, 0x17, 0x46, 0x7c, 0x29, 0x4c, 0x4d, 0x03, 0xe9, 0x25, 0x68, 0x11, 0x86, 0xb3, 0xbd, 0xf7, 0x6f, 0x61, 0x22, 0xa2, 0x26, 0x34, 0x2a, 0xbe, 0x1e, 0x46, 0x14, 0x68, 0x9d, 0x44, 0x18, 0xc2, 0x40, 0xf4, 0x7e, 0x5f, 0x1b, 0xad, 0x0b, 0x94, 0xb6, 0x67, 0xb4, 0x0b, 0xe1, 0xea, 0x95, 0x9c, 0x66, 0xdc, 0xe7, 0x5d, 0x6c, 0x05, 0xda, 0xd5, 0xdf, 0x7a, 0xef, 0xf6, 0xdb, 0x1f, 0x82, 0x4c, 0xc0, 0x68, 0x47, 0xa1, 0xbd, 0xee, 0x39, 0x50, 0x56, 0x4a, 0xdd, 0xdf, 0xa5, 0xf8, 0xc6, 0xda, 0xca, 0x90, 0xca, 0x01, 0x42, 0x9d, 0x8b, 0x0c, 0x73, 0x43, 0x75, 0x05, 0x94, 0xde, 0x24, 0xb3, 0x80, 0x34, 0xe5, 0x2c, 0xdc, 0x9b, 0x3f, 0xca, 0x33, 0x45, 0xd0, 0xdb, 0x5f, 0xf5, 0x52, 0xc3, 0x21, 0xda, 0xe2, 0x22, 0x72, 0x6b, 0x3e, 0xd0, 0x5b, 0xa8, 0x87, 0x8c, 0x06, 0x5d, 0x0f, 0xdd, 0x09, 0x19, 0x93, 0xd0, 0xb9, 0xfc, 0x8b, 0x0f, 0x84, 0x60, 0x33, 0x1c, 0x9b, 0x45, 0xf1, 0xf0, 0xa3, 0x94, 0x3a, 0x12, 0x77, 0x33, 0x4d, 0x44, 0x78, 0x28, 0x3c, 0x9e, 0xfd, 0x65, 0x57, 0x16, 0x94, 0x6b, 0xfb, 0x59, 0xd0, 0xc8, 0x22, 0x36, 0xdb, 0xd2, 0x63, 0x98, 0x43, 0xa1, 0x04, 0x87, 0x86, 0xf7, 0xa6, 0x26, 0xbb, 0xd6, 0x59, 0x4d, 0xbf, 0x6a, 0x2e, 0xaa, 0x2b, 0xef, 0xe6, 0x78, 0xb6, 0x4e, 0xe0, 0x2f, 0xdc, 0x7c, 0xbe, 0x57, 0x19, 0x32, 0x7e, 0x2a, 0xd0, 0xb8, 0xba, 0x29, 0x00, 0x3c, 0x52, 0x7d, 0xa8, 0x49, 0x3b, 0x2d, 0xeb, 0x25, 0x49, 0xfa, 0xa3, 0xaa, 0x39, 0xa7, 0xc5, 0xa7, 0x50, 0x11, 0x36, 0xfb, 0xc6, 0x67, 0x4a, 0xf5, 0xa5, 0x12, 0x65, 0x7e, 0xb0, 0xdf, 0xaf, 0x4e, 0xb3, 0x61, 0x7f, 0x2f} }; void LibRaw::processNikonLensData(uchar *LensData, unsigned len) { ushort i=0; if (imgdata.lens.nikon.LensType & 0x80) { strcpy (ilm.LensFeatures_pre, "AF-P"); } else if (!(imgdata.lens.nikon.LensType & 0x01)) { ilm.LensFeatures_pre[0] = 'A'; ilm.LensFeatures_pre[1] = 'F'; } else { ilm.LensFeatures_pre[0] = 'M'; ilm.LensFeatures_pre[1] = 'F'; } if (imgdata.lens.nikon.LensType & 0x40) { ilm.LensFeatures_suf[0] = 'E'; } else if (imgdata.lens.nikon.LensType & 0x04) { ilm.LensFeatures_suf[0] = 'G'; } else if (imgdata.lens.nikon.LensType & 0x02) { ilm.LensFeatures_suf[0] = 'D'; } if (imgdata.lens.nikon.LensType & 0x08) { ilm.LensFeatures_suf[1] = ' '; ilm.LensFeatures_suf[2] = 'V'; ilm.LensFeatures_suf[3] = 'R'; } if (imgdata.lens.nikon.LensType & 0x10) { ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX; ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_1INCH; } else ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Nikon_F; if (imgdata.lens.nikon.LensType & 0x20) { strcpy(ilm.Adapter, "FT-1"); ilm.LensMount = LIBRAW_MOUNT_Nikon_F; ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX; ilm.CameraFormat = LIBRAW_FORMAT_1INCH; } imgdata.lens.nikon.LensType = imgdata.lens.nikon.LensType & 0xdf; if ((len < 20) || (len == 58) || (len == 108)) { switch (len) { case 9: i = 2; break; case 15: i = 7; break; case 16: i = 8; break; case 58: // "Z 6", "Z 6 II", "Z 7", "Z 7 II", "Z 50", D780, "Z 5", "Z fc" case 108: // "Z 9" if (model[6] == 'Z') ilm.CameraMount = LIBRAW_MOUNT_Nikon_Z; if (imNikon.HighSpeedCropFormat != 12) ilm.CameraFormat = LIBRAW_FORMAT_FF; i = 1; while ((LensData[i] == LensData[0]) && (i < 17)) i++; if (i == 17) { ilm.LensMount = LIBRAW_MOUNT_Nikon_Z; ilm.LensID = sget2(LensData + 0x2c); if ( (ilm.LensID == 11) || (ilm.LensID == 12) || (ilm.LensID == 26) ) ilm.LensFormat = LIBRAW_FORMAT_APSC; else ilm.LensFormat = LIBRAW_FORMAT_FF; if (ilm.MaxAp4CurFocal < 0.7f) ilm.MaxAp4CurFocal = libraw_powf64l( 2.0f, (float)sget2(LensData + 0x32) / 384.0f - 1.0f); if (ilm.CurAp < 0.7f) ilm.CurAp = libraw_powf64l( 2.0f, (float)sget2(LensData + 0x34) / 384.0f - 1.0f); if (fabsf(ilm.CurFocal) < 1.1f) ilm.CurFocal = sget2(LensData + 0x38); return; } i = 9; ilm.LensMount = LIBRAW_MOUNT_Nikon_F; if (ilm.CameraMount == LIBRAW_MOUNT_Nikon_Z) strcpy(ilm.Adapter, "FTZ"); break; } imgdata.lens.nikon.LensIDNumber = LensData[i]; imgdata.lens.nikon.LensFStops = LensData[i + 1]; ilm.LensFStops = (float)imgdata.lens.nikon.LensFStops / 12.0f; if (fabsf(ilm.MinFocal) < 1.1f) { if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 2]) ilm.MinFocal = 5.0f * libraw_powf64l(2.0f, (float)LensData[i + 2] / 24.0f); if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 3]) ilm.MaxFocal = 5.0f * libraw_powf64l(2.0f, (float)LensData[i + 3] / 24.0f); if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 4]) ilm.MaxAp4MinFocal = libraw_powf64l(2.0f, (float)LensData[i + 4] / 24.0f); if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 5]) ilm.MaxAp4MaxFocal = libraw_powf64l(2.0f, (float)LensData[i + 5] / 24.0f); } imgdata.lens.nikon.MCUVersion = LensData[i + 6]; if (i != 2) { if ((LensData[i - 1]) && (fabsf(ilm.CurFocal) < 1.1f)) ilm.CurFocal = 5.0f * libraw_powf64l(2.0f, (float)LensData[i - 1] / 24.0f); if (LensData[i + 7]) imgdata.lens.nikon.EffectiveMaxAp = libraw_powf64l(2.0f, (float)LensData[i + 7] / 24.0f); } ilm.LensID = (unsigned long long)LensData[i] << 56 | (unsigned long long)LensData[i + 1] << 48 | (unsigned long long)LensData[i + 2] << 40 | (unsigned long long)LensData[i + 3] << 32 | (unsigned long long)LensData[i + 4] << 24 | (unsigned long long)LensData[i + 5] << 16 | (unsigned long long)LensData[i + 6] << 8 | (unsigned long long)imgdata.lens.nikon.LensType; } else if ((len == 459) || (len == 590)) { memcpy(ilm.Lens, LensData + 390, 64); } else if (len == 509) { memcpy(ilm.Lens, LensData + 391, 64); } else if (len == 879) { memcpy(ilm.Lens, LensData + 680, 64); } return; } void LibRaw::Nikon_NRW_WBtag(int wb, int skip) { int r, g0, g1, b; if (skip) get4(); // skip wb "CCT", it is not unique r = get4(); g0 = get4(); g1 = get4(); b = get4(); if (r && g0 && g1 && b) { icWBC[wb][0] = r << 1; icWBC[wb][1] = g0; icWBC[wb][2] = b << 1; icWBC[wb][3] = g1; } return; } void LibRaw::parseNikonMakernote(int base, int uptag, unsigned /*dng_writer */) { unsigned offset = 0, entries, tag, type, len, save; unsigned c, i; unsigned LensData_len = 0; uchar *LensData_buf=0; uchar ColorBalanceData_buf[324]; int ColorBalanceData_ready = 0; uchar ci, cj, ck; unsigned serial = 0; unsigned custom_serial = 0; unsigned ShotInfo_len = 0; uchar *ShotInfo_buf=0; /* for dump: uchar *cj_block, *ck_block; */ short morder, sorder = order; char buf[10]; INT64 fsize = ifp->size(); fread(buf, 1, 10, ifp); if (!strcmp(buf, "Nikon")) { if (buf[6] != '\2') return; base = ftell(ifp); order = get2(); if (get2() != 42) goto quit; offset = get4(); fseek(ifp, INT64(offset) - 8LL, SEEK_CUR); } else { fseek(ifp, -10, SEEK_CUR); } entries = get2(); if (entries > 1000) return; morder = order; while (entries--) { order = morder; tiff_get(base, &tag, &type, &len, &save); INT64 pos = ifp->tell(); if (len > 8 && pos + len > 2 * fsize) { fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! continue; } tag |= uptag << 16; if (len > 100 * 1024 * 1024) goto next; // 100Mb tag? No! if (tag == 0x0002) { if (!iso_speed) iso_speed = (get2(), get2()); } else if (tag == 0x000a) { ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_FixedLens; ilm.FocalType = LIBRAW_FT_ZOOM_LENS; } else if ((tag == 0x000c) && (len == 4) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_RATIONAL)) { cam_mul[0] = getreal(type); cam_mul[2] = getreal(type); cam_mul[1] = getreal(type); cam_mul[3] = getreal(type); } else if (tag == 0x0011) { if (is_raw) { fseek(ifp, get4() + base, SEEK_SET); parse_tiff_ifd(base); } } else if (tag == 0x0012) { uchar uc1 = fgetc(ifp); uchar uc2 = fgetc(ifp); uchar uc3 = fgetc(ifp); if (uc3) imCommon.FlashEC = (float)(uc1 * uc2) / (float)uc3; } else if (tag == 0x0014) { if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary)) { if (len == 2560) { // E5400, E8400, E8700, E8800 fseek(ifp, 0x4e0L, SEEK_CUR); order = 0x4d4d; cam_mul[0] = get2() / 256.0; cam_mul[2] = get2() / 256.0; cam_mul[1] = cam_mul[3] = 1.0; icWBC[LIBRAW_WBI_Auto][0] = get2(); icWBC[LIBRAW_WBI_Auto][2] = get2(); icWBC[LIBRAW_WBI_Daylight][0] = get2(); icWBC[LIBRAW_WBI_Daylight][2] = get2(); fseek(ifp, 0x18L, SEEK_CUR); icWBC[LIBRAW_WBI_Tungsten][0] = get2(); icWBC[LIBRAW_WBI_Tungsten][2] = get2(); fseek(ifp, 0x18L, SEEK_CUR); icWBC[LIBRAW_WBI_FL_W][0] = get2(); icWBC[LIBRAW_WBI_FL_W][2] = get2(); icWBC[LIBRAW_WBI_FL_N][0] = get2(); icWBC[LIBRAW_WBI_FL_N][2] = get2(); icWBC[LIBRAW_WBI_FL_D][0] = get2(); icWBC[LIBRAW_WBI_FL_D][2] = get2(); icWBC[LIBRAW_WBI_Cloudy][0] = get2(); icWBC[LIBRAW_WBI_Cloudy][2] = get2(); fseek(ifp, 0x18L, SEEK_CUR); icWBC[LIBRAW_WBI_Flash][0] = get2(); icWBC[LIBRAW_WBI_Flash][2] = get2(); icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] = icWBC[LIBRAW_WBI_Daylight][1] = icWBC[LIBRAW_WBI_Daylight][3] = icWBC[LIBRAW_WBI_Tungsten][1] = icWBC[LIBRAW_WBI_Tungsten][3] = icWBC[LIBRAW_WBI_FL_W][1] = icWBC[LIBRAW_WBI_FL_W][3] = icWBC[LIBRAW_WBI_FL_N][1] = icWBC[LIBRAW_WBI_FL_N][3] = icWBC[LIBRAW_WBI_FL_D][1] = icWBC[LIBRAW_WBI_FL_D][3] = icWBC[LIBRAW_WBI_Cloudy][1] = icWBC[LIBRAW_WBI_Cloudy][3] = icWBC[LIBRAW_WBI_Flash][1] = icWBC[LIBRAW_WBI_Flash][3] = 256; if (strncmp(model, "E8700", 5)) { fseek(ifp, 0x18L, SEEK_CUR); icWBC[LIBRAW_WBI_Shade][0] = get2(); icWBC[LIBRAW_WBI_Shade][2] = get2(); icWBC[LIBRAW_WBI_Shade][1] = icWBC[LIBRAW_WBI_Shade][3] = 256; } } else if (len == 1280) { // E5000, E5700 cam_mul[0] = cam_mul[1] = cam_mul[2] = cam_mul[3] = 1.0; } else { fread(buf, 1, 10, ifp); if (!strncmp(buf, "NRW ", 4)) { // P6000, P7000, P7100, B700, P1000 if (!strcmp(buf + 4, "0100")) { // P6000 fseek(ifp, 0x13deL, SEEK_CUR); cam_mul[0] = get4() << 1; cam_mul[1] = get4(); cam_mul[3] = get4(); cam_mul[2] = get4() << 1; Nikon_NRW_WBtag(LIBRAW_WBI_Daylight, 0); Nikon_NRW_WBtag(LIBRAW_WBI_Cloudy, 0); fseek(ifp, 0x10L, SEEK_CUR); Nikon_NRW_WBtag(LIBRAW_WBI_Tungsten, 0); Nikon_NRW_WBtag(LIBRAW_WBI_FL_W, 0); Nikon_NRW_WBtag(LIBRAW_WBI_Flash, 0); fseek(ifp, 0x10L, SEEK_CUR); Nikon_NRW_WBtag(LIBRAW_WBI_Custom, 0); Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 0); } else { // P7000, P7100, B700, P1000 fseek(ifp, 0x16L, SEEK_CUR); black = get2(); if (cam_mul[0] < 0.1f) { fseek(ifp, 0x16L, SEEK_CUR); cam_mul[0] = get4() << 1; cam_mul[1] = get4(); cam_mul[3] = get4(); cam_mul[2] = get4() << 1; } else { fseek(ifp, 0x26L, SEEK_CUR); } if (len != 332) { // not A1000 Nikon_NRW_WBtag(LIBRAW_WBI_Daylight, 1); Nikon_NRW_WBtag(LIBRAW_WBI_Cloudy, 1); Nikon_NRW_WBtag(LIBRAW_WBI_Shade, 1); Nikon_NRW_WBtag(LIBRAW_WBI_Tungsten, 1); Nikon_NRW_WBtag(LIBRAW_WBI_FL_W, 1); Nikon_NRW_WBtag(LIBRAW_WBI_FL_N, 1); Nikon_NRW_WBtag(LIBRAW_WBI_FL_D, 1); Nikon_NRW_WBtag(LIBRAW_WBI_HT_Mercury, 1); fseek(ifp, 0x14L, SEEK_CUR); Nikon_NRW_WBtag(LIBRAW_WBI_Custom, 1); Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 1); } else { fseek(ifp, 0xc8L, SEEK_CUR); Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 1); } } } } } } else if (tag == 0x001b) { imNikon.HighSpeedCropFormat = get2(); imNikon.SensorHighSpeedCrop.cwidth = get2(); imNikon.SensorHighSpeedCrop.cheight = get2(); imNikon.SensorWidth = get2(); imNikon.SensorHeight = get2(); imNikon.SensorHighSpeedCrop.cleft = get2(); imNikon.SensorHighSpeedCrop.ctop = get2(); switch (imNikon.HighSpeedCropFormat) { case 0: case 1: case 2: case 4: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; break; case 11: ilm.CameraFormat = LIBRAW_FORMAT_FF; imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; break; case 12: ilm.CameraFormat = LIBRAW_FORMAT_APSC; imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; break; case 3: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_5to4; break; case 6: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9; break; case 17: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; break; default: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_OTHER; break; } } else if (tag == 0x001d) { // serial number if (len > 0) { int model_len = (int)strbuflen(model); while ((c = fgetc(ifp)) && (len-- > 0) && (c != (unsigned)EOF)) { if ((!custom_serial) && (!isdigit(c))) { if (((model_len == 3) && !strcmp(model, "D50")) || ((model_len >= 4) && !isalnum(model[model_len - 4]) && !strncmp(&model[model_len - 3], "D50", 3))) { custom_serial = 34; } else { custom_serial = 96; } break; } serial = serial * 10 + (isdigit(c) ? c - '0' : c % 10); } if (!imgdata.shootinginfo.BodySerial[0]) sprintf(imgdata.shootinginfo.BodySerial, "%d", serial); } } else if (tag == 0x001e) { switch (get2()) { case 1: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 2: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } } else if (tag == 0x0025) { imCommon.real_ISO = int(100.0 * libraw_powf64l(2.0, double((uchar)fgetc(ifp)) / 12.0 - 5.0)); if (!iso_speed || (iso_speed == 65535)) { iso_speed = imCommon.real_ISO; } } else if (tag == 0x0022) { imNikon.Active_D_Lighting = get2(); } else if (tag == 0x003b) { // WB for multi-exposure (ME); all 1s for regular exposures imNikon.ME_WB[0] = getreal(type); imNikon.ME_WB[2] = getreal(type); imNikon.ME_WB[1] = getreal(type); imNikon.ME_WB[3] = getreal(type); } else if (tag == 0x003d) { // not corrected for file bitcount, to be patched in open_datastream FORC4 cblack[RGGB_2_RGBG(c)] = get2(); i = cblack[3]; FORC3 if (i > cblack[c]) i = cblack[c]; FORC4 cblack[c] -= i; black += i; } else if (tag == 0x0045) { /* upper left pixel (x,y), size (width,height) */ imgdata.sizes.raw_inset_crops[0].cleft = get2(); imgdata.sizes.raw_inset_crops[0].ctop = get2(); imgdata.sizes.raw_inset_crops[0].cwidth = get2(); imgdata.sizes.raw_inset_crops[0].cheight = get2(); } else if (tag == 0x0051) { fseek(ifp, 10LL, SEEK_CUR); imNikon.NEFCompression = get2(); } else if (tag == 0x0082) { // lens attachment stmread(ilm.Attachment, len, ifp); } else if (tag == 0x0083) { // lens type imgdata.lens.nikon.LensType = fgetc(ifp); } else if (tag == 0x0084) { // lens ilm.MinFocal = getreal(type); ilm.MaxFocal = getreal(type); ilm.MaxAp4MinFocal = getreal(type); ilm.MaxAp4MaxFocal = getreal(type); } else if (tag == 0x0088) // AFInfo { if (!imCommon.afcount) { imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; imCommon.afdata[imCommon.afcount].AFInfoData_order = order; imCommon.afdata[imCommon.afcount].AFInfoData_length = len; imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length,1); fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); imCommon.afcount = 1; } } else if (tag == 0x008b) // lens f-stops { uchar uc1 = fgetc(ifp); uchar uc2 = fgetc(ifp); uchar uc3 = fgetc(ifp); if (uc3) { imgdata.lens.nikon.LensFStops = uc1 * uc2 * (12 / uc3); ilm.LensFStops = (float)imgdata.lens.nikon.LensFStops / 12.0f; } } else if ((tag == 0x008c) || (tag == 0x0096)) { meta_offset = ftell(ifp); } else if ((tag == 0x0091) && (len > 4)) { ShotInfo_len = len; ShotInfo_buf = (uchar *)calloc(ShotInfo_len,1); /* for dump: cj_block = (uchar *)malloc(ShotInfo_len); ck_block = (uchar *)malloc(ShotInfo_len); */ fread(ShotInfo_buf, ShotInfo_len, 1, ifp); FORC4 imNikon.ShotInfoVersion = imNikon.ShotInfoVersion * 10 + ShotInfo_buf[c] - '0'; } else if (tag == 0x0093) { imNikon.NEFCompression = i = get2(); if ((i == 7) || (i == 9)) { ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.CameraMount = LIBRAW_MOUNT_FixedLens; } } else if (tag == 0x0097) { // ver97 FORC4 imNikon.ColorBalanceVersion = imNikon.ColorBalanceVersion * 10 + fgetc(ifp) - '0'; switch (imNikon.ColorBalanceVersion) { case 100: // NIKON D100 fseek(ifp, 0x44L, SEEK_CUR); FORC4 cam_mul[RBGG_2_RGBG(c)] = get2(); break; case 102: // NIKON D2H fseek(ifp, 0x6L, SEEK_CUR); FORC4 cam_mul[RGGB_2_RGBG(c)] = get2(); break; case 103: // NIKON D70, D70s fseek(ifp, 0x10L, SEEK_CUR); FORC4 cam_mul[c] = get2(); } if (imNikon.ColorBalanceVersion >= 200) { /* 204: NIKON D2X, D2Xs 205: NIKON D50 206: NIKON D2Hs 207: NIKON D200 208: NIKON D40, D40X, D80 209: NIKON D3, D3X, D300, D700 210: NIKON D60 211: NIKON D90, D5000 212: NIKON D300S 213: NIKON D3000 214: NIKON D3S 215: NIKON D3100 216: NIKON D5100, D7000 217: NIKON D4, D600, D800, D800E, D3200 -= unknown =- 218: NIKON D5200, D7100 219: NIKON D5300 220: NIKON D610, Df 221: NIKON D3300 222: NIKON D4S 223: NIKON D750, D810 224: NIKON D3400, D3500, D5500, D5600, D7200 225: NIKON D5, D500 226: NIKON D7500 227: NIKON D850 */ if (imNikon.ColorBalanceVersion != 205) { fseek(ifp, 0x118L, SEEK_CUR); } ColorBalanceData_ready = (fread(ColorBalanceData_buf, 324, 1, ifp) == 1); } if ((imNikon.ColorBalanceVersion >= 400) && (imNikon.ColorBalanceVersion <= 405)) { // 1 J1, 1 V1, 1 J2, 1 V2, 1 J3, 1 S1, 1 AW1, 1 S2, 1 J4, 1 V3, 1 J5 ilm.CameraFormat = LIBRAW_FORMAT_1INCH; ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX; } else if ((imNikon.ColorBalanceVersion >= 500) && (imNikon.ColorBalanceVersion <= 502)) { // P7700, P7800, P330, P340 ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.FocalType = LIBRAW_FT_ZOOM_LENS; } else if (imNikon.ColorBalanceVersion == 601) { // Coolpix A ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.FocalType = LIBRAW_FT_PRIME_LENS; } } else if (tag == 0x0098) // contains lens data { FORC4 imNikon.LensDataVersion = imNikon.LensDataVersion * 10 + fgetc(ifp) - '0'; switch (imNikon.LensDataVersion) { case 100: LensData_len = 9; break; case 101: case 201: // encrypted, starting from v.201 case 202: case 203: LensData_len = 15; break; case 204: LensData_len = 16; break; case 400: LensData_len = 459; break; case 401: LensData_len = 590; break; case 402: LensData_len = 509; break; case 403: LensData_len = 879; break; case 800: case 801: LensData_len = 58; break; case 802: LensData_len = 108; break; } if (LensData_len) { LensData_buf = (uchar *)calloc(LensData_len,1); fread(LensData_buf, LensData_len, 1, ifp); } } else if (tag == 0x00a0) { stmread(imgdata.shootinginfo.BodySerial, len, ifp); } else if (tag == 0x00a7) // shutter count { imNikon.key = fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp); if (custom_serial) { ci = xlat[0][custom_serial]; } else { ci = xlat[0][serial & 0xff]; } cj = xlat[1][imNikon.key]; ck = 0x60; if (((unsigned)(imNikon.ColorBalanceVersion - 200) < 18) && ColorBalanceData_ready) { for (i = 0; i < 324; i++) ColorBalanceData_buf[i] ^= (cj += ci * ck++); i = "66666>666;6A;:;555"[imNikon.ColorBalanceVersion - 200] - '0'; FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] = sget2(ColorBalanceData_buf + (i & -2) + c * 2); } if (LensData_len) { if (imNikon.LensDataVersion > 200) { cj = xlat[1][imNikon.key]; ck = 0x60; for (i = 0; i < LensData_len; i++) { LensData_buf[i] ^= (cj += ci * ck++); } } processNikonLensData(LensData_buf, LensData_len); LensData_len = 0; free(LensData_buf); } if (ShotInfo_len && (imNikon.ShotInfoVersion >= 208)) { unsigned RotationOffset = 0, OrientationOffset = 0; cj = xlat[1][imNikon.key]; ck = 0x60; for (i = 4; i < ShotInfo_len; i++) { ShotInfo_buf[i] ^= (cj += ci * ck++); /* for dump: cj_block[i-4] = cj; ck_block[i-4] = ck-1; */ } /* for dump: printf ("==>> ci: 0x%02x, cj at start: 0x%02x\n", ci, xlat[1][imNikon.key]); hexDump("ck array:", ck_block, ShotInfo_len-4); hexDump("cj array:", cj_block, ShotInfo_len-4); free(cj_block); free(ck_block); */ switch (imNikon.ShotInfoVersion) { case 208: // ShotInfoD80, Rotation RotationOffset = 590; if (RotationOffset>4) & 0x03; } break; case 233: // ShotInfoD810, Roll/Pitch/Yaw OrientationOffset = sget4_order(morder, ShotInfo_buf+0x84); break; case 238: // D5, ShotInfoD500, Rotation, Roll/Pitch/Yaw case 239: // D500, ShotInfoD500, Rotation, Roll/Pitch/Yaw RotationOffset = sget4_order(morder, ShotInfo_buf+0x10) + 0xca; if (RotationOffset > 0xca) { RotationOffset -= 0xb0; } if (RotationOffset= 0)) imNikon.MakernotesFlip = "0863"[imNikon.MakernotesFlip] - '0'; ShotInfo_len = 0; free(ShotInfo_buf); } } else if (tag == 0x00a8) { // contains flash data FORC4 imNikon.FlashInfoVersion = imNikon.FlashInfoVersion * 10 + fgetc(ifp) - '0'; } else if (tag == 0x00b0) { get4(); // ME (multi-exposure) tag version, 4 symbols imNikon.ExposureMode = get4(); imNikon.nMEshots = get4(); imNikon.MEgainOn = get4(); } else if (tag == 0x00b7) // AFInfo2 { if (!imCommon.afcount && len > 4) { imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; imCommon.afdata[imCommon.afcount].AFInfoData_order = order; int ver = 0; FORC4 ver = ver * 10 + (fgetc(ifp) - '0'); imCommon.afdata[imCommon.afcount].AFInfoData_version = ver; imCommon.afdata[imCommon.afcount].AFInfoData_length = len-4; imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length,1); fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); imCommon.afcount = 1; } } else if (tag == 0x00b9) { imNikon.AFFineTune = fgetc(ifp); imNikon.AFFineTuneIndex = fgetc(ifp); imNikon.AFFineTuneAdj = (int8_t)fgetc(ifp); } else if ((tag == 0x0100) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED)) { thumb_offset = ftell(ifp); thumb_length = len; } else if (tag == 0x0e01) { /* Nikon Software / in-camera edit Note */ int loopc = 0; int WhiteBalanceAdj_active = 0; order = 0x4949; fseek(ifp, 22, SEEK_CUR); for (offset = 22; offset + 22 < len; offset += 22 + i) { if (loopc++ > 1024) throw LIBRAW_EXCEPTION_IO_CORRUPT; tag = get4(); fseek(ifp, 14, SEEK_CUR); i = get4() - 4; if (tag == 0x76a43204) { WhiteBalanceAdj_active = fgetc(ifp); } else if (tag == 0xbf3c6c20) { if (WhiteBalanceAdj_active) { union { double dbl; unsigned long long lng; } un; un.dbl = getreal(LIBRAW_EXIFTAG_TYPE_DOUBLE); if ((un.lng != 0x3FF0000000000000ULL) && (un.lng != 0x000000000000F03FULL)) { cam_mul[0] = un.dbl; cam_mul[2] = getreal(LIBRAW_EXIFTAG_TYPE_DOUBLE); cam_mul[1] = cam_mul[3] = 1.0; i -= 16; } else i -= 8; } fseek(ifp, i, SEEK_CUR); } else if (tag == 0x76a43207) { flip = get2(); } else { fseek(ifp, i, SEEK_CUR); } } } else if (tag == 0x0e22) { FORC4 imNikon.NEFBitDepth[c] = get2(); } next: fseek(ifp, save, SEEK_SET); } quit: order = sorder; } unsigned sget4_order (short _order, uchar *s) { unsigned v; if (_order == 0x4949) v= s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; else v= s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; return v; } double sget_fixed32u (short _order, uchar *s) { unsigned v = sget4_order (_order, s); return ((double)v / 6.5536 + 0.5) / 10000.0; } double AngleConversion_a (short _order, uchar *s) { double v = sget_fixed32u(_order, s); if (v < 180.0) return -v; return 360.0-v; } double AngleConversion (short _order, uchar *s) { double v = sget_fixed32u(_order, s); if (v <= 180.0) return v; return v-360.0; } /* ========= */ /* void hexDump(char *title, void *addr, int len) { int i; unsigned char buff[17]; unsigned char *pc = (unsigned char*)addr; // Output description if given. if (title != NULL) printf ("%s:\n", title); // Process every byte in the data. for (i = 0; i < len; i++) { // Multiple of 16 means new line (with line offset). if ((i % 16) == 0) { // Just don't print ASCII for the zeroth line. if (i != 0) printf(" %s\n", buff); // Output the offset. printf(" %04x ", i); } // Now the hex code for the specific character. printf(" %02x", pc[i]); // And store a printable ASCII character for later. if ((pc[i] < 0x20) || (pc[i] > 0x7e)) { buff[i % 16] = '.'; } else { buff[i % 16] = pc[i]; } buff[(i % 16) + 1] = '\0'; } // Pad out last line if not exactly 16 characters. while ((i % 16) != 0) { printf(" "); i++; } // And print the final ASCII bit. printf(" %s\n", buff); } */ LibRaw-0.21.4/src/metadata/normalize_model.cpp000066400000000000000000001404161477673233700212420ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" #include "../../internal/libraw_cameraids.h" void LibRaw::GetNormalizedModel() { int i, j; char *ps; int try_xml = 0; static const struct { unsigned long long id; char t_model[20]; } unique[] = // clang-format off { { CanonID_EOS_M50, "EOS M50"}, // Kiss M { CanonID_EOS_M6_Mark_II, "EOS M6 Mark II"}, { CanonID_EOS_M200, "EOS M200"}, { CanonID_EOS_D30, "EOS D30"}, { CanonID_EOS_D60, "EOS D60"}, { CanonID_EOS_M3, "EOS M3"}, { CanonID_EOS_M10, "EOS M10"}, { CanonID_EOS_M5, "EOS M5"}, { CanonID_EOS_M100, "EOS M100"}, { CanonID_EOS_M6, "EOS M6"}, { CanonID_EOS_1D, "EOS-1D"}, { CanonID_EOS_1Ds, "EOS-1Ds"}, { CanonID_EOS_10D, "EOS 10D"}, { CanonID_EOS_1D_Mark_III, "EOS-1D Mark III"}, { CanonID_EOS_300D, "EOS 300D"}, // Digital Rebel / Kiss Digital { CanonID_EOS_1D_Mark_II, "EOS-1D Mark II"}, { CanonID_EOS_20D, "EOS 20D"}, { CanonID_EOS_450D, "EOS 450D"}, // Digital Rebel XSi / Kiss X2 { CanonID_EOS_1Ds_Mark_II, "EOS-1Ds Mark II"}, { CanonID_EOS_350D, "EOS 350D"}, // Digital Rebel XT / Kiss Digital N { CanonID_EOS_40D, "EOS 40D"}, { CanonID_EOS_5D, "EOS 5D"}, { CanonID_EOS_1Ds_Mark_III, "EOS-1Ds Mark III"}, { CanonID_EOS_5D_Mark_II, "EOS 5D Mark II"}, { CanonID_EOS_1D_Mark_II_N, "EOS-1D Mark II N"}, { CanonID_EOS_30D, "EOS 30D"}, { CanonID_EOS_400D, "EOS 400D"}, // Digital Rebel XTi / Kiss Digital X { CanonID_EOS_7D, "EOS 7D"}, { CanonID_EOS_500D, "EOS 500D"}, // Rebel T1i / Kiss X3 { CanonID_EOS_1000D, "EOS 1000D"}, // Digital Rebel XS / Kiss F { CanonID_EOS_50D, "EOS 50D"}, { CanonID_EOS_1D_X, "EOS-1D X"}, { CanonID_EOS_550D, "EOS 550D"}, // Rebel T2i / Kiss X4 { CanonID_EOS_1D_Mark_IV, "EOS-1D Mark IV"}, { CanonID_EOS_5D_Mark_III, "EOS 5D Mark III"}, { CanonID_EOS_600D, "EOS 600D"}, // Rebel T3i / Kiss X5 { CanonID_EOS_60D, "EOS 60D"}, { CanonID_EOS_1100D, "EOS 1100D"}, // Rebel T3 / Kiss X50 { CanonID_EOS_7D_Mark_II, "EOS 7D Mark II"}, { CanonID_EOS_650D, "EOS 650D"}, // Rebel T4i / Kiss X6i { CanonID_EOS_6D, "EOS 6D"}, { CanonID_EOS_1D_C, "EOS-1D C"}, { CanonID_EOS_70D, "EOS 70D"}, { CanonID_EOS_700D, "EOS 700D"}, // Rebel T5i / Kiss X7i { CanonID_EOS_1200D, "EOS 1200D"}, // Rebel T5 / Kiss X70 / Hi { CanonID_EOS_1D_X_Mark_II, "EOS-1D X Mark II"}, { CanonID_EOS_M, "EOS M"}, { CanonID_EOS_100D, "EOS 100D"}, // Rebel SL1 / Kiss X7 { CanonID_EOS_760D, "EOS 760D"}, // Rebel T6s / 8000D { CanonID_EOS_5D_Mark_IV, "EOS 5D Mark IV"}, { CanonID_EOS_80D, "EOS 80D"}, { CanonID_EOS_M2, "EOS M2"}, { CanonID_EOS_5DS, "EOS 5DS"}, { CanonID_EOS_750D, "EOS 750D"}, // Rebel T6i / Kiss X8i { CanonID_EOS_5DS_R, "EOS 5DS R"}, { CanonID_EOS_1300D, "EOS 1300D"}, // Rebel T6 / Kiss X80 { CanonID_EOS_800D, "EOS 800D"}, // Rebel T7i / Kiss X9i { CanonID_EOS_6D_Mark_II, "EOS 6D Mark II"}, { CanonID_EOS_77D, "EOS 77D"}, // 9000D { CanonID_EOS_200D, "EOS 200D"}, // Rebel SL2 / Kiss X9 { CanonID_EOS_R5, "EOS R5"}, { CanonID_EOS_3000D, "EOS 3000D"}, // Rebel T100 / 4000D { CanonID_EOS_R, "EOS R"}, { CanonID_EOS_1D_X_Mark_III, "EOS-1D X Mark III"}, { CanonID_EOS_1500D, "EOS 1500D"}, // Rebel T7 / 2000D / Kiss X90 { CanonID_EOS_RP, "EOS RP"}, { CanonID_EOS_850D, "EOS 850D"}, // EOS Rebel T8i / X10i { CanonID_EOS_250D, "EOS 250D"}, // Rebel SL3 / 200D II / Kiss X10 { CanonID_EOS_90D, "EOS 90D"}, { CanonID_EOS_R3, "EOS R3"}, { CanonID_EOS_R6, "EOS R6"}, { CanonID_EOS_R7, "EOS R7"}, { CanonID_EOS_R10, "EOS R10"}, { CanonID_EOS_M50_Mark_II, "EOS M50 Mark II"}, // M50m2, Kiss M2 }, #if 0 olyque[] = { { OlyID_E_20, "E-20"}, { OlyID_E_20, "E-20,E-20N,E-20P"}, { OlyID_E_1, "E-1"}, { OlyID_E_300, "E-300"}, { OlyID_SP_550UZ, "SP-550UZ"}, { OlyID_SP_550UZ, "SP550UZ"}, { OlyID_SP_510UZ, "SP-510UZ"}, { OlyID_SP_510UZ, "SP510UZ"}, { OlyID_SP_560UZ, "SP-560UZ"}, { OlyID_SP_560UZ, "SP560UZ"}, { OlyID_SP_570UZ, "SP-570UZ"}, { OlyID_SP_570UZ, "SP570UZ"}, { OlyID_SP_565UZ, "SP-565UZ"}, { OlyID_SP_565UZ, "SP565UZ"}, { OlyID_XZ_1, "XZ-1"}, { OlyID_XZ_2, "XZ-2"}, { OlyID_XZ_10, "XZ-10"}, { OlyID_STYLUS_1, "Stylus 1"}, { OlyID_STYLUS_1, "STYLUS1"}, { OlyID_STYLUS_1, "STYLUS1,1s"}, { OlyID_SH_2, "SH-2"}, { OlyID_TG_4, "TG-4"}, { OlyID_TG_5, "TG-5"}, { OlyID_TG_6, "TG-6"}, { OlyID_E_10, "E-10"}, { OlyID_AIR_A01, "AIR A01"}, { OlyID_AIR_A01, "AIR-A01"}, { OlyID_E_330, "E-330"}, { OlyID_E_500, "E-500"}, { OlyID_E_400, "E-400"}, { OlyID_E_510, "E-510"}, { OlyID_E_3, "E-3"}, { OlyID_E_410, "E-410"}, { OlyID_E_420, "E-420"}, { OlyID_E_30, "E-30"}, { OlyID_E_520, "E-520"}, { OlyID_E_P1, "E-P1"}, { OlyID_E_620, "E-620"}, { OlyID_E_P2, "E-P2"}, { OlyID_E_PL1, "E-PL1"}, { OlyID_E_450, "E-450"}, { OlyID_E_600, "E-600"}, { OlyID_E_P3, "E-P3"}, { OlyID_E_5, "E-5"}, { OlyID_E_PL2, "E-PL2"}, { OlyID_E_M5, "E-M5"}, { OlyID_E_PL3, "E-PL3"}, { OlyID_E_PM1, "E-PM1"}, { OlyID_E_PL1s, "E-PL1s"}, { OlyID_E_PL5, "E-PL5"}, { OlyID_E_PM2, "E-PM2"}, { OlyID_E_P5, "E-P5"}, { OlyID_E_PL6, "E-PL6"}, { OlyID_E_PL7, "E-PL7"}, { OlyID_E_M1, "E-M1"}, { OlyID_E_M10, "E-M10"}, { OlyID_E_M5_Mark_II, "E-M5 Mark II"}, { OlyID_E_M5_Mark_II, "E-M5MarkII"}, { OlyID_E_M5_Mark_II, "E-M5_M2"}, { OlyID_E_M10_Mark_II, "E-M10 Mark II"}, // Clauss piX 5oo { OlyID_E_M10_Mark_II, "E-M10MarkII"}, { OlyID_E_M10_Mark_II, "E-M10_M2"}, { OlyID_PEN_F, "PEN-F"}, { OlyID_E_PL8, "E-PL8"}, { OlyID_E_M1_Mark_II, "E-M1 Mark II"}, { OlyID_E_M1_Mark_II, "E-M1MarkII"}, { OlyID_E_M1_Mark_II, "E-M1_M2"}, { OlyID_E_M10_Mark_III, "E-M10 Mark III"}, { OlyID_E_M10_Mark_III, "E-M10_M3"}, { OlyID_E_PL9, "E-PL9"}, { OlyID_E_M1X, "E-M1X"}, { OlyID_E_PL10, "E-PL10"}, { OlyID_E_M10_Mark_IV, "E-M10 Mark IV"}, { OlyID_E_M10_Mark_IV, "E-M10MarkIV"}, { OlyID_E_M10_Mark_IV, "E-M10_M4"}, { OlyID_E_M5_Mark_III, "E-M5 Mark III"}, { OlyID_E_M5_Mark_III, "E-M5MarkIII"}, { OlyID_E_M5_Mark_III, "E-M5_M3"}, { OlyID_E_M1_Mark_III, "E-M1 Mark III"}, { OlyID_E_M1_Mark_III, "E-M1MarkIII"}, { OlyID_E_M1_Mark_III, "E-M1_M3"}, { OlyID_E_P7 "E-P7"}, { OlyID_C_3030Z, "C-3030Z"}, { OlyID_C_3030Z, "C3030Z"}, { OlyID_C_5050Z, "C-5050Z"}, { OlyID_C_5050Z, "C5050Z"}, { OlyID_C_350Z, "C-350Z"}, { OlyID_C_350Z, "X200,D560Z,C350Z"}, { OlyID_C_740UZ, "C-740UZ"}, { OlyID_C_740UZ, "C740UZ"}, { OlyID_C_5060WZ, "C-5060WZ"}, { OlyID_C_5060WZ, "C5060WZ"}, { OlyID_C_8080WZ, "C-8080WZ"}, { OlyID_C_8080WZ, "C8080WZ"}, { OlyID_C_770UZ, "C-770UZ"}, { OlyID_C_770UZ, "C770UZ"}, { OlyID_C_7070WZ, "C-7070WZ"}, { OlyID_C_7070WZ, "C7070WZ"}, { OlyID_C_7000Z, "C-7000Z"}, { OlyID_C_7000Z, "C70Z,C7000Z"}, { OlyID_SP_500UZ, "SP-500UZ"}, { OlyID_SP_500UZ, "SP500UZ"}, { OlyID_SP_310, "SP-310"}, { OlyID_SP_310, "SP310"}, { OlyID_SP_350, "SP-350"}, { OlyID_SP_350, "SP350"}, { OlyID_SP_320, "SP-320"}, { OlyID_SP_320, "SP320"}, }, penique[] = { { PentaxID_Optio_S, "Optio S"}, { PentaxID_Optio_S_V101, "Optio S V1.01"}, { PentaxID_staristD, "*istD"}, { PentaxID_staristD, "*ist D"}, { PentaxID_Optio_33WR, "Optio 33WR"}, { PentaxID_Optio_S4, "Optio S4"}, { PentaxID_Optio_750Z, "Optio 750Z"}, { PentaxID_staristDS, "*istDS"}, { PentaxID_staristDS, "*ist DS"}, { PentaxID_staristDL, "*istDL"}, { PentaxID_staristDL, "*ist DL"}, { PentaxID_staristDS2, "*istDS2"}, { PentaxID_staristDS2, "*ist DS2"}, { PentaxID_GX_1S, "GX-1S"}, // Samsung { PentaxID_staristDL2, "*istDL2"}, { PentaxID_staristDL2, "*ist DL2"}, { PentaxID_GX_1L, "GX-1L"}, // Samsung { PentaxID_K100D, "K100D"}, { PentaxID_K110D, "K110D"}, { PentaxID_K100D_Super, "K100D Super"}, { PentaxID_K10D, "K10D"}, { PentaxID_GX10, "GX10"}, // Samsung { PentaxID_GX10, "GX-10"}, // Samsung { PentaxID_K20D, "K20D"}, { PentaxID_GX20, "GX20"}, // Samsung { PentaxID_GX20, "GX-20"}, // Samsung { PentaxID_K200D, "K200D"}, { PentaxID_K2000, "K2000"}, { PentaxID_K_m, "K-m"}, { PentaxID_K_7, "K-7"}, { PentaxID_K_x, "K-x"}, { PentaxID_645D, "645D"}, { PentaxID_K_r, "K-r"}, { PentaxID_K_5, "K-5"}, { PentaxID_Q, "Q"}, { PentaxID_K_01, "K-01"}, { PentaxID_K_30, "K-30"}, { PentaxID_Q10, "Q10"}, { PentaxID_K_5_II, "K-5 II"}, { PentaxID_K_5_II_s, "K-5 II s"}, { PentaxID_Q7, "Q7"}, { PentaxID_MX_1, "MX-1"}, { PentaxID_K_50, "K-50"}, { PentaxID_K_3, "K-3"}, { PentaxID_K_500, "K-500"}, { PentaxID_645Z, "645Z"}, { PentaxID_K_S1, "K-S1"}, { PentaxID_K_S2, "K-S2"}, // Ricoh { PentaxID_Q_S1, "Q-S1"}, { PentaxID_K_1, "K-1"}, // Ricoh { PentaxID_K_3_II, "K-3 II"}, // Ricoh { PentaxID_GR_III, "GR III"}, // Ricoh { PentaxID_K_70, "K-70"}, // Ricoh { PentaxID_KP, "KP"}, // Ricoh { PentaxID_K_1_Mark_II, "K-1 Mark II"}, // Ricoh { PentaxID_K_3_III, "K-3 Mark III"}, // Ricoh { PentaxID_GR_IIIx, "GR IIIx"}, }, #endif sonique[] = { { SonyID_DSC_R1, "DSC-R1"}, { SonyID_DSLR_A100, "DSLR-A100"}, { SonyID_DSLR_A900, "DSLR-A900"}, { SonyID_DSLR_A700, "DSLR-A700"}, { SonyID_DSLR_A200, "DSLR-A200"}, { SonyID_DSLR_A350, "DSLR-A350"}, { SonyID_DSLR_A300, "DSLR-A300"}, { SonyID_DSLR_A900_APSC, "DSLR-A900"}, { SonyID_DSLR_A380, "DSLR-A380"}, // DSLR-A390 { SonyID_DSLR_A330, "DSLR-A330"}, { SonyID_DSLR_A230, "DSLR-A230"}, { SonyID_DSLR_A290, "DSLR-A290"}, { SonyID_DSLR_A850, "DSLR-A850"}, { SonyID_DSLR_A850_APSC, "DSLR-A850"}, { SonyID_DSLR_A550, "DSLR-A550"}, { SonyID_DSLR_A500, "DSLR-A500"}, { SonyID_DSLR_A450, "DSLR-A450"}, { SonyID_NEX_5, "NEX-5"}, { SonyID_NEX_3, "NEX-3"}, { SonyID_SLT_A33, "SLT-A33"}, { SonyID_SLT_A55, "SLT-A55"}, // SLT-A55V { SonyID_DSLR_A560, "DSLR-A560"}, { SonyID_DSLR_A580, "DSLR-A580"}, { SonyID_NEX_C3, "NEX-C3"}, { SonyID_SLT_A35, "SLT-A35"}, { SonyID_SLT_A65, "SLT-A65"}, // SLT-A65V { SonyID_SLT_A77, "SLT-A77"}, // SLT-A77V { SonyID_NEX_5N, "NEX-5N"}, { SonyID_NEX_7, "NEX-7"}, // Hasselblad Lunar { SonyID_NEX_VG20, "NEX-VG20"}, { SonyID_SLT_A37, "SLT-A37"}, { SonyID_SLT_A57, "SLT-A57"}, { SonyID_NEX_F3, "NEX-F3"}, { SonyID_SLT_A99, "SLT-A99"}, // SLT-A99V / Hasselblad HV { SonyID_NEX_6, "NEX-6"}, { SonyID_NEX_5R, "NEX-5R"}, { SonyID_DSC_RX100, "DSC-RX100"}, // Hasselblad Stellar { SonyID_DSC_RX1, "DSC-RX1"}, { SonyID_NEX_VG900, "NEX-VG900"}, { SonyID_NEX_VG30, "NEX-VG30"}, { SonyID_ILCE_3000, "ILCE-3000"}, // ILCE-3500 { SonyID_SLT_A58, "SLT-A58"}, { SonyID_NEX_3N, "NEX-3N"}, { SonyID_ILCE_7, "ILCE-7"}, { SonyID_NEX_5T, "NEX-5T"}, { SonyID_DSC_RX100M2, "DSC-RX100M2"}, // Hasselblad Stellar II { SonyID_DSC_RX10, "DSC-RX10"}, { SonyID_DSC_RX1R, "DSC-RX1R"}, { SonyID_ILCE_7R, "ILCE-7R"}, // Hasselblad Lusso { SonyID_ILCE_6000, "ILCE-6000"}, { SonyID_ILCE_5000, "ILCE-5000"}, { SonyID_DSC_RX100M3, "DSC-RX100M3"}, { SonyID_ILCE_7S, "ILCE-7S"}, { SonyID_ILCA_77M2, "ILCA-77M2"}, { SonyID_ILCE_5100, "ILCE-5100"}, { SonyID_ILCE_7M2, "ILCE-7M2"}, { SonyID_DSC_RX100M4, "DSC-RX100M4"}, { SonyID_DSC_RX10M2, "DSC-RX10M2"}, { SonyID_DSC_RX1RM2, "DSC-RX1RM2"}, { SonyID_ILCE_QX1, "ILCE-QX1"}, { SonyID_ILCE_7RM2, "ILCE-7RM2"}, { SonyID_ILCE_7SM2, "ILCE-7SM2"}, { SonyID_ILCA_68, "ILCA-68"}, { SonyID_ILCA_99M2, "ILCA-99M2"}, { SonyID_DSC_RX10M3, "DSC-RX10M3"}, { SonyID_DSC_RX100M5, "DSC-RX100M5"}, { SonyID_ILCE_6300, "ILCE-6300"}, { SonyID_ILCE_9, "ILCE-9"}, { SonyID_ILCE_6500, "ILCE-6500"}, { SonyID_ILCE_7RM3, "ILCE-7RM3"}, { SonyID_ILCE_7M3, "ILCE-7M3"}, { SonyID_DSC_RX0, "DSC-RX0"}, { SonyID_DSC_RX10M4, "DSC-RX10M4"}, { SonyID_DSC_RX100M6, "DSC-RX100M6"}, { SonyID_DSC_HX99, "DSC-HX99"}, { SonyID_DSC_RX100M5A, "DSC-RX100M5A"}, { SonyID_ILCE_6400, "ILCE-6400"}, { SonyID_DSC_RX0M2, "DSC-RX0M2"}, { SonyID_DSC_RX100M7, "DSC-RX100M7"}, { SonyID_ILCE_7RM4, "ILCE-7RM4"}, { SonyID_ILCE_9M2, "ILCE-9M2"}, { SonyID_ILCE_6600, "ILCE-6600"}, { SonyID_ILCE_6100, "ILCE-6100"}, { SonyID_ZV_1, "ZV-1"}, { SonyID_ILCE_7C, "ILCE-7C"}, { SonyID_ZV_E10, "ZV-E10"}, { SonyID_ILCE_7SM3, "ILCE-7SM3"}, { SonyID_ILCE_1, "ILCE-1"}, { SonyID_ILME_FX3, "ILME-FX3"}, { SonyID_ILCE_7RM3A, "ILCE-7RM3A"}, { SonyID_ILCE_7RM4A, "ILCE-7RM4A"}, { SonyID_ILCE_7M4, "ILCE-7M4"}, }; static const char *orig; static const char fujialias[][16] = { "@DBP for GX680", "DX-2000", "@F500EXR", "F505EXR", "@F600EXR", "F605EXR", "@F770EXR", "F775EXR", "@HS10", "HS10 HS11", "@HS20EXR", "HS22EXR", "@HS30EXR", "HS33EXR", "HS35EXR", "@S5100", "S5500", "@S5200", "S5600", "@S6000fd", "S6500fd", "@S9000", "S9500", "@S9100", "S9600", "@S200EXR", "S205EXR", "@X-T1 IR", "X-T1IR", "@GFX 100S", "GFX100S", "@GFX 50S II", "GFX50S II" }; static const char kodakalias[][16] = { "@DCS Pro 14N", "Camerz ZDS 14", // Camerz rebadge make: "Photo Control" "@DCS720X", "SCS2000", "@DCS520C", "EOS D2000C", "EOS D2000", // EOS rebadge make: Canon "@DCS560C", "EOS D6000C", "EOS D6000", // EOS rebadge make: Canon "@DCS460M", "DCS460A", // 'A' was supposed to stand for 'achromatic', marketing changed it to 'M' "@DCS460", "DCS460C", "DCS460D", "@DCS465", "DCS465C", "DCS465D", "@EOSDCS1", "EOSDCS1B", "EOSDCS1C", "@EOSDCS3", "EOSDCS3B", "EOSDCS3C", }; static const struct { const char *Kmodel; ushort mount; } Kodak_mounts[] = { {"DCS465", LIBRAW_MOUNT_DigitalBack}, {"DCS5", LIBRAW_MOUNT_Canon_EF}, {"DCS Pro SLR/c", LIBRAW_MOUNT_Canon_EF}, {"DCS", LIBRAW_MOUNT_Nikon_F}, {"EOS", LIBRAW_MOUNT_Canon_EF}, {"NC2000", LIBRAW_MOUNT_Nikon_F}, // AP "News Camera" {"Pixpro S-1", LIBRAW_MOUNT_mFT}, {"ProBack", LIBRAW_MOUNT_DigitalBack}, {"SCS1000", LIBRAW_MOUNT_Canon_EF}, }; static const char *KodakMonochrome[] = { "DCS420M", "DCS420A", "DCS420I", "DCS460M", "DCS460A", "DCS460I", "DCS465M", "DCS465A", "DCS465I", "DCS560M", "DCS660M", "DCS760M", "EOS D2000M", "EOS D6000M", "EOSDCS1M", "EOSDCS1I", "EOSDCS3M", "EOSDCS3I", "EOSDCS5M", "EOSDCS5I", "NC2000M", "NC2000A", "NC2000I", }; static const char leafalias[][16] = { // Leaf re-badged to Mamiya "@Aptus-II 5", "DM22", "@Aptus-II 6", "DM28", "@Aptus-II 7", "DM33", "@Aptus-II 8", "DM40", "@Aptus-II 10", "DM56", }; static const char KonicaMinolta_aliases[][24] = { "@DG-5D", "DYNAX 5D", "MAXXUM 5D", "ALPHA-5 DIGITAL", "ALPHA SWEET DIGITAL", "@DG-7D", "DYNAX 7D", "MAXXUM 7D", "ALPHA-7 DIGITAL", }; static const char nikonalias[][16] = { "@COOLPIX 2100", "E2100", "@COOLPIX 2500", "E2500", "@COOLPIX 3200", "E3200", "@COOLPIX 3700", "E3700", "@COOLPIX 4300", "E4300", "@COOLPIX 4500", "E4500", "@COOLPIX 5000", "E5000", "@COOLPIX 5400", "E5400", "@COOLPIX 5700", "E5700", "@COOLPIX 8400", "E8400", "@COOLPIX 8700", "E8700", "@COOLPIX 8800", "E8800", "@COOLPIX 700", "E700", "@COOLPIX 800", "E800", "@COOLPIX 880", "E880", "@COOLPIX 900", "E900", "@COOLPIX 950", "E950", "@COOLPIX 990", "E990", "@COOLPIX 995", "E995", "@COOLPIX P7700", "COOLPIX Deneb", "@COOLPIX P7800", "COOLPIX Kalon", }; static const char olyalias[][32] = { // Olympus "@AIR A01", "AIR-A01", "@C-3030Z", "C3030Z", "@C-5050Z", "C5050Z", "@C-5060WZ", "C5060WZ", "@C-7000Z", "C7000Z", "C70Z,C7000Z", "C70Z", "@C-7070WZ", "C7070WZ", "@C-8080WZ", "C8080WZ", "@C-350Z", "C350Z", "X200,D560Z,C350Z", "X200", "D560Z", "@C-740UZ", "C740UZ", "@C-770UZ", "C770UZ", "@E-20", "E-20,E-20N,E-20P", "E-20N", "E-20P", "@E-M10 Mark II", "E-M10MarkII", "E-M10_M2", "piX 5oo", "@E-M10 Mark III", "E-M10MarkIII", "E-M10_M3", "@E-M10 Mark IV", "E-M10MarkIV", "E-M10_M4", "@E-M1 Mark II", "E-M1MarkII", "E-M1_M2", "@E-M1 Mark III", "E-M1MarkIII", "E-M1_M3", "@E-M5 Mark II", "E-M5MarkII", "E-M5_M2", "@E-M5 Mark III", "E-M5MarkIII", "E-M5_M3", "@SH-2", "SH-3", "@SP-310", "SP310", "@SP-320", "SP320", "@SP-350", "SP350", "@SP-500UZ", "SP500UZ", "@SP-510UZ", "SP510UZ", "@SP-550UZ", "SP550UZ", "@SP-560UZ", "SP560UZ", "@SP-565UZ", "SP565UZ", "@SP-570UZ", "SP570UZ", "@Stylus 1", "STYLUS1", "STYLUS1s", "STYLUS1,1s", }; static const char panalias[][16] = { // Panasonic, PanaLeica // fixed lens "@DMC-FX150", "DMC-FX180", "@DC-FZ1000M2", "DC-FZ10002", "V-Lux 5", "@DMC-FZ1000", "V-LUX (Typ 114)", "@DMC-FZ2500", "DMC-FZ2000", "DMC-FZH1", "@DMC-FZ100", "V-LUX 2", "@DMC-FZ150", "V-LUX 3", "@DMC-FZ200", "V-LUX 4", "@DMC-FZ300", "DMC-FZ330", "@DMC-FZ35", "DMC-FZ38", "@DMC-FZ40", "DMC-FZ42", "DMC-FZ45", "DC-FZ40", "DC-FZ42", "DC-FZ45", "@DMC-FZ50", "V-LUX 1", "V-LUX1", "@DMC-FZ70", "DMC-FZ72", "@DC-FZ80", "DC-FZ81", "DC-FZ82", "DC-FZ83", "DC-FZ85", "@DMC-LC1", "DIGILUX 2", "Digilux 2", "DIGILUX2", "@DMC-LF1", "C (Typ 112)", "@DC-LX100M2", "D-Lux 7", "@DMC-LX100", "D-LUX (Typ 109)", "D-Lux (Typ 109)", "@DMC-LX1", "D-Lux2", "D-LUX2", "D-LUX 2", "@DMC-LX2", "D-LUX 3", "D-LUX3", "@DMC-LX3", "D-LUX 4", "@DMC-LX5", "D-LUX 5", "@DMC-LX7", "D-LUX 6", "@DMC-LX9", "DMC-LX10", "DMC-LX15", "@DMC-ZS100", "DMC-ZS110", "DMC-TZ100", "DMC-TZ101", "DMC-TZ110", "DMC-TX1", "@DC-ZS200", "DC-ZS220", "DC-TZ200", "DC-TZ202", "DC-TZ220", "DC-TX2", "C-Lux", "CAM-DC25", "@DMC-ZS40", "DMC-TZ60", "DMC-TZ61", "@DMC-ZS50", "DMC-TZ70", "DMC-TZ71", "@DMC-ZS60", "DMC-TZ80", "DMC-TZ81", "DMC-TZ82", "DMC-TZ85", "@DC-ZS70", "DC-TZ90", "DC-TZ91", "DC-TZ92", "DC-TZ93", "@DC-ZS80", "DC-TZ95", "DC-TZ96", "DC-TZ97", // interchangeable lens "@DC-G100", "DC-G110", "@DC-G99", "DC-G90", "DC-G91", "DC-G95", "@DMC-G7", "DMC-G70", "@DMC-G8", "DMC-G80", "DMC-G81", "DMC-G85", "@DMC-GH4", "AG-GH4", "CGO4", "@DC-GF10", "DC-GF90", "DC-GX880", "@DC-GF9", "DC-GX850", "DC-GX800", "@DMC-GM1", "DMC-GM1S", "@DMC-GX85", "DMC-GX80", "DMC-GX7MK2", "@DC-GX9", "DC-GX7MK3", "@DMC-L1", "DIGILUX 3", "DIGILUX3", // full 4/3 mount, not m43 }; static const char phase1alias[][16] = { "@H20", "H 20", "@H25", "H 25", "@P20+", "P 20+", "@P20", "P 20", "@P21+", "P 21+", "M18", // "Mamiya M18" "@P21", "P 21", "@P25+", "P 25+", "M22", // "Mamiya M22" "@P25", "P 25", "@P30+", "P 30+", "M31", // "Mamiya M31" "@P30", "P 30", "@P40+", "P 40+", "@P40", "P 40", "@P45+", "P 45+", "@P45", "P 45", "@P65+", "P 65+", "@P65", "P 65", }; static const char SamsungPentax_aliases[][16] = { "@*istDL2", "*ist DL2", "GX-1L", "@*istDS2", "*ist DS2", "GX-1S", "@*istDL", "*ist DL", "@*istDS", "*ist DS", "@*istD", "*ist D", "@K10D", "GX10", "GX-10", "@K20D", "GX20", "GX-20", "@K-m", "K2000", }; static const char samsungalias[][64] = { "@EX1", "TL500", "@NX U", "EK-GN100", "EK-GN110", "EK-GN120", "EK-KN120", "Galaxy NX", "@NX mini", "NXF1", "@WB2000", "TL350", // "@WB5000", "WB5000/HZ25W", // no spaces around the slash separating names // "@WB5500", "WB5500 / VLUU WB5500 / SAMSUNG HZ50W", // "@WB500", "WB510 / VLUU WB500 / SAMSUNG HZ10W", // "@WB550", "WB560 / VLUU WB550 / SAMSUNG HZ15W", // "@WB650", "SAMSUNG WB650 / VLUU WB650 / SAMSUNG WB660" aka HZ35W }; //clang-format on if (makeIs(LIBRAW_CAMERAMAKER_VLUU)) { setMakeFromIndex(LIBRAW_CAMERAMAKER_Samsung); } if (makeIs(LIBRAW_CAMERAMAKER_Samsung) && (ilm.CameraMount == LIBRAW_MOUNT_Pentax_K)) { setMakeFromIndex(LIBRAW_CAMERAMAKER_Pentax); } else if (makeIs(LIBRAW_CAMERAMAKER_Unknown)) { if (strcasestr(model, "Google")) { setMakeFromIndex(LIBRAW_CAMERAMAKER_Google); } #ifdef USE_6BY9RPI else if(strcasestr(make,"RaspberryPi")) setMakeFromIndex(LIBRAW_CAMERAMAKER_RaspberryPi); #endif } else if (makeIs(LIBRAW_CAMERAMAKER_Hasselblad) && is_Sony) { setMakeFromIndex(LIBRAW_CAMERAMAKER_Sony); } else if (makeIs(LIBRAW_CAMERAMAKER_OmDigital)) { setMakeFromIndex(LIBRAW_CAMERAMAKER_Olympus); } else if (makeIs(LIBRAW_CAMERAMAKER_Clauss) && (OlyID == OlyID_E_M10_Mark_II)) { setMakeFromIndex(LIBRAW_CAMERAMAKER_Olympus); } else if (makeIs(LIBRAW_CAMERAMAKER_Canon) && (!strncmp(model, "EOS D2000", 9) || // don't use unique_id here !strncmp(model, "EOS D6000", 9) || // because ids for Monochrome models are unknown !strncmp(model, "EOSDCS", 6))) { setMakeFromIndex(LIBRAW_CAMERAMAKER_Kodak); // if (unique_id == CanonID_EOS_D2000C) { // // } else if (unique_id == CanonID_EOS_D6000C) { /// // } } else if (makeIs(LIBRAW_CAMERAMAKER_PhotoControl) && !strncasecmp(model, "Camerz ZDS 14", 13)) { setMakeFromIndex(LIBRAW_CAMERAMAKER_Kodak); } else { strcpy(normalized_make, make); } if (makeIs(LIBRAW_CAMERAMAKER_Apple)) { if ((imgdata.color.UniqueCameraModel[0]) && (!strncmp(model, "iPad", 4) || !strncmp(model, "iPhone", 6))) strcpy(model, imgdata.color.UniqueCameraModel); } else if (makeIs(LIBRAW_CAMERAMAKER_Kodak)) { if ((model[6] == ' ') && (!strncmp(model, "DCS4", 4) || !strncmp(model, "NC2000", 6))) { model[6] = 0; } if ((model[6] != 'A') && (model[6] != 'I') && (model[6] != 'M') && !strncmp(model, "NC2000", 6)) { model[6] = 0; } } else if (makeIs(LIBRAW_CAMERAMAKER_Ricoh) && !strncmp(model, "GXR", 3)) { strcpy(ilm.body, "Ricoh GXR"); if (!imgdata.lens.Lens[0] && imgdata.color.UniqueCameraModel[0]) { strcpy (imgdata.lens.Lens, imgdata.color.UniqueCameraModel); remove_caseSubstr (imgdata.lens.Lens, (char *)"Ricoh"); remove_caseSubstr (imgdata.lens.Lens, (char *)"Lens"); removeExcessiveSpaces (imgdata.lens.Lens); } if (ilm.LensID == LIBRAW_LENS_NOT_SET) { if (strstr(imgdata.lens.Lens, "50mm")) ilm.LensID = 1; else if (strstr(imgdata.lens.Lens, "S10")) ilm.LensID = 2; else if (strstr(imgdata.lens.Lens, "P10")) ilm.LensID = 3; else if (strstr(imgdata.lens.Lens, "28mm")) ilm.LensID = 5; else if (strstr(imgdata.lens.Lens, "A16")) ilm.LensID = 6; } switch (ilm.LensID) { case 1: // GR Lens A12 50mm F2.5 Macro strcpy(model, "GXR A12 50mm"); ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = LIBRAW_MOUNT_RicohModule; ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.FocalType = LIBRAW_FT_PRIME_LENS; break; case 2: strcpy(model, "GXR S10"); ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_1div1p7INCH; ilm.CameraMount = LIBRAW_MOUNT_RicohModule; ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.FocalType = LIBRAW_FT_ZOOM_LENS; break; case 3: // Ricoh Lens P10 28-300mm F3.5-5.6 VC strcpy(model, "GXR P10"); ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_1div2p3INCH; ilm.CameraMount = LIBRAW_MOUNT_RicohModule; ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.FocalType = LIBRAW_FT_ZOOM_LENS; break; case 5: // GR Lens A12 28mm F2.5 strcpy(model, "GXR A12 28mm"); ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = LIBRAW_MOUNT_RicohModule; ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.FocalType = LIBRAW_FT_PRIME_LENS; break; case 6: // Ricoh Lens A16 24-85mm F3.5-5.5 strcpy(model, "GXR A16"); ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = LIBRAW_MOUNT_RicohModule; ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.FocalType = LIBRAW_FT_ZOOM_LENS; break; case 8: // Ricoh Mount A12 (Leica M lenses) strcpy(model, "GXR Mount A12"); ilm.CameraFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = LIBRAW_MOUNT_Leica_M; ilm.LensID = LIBRAW_LENS_NOT_SET; break; } } strcpy(normalized_model, model); if (makeIs(LIBRAW_CAMERAMAKER_Canon)) { if (unique_id) { if ((unique_id != CanonID_EOS_D2000C) && (unique_id != CanonID_EOS_D6000C)) { for (i = 0; i < int(sizeof unique / sizeof *unique); i++) { if (unique_id == unique[i].id) { strcpy(model, unique[i].t_model); strcpy(normalized_model, unique[i].t_model); break; } } } } else { if ((dng_version) && (strlen(imgdata.color.UniqueCameraModel) > 6) && strncmp(imgdata.color.UniqueCameraModel+6, "PowerShot", 9)) { for (i = 0; i < int(sizeof unique / sizeof *unique); i++) { if (!strcmp(unique[i].t_model, imgdata.color.UniqueCameraModel+6)) { ilm.CamID = unique_id = unique[i].id; strcpy(normalized_model, unique[i].t_model); try_xml = 1; break; } } } } } else if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm)) { for (i = 0; i < int(sizeof fujialias / sizeof *fujialias); i++) { if (fujialias[i][0] == '@') { orig = fujialias[i] + 1; if (!strcmp(model, orig)) break; } else if (!strcmp(model, fujialias[i])) { strcpy(normalized_model, orig); break; } } } else if (makeIs(LIBRAW_CAMERAMAKER_Hasselblad)) { parseHassyModel(); } else if (makeIs(LIBRAW_CAMERAMAKER_Mamiya)) { for (i = 0; i < int(sizeof phase1alias / sizeof *phase1alias); i++) { // re-badged Phase One backs if (phase1alias[i][0] == '@') orig = phase1alias[i] + 1; else if (!strcmp(model, phase1alias[i])) { setMakeFromIndex(LIBRAW_CAMERAMAKER_PhaseOne); strcpy(normalized_model, orig); break; } } for (i = 0; i < int(sizeof leafalias / sizeof *leafalias); i++) { // re-badged Leaf backs if (leafalias[i][0] == '@') orig = leafalias[i] + 1; else if (!strcmp(model, leafalias[i])) { setMakeFromIndex(LIBRAW_CAMERAMAKER_Leaf); strcpy(normalized_model, orig); break; } } /* repeating, because make for some Mamiya re-badged Leaf backs is set to * Leaf */ } else if (makeIs(LIBRAW_CAMERAMAKER_Leaf)) { for (i = 0; i < int(sizeof leafalias / sizeof *leafalias); i++) { // re-badged Leaf backs if (leafalias[i][0] == '@') { orig = leafalias[i] + 1; if (!strcmp(model, orig)) break; } else if (!strcmp(model, leafalias[i])) { // maybe to change regular "make" to "Mamiya" too strcpy(normalized_model, orig); break; } } if ((ps = strchr(normalized_model, '('))) *ps = 0; } else if (makeIs(LIBRAW_CAMERAMAKER_Minolta) || makeIs(LIBRAW_CAMERAMAKER_Konica)) { if (makeIs(LIBRAW_CAMERAMAKER_Konica) && !strncasecmp(model, "DiMAGE", 6)) { setMakeFromIndex(LIBRAW_CAMERAMAKER_Minolta); strcpy(make, "Minolta"); } else { for (i = 0; i 9)) { if (makeIs(LIBRAW_CAMERAMAKER_Canon) && try_xml && (ps = strstr(xmpdata, "LensID=\""))) { ilm.LensID = atoi(ps + 8); if (ilm.LensID == 61182) { ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Canon_RF; } } else if (makeIs(LIBRAW_CAMERAMAKER_Samsung)) { if ((ilm.LensMount == LIBRAW_MOUNT_Samsung_NX) && (ps = strstr(xmpdata, "LensID=\"("))) { ilm.LensID = atoi(ps + 9); } } } if (ilm.CameraMount == LIBRAW_MOUNT_FixedLens) { if (ilm.CameraFormat) ilm.LensFormat = ilm.CameraFormat; if (ilm.LensMount == LIBRAW_MOUNT_Unknown) ilm.LensMount = LIBRAW_MOUNT_FixedLens; } if ((ilm.CameraMount != LIBRAW_MOUNT_Unknown) && (ilm.CameraMount != LIBRAW_MOUNT_FixedLens) && (ilm.LensMount == LIBRAW_MOUNT_Unknown)) { if (ilm.LensID == LIBRAW_LENS_NOT_SET) ilm.LensMount = LIBRAW_MOUNT_IL_UM; else ilm.LensMount = ilm.CameraMount; } } void LibRaw::SetStandardIlluminants (unsigned makerIdx, const char* /*normModel*/) { // int i = -1; int c; if (!icWBC[LIBRAW_WBI_Ill_A][0] && !icWBC[LIBRAW_WBI_D65][0]) { if (makerIdx == LIBRAW_CAMERAMAKER_Olympus ) { for (int i = 0; i < 64 && icWBCCTC[i][0]; i++) { if (icWBCCTC[i][0] == 3000) FORC4 icWBC[LIBRAW_WBI_Ill_A][c] = icWBCCTC[i][c+1]; else if (icWBCCTC[i][0] == 6600) FORC4 icWBC[LIBRAW_WBI_D65][c] = icWBCCTC[i][c+1]; } } } if (!icWBC[LIBRAW_WBI_Ill_A][0] && icWBC[LIBRAW_WBI_Tungsten][0]) FORC4 icWBC[LIBRAW_WBI_Ill_A][c] = icWBC[LIBRAW_WBI_Tungsten][c]; if (!icWBC[LIBRAW_WBI_D65][0] && icWBC[LIBRAW_WBI_FL_N][0]) FORC4 icWBC[LIBRAW_WBI_D65][c] = icWBC[LIBRAW_WBI_FL_N][c]; return; } LibRaw-0.21.4/src/metadata/olympus.cpp000066400000000000000000000422531477673233700175720ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" #include "../../internal/libraw_cameraids.h" void LibRaw::setOlympusBodyFeatures(unsigned long long id) { ilm.CamID = id; if ((id == OlyID_E_1) || (id == OlyID_E_300) || ((id & 0x00ffff0000ULL) == 0x0030300000ULL)) { ilm.CameraFormat = LIBRAW_FORMAT_FT; if ((id == OlyID_E_1) || (id == OlyID_E_300) || ((id >= OlyID_E_330) && (id <= OlyID_E_520)) || (id == OlyID_E_620) || (id == OlyID_E_450) || (id == OlyID_E_600) || (id == OlyID_E_5)) { ilm.CameraMount = LIBRAW_MOUNT_FT; } else { ilm.CameraMount = LIBRAW_MOUNT_mFT; } } else { ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_FixedLens; } return; } void LibRaw::getOlympus_CameraType2() { if (OlyID != 0x0ULL) return; int i = 0; fread(imOly.CameraType2, 6, 1, ifp); imOly.CameraType2[5] = 0; while ((i < 6) && imOly.CameraType2[i]) { OlyID = OlyID << 8 | imOly.CameraType2[i]; if (i < 5 && isspace(imOly.CameraType2[i + 1])) { imOly.CameraType2[i + 1] = '\0'; break; } i++; } if (OlyID == OlyID_NORMA) { if (strcmp(model, "SP510UZ")) OlyID = OlyID_SP_510UZ; else OlyID = 0x0ULL; } unique_id = OlyID; setOlympusBodyFeatures(OlyID); return; } void LibRaw::getOlympus_SensorTemperature(unsigned len) { if (OlyID != 0x0ULL) { short temp = get2(); if ((OlyID == OlyID_E_1) || (OlyID == OlyID_E_M5) || (len != 1)) imCommon.SensorTemperature = (float)temp; else if ((temp != -32768) && (temp != 0)) { if (temp > 199) imCommon.SensorTemperature = 86.474958f - 0.120228f * (float)temp; else imCommon.SensorTemperature = (float)temp; } } return; } void LibRaw::parseOlympus_Equipment(unsigned tag, unsigned /*type */, unsigned len, unsigned dng_writer) { // uptag 2010 switch (tag) { case 0x0100: getOlympus_CameraType2(); break; case 0x0101: if ((!imgdata.shootinginfo.BodySerial[0]) && (dng_writer == nonDNG)) stmread(imgdata.shootinginfo.BodySerial, len, ifp); break; case 0x0102: stmread(imgdata.shootinginfo.InternalBodySerial, len, ifp); break; case 0x0201: { unsigned char bits[4]; fread(bits, 1, 4, ifp); ilm.LensID = (unsigned long long)bits[0] << 16 | (unsigned long long)bits[2] << 8 | (unsigned long long)bits[3]; ilm.LensMount = LIBRAW_MOUNT_FT; ilm.LensFormat = LIBRAW_FORMAT_FT; if (((ilm.LensID < 0x20000) || (ilm.LensID > 0x4ffff)) && (ilm.LensID & 0x10)) ilm.LensMount = LIBRAW_MOUNT_mFT; } break; case 0x0202: if ((!imgdata.lens.LensSerial[0])) stmread(imgdata.lens.LensSerial, len, ifp); break; case 0x0203: stmread(ilm.Lens, len, ifp); break; case 0x0205: ilm.MaxAp4MinFocal = libraw_powf64l(sqrt(2.0f), get2() / 256.0f); break; case 0x0206: ilm.MaxAp4MaxFocal = libraw_powf64l(sqrt(2.0f), get2() / 256.0f); break; case 0x0207: ilm.MinFocal = (float)get2(); break; case 0x0208: ilm.MaxFocal = (float)get2(); if (ilm.MaxFocal > 1000.0f) ilm.MaxFocal = ilm.MinFocal; break; case 0x020a: ilm.MaxAp4CurFocal = libraw_powf64l(sqrt(2.0f), get2() / 256.0f); break; case 0x0301: ilm.TeleconverterID = fgetc(ifp) << 8; fgetc(ifp); ilm.TeleconverterID = ilm.TeleconverterID | fgetc(ifp); break; case 0x0303: stmread(ilm.Teleconverter, len, ifp); if (!strlen(ilm.Teleconverter) && strchr(ilm.Lens, '+')) { if (strstr(ilm.Lens, "MC-20")) strcpy(ilm.Teleconverter, "MC-20"); else if (strstr(ilm.Lens, "MC-14")) strcpy(ilm.Teleconverter, "MC-14"); else if (strstr(ilm.Lens, "EC-20")) strcpy(ilm.Teleconverter, "EC-20"); else if (strstr(ilm.Lens, "EC-14")) strcpy(ilm.Teleconverter, "EC-14"); } break; case 0x0403: stmread(ilm.Attachment, len, ifp); break; } return; } void LibRaw::parseOlympus_CameraSettings(int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer) { // uptag 0x2020 int c; switch (tag) { case 0x0101: if (dng_writer == nonDNG) { thumb_offset = get4() + base; } break; case 0x0102: if (dng_writer == nonDNG) { thumb_length = get4(); } break; case 0x0200: imgdata.shootinginfo.ExposureMode = get2(); break; case 0x0202: imgdata.shootinginfo.MeteringMode = get2(); break; case 0x0301: imgdata.shootinginfo.FocusMode = imOly.FocusMode[0] = get2(); if (len == 2) { imOly.FocusMode[1] = get2(); } break; case 0x0304: for (c = 0; c < 64; c++) { imOly.AFAreas[c] = get4(); } break; case 0x0305: for (c = 0; c < 5; c++) { imOly.AFPointSelected[c] = getreal(type); } break; case 0x0306: imOly.AFFineTune = fgetc(ifp); break; case 0x0307: FORC3 imOly.AFFineTuneAdj[c] = get2(); break; case 0x0401: imCommon.FlashEC = getreal(type); break; case 0x0507: imOly.ColorSpace = get2(); switch (imOly.ColorSpace) { case 0: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 1: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; case 2: imCommon.ColorSpace = LIBRAW_COLORSPACE_ProPhotoRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } break; case 0x0600: imgdata.shootinginfo.DriveMode = imOly.DriveMode[0] = get2(); for (c = 1; c < (int)len && c < 5; c++) { imOly.DriveMode[c] = get2(); } break; case 0x0601: imOly.Panorama_mode = get2(); imOly.Panorama_frameNum = get2(); break; case 0x0604: imgdata.shootinginfo.ImageStabilization = get4(); break; case 0x0804: imOly.StackedImage[0] = get4(); imOly.StackedImage[1] = get4(); if (imOly.StackedImage[0] == 3) { imOly.isLiveND = 1; imOly.LiveNDfactor = imOly.StackedImage[1]; } else { imOly.isLiveND = 0; } break; } return; } void LibRaw::parseOlympus_ImageProcessing(unsigned tag, unsigned type, unsigned len, unsigned dng_writer) { // uptag 0x2040 int i, c, wb[4], nWB, tWB, wbG; ushort CT; short sorder; if ((tag == 0x0100) && (dng_writer == nonDNG)) { cam_mul[0] = get2() / 256.0; cam_mul[2] = get2() / 256.0; } else if ((tag == 0x0101) && (len == 2) && ((OlyID == OlyID_E_410) || (OlyID == OlyID_E_510))) { for (i = 0; i < 64; i++) { icWBCCTC[i][2] = icWBCCTC[i][4] = icWBC[i][1] = icWBC[i][3] = 0x100; } for (i = 64; i < 256; i++) { icWBC[i][1] = icWBC[i][3] = 0x100; } } else if ((tag > 0x0101) && (tag <= 0x0111)) { nWB = tag - 0x0101; tWB = Oly_wb_list2[nWB << 1]; CT = Oly_wb_list2[(nWB << 1) | 1]; wb[0] = get2(); wb[2] = get2(); if (tWB != 0x100) { icWBC[tWB][0] = wb[0]; icWBC[tWB][2] = wb[2]; } if (CT) { icWBCCTC[nWB - 1][0] = CT; icWBCCTC[nWB - 1][1] = wb[0]; icWBCCTC[nWB - 1][3] = wb[2]; } if (len == 4) { wb[1] = get2(); wb[3] = get2(); if (tWB != 0x100) { icWBC[tWB][1] = wb[1]; icWBC[tWB][3] = wb[3]; } if (CT) { icWBCCTC[nWB - 1][2] = wb[1]; icWBCCTC[nWB - 1][4] = wb[3]; } } } else if ((tag >= 0x0112) && (tag <= 0x011e)) { nWB = tag - 0x0112; wbG = get2(); tWB = Oly_wb_list2[nWB << 1]; if (nWB) icWBCCTC[nWB - 1][2] = icWBCCTC[nWB - 1][4] = wbG; if (tWB != 0x100) icWBC[tWB][1] = icWBC[tWB][3] = wbG; } else if (tag == 0x011f) { wbG = get2(); if (icWBC[LIBRAW_WBI_Flash][0]) icWBC[LIBRAW_WBI_Flash][1] = icWBC[LIBRAW_WBI_Flash][3] = wbG; FORC4 if (icWBC[LIBRAW_WBI_Custom1 + c][0]) icWBC[LIBRAW_WBI_Custom1 + c][1] = icWBC[LIBRAW_WBI_Custom1 + c][3] = wbG; } else if (tag == 0x0121) { icWBC[LIBRAW_WBI_Flash][0] = get2(); icWBC[LIBRAW_WBI_Flash][2] = get2(); if (len == 4) { icWBC[LIBRAW_WBI_Flash][1] = get2(); icWBC[LIBRAW_WBI_Flash][3] = get2(); } } else if ((tag == 0x0200) && (dng_writer == nonDNG) && strcmp(software, "v757-71")) { for (i = 0; i < 3; i++) { if (!imOly.ColorSpace) { FORC3 cmatrix[i][c] = ((short)get2()) / 256.0; } else { FORC3 imgdata.color.ccm[i][c] = ((short)get2()) / 256.0; } } } else if ((tag == 0x0600) && (dng_writer == nonDNG)) { FORC4 cblack[RGGB_2_RGBG(c)] = get2(); } else if ((tag == 0x0611) && (dng_writer == nonDNG)) { imOly.ValidBits = get2(); } else if ((tag == 0x0612) && (dng_writer == nonDNG)) { imgdata.sizes.raw_inset_crops[0].cleft = get2(); } else if ((tag == 0x0613) && (dng_writer == nonDNG)) { imgdata.sizes.raw_inset_crops[0].ctop = get2(); } else if ((tag == 0x0614) && (dng_writer == nonDNG)) { imgdata.sizes.raw_inset_crops[0].cwidth = get2(); } else if ((tag == 0x0615) && (dng_writer == nonDNG)) { imgdata.sizes.raw_inset_crops[0].cheight = get2(); } else if ((tag == 0x0805) && (len == 2)) { imOly.SensorCalibration[0] = getreal(type); imOly.SensorCalibration[1] = getreal(type); if ((dng_writer == nonDNG) && (OlyID != OlyID_XZ_1)) FORC4 imgdata.color.linear_max[c] = imOly.SensorCalibration[0]; } else if (tag == 0x1112) { sorder = order; order = 0x4d4d; c = get2(); order = sorder; switch (c) { case 0x0101: case 0x0901: case 0x0909: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3; break; case 0x0104: case 0x0401: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; break; case 0x0201: case 0x0202: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; break; case 0x0301: case 0x0303: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9; break; case 0x0404: // imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_6to6; imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; break; case 0x0505: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_5to4; break; case 0x0606: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_7to6; break; case 0x0707: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_6to5; break; case 0x0808: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_7to5; break; default: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_OTHER; break; } } else if (tag == 0x1113) { imOly.AspectFrame[0] = get2(); imOly.AspectFrame[1] = get2(); imOly.AspectFrame[2] = get2(); imOly.AspectFrame[3] = get2(); } else if (tag == 0x1306) { c = get2(); if ((c != 0) && (c != 100)) { if (c < 61) imCommon.CameraTemperature = (float)c; else imCommon.CameraTemperature = (float)(c - 32) / 1.8f; if ((imCommon.exifAmbientTemperature > -273.15f) && ((OlyID == OlyID_TG_5) || (OlyID == OlyID_TG_6)) ) imCommon.CameraTemperature += imCommon.exifAmbientTemperature; } } return; } void LibRaw::parseOlympus_RawInfo(unsigned tag, unsigned /*type */, unsigned len, unsigned dng_writer) { // uptag 0x3000 int wb_ind, c, i; if ((tag == 0x0110) && strcmp(software, "v757-71")) { icWBC[LIBRAW_WBI_Auto][0] = get2(); icWBC[LIBRAW_WBI_Auto][2] = get2(); if (len == 2) { for (i = 0; i < 256; i++) icWBC[i][1] = icWBC[i][3] = 0x100; } } else if ((((tag >= 0x0120) && (tag <= 0x0124)) || ((tag >= 0x0130) && (tag <= 0x0133))) && strcmp(software, "v757-71")) { if (tag <= 0x0124) wb_ind = tag - 0x0120; else wb_ind = tag - 0x0130 + 5; icWBC[Oly_wb_list1[wb_ind]][0] = get2(); icWBC[Oly_wb_list1[wb_ind]][2] = get2(); } else if ((tag == 0x0200) && (dng_writer == nonDNG)) { for (i = 0; i < 3; i++) { if (!imOly.ColorSpace) { FORC3 cmatrix[i][c] = ((short)get2()) / 256.0; } else { FORC3 imgdata.color.ccm[i][c] = ((short)get2()) / 256.0; } } } else if ((tag == 0x0600) && (dng_writer == nonDNG)) { FORC4 cblack[RGGB_2_RGBG(c)] = get2(); } else if ((tag == 0x0612) && (dng_writer == nonDNG)) { imgdata.sizes.raw_inset_crops[0].cleft = get2(); } else if ((tag == 0x0613) && (dng_writer == nonDNG)) { imgdata.sizes.raw_inset_crops[0].ctop = get2(); } else if ((tag == 0x0614) && (dng_writer == nonDNG)) { imgdata.sizes.raw_inset_crops[0].cwidth = get2(); } else if ((tag == 0x0615) && (dng_writer == nonDNG)) { imgdata.sizes.raw_inset_crops[0].cheight = get2(); } return; } void LibRaw::parseOlympusMakernotes (int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer) { int c; unsigned a; if ((tag >= 0x20100000) && (tag <= 0x2010ffff)) { parseOlympus_Equipment((tag & 0x0000ffff), type, len, dng_writer); } else if ((tag >= 0x20200000) && (tag <= 0x2020ffff)) { parseOlympus_CameraSettings(base, (tag & 0x0000ffff), type, len, dng_writer); } else if ((tag >= 0x20400000) && (tag <= 0x2040ffff)) { parseOlympus_ImageProcessing((tag & 0x0000ffff), type, len, dng_writer); } else if ((tag >= 0x30000000) && (tag <= 0x3000ffff)) { parseOlympus_RawInfo((tag & 0x0000ffff), type, len, dng_writer); } else { switch (tag) { case 0x0200: FORC3 if ((imOly.SpecialMode[c] = get4()) >= 0xff) imOly.SpecialMode[c] = 0xffffffff; break; case 0x0207: getOlympus_CameraType2(); break; case 0x0404: case 0x101a: if (!imgdata.shootinginfo.BodySerial[0] && (dng_writer == nonDNG)) stmread(imgdata.shootinginfo.BodySerial, len, ifp); break; case 0x1002: ilm.CurAp = libraw_powf64l(2.0f, getreal(type) / 2); break; case 0x1007: imCommon.SensorTemperature = (float)get2(); break; case 0x1008: imCommon.LensTemperature = (float)get2(); break; case 0x100b: if (imOly.FocusMode[0] == 0xffff) { imgdata.shootinginfo.FocusMode = imOly.FocusMode[0] = get2(); if (imgdata.shootinginfo.FocusMode == 1) imgdata.shootinginfo.FocusMode = imOly.FocusMode[0] = 10; } break; case 0x100d: if (imOly.ZoomStepCount == 0xffff) imOly.ZoomStepCount = get2(); break; case 0x100e: if (imOly.FocusStepCount == 0xffff) imOly.FocusStepCount = get2(); break; case 0x1011: if (strcmp(software, "v757-71") && (dng_writer == nonDNG)) { for (int i = 0; i < 3; i++) { if (!imOly.ColorSpace) { FORC3 cmatrix[i][c] = ((short)get2()) / 256.0; } else { FORC3 imgdata.color.ccm[i][c] = ((short)get2()) / 256.0; } } } break; case 0x1012: if (dng_writer == nonDNG) FORC4 cblack[RGGB_2_RGBG(c)] = get2(); break; case 0x1017: if (dng_writer == nonDNG) cam_mul[0] = get2() / 256.0; break; case 0x1018: if (dng_writer == nonDNG) cam_mul[2] = get2() / 256.0; break; case 0x102c: if (dng_writer == nonDNG) imOly.ValidBits = get2(); break; case 0x1038: imOly.AFResult = get2(); break; case 0x103b: if (imOly.FocusStepInfinity == 0xffff) imOly.FocusStepInfinity = get2(); break; case 0x103c: if (imOly.FocusStepNear == 0xffff) imOly.FocusStepNear = get2(); break; case 0x20300108: case 0x20310109: if (dng_writer == nonDNG) { imOly.ColorSpace = get2(); switch (imOly.ColorSpace) { case 0: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 1: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; case 2: imCommon.ColorSpace = LIBRAW_COLORSPACE_ProPhotoRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } } case 0x20500209: imOly.AutoFocus = get2(); break; case 0x20500300: imOly.ZoomStepCount = get2(); break; case 0x20500301: imOly.FocusStepCount = get2(); break; case 0x20500303: imOly.FocusStepInfinity = get2(); break; case 0x20500304: imOly.FocusStepNear = get2(); break; case 0x20500305: a = get4(); /*b = */ get4(); // b is not used, so removed if (a >= 0x7f000000) imOly.FocusDistance = -1.0; // infinity else imOly.FocusDistance = (double) a / 1000.0; // convert to meters break; case 0x20500308: imOly.AFPoint = get2(); break; case 0x20501500: getOlympus_SensorTemperature(len); break; } } } LibRaw-0.21.4/src/metadata/p1.cpp000066400000000000000000000277071477673233700164110ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" void LibRaw::setPhaseOneFeatures(unsigned long long id) { ushort i; static const struct { unsigned long long id; char t_model[32]; int CamMnt; int CamFmt; } p1_unique[] = { // Phase One section: {0x001ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x00aULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x00cULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x010ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x011ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x012ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x013ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x014ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x015ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x016ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x017ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x018ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x019ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x020ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x022ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x023ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x024ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x025ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x026ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x027ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x028ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x029ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x02aULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x02cULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x02dULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x02eULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x02fULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x030ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x031ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x032ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x033ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x034ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x035ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x036ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x037ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x043ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x044ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x045ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x046ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x047ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x048ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x049ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x04aULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x04cULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x04dULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x04eULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x04fULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x050ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x051ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x052ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x053ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x054ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x055ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x056ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x057ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x063ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x064ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x065ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x066ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x067ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x068ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x069ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x06aULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x070ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x071ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x072ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x073ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x083ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x084ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x085ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x086ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x087ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x088ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x089ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x08aULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x08cULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x08dULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x08eULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x08fULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x094ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x095ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x096ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x097ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x0a0ULL, "A-250", LIBRAW_MOUNT_Alpa, LIBRAW_FORMAT_69}, {0x0a1ULL, "A-260", LIBRAW_MOUNT_Alpa, LIBRAW_FORMAT_69}, {0x0a2ULL, "A-280", LIBRAW_MOUNT_Alpa, LIBRAW_FORMAT_69}, {0x0a7ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x0a8ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x0a9ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x0aaULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x0acULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x0adULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x0aeULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x0afULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x0b0ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x0b1ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x0b2ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x0b3ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x0b4ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x0b5ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x0b6ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x0b7ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x0d0ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, {0x0d3ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x1c0ULL, "Phase One 645AF", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x1c9ULL, "Phase One 645DF", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x1d7ULL, "Phase One 645DF+", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, {0x2c0ULL, "Phase One iXA", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, {0x2c1ULL, "Phase One iXA - R", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, {0x2c2ULL, "Phase One iXU 150", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, {0x2c3ULL, "Phase One iXU 150 - NIR", LIBRAW_MOUNT_Unknown,LIBRAW_FORMAT_Unknown}, {0x2c4ULL, "Phase One iXU 180", LIBRAW_MOUNT_Unknown,LIBRAW_FORMAT_Unknown}, {0x2d1ULL, "Phase One iXR", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, // Leaf section: {0x140ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, {0x141ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x142ULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x143ULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, {0x144ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, {0x145ULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x146ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x147ULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, {0x149ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, {0x14aULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x14cULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x14dULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, {0x14eULL, "AFi", LIBRAW_MOUNT_Rollei_bayonet, LIBRAW_FORMAT_66}, {0x14fULL, "AFi", LIBRAW_MOUNT_Rollei_bayonet, LIBRAW_FORMAT_66}, {0x150ULL, "AFi", LIBRAW_MOUNT_Rollei_bayonet, LIBRAW_FORMAT_66}, {0x151ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, {0x152ULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x153ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x154ULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, {0x16cULL, "Phase One iXM-RS150F", LIBRAW_MOUNT_PhaseOne_iXM_RS, LIBRAW_FORMAT_645}, {0x171ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, {0x172ULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, {0x173ULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, {0x174ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, {0x175ULL, "AFi", LIBRAW_MOUNT_Rollei_bayonet, LIBRAW_FORMAT_66}, }; ilm.CamID = id; if (id && !ilm.body[0]) { for (i = 0; i < sizeof p1_unique / sizeof *p1_unique; i++) if (id == p1_unique[i].id) { strcpy(ilm.body, p1_unique[i].t_model); ilm.CameraFormat = p1_unique[i].CamFmt; ilm.CameraMount = p1_unique[i].CamMnt; if ((ilm.CameraMount == LIBRAW_MOUNT_PhaseOne_iXM_RS) || (ilm.CameraMount == LIBRAW_MOUNT_PhaseOne_iXM)) { ilm.FocalType = LIBRAW_FT_PRIME_LENS; ilm.LensMount = ilm.CameraMount; } else if (ilm.CameraMount == LIBRAW_MOUNT_PhaseOne_iXM_MV) { ilm.LensMount = ilm.CameraMount; } break; } } return; } LibRaw-0.21.4/src/metadata/pentax.cpp000066400000000000000000000456361477673233700173710ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" #include "../../internal/libraw_cameraids.h" void LibRaw::setPentaxBodyFeatures(unsigned long long id) { ilm.CamID = id; switch (id) { case PentaxID_staristD: case PentaxID_staristDS: case PentaxID_staristDL: case PentaxID_staristDS2: case PentaxID_GX_1S: case PentaxID_staristDL2: case PentaxID_GX_1L: case PentaxID_K100D: case PentaxID_K110D: case PentaxID_K100D_Super: case PentaxID_K10D: case PentaxID_GX10: case PentaxID_K20D: case PentaxID_GX20: case PentaxID_K200D: case PentaxID_K2000: case PentaxID_K_m: case PentaxID_K_7: case PentaxID_K_x: case PentaxID_K_r: case PentaxID_K_5: case PentaxID_K_01: case PentaxID_K_30: case PentaxID_K_5_II: case PentaxID_K_5_II_s: case PentaxID_K_50: case PentaxID_K_3: case PentaxID_K_500: case PentaxID_K_S1: case PentaxID_K_S2: case PentaxID_K_3_II: case PentaxID_K_3_III: case PentaxID_K_70: case PentaxID_KP: ilm.CameraMount = LIBRAW_MOUNT_Pentax_K; ilm.CameraFormat = LIBRAW_FORMAT_APSC; break; case PentaxID_K_1: case PentaxID_K_1_Mark_II: ilm.CameraMount = LIBRAW_MOUNT_Pentax_K; ilm.CameraFormat = LIBRAW_FORMAT_FF; break; case PentaxID_645D: case PentaxID_645Z: ilm.CameraMount = LIBRAW_MOUNT_Pentax_645; ilm.CameraFormat = LIBRAW_FORMAT_CROP645; break; case PentaxID_Q: case PentaxID_Q10: ilm.CameraMount = LIBRAW_MOUNT_Pentax_Q; ilm.CameraFormat = LIBRAW_FORMAT_1div2p3INCH; break; case PentaxID_Q7: case PentaxID_Q_S1: ilm.CameraMount = LIBRAW_MOUNT_Pentax_Q; ilm.CameraFormat = LIBRAW_FORMAT_1div1p7INCH; break; case PentaxID_MX_1: ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.CameraMount = LIBRAW_MOUNT_FixedLens; ilm.CameraFormat = LIBRAW_FORMAT_1div1p7INCH; ilm.FocalType = LIBRAW_FT_ZOOM_LENS; break; case PentaxID_GR_III: case PentaxID_GR_IIIx: ilm.CameraMount = LIBRAW_MOUNT_FixedLens; ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.CameraFormat = LIBRAW_FORMAT_APSC; ilm.LensFormat = LIBRAW_FORMAT_APSC; ilm.FocalType = LIBRAW_FT_PRIME_LENS; break; default: ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.CameraMount = LIBRAW_MOUNT_FixedLens; } return; } void LibRaw::PentaxISO(ushort c) { int code[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 50, 100, 200, 400, 800, 1600, 3200, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278}; double value[] = { 50, 64, 80, 100, 125, 160, 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 8000, 10000, 12800, 16000, 20000, 25600, 32000, 40000, 51200, 64000, 80000, 102400, 128000, 160000, 204800, 258000, 325000, 409600, 516000, 650000, 819200, 50, 100, 200, 400, 800, 1600, 3200, 50, 70, 100, 140, 200, 280, 400, 560, 800, 1100, 1600, 2200, 3200, 4500, 6400, 9000, 12800, 18000, 25600, 36000, 51200}; #define numel (sizeof(code) / sizeof(code[0])) int i; for (i = 0; i < (int)numel; i++) { if (code[i] == c) { iso_speed = value[i]; return; } } if (i == numel) iso_speed = 65535.0f; } #undef numel void LibRaw::PentaxLensInfo(unsigned long long id, unsigned len) // tag 0x0207 { ushort iLensData = 0; uchar *table_buf; table_buf = (uchar *)calloc(MAX(len, 128),1); fread(table_buf, len, 1, ifp); if ((id < PentaxID_K100D) || (((id == PentaxID_K100D) || (id == PentaxID_K110D) || (id == PentaxID_K100D_Super)) && ((!table_buf[20] || (table_buf[20] == 0xff))))) { iLensData = 3; if (ilm.LensID == LIBRAW_LENS_NOT_SET) ilm.LensID = (((unsigned)table_buf[0]) << 8) + table_buf[1]; } else switch (len) { case 90: // LensInfo3 iLensData = 13; if (ilm.LensID == LIBRAW_LENS_NOT_SET) ilm.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) << 8) + table_buf[4]; break; case 91: // LensInfo4 iLensData = 12; if (ilm.LensID == LIBRAW_LENS_NOT_SET) ilm.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) << 8) + table_buf[4]; break; case 80: // LensInfo5 case 128: iLensData = 15; if (ilm.LensID == LIBRAW_LENS_NOT_SET) ilm.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[4]) << 8) + table_buf[5]; break; case 168: // Ricoh GR III, id 0x1320e break; default: if (id >= 0x12b9cULL) // LensInfo2 { iLensData = 4; if (ilm.LensID == LIBRAW_LENS_NOT_SET) ilm.LensID = ((unsigned)((table_buf[0] & 0x0f) + table_buf[2]) << 8) + table_buf[3]; } } if (iLensData) { if (table_buf[iLensData + 9] && (fabs(ilm.CurFocal) < 0.1f)) ilm.CurFocal = 10 * (table_buf[iLensData + 9] >> 2) * libraw_powf64l(4, (table_buf[iLensData + 9] & 0x03) - 2); if (table_buf[iLensData + 10] & 0xf0) ilm.MaxAp4CurFocal = libraw_powf64l( 2.0f, (float)((table_buf[iLensData + 10] & 0xf0) >> 4) / 4.0f); if (table_buf[iLensData + 10] & 0x0f) ilm.MinAp4CurFocal = libraw_powf64l( 2.0f, (float)((table_buf[iLensData + 10] & 0x0f) + 10) / 4.0f); if (iLensData != 12) { switch (table_buf[iLensData] & 0x06) { case 0: ilm.MinAp4MinFocal = 22.0f; break; case 2: ilm.MinAp4MinFocal = 32.0f; break; case 4: ilm.MinAp4MinFocal = 45.0f; break; case 6: ilm.MinAp4MinFocal = 16.0f; break; } if (table_buf[iLensData] & 0x70) ilm.LensFStops = ((float)(((table_buf[iLensData] & 0x70) >> 4) ^ 0x07)) / 2.0f + 5.0f; ilm.MinFocusDistance = (float)(table_buf[iLensData + 3] & 0xf8); ilm.FocusRangeIndex = (float)(table_buf[iLensData + 3] & 0x07); if ((table_buf[iLensData + 14] > 1) && (fabs(ilm.MaxAp4CurFocal) < 0.7f)) ilm.MaxAp4CurFocal = libraw_powf64l( 2.0f, (float)((table_buf[iLensData + 14] & 0x7f) - 1) / 32.0f); } else if ((id != 0x12e76ULL) && // K-5 (table_buf[iLensData + 15] > 1) && (fabs(ilm.MaxAp4CurFocal) < 0.7f)) { ilm.MaxAp4CurFocal = libraw_powf64l( 2.0f, (float)((table_buf[iLensData + 15] & 0x7f) - 1) / 32.0f); } } free(table_buf); return; } void LibRaw::parsePentaxMakernotes(int /*base*/, unsigned tag, unsigned type, unsigned len, unsigned dng_writer) { int c; // printf ("==>> =%s= tag:0x%x, type: %d, len:%d\n", model, tag, type, len); if (tag == 0x0005) { unique_id = get4(); setPentaxBodyFeatures(unique_id); } else if (tag == 0x0008) { /* 4 is raw, 7 is raw w/ pixel shift, 8 is raw w/ dynamic pixel shift */ imPentax.Quality = get2(); } else if (tag == 0x000d) { imgdata.shootinginfo.FocusMode = imPentax.FocusMode[0] = get2(); } else if (tag == 0x000e) { imgdata.shootinginfo.AFPoint = imPentax.AFPointSelected[0] = get2(); if (len == 2) imPentax.AFPointSelected_Area = get2(); } else if (tag == 0x000f) { if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) { imPentax.AFPointsInFocus = get4(); if (!imPentax.AFPointsInFocus) imPentax.AFPointsInFocus = 0xffffffff; else imPentax.AFPointsInFocus_version = 3; } else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) { imPentax.AFPointsInFocus = (unsigned) get2(); if (imPentax.AFPointsInFocus == 0x0000ffff) imPentax.AFPointsInFocus = 0xffffffff; else imPentax.AFPointsInFocus_version = 2; } } else if (tag == 0x0010) { imPentax.FocusPosition = get2(); } else if (tag == 0x0013) { ilm.CurAp = (float)get2() / 10.0f; } else if (tag == 0x0014) { PentaxISO(get2()); } else if (tag == 0x0017) { imgdata.shootinginfo.MeteringMode = get2(); } else if (tag == 0x001b) { cam_mul[2] = get2() / 256.0; } else if (tag == 0x001c) { cam_mul[0] = get2() / 256.0; } else if (tag == 0x001d) { ilm.CurFocal = (float)get4() / 100.0f; } else if (tag == 0x0034) { uchar uc; FORC4 { fread(&uc, 1, 1, ifp); imPentax.DriveMode[c] = uc; } imgdata.shootinginfo.DriveMode = imPentax.DriveMode[0]; } else if (tag == 0x0037) { switch (get2()) { case 0: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 1: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } } else if (tag == 0x0038) { imgdata.sizes.raw_inset_crops[0].cleft = get2(); imgdata.sizes.raw_inset_crops[0].ctop = get2(); } else if (tag == 0x0039) { imgdata.sizes.raw_inset_crops[0].cwidth = get2(); imgdata.sizes.raw_inset_crops[0].cheight = get2(); } else if (tag == 0x003c) { if ((len == 4) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED)) { imPentax.AFPointsInFocus = get4() & 0x7ff; if (!imPentax.AFPointsInFocus) { imPentax.AFPointsInFocus = 0xffffffff; } else { imPentax.AFPointsInFocus_version = 1; } } } else if (tag == 0x003f) { unsigned a = unsigned(fgetc(ifp)) << 8; ilm.LensID = a | fgetc(ifp); } else if (tag == 0x0047) { imCommon.CameraTemperature = (float)fgetc(ifp); } else if (tag == 0x004d) { if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SLONG)) imCommon.FlashEC = getreal(type) / 256.0f; else imCommon.FlashEC = (float)((signed short)fgetc(ifp)) / 6.0f; } else if (tag == 0x005c) { fgetc(ifp); imgdata.shootinginfo.ImageStabilization = (short)fgetc(ifp); } else if (tag == 0x0072) { imPentax.AFAdjustment = get2(); } else if ((tag == 0x007e) && (dng_writer == nonDNG)) { imgdata.color.linear_max[0] = imgdata.color.linear_max[1] = imgdata.color.linear_max[2] = imgdata.color.linear_max[3] = get4(); } else if (tag == 0x0080) { short a = (short)fgetc(ifp); switch (a) { case 0: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3; break; case 1: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; break; case 2: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9; break; case 3: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; break; } } else if ((tag == 0x0200) && (dng_writer == nonDNG)) { // Pentax black level FORC4 cblack[RGGB_2_RGBG(c)] = get2(); } else if ((tag == 0x0201) && (dng_writer == nonDNG)) { // Pentax As Shot WB FORC4 cam_mul[RGGB_2_RGBG(c)] = get2(); } else if ((tag == 0x0203) && (dng_writer == nonDNG)) { for (int i = 0; i < 3; i++) FORC3 cmatrix[i][c] = ((short)get2()) / 8192.0; } else if (tag == 0x0205) { if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) { imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; imCommon.afdata[imCommon.afcount].AFInfoData_order = order; imCommon.afdata[imCommon.afcount].AFInfoData_length = len; imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length,1); fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); if ((len < 25) && (len >= 11)) { imPentax.AFPointMode = (imCommon.afdata[imCommon.afcount].AFInfoData[3] >>4) & 0x0f; imPentax.FocusMode[1] = imCommon.afdata[imCommon.afcount].AFInfoData[3] & 0x0f; imPentax.AFPointSelected[1] = sget2(imCommon.afdata[imCommon.afcount].AFInfoData+4); // Pentax K-m has multiexposure set to 8 when no multi-exposure is in effect imPentax.MultiExposure = imCommon.afdata[imCommon.afcount].AFInfoData[10] & 0x0f; } imCommon.afcount++; } } else if (tag == 0x0207) { if (len < 65535) // Safety belt PentaxLensInfo(ilm.CamID, len); } else if ((tag >= 0x020d) && (tag <= 0x0214)) { FORC4 icWBC[Pentax_wb_list1[tag - 0x020d]][RGGB_2_RGBG(c)] = get2(); } else if ((tag == 0x021d) && (len == 18) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) && (dng_writer == nonDNG)) { for (int i = 0; i < 3; i++) FORC3 cmatrix[i][c] = ((short)get2()) / 8192.0; } else if (tag == 0x021f) { if ((unique_id != PentaxID_K_1) && (unique_id != PentaxID_K_3) && (unique_id != PentaxID_K_3_II) && (unique_id != PentaxID_K_1_Mark_II)) { fseek (ifp, 0x0b, SEEK_CUR); imPentax.AFPointsInFocus = (unsigned) fgetc(ifp); if (!imPentax.AFPointsInFocus) imPentax.AFPointsInFocus = 0xffffffff; else imPentax.AFPointsInFocus_version = 4; } } else if ((tag == 0x0220) && (dng_writer == nonDNG)) { meta_offset = ftell(ifp); } else if (tag == 0x0221) { int nWB = get2(); if (nWB > 0 && nWB <= int(sizeof(icWBCCTC) / sizeof(icWBCCTC[0]))) FORC(nWB) { icWBCCTC[c][0] = (unsigned)0xcfc6 - get2(); fseek(ifp, 2, SEEK_CUR); icWBCCTC[c][1] = get2(); icWBCCTC[c][2] = icWBCCTC[c][4] = 0x2000; icWBCCTC[c][3] = get2(); } } else if (tag == 0x0215) { fseek(ifp, 16, SEEK_CUR); sprintf(imgdata.shootinginfo.InternalBodySerial, "%d", get4()); } else if (tag == 0x0229) { stmread(imgdata.shootinginfo.BodySerial, len, ifp); } else if (tag == 0x022d) { int wb_ind; getc(ifp); for (int wb_cnt = 0; wb_cnt < (int)Pentax_wb_list2.size(); wb_cnt++) { wb_ind = getc(ifp); if (wb_ind >= 0 && wb_ind < (int)Pentax_wb_list2.size() ) FORC4 icWBC[Pentax_wb_list2[wb_ind]][RGGB_2_RGBG(c)] = get2(); } } else if (tag == 0x0239) // Q-series lens info (LensInfoQ) { char LensInfo[20]; fseek(ifp, 12, SEEK_CUR); stread(ilm.Lens, 30, ifp); strcat(ilm.Lens, " "); stread(LensInfo, 20, ifp); strcat(ilm.Lens, LensInfo); } else if (tag == 0x0245) { if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) { imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; imCommon.afdata[imCommon.afcount].AFInfoData_order = order; imCommon.afdata[imCommon.afcount].AFInfoData_length = len; imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length,1); fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); imCommon.afcount++; } } } void LibRaw::parseRicohMakernotes(int /*base*/, unsigned tag, unsigned type, unsigned /*len*/, unsigned /*dng_writer */) { char buffer[17]; if (tag == 0x0005) { int c; int count = 0; fread(buffer, 16, 1, ifp); buffer[16] = 0; FORC(16) { if ((isspace(buffer[c])) || (buffer[c] == 0x2D) || (isalnum(buffer[c]))) count++; else break; } if (count == 16) { if (strncmp(model, "GXR", 3)) { sprintf(imgdata.shootinginfo.BodySerial, "%8s", buffer + 8); } buffer[8] = 0; sprintf(imgdata.shootinginfo.InternalBodySerial, "%8s", buffer); } else { sprintf(imgdata.shootinginfo.BodySerial, "%02x%02x%02x%02x", buffer[4], buffer[5], buffer[6], buffer[7]); sprintf(imgdata.shootinginfo.InternalBodySerial, "%02x%02x%02x%02x", buffer[8], buffer[9], buffer[10], buffer[11]); } } else if ((tag == 0x1001) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) { ilm.CameraMount = LIBRAW_MOUNT_FixedLens; ilm.LensMount = LIBRAW_MOUNT_FixedLens; ilm.CameraFormat = LIBRAW_FORMAT_APSC; ilm.LensID = LIBRAW_LENS_NOT_SET; ilm.FocalType = LIBRAW_FT_PRIME_LENS; imgdata.shootinginfo.ExposureProgram = get2(); } else if ((tag == 0x1002) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) { imgdata.shootinginfo.DriveMode = get2(); } else if (tag == 0x1006) { imgdata.shootinginfo.FocusMode = get2(); } else if (tag == 0x1007) { imRicoh.AutoBracketing = get2(); } else if (tag == 0x1009) { imRicoh.MacroMode = get2(); } else if (tag == 0x100a) { imRicoh.FlashMode = get2(); } else if (tag == 0x100b) { imRicoh.FlashExposureComp = getreal(type); } else if (tag == 0x100c) { imRicoh.ManualFlashOutput = getreal(type); } else if ((tag == 0x100b) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL)) { imCommon.FlashEC = getreal(type); } else if ((tag == 0x1017) && ((imRicoh.WideAdapter = get2()) == 2)) { strcpy(ilm.Attachment, "Wide-Angle Adapter"); } else if (tag == 0x1018) { imRicoh.CropMode = get2(); } else if (tag == 0x1019) { imRicoh.NDFilter = get2(); } else if (tag == 0x1200) { imRicoh.AFStatus = get2(); } else if (tag == 0x1201) { imRicoh.AFAreaXPosition[1] = get4(); } else if (tag == 0x1202) { imRicoh.AFAreaYPosition[1] = get4(); } else if (tag == 0x1203) { imRicoh.AFAreaXPosition[0] = get4(); } else if (tag == 0x1204) { imRicoh.AFAreaYPosition[0] = get4(); } else if (tag == 0x1205) { imRicoh.AFAreaMode = get2(); } else if (tag == 0x1500) { ilm.CurFocal = getreal(type); } else if (tag == 0x1601) { imRicoh.SensorWidth = get4(); } else if (tag == 0x1602) { imRicoh.SensorHeight = get4(); } else if (tag == 0x1603) { imRicoh.CroppedImageWidth = get4(); } else if (tag == 0x1604) { imRicoh.CroppedImageHeight= get4(); } else if ((tag == 0x2001) && !strncmp(model, "GXR", 3)) { short cur_tag; fseek(ifp, 20, SEEK_CUR); /*ntags =*/ get2(); cur_tag = get2(); while (cur_tag != 0x002c) { fseek(ifp, 10, SEEK_CUR); cur_tag = get2(); } fseek(ifp, 6, SEEK_CUR); fseek(ifp, get4(), SEEK_SET); for (int i=0; i<4; i++) { stread(buffer, 16, ifp); if ((buffer[0] == 'S') && (buffer[1] == 'I') && (buffer[2] == 'D')) memcpy(imgdata.shootinginfo.BodySerial, buffer+4, 12); else if ((buffer[0] == 'R') && (buffer[1] == 'L')) ilm.LensID = buffer[2] - '0'; else if ((buffer[0] == 'L') && (buffer[1] == 'I') && (buffer[2] == 'D')) memcpy(imgdata.lens.LensSerial, buffer+4, 12); } } } LibRaw-0.21.4/src/metadata/samsung.cpp000066400000000000000000000116451477673233700175400ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" void LibRaw::parseSamsungMakernotes(int /*base*/, unsigned tag, unsigned type, unsigned len, unsigned dng_writer) { int i, c; if (tag == 0x0002) { imSamsung.DeviceType = get4(); if (imSamsung.DeviceType == 0x2000) { ilm.CameraMount = LIBRAW_MOUNT_Samsung_NX; ilm.CameraFormat = LIBRAW_FORMAT_APSC; } else if (!strncmp(model, "NX mini", 7)) { // device type 0x1000: 'NX mini', EX2F, EX1, WB2000 ilm.CameraMount = LIBRAW_MOUNT_Samsung_NX_M; ilm.CameraFormat = LIBRAW_FORMAT_1INCH; } else { ilm.CameraMount = LIBRAW_MOUNT_FixedLens; ilm.LensMount = LIBRAW_MOUNT_FixedLens; } } else if (tag == 0x0003) { ilm.CamID = unique_id = get4(); } else if (tag == 0x0043) { if ((i = get4())) { imCommon.CameraTemperature = (float)i; if (get4() == 10) imCommon.CameraTemperature /= 10.0f; } } else if ((tag == 0xa002) && (dng_writer != AdobeDNG)) { stmread(imgdata.shootinginfo.BodySerial, len, ifp); } else if (tag == 0xa003) { ilm.LensID = get2(); if (ilm.LensID) ilm.LensMount = LIBRAW_MOUNT_Samsung_NX; } else if (tag == 0xa004) { // LensFirmware stmread(imSamsung.LensFirmware, len, ifp); } else if (tag == 0xa005) { stmread(imgdata.lens.InternalLensSerial, len, ifp); } else if (tag == 0xa010) { FORC4 imSamsung.ImageSizeFull[c] = get4(); FORC4 imSamsung.ImageSizeCrop[c] = get4(); } else if ((tag == 0xa011) && ((len == 1) || (len == 2)) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) { imSamsung.ColorSpace[0] = (int)get2(); switch (imSamsung.ColorSpace[0]) { case 0: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 1: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } if (len == 2) imSamsung.ColorSpace[1] = (int)get2(); } else if (tag == 0xa019) { ilm.CurAp = getreal(type); } else if ((tag == 0xa01a) && (unique_id != 0x5000000) && (!imgdata.lens.FocalLengthIn35mmFormat)) { ilm.FocalLengthIn35mmFormat = get4(); if (ilm.FocalLengthIn35mmFormat >= 160) ilm.FocalLengthIn35mmFormat /= 10.0f; if ((ilm.CameraMount == LIBRAW_MOUNT_Samsung_NX_M) && (imSamsung.LensFirmware[10] < '6')) ilm.FocalLengthIn35mmFormat *= 1.6f; } else if (tag == 0xa020) { FORC(11) imSamsung.key[c] = get4(); } else if ((tag == 0xa021) && (dng_writer == nonDNG)) { FORC4 cam_mul[RGGB_2_RGBG(c)] = get4() - imSamsung.key[c]; } else if (tag == 0xa022) { FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get4() - imSamsung.key[c + 4]; if (icWBC[LIBRAW_WBI_Auto][0] < (icWBC[LIBRAW_WBI_Auto][1] >> 1)) { icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][1] >> 4; icWBC[LIBRAW_WBI_Auto][3] = icWBC[LIBRAW_WBI_Auto][3] >> 4; } } else if (tag == 0xa023) { ushort ki[4] = {8, 9, 10, 0}; FORC4 icWBC[LIBRAW_WBI_Ill_A][RGGB_2_RGBG(c)] = get4() - imSamsung.key[ki[c]]; if (icWBC[LIBRAW_WBI_Ill_A][0] < (icWBC[LIBRAW_WBI_Ill_A][1] >> 1)) { icWBC[LIBRAW_WBI_Ill_A][1] = icWBC[LIBRAW_WBI_Ill_A][1] >> 4; icWBC[LIBRAW_WBI_Ill_A][3] = icWBC[LIBRAW_WBI_Ill_A][3] >> 4; } } else if (tag == 0xa024) { FORC4 icWBC[LIBRAW_WBI_D65][RGGB_2_RGBG(c)] = get4() - imSamsung.key[c + 1]; if (icWBC[LIBRAW_WBI_D65][0] < (icWBC[LIBRAW_WBI_D65][1] >> 1)) { icWBC[LIBRAW_WBI_D65][1] = icWBC[LIBRAW_WBI_D65][1] >> 4; icWBC[LIBRAW_WBI_D65][3] = icWBC[LIBRAW_WBI_D65][3] >> 4; } } else if (tag == 0xa025) { unsigned t = get4() + imSamsung.key[0]; if (t == 4096) imSamsung.DigitalGain = 1.0; else imSamsung.DigitalGain = ((double)t) / 4096.0; } else if ((tag == 0xa028) && (dng_writer == nonDNG)) { FORC4 cblack[RGGB_2_RGBG(c)] = get4() - imSamsung.key[c]; } else if ((tag == 0xa030) && (len == 9)) { for (i = 0; i < 3; i++) FORC3 imgdata.color.ccm[i][c] = (float)((short)((get4() + imSamsung.key[i * 3 + c]))) / 256.0; } else if ((tag == 0xa032) && (len == 9) && (dng_writer == nonDNG)) { double aRGB_cam[3][3]; FORC(9) ((double *)aRGB_cam)[c] = ((double)((short)((get4() + imSamsung.key[c])))) / 256.0; aRGB_coeff(aRGB_cam); } } LibRaw-0.21.4/src/metadata/sony.cpp000066400000000000000000002471561477673233700170630ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" #include "../../internal/libraw_cameraids.h" static ushort saneSonyCameraInfo(uchar a, uchar b, uchar c, uchar d, uchar e, uchar f) { if ((a >> 4) > 9) return 0; else if ((a & 0x0f) > 9) return 0; else if ((b >> 4) > 9) return 0; else if ((b & 0x0f) > 9) return 0; else if ((c >> 4) > 9) return 0; else if ((c & 0x0f) > 9) return 0; else if ((d >> 4) > 9) return 0; else if ((d & 0x0f) > 9) return 0; else if ((e >> 4) > 9) return 0; else if ((e & 0x0f) > 9) return 0; else if ((f >> 4) > 9) return 0; else if ((f & 0x0f) > 9) return 0; return 1; } static float my_roundf(float x) { float t; if (x >= 0.0) { t = ceilf(x); if (t - x > 0.5) t -= 1.0; return t; } else { t = ceilf(-x); if (t + x > 0.5) t -= 1.0; return -t; } } static ushort bcd2dec(uchar data) { if ((data >> 4) > 9) return 0; else if ((data & 0x0f) > 9) return 0; else return (data >> 4) * 10 + (data & 0x0f); } static uchar SonySubstitution[257] = "\x00\x01\x32\xb1\x0a\x0e\x87\x28\x02\xcc\xca\xad\x1b\xdc\x08\xed\x64\x86" "\xf0\x4f\x8c\x6c\xb8\xcb\x69\xc4\x2c\x03" "\x97\xb6\x93\x7c\x14\xf3\xe2\x3e\x30\x8e\xd7\x60\x1c\xa1\xab\x37\xec\x75" "\xbe\x23\x15\x6a\x59\x3f\xd0\xb9\x96\xb5" "\x50\x27\x88\xe3\x81\x94\xe0\xc0\x04\x5c\xc6\xe8\x5f\x4b\x70\x38\x9f\x82" "\x80\x51\x2b\xc5\x45\x49\x9b\x21\x52\x53" "\x54\x85\x0b\x5d\x61\xda\x7b\x55\x26\x24\x07\x6e\x36\x5b\x47\xb7\xd9\x4a" "\xa2\xdf\xbf\x12\x25\xbc\x1e\x7f\x56\xea" "\x10\xe6\xcf\x67\x4d\x3c\x91\x83\xe1\x31\xb3\x6f\xf4\x05\x8a\x46\xc8\x18" "\x76\x68\xbd\xac\x92\x2a\x13\xe9\x0f\xa3" "\x7a\xdb\x3d\xd4\xe7\x3a\x1a\x57\xaf\x20\x42\xb2\x9e\xc3\x8b\xf2\xd5\xd3" "\xa4\x7e\x1f\x98\x9c\xee\x74\xa5\xa6\xa7" "\xd8\x5e\xb0\xb4\x34\xce\xa8\x79\x77\x5a\xc1\x89\xae\x9a\x11\x33\x9d\xf5" "\x39\x19\x65\x78\x16\x71\xd2\xa9\x44\x63" "\x40\x29\xba\xa0\x8f\xe4\xd6\x3b\x84\x0d\xc2\x4e\x58\xdd\x99\x22\x6b\xc9" "\xbb\x17\x06\xe5\x7d\x66\x43\x62\xf6\xcd" "\x35\x90\x2e\x41\x8d\x6d\xaa\x09\x73\x95\x0c\xf1\x1d\xde\x4c\x2f\x2d\xf7" "\xd1\x72\xeb\xef\x48\xc7\xf8\xf9\xfa\xfb" "\xfc\xfd\xfe\xff"; void LibRaw::sony_decrypt(unsigned *data, int len, int start, int key) { #ifndef LIBRAW_NOTHREADS #define pad tls->sony_decrypt.pad #define p tls->sony_decrypt.p #else static unsigned pad[128], p; #endif if (start) { for (p = 0; p < 4; p++) pad[p] = key = key * 48828125ULL + 1; pad[3] = pad[3] << 1 | (pad[0] ^ pad[2]) >> 31; for (p = 4; p < 127; p++) pad[p] = (pad[p - 4] ^ pad[p - 2]) << 1 | (pad[p - 3] ^ pad[p - 1]) >> 31; for (p = 0; p < 127; p++) pad[p] = htonl(pad[p]); } while (len--) { *data++ ^= pad[p & 127] = pad[(p + 1) & 127] ^ pad[(p + 65) & 127]; p++; } #ifndef LIBRAW_NOTHREADS #undef pad #undef p #endif } void LibRaw::setSonyBodyFeatures(unsigned long long id) { static const struct { ushort scf[11]; /* scf[0] camera id scf[1] camera format scf[2] camera mount: Minolta A, Sony E, fixed, scf[3] camera type: DSLR, NEX, SLT, ILCE, ILCA, DSC scf[4] lens mount, LIBRAW_MOUNT_FixedLens or LIBRAW_MOUNT_Unknown scf[5] tag 0x2010 group (0 if not used) scf[6] offset of Sony ISO in 0x2010 table, 0xffff if not valid scf[7] offset of ShutterCount3 in 0x9050 table, 0xffff if not valid scf[8] offset of MeteringMode in 0x2010 table, 0xffff if not valid scf[9] offset of ExposureProgram in 0x2010 table, 0xffff if not valid scf[10] offset of ReleaseMode2 in 0x2010 table, 0xffff if not valid */ } SonyCamFeatures[] = { {SonyID_DSLR_A100, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A900, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A700, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A200, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A350, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A300, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A900, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A380, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A330, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A230, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A290, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A850, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A850, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A550, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A500, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A450, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_NEX_5, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_NEX_3, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_SLT_A33, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_SLT_A55, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A560, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_DSLR_A580, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_NEX_C3, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_SLT_A35, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_SLT_A65, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010b, 0x1218, 0x01bd, 0x1178, 0x1179, 0x112c}, {SonyID_SLT_A77, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010b, 0x1218, 0x01bd, 0x1178, 0x1179, 0x112c}, {SonyID_NEX_5N, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010a, 0x113e, 0x01bd, 0x1174, 0x1175, 0x112c}, {SonyID_NEX_7, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010b, 0x1218, 0x01bd, 0x1178, 0x1179, 0x112c}, {SonyID_NEX_VG20, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010b, 0x1218, 0x01bd, 0x1178, 0x1179, 0x112c}, {SonyID_SLT_A37, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010c, 0x11f4, 0x01bd, 0x1154, 0x1155, 0x1108}, {SonyID_SLT_A57, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010c, 0x11f4, 0x01bd, 0x1154, 0x1155, 0x1108}, {SonyID_NEX_F3, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010c, 0x11f4, 0x01bd, 0x1154, 0x1155, 0x1108}, {SonyID_SLT_A99, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160}, {SonyID_NEX_6, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160}, {SonyID_NEX_5R, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160}, {SonyID_DSC_RX100, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010e, 0x1254, 0xffff, 0x11ac, 0x11ad, 0x1160}, {SonyID_DSC_RX1, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010e, 0x1258, 0xffff, 0x11ac, 0x11ad, 0x1160}, {SonyID_NEX_VG900, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160}, {SonyID_NEX_VG30, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160}, {SonyID_ILCE_3000, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010e, 0x1280, 0x01aa, 0x11ac, 0x11ad, 0x1160}, {SonyID_SLT_A58, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010e, 0x1280, 0x01aa, 0x11ac, 0x11ad, 0x1160}, {SonyID_NEX_3N, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010e, 0x1280, 0x01aa, 0x11ac, 0x11ad, 0x1160}, {SonyID_ILCE_7, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, {SonyID_NEX_5T, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160}, {SonyID_DSC_RX100M2, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010f, 0x113c, 0xffff, 0x1064, 0x1065, 0x1018}, {SonyID_DSC_RX10, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, {SonyID_DSC_RX1R, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010e, 0x1258, 0xffff, 0x11ac, 0x11ad, 0x1160}, {SonyID_ILCE_7R, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, {SonyID_ILCE_6000, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, {SonyID_ILCE_5000, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010g, 0x0344, 0x01aa, 0x025c, 0x025d, 0x0210}, {SonyID_DSC_RX100M3, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, {SonyID_ILCE_7S, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, {SonyID_ILCA_77M2, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_ILCA, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010g, 0x0344, 0x01a0, 0x025c, 0x025d, 0x0210}, {SonyID_ILCE_5100, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010g, 0x0344, 0x01a0, 0x025c, 0x025d, 0x0210}, {SonyID_ILCE_7M2, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, {SonyID_DSC_RX100M4, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210}, {SonyID_DSC_RX10M2, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210}, {SonyID_DSC_RX1RM2, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210}, {SonyID_ILCE_QX1, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010g, 0x0344, 0x01a0, 0x025c, 0x025d, 0x0210}, {SonyID_ILCE_7RM2, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010h, 0x0346, 0x01cb, 0x025c, 0x025d, 0x0210}, {SonyID_ILCE_7SM2, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010h, 0x0346, 0x01cb, 0x025c, 0x025d, 0x0210}, {SonyID_ILCA_68, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_ILCA, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010g, 0x0344, 0x01a0, 0x025c, 0x025d, 0x0210}, {SonyID_ILCA_99M2, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_ILCA, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010h, 0x0346, 0x01cd, 0x025c, 0x025d, 0x0210}, {SonyID_DSC_RX10M3, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210}, {SonyID_DSC_RX100M5, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210}, {SonyID_ILCE_6300, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010h, 0x0346, 0x01cd, 0x025c, 0x025d, 0x0210}, {SonyID_ILCE_9, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, {SonyID_ILCE_6500, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010h, 0x0346, 0x01cd, 0x025c, 0x025d, 0x0210}, {SonyID_ILCE_7RM3, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, {SonyID_ILCE_7M3, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, {SonyID_DSC_RX0, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210}, {SonyID_DSC_RX10M4, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, {SonyID_DSC_RX100M6, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, {SonyID_DSC_HX99, LIBRAW_FORMAT_1div2p3INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, {SonyID_DSC_RX100M5A, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, {SonyID_ILCE_6400, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, {SonyID_DSC_RX0M2, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, {SonyID_DSC_RX100M7, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, {SonyID_ILCE_7RM4, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, {SonyID_ILCE_9M2, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, {SonyID_ILCE_6600, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, {SonyID_ILCE_6100, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, {SonyID_ZV_1, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, {SonyID_ILCE_7C, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, // a la SonyID_ILCE_6100 {SonyID_ZV_E10, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, {SonyID_ILCE_7SM3, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_ILCE_1, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_ILME_FX3, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, {SonyID_ILCE_7RM3A, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, {SonyID_ILCE_7RM4A, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, {SonyID_ILCE_7M4, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, }; ilm.CamID = id; if (id == SonyID_DSC_R1) { ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; imSony.CameraType = LIBRAW_SONY_DSC; imSony.group2010 = LIBRAW_SONY_Tag2010None; imSony.group9050 = LIBRAW_SONY_Tag9050None; return; } for (unsigned i = 0; i < (sizeof SonyCamFeatures / sizeof *SonyCamFeatures); i++) { if (SonyCamFeatures[i].scf[0] == id) { ilm.CameraFormat = SonyCamFeatures[i].scf[1]; ilm.CameraMount = SonyCamFeatures[i].scf[2]; imSony.CameraType = SonyCamFeatures[i].scf[3]; if (SonyCamFeatures[i].scf[4]) ilm.LensMount = SonyCamFeatures[i].scf[4]; imSony.group2010 = SonyCamFeatures[i].scf[5]; imSony.real_iso_offset = SonyCamFeatures[i].scf[6]; imSony.ImageCount3_offset = SonyCamFeatures[i].scf[7]; imSony.MeteringMode_offset = SonyCamFeatures[i].scf[8]; imSony.ExposureProgram_offset = SonyCamFeatures[i].scf[9]; imSony.ReleaseMode2_offset = SonyCamFeatures[i].scf[10]; break; } } switch (id) { case SonyID_ILCE_6100: case SonyID_ILCE_6300: case SonyID_ILCE_6400: case SonyID_ILCE_6500: case SonyID_ILCE_6600: case SonyID_ILCE_7C: case SonyID_ILCE_7M3: case SonyID_ILCE_7RM2: case SonyID_ILCE_7RM3A: case SonyID_ILCE_7RM3: case SonyID_ILCE_7RM4: case SonyID_ILCE_7RM4A: case SonyID_ILCE_7SM2: case SonyID_ILCE_9: case SonyID_ILCE_9M2: case SonyID_ILCA_99M2: case SonyID_ZV_E10: imSony.group9050 = LIBRAW_SONY_Tag9050b; break; case SonyID_ILCE_7SM3: case SonyID_ILCE_1: case SonyID_ILME_FX3: case SonyID_ILCE_7M4: imSony.group9050 = LIBRAW_SONY_Tag9050c; break; default: if ((imSony.CameraType != LIBRAW_SONY_DSC) && (imSony.CameraType != LIBRAW_SONY_DSLR)) imSony.group9050 = LIBRAW_SONY_Tag9050a; else imSony.group9050 = LIBRAW_SONY_Tag9050None; break; } char *sbstr = strstr(software, " v"); if (sbstr != NULL) { sbstr += 2; strcpy(imCommon.firmware, sbstr); imSony.firmware = atof(sbstr); if ((id == SonyID_ILCE_7) || (id == SonyID_ILCE_7R)) { if (imSony.firmware < 1.2f) imSony.ImageCount3_offset = 0x01aa; else imSony.ImageCount3_offset = 0x01c0; } else if (id == SonyID_ILCE_6000) { if (imSony.firmware < 2.0f) imSony.ImageCount3_offset = 0x01aa; else imSony.ImageCount3_offset = 0x01c0; } else if ((id == SonyID_ILCE_7S) || (id == SonyID_ILCE_7M2)) { if (imSony.firmware < 1.2f) imSony.ImageCount3_offset = 0x01a0; else imSony.ImageCount3_offset = 0x01b6; } } if ((id == SonyID_ILCE_7SM3) && !strcmp(model, "MODEL-NAME")) { imSony.group9050 = LIBRAW_SONY_Tag9050a; } } void LibRaw::parseSonyLensType2(uchar a, uchar b) { ushort lid2; lid2 = (((ushort)a) << 8) | ((ushort)b); if (!lid2) return; if (lid2 < 0x100) { if ((ilm.AdapterID != 0x4900) && (ilm.AdapterID != 0xef00)) { ilm.AdapterID = lid2; switch (lid2) { case 1: // Sony LA-EA1 or Sigma MC-11 Adapter case 2: // Sony LA-EA2 case 3: // Sony LA-EA3 case 6: // Sony LA-EA4 case 7: // Sony LA-EA5 case 24593: // LA-EA4r MonsterAdapter, id = 0x6011 ilm.LensMount = LIBRAW_MOUNT_Minolta_A; break; case 44: // Metabones Canon EF Smart Adapter case 78: // Metabones Canon EF Smart Adapter Mark III or Other Adapter case 184: // Metabones Canon EF Speed Booster Ultra case 234: // Metabones Canon EF Smart Adapter Mark IV case 239: // Metabones Canon EF Speed Booster ilm.LensMount = LIBRAW_MOUNT_Canon_EF; break; } } } else ilm.LensID = lid2; if ((lid2 >= 50481) && (lid2 < 50500)) { strcpy(ilm.Adapter, "MC-11"); ilm.AdapterID = 0x4900; } else if ((lid2 > 0xef00) && (lid2 < 0xffff) && (lid2 != 0xff00)) { ilm.AdapterID = 0xef00; ilm.LensID -= ilm.AdapterID; ilm.LensMount = LIBRAW_MOUNT_Canon_EF; } return; } void LibRaw::parseSonyLensFeatures(uchar a, uchar b) { ushort features; features = (((ushort)a) << 8) | ((ushort)b); if ((ilm.LensMount == LIBRAW_MOUNT_Canon_EF) || (ilm.LensMount != LIBRAW_MOUNT_Sigma_X3F) || !features) return; ilm.LensFeatures_pre[0] = 0; ilm.LensFeatures_suf[0] = 0; if ((features & 0x0200) && (features & 0x0100)) strcpy(ilm.LensFeatures_pre, "E"); else if (features & 0x0200) strcpy(ilm.LensFeatures_pre, "FE"); else if (features & 0x0100) strcpy(ilm.LensFeatures_pre, "DT"); if (!ilm.LensFormat && !ilm.LensMount) { ilm.LensFormat = LIBRAW_FORMAT_FF; ilm.LensMount = LIBRAW_MOUNT_Minolta_A; if ((features & 0x0200) && (features & 0x0100)) { ilm.LensFormat = LIBRAW_FORMAT_APSC; ilm.LensMount = LIBRAW_MOUNT_Sony_E; } else if (features & 0x0200) { ilm.LensMount = LIBRAW_MOUNT_Sony_E; } else if (features & 0x0100) { ilm.LensFormat = LIBRAW_FORMAT_APSC; } } if (features & 0x4000) strnXcat(ilm.LensFeatures_pre, " PZ"); if (features & 0x0008) strnXcat(ilm.LensFeatures_suf, " G"); else if (features & 0x0004) strnXcat(ilm.LensFeatures_suf, " ZA"); if ((features & 0x0020) && (features & 0x0040)) strnXcat(ilm.LensFeatures_suf, " Macro"); else if (features & 0x0020) strnXcat(ilm.LensFeatures_suf, " STF"); else if (features & 0x0040) strnXcat(ilm.LensFeatures_suf, " Reflex"); else if (features & 0x0080) strnXcat(ilm.LensFeatures_suf, " Fisheye"); if (features & 0x0001) strnXcat(ilm.LensFeatures_suf, " SSM"); else if (features & 0x0002) strnXcat(ilm.LensFeatures_suf, " SAM"); if (features & 0x8000) strnXcat(ilm.LensFeatures_suf, " OSS"); if (features & 0x2000) strnXcat(ilm.LensFeatures_suf, " LE"); if (features & 0x0800) strnXcat(ilm.LensFeatures_suf, " II"); if (ilm.LensFeatures_suf[0] == ' ') memmove(ilm.LensFeatures_suf, ilm.LensFeatures_suf + 1, strbuflen(ilm.LensFeatures_suf) - 1); return; } void LibRaw::process_Sony_0x0116(uchar *buf, ushort len, unsigned long long id) { int i = 0; if (((id == SonyID_DSLR_A900) || (id == SonyID_DSLR_A900_APSC) || (id == SonyID_DSLR_A850) || (id == SonyID_DSLR_A850_APSC)) && (len >= 2)) i = 1; else if ((id >= SonyID_DSLR_A550) && (len >= 3)) i = 2; else return; imCommon.BatteryTemperature = (float)(buf[i] - 32) / 1.8f; } void LibRaw::process_Sony_0x2010(uchar *buf, ushort len) { if (imSony.group2010 == LIBRAW_SONY_Tag2010None) return; if ((imSony.real_iso_offset != 0xffff) && (len >= (imSony.real_iso_offset + 2)) && (imCommon.real_ISO < 0.1f)) { uchar s[2]; s[0] = SonySubstitution[buf[imSony.real_iso_offset]]; s[1] = SonySubstitution[buf[imSony.real_iso_offset + 1]]; imCommon.real_ISO = 100.0f * libraw_powf64l(2.0f, (16 - ((float)sget2(s)) / 256.0f)); } if ((imSony.MeteringMode_offset != 0xffff) && (imSony.ExposureProgram_offset != 0xffff) && (len >= (imSony.MeteringMode_offset + 2))) { imgdata.shootinginfo.MeteringMode = SonySubstitution[buf[imSony.MeteringMode_offset]]; imgdata.shootinginfo.ExposureProgram = SonySubstitution[buf[imSony.ExposureProgram_offset]]; } if ((imSony.ReleaseMode2_offset != 0xffff) && (len >= (imSony.ReleaseMode2_offset + 2))) { imgdata.shootinginfo.DriveMode = SonySubstitution[buf[imSony.ReleaseMode2_offset]]; } } void LibRaw::process_Sony_0x9050(uchar *buf, ushort len, unsigned long long id) { ushort lid; uchar s[4]; int c; if ((imSony.group9050 == LIBRAW_SONY_Tag9050None) && (imSony.CameraType != LIBRAW_SONY_DSC) && (imSony.CameraType != LIBRAW_SONY_DSLR)) imSony.group9050 = LIBRAW_SONY_Tag9050a; if (imSony.group9050 == LIBRAW_SONY_Tag9050None) return; if ((ilm.CameraMount != LIBRAW_MOUNT_Sony_E) && (imSony.CameraType != LIBRAW_SONY_DSC)) { if (len < 2) return; if (buf[0]) ilm.MaxAp4CurFocal = my_roundf( libraw_powf64l(2.0f, ((float)SonySubstitution[buf[0]] / 8.0 - 1.06f) / 2.0f) * 10.0f) / 10.0f; if (buf[1]) ilm.MinAp4CurFocal = my_roundf( libraw_powf64l(2.0f, ((float)SonySubstitution[buf[1]] / 8.0 - 1.06f) / 2.0f) * 10.0f) / 10.0f; } if ((imSony.group9050 == LIBRAW_SONY_Tag9050b) || (imSony.group9050 == LIBRAW_SONY_Tag9050c)) { if (len <= 0x8d) return; unsigned long long b88 = SonySubstitution[buf[0x88]]; unsigned long long b89 = SonySubstitution[buf[0x89]]; unsigned long long b8a = SonySubstitution[buf[0x8a]]; unsigned long long b8b = SonySubstitution[buf[0x8b]]; unsigned long long b8c = SonySubstitution[buf[0x8c]]; unsigned long long b8d = SonySubstitution[buf[0x8d]]; sprintf(imgdata.shootinginfo.InternalBodySerial, "%06llx", (b88 << 40) + (b89 << 32) + (b8a << 24) + (b8b << 16) + (b8c << 8) + b8d); } else if (imSony.group9050 == LIBRAW_SONY_Tag9050a) { if ((ilm.CameraMount == LIBRAW_MOUNT_Sony_E) && (id != SonyID_NEX_5N) && (id != SonyID_NEX_7) && (id != SonyID_NEX_VG20)) { if (len <= 0x7f) return; unsigned b7c = SonySubstitution[buf[0x7c]]; unsigned b7d = SonySubstitution[buf[0x7d]]; unsigned b7e = SonySubstitution[buf[0x7e]]; unsigned b7f = SonySubstitution[buf[0x7f]]; sprintf(imgdata.shootinginfo.InternalBodySerial, "%04x", (b7c << 24) + (b7d << 16) + (b7e << 8) + b7f); } else if (ilm.CameraMount == LIBRAW_MOUNT_Minolta_A) { if (len <= 0xf4) return; unsigned long long bf0 = SonySubstitution[buf[0xf0]]; unsigned long long bf1 = SonySubstitution[buf[0xf1]]; unsigned long long bf2 = SonySubstitution[buf[0xf2]]; unsigned long long bf3 = SonySubstitution[buf[0xf3]]; unsigned long long bf4 = SonySubstitution[buf[0xf4]]; sprintf(imgdata.shootinginfo.InternalBodySerial, "%05llx", (bf0 << 32) + (bf1 << 24) + (bf2 << 16) + (bf3 << 8) + bf4); } } if (imSony.CameraType != LIBRAW_SONY_DSC) { if (len <= 0x106) return; if (buf[0x3d] | buf[0x3c]) { lid = SonySubstitution[buf[0x3d]] << 8 | SonySubstitution[buf[0x3c]]; ilm.CurAp = libraw_powf64l(2.0f, ((float)lid / 256.0f - 16.0f) / 2.0f); } if (buf[0x105] && (ilm.LensMount != LIBRAW_MOUNT_Canon_EF) && (ilm.LensMount != LIBRAW_MOUNT_Sigma_X3F)) { switch (SonySubstitution[buf[0x105]]) { case 1: ilm.LensMount = LIBRAW_MOUNT_Minolta_A; break; case 2: ilm.LensMount = LIBRAW_MOUNT_Sony_E; break; } } if (buf[0x106]) { switch (SonySubstitution[buf[0x106]]) { case 1: ilm.LensFormat = LIBRAW_FORMAT_APSC; break; case 2: ilm.LensFormat = LIBRAW_FORMAT_FF; break; } } } if (ilm.CameraMount == LIBRAW_MOUNT_Sony_E) { if (len <= 0x108) return; parseSonyLensType2( SonySubstitution[buf[0x0108]], // LensType2 - Sony lens ids SonySubstitution[buf[0x0107]]); } if (len <= 0x10a) return; if ((ilm.LensID == LIBRAW_LENS_NOT_SET) && (ilm.CameraMount == LIBRAW_MOUNT_Minolta_A) && (buf[0x010a] | buf[0x0109])) { ilm.LensID = // LensType - Minolta/Sony lens ids SonySubstitution[buf[0x010a]] << 8 | SonySubstitution[buf[0x0109]]; if ((ilm.LensID > 0x4900) && (ilm.LensID <= 0x5900)) { ilm.AdapterID = 0x4900; ilm.LensID -= ilm.AdapterID; ilm.LensMount = LIBRAW_MOUNT_Sigma_X3F; strcpy(ilm.Adapter, "MC-11"); } else if ((ilm.LensID > 0xef00) && (ilm.LensID < 0xffff) && (ilm.LensID != 0xff00)) { ilm.AdapterID = 0xef00; ilm.LensID -= ilm.AdapterID; ilm.LensMount = LIBRAW_MOUNT_Canon_EF; } } if ((id >= SonyID_SLT_A65) && (id <= SonyID_NEX_F3)) { if (len <= 0x116) return; // "SLT-A65", "SLT-A77", "NEX-7", "NEX-VG20", // "SLT-A37", "SLT-A57", "NEX-F3", "Lunar" parseSonyLensFeatures(SonySubstitution[buf[0x115]], SonySubstitution[buf[0x116]]); } else if (ilm.CameraMount != LIBRAW_MOUNT_FixedLens) { if (len <= 0x117) return; parseSonyLensFeatures(SonySubstitution[buf[0x116]], SonySubstitution[buf[0x117]]); } if ((imSony.ImageCount3_offset != 0xffff) && (len >= (imSony.ImageCount3_offset + 4))) { FORC4 s[c] = SonySubstitution[buf[imSony.ImageCount3_offset + c]]; imSony.ImageCount3 = sget4(s); } return; } void LibRaw::process_Sony_0x9400(uchar *buf, ushort len, unsigned long long /*id*/) { uchar s[4]; int c; uchar bufx = buf[0]; if (((bufx == 0x23) || (bufx == 0x24) || (bufx == 0x26) || (bufx == 0x28) || (bufx == 0x31)) && (len >= 0x1f)) // 0x9400 'c' version { imSony.Sony0x9400_version = 0xc; imSony.Sony0x9400_ReleaseMode2 = SonySubstitution[buf[0x09]]; if ((imSony.group2010 == LIBRAW_SONY_Tag2010g) || (imSony.group2010 == LIBRAW_SONY_Tag2010h)) { FORC4 s[c] = SonySubstitution[buf[0x0a + c]]; imSony.ShotNumberSincePowerUp = sget4(s); } else { imSony.ShotNumberSincePowerUp = SonySubstitution[buf[0x0a]]; } FORC4 s[c] = SonySubstitution[buf[0x12 + c]]; imSony.Sony0x9400_SequenceImageNumber = sget4(s); imSony.Sony0x9400_SequenceLength1 = SonySubstitution[buf[0x16]]; // shots FORC4 s[c] = SonySubstitution[buf[0x1a + c]]; imSony.Sony0x9400_SequenceFileNumber = sget4(s); imSony.Sony0x9400_SequenceLength2 = SonySubstitution[buf[0x1e]]; // files } else if ((bufx == 0x0c) && (len >= 0x1f)) // 0x9400 'b' version { imSony.Sony0x9400_version = 0xb; FORC4 s[c] = SonySubstitution[buf[0x08 + c]]; imSony.Sony0x9400_SequenceImageNumber = sget4(s); FORC4 s[c] = SonySubstitution[buf[0x0c + c]]; imSony.Sony0x9400_SequenceFileNumber = sget4(s); imSony.Sony0x9400_ReleaseMode2 = SonySubstitution[buf[0x10]]; imSony.Sony0x9400_SequenceLength1 = SonySubstitution[buf[0x1e]]; } else if ((bufx == 0x0a) && (len >= 0x23)) // 0x9400 'a' version { imSony.Sony0x9400_version = 0xa; FORC4 s[c] = SonySubstitution[buf[0x08 + c]]; imSony.Sony0x9400_SequenceImageNumber = sget4(s); FORC4 s[c] = SonySubstitution[buf[0x0c + c]]; imSony.Sony0x9400_SequenceFileNumber = sget4(s); imSony.Sony0x9400_ReleaseMode2 = SonySubstitution[buf[0x10]]; imSony.Sony0x9400_SequenceLength1 = SonySubstitution[buf[0x22]]; } else return; } void LibRaw::process_Sony_0x9402(uchar *buf, ushort len) { if (len < 0x17) return; if ((imSony.CameraType == LIBRAW_SONY_SLT) || (imSony.CameraType == LIBRAW_SONY_ILCA) || (buf[0x00] == 0x05) || (buf[0x00] == 0xff)) return; if (buf[0x02] == 0xff) { imCommon.AmbientTemperature = (float)((short)SonySubstitution[buf[0x04]]); } if (imgdata.shootinginfo.FocusMode == LIBRAW_SONY_FOCUSMODE_UNKNOWN) { imgdata.shootinginfo.FocusMode = SonySubstitution[buf[0x16]]&0x7f; } if (len >= 0x18) imSony.AFAreaMode = (uint16_t)SonySubstitution[buf[0x17]]; if ((len >= 0x2e) && (imSony.CameraType != LIBRAW_SONY_DSC)) { imSony.FocusPosition = (ushort)SonySubstitution[buf[0x2d]]; // FocusPosition2 } return; } void LibRaw::process_Sony_0x9403(uchar *buf, ushort len) { if ((len < 6) || (unique_id == SonyID_ILCE_7C)) return; uchar bufx = SonySubstitution[buf[4]]; if ((bufx == 0x00) || (bufx == 0x94)) return; imCommon.SensorTemperature = (float)((short)SonySubstitution[buf[5]]); return; } void LibRaw::process_Sony_0x9406(uchar *buf, ushort len) { if (len < 6) return; uchar bufx = buf[0]; if ((bufx != 0x01) && (bufx != 0x08) && (bufx != 0x1b)) return; bufx = buf[2]; if ((bufx != 0x08) && (bufx != 0x1b)) return; imCommon.BatteryTemperature = (float)(SonySubstitution[buf[5]] - 32) / 1.8f; return; } void LibRaw::process_Sony_0x940c(uchar *buf, ushort len) { if ((imSony.CameraType != LIBRAW_SONY_ILCE) && (imSony.CameraType != LIBRAW_SONY_NEX)) return; if (len <= 0x000a) return; ushort lid2; if ((ilm.LensMount != LIBRAW_MOUNT_Canon_EF) && (ilm.LensMount != LIBRAW_MOUNT_Sigma_X3F)) { switch (SonySubstitution[buf[0x0008]]) { case 1: case 5: ilm.LensMount = LIBRAW_MOUNT_Minolta_A; break; case 4: ilm.LensMount = LIBRAW_MOUNT_Sony_E; break; } } if (ilm.LensMount != LIBRAW_MOUNT_Unknown) { lid2 = (((ushort)SonySubstitution[buf[0x000a]]) << 8) | ((ushort)SonySubstitution[buf[0x0009]]); if ((lid2 > 0) && ((lid2 < 32784) || (ilm.LensID == 0x1999) || (ilm.LensID == 0xffff))) parseSonyLensType2( SonySubstitution[buf[0x000a]], // LensType2 - Sony lens ids SonySubstitution[buf[0x0009]]); if ((lid2 == 44) || (lid2 == 78) || (lid2 == 184) || (lid2 == 234) || (lid2 == 239)) ilm.AdapterID = lid2; } return; } void LibRaw::process_Sony_0x940e(uchar *buf, ushort len, unsigned long long id) { if (len < 3) return; if (((imSony.CameraType != LIBRAW_SONY_SLT) && (imSony.CameraType != LIBRAW_SONY_ILCA)) || (id == SonyID_SLT_A33) || (id == SonyID_SLT_A35) || (id == SonyID_SLT_A55)) return; int c; imSony.AFType = SonySubstitution[buf[0x02]]; if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) { unsigned tag = 0x940e; imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; imCommon.afdata[imCommon.afcount].AFInfoData_order = order; imCommon.afdata[imCommon.afcount].AFInfoData_length = len; imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length); FORC((int)imCommon.afdata[imCommon.afcount].AFInfoData_length) imCommon.afdata[imCommon.afcount].AFInfoData[c] = SonySubstitution[buf[c]]; imCommon.afcount++; } if (imSony.CameraType == LIBRAW_SONY_ILCA) { if (len >= 0x0051) { imgdata.shootinginfo.FocusMode = SonySubstitution[buf[0x05]]; imSony.nAFPointsUsed = MIN(10, sizeof imSony.AFPointsUsed); FORC(imSony.nAFPointsUsed) imSony.AFPointsUsed[c] = SonySubstitution[buf[0x10 +c]]; imSony.AFAreaMode = (uint16_t)SonySubstitution[buf[0x3a]]; imSony.AFMicroAdjValue = SonySubstitution[buf[0x0050]]; if (!imSony.AFMicroAdjValue) imSony.AFMicroAdjValue = 0x7f; else imSony.AFMicroAdjOn = 1; } } else { if (len >= 0x017e) { imSony.AFAreaMode = (uint16_t)SonySubstitution[buf[0x0a]]; imgdata.shootinginfo.FocusMode = SonySubstitution[buf[0x0b]]; imSony.nAFPointsUsed = MIN(4, sizeof imSony.AFPointsUsed); FORC(imSony.nAFPointsUsed) imSony.AFPointsUsed[c] = SonySubstitution[buf[0x016e +c]]; imSony.AFMicroAdjValue = SonySubstitution[buf[0x017d]]; if (!imSony.AFMicroAdjValue) imSony.AFMicroAdjValue = 0x7f; else imSony.AFMicroAdjOn = 1; } } } void LibRaw::parseSonyMakernotes( int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer, uchar *&table_buf_0x0116, ushort &table_buf_0x0116_len, uchar *&table_buf_0x2010, ushort &table_buf_0x2010_len, uchar *&table_buf_0x9050, ushort &table_buf_0x9050_len, uchar *&table_buf_0x9400, ushort &table_buf_0x9400_len, uchar *&table_buf_0x9402, ushort &table_buf_0x9402_len, uchar *&table_buf_0x9403, ushort &table_buf_0x9403_len, uchar *&table_buf_0x9406, ushort &table_buf_0x9406_len, uchar *&table_buf_0x940c, ushort &table_buf_0x940c_len, uchar *&table_buf_0x940e, ushort &table_buf_0x940e_len) { ushort lid, a, c, d; uchar *table_buf; uchar uc; uchar s[2]; int LensDataValid = 0; unsigned uitemp; // printf ("==>> tag 0x%x, len %d, type %d, model =%s=, cam.id 0x%llx, cam.type %d, =%s=\n", // tag, len, type, model, ilm.CamID, imSony.CameraType, imSony.MetaVersion); if (tag == 0xb001) // Sony ModelID { unique_id = get2(); setSonyBodyFeatures(unique_id); if (table_buf_0x0116_len) { process_Sony_0x0116(table_buf_0x0116, table_buf_0x0116_len, unique_id); free(table_buf_0x0116); table_buf_0x0116_len = 0; } if (table_buf_0x2010_len) { process_Sony_0x2010(table_buf_0x2010, table_buf_0x2010_len); free(table_buf_0x2010); table_buf_0x2010_len = 0; } if (table_buf_0x9050_len) { process_Sony_0x9050(table_buf_0x9050, table_buf_0x9050_len, unique_id); free(table_buf_0x9050); table_buf_0x9050_len = 0; } if (table_buf_0x9400_len) { process_Sony_0x9400(table_buf_0x9400, table_buf_0x9400_len, unique_id); free(table_buf_0x9400); table_buf_0x9400_len = 0; } if (table_buf_0x9402_len) { process_Sony_0x9402(table_buf_0x9402, table_buf_0x9402_len); free(table_buf_0x9402); table_buf_0x9402_len = 0; } if (table_buf_0x9403_len) { process_Sony_0x9403(table_buf_0x9403, table_buf_0x9403_len); free(table_buf_0x9403); table_buf_0x9403_len = 0; } if (table_buf_0x9406_len) { process_Sony_0x9406(table_buf_0x9406, table_buf_0x9406_len); free(table_buf_0x9406); table_buf_0x9406_len = 0; } if (table_buf_0x940c_len) { process_Sony_0x940c(table_buf_0x940c, table_buf_0x940c_len); free(table_buf_0x940c); table_buf_0x940c_len = 0; } if (table_buf_0x940e_len) { process_Sony_0x940e(table_buf_0x940e, table_buf_0x940e_len, unique_id); free(table_buf_0x940e); table_buf_0x940e_len = 0; } } else if (tag == 0xb000) { FORC4 imSony.FileFormat = imSony.FileFormat * 10 + fgetc(ifp); } else if (tag == 0xb026) { uitemp = get4(); if (uitemp != 0xffffffff) imgdata.shootinginfo.ImageStabilization = uitemp; } else if (((tag == 0x0001) || // Minolta CameraSettings, big endian (tag == 0x0003)) && (len >= 196)) { table_buf = (uchar *)calloc(len,1); fread(table_buf, len, 1, ifp); lid = 0x01 << 2; imgdata.shootinginfo.ExposureMode = (unsigned)table_buf[lid] << 24 | (unsigned)table_buf[lid + 1] << 16 | (unsigned)table_buf[lid + 2] << 8 | (unsigned)table_buf[lid + 3]; lid = 0x06 << 2; imgdata.shootinginfo.DriveMode = (unsigned)table_buf[lid] << 24 | (unsigned)table_buf[lid + 1] << 16 | (unsigned)table_buf[lid + 2] << 8 | (unsigned)table_buf[lid + 3]; lid = 0x07 << 2; imgdata.shootinginfo.MeteringMode = (unsigned)table_buf[lid] << 24 | (unsigned)table_buf[lid + 1] << 16 | (unsigned)table_buf[lid + 2] << 8 | (unsigned)table_buf[lid + 3]; lid = 0x25 << 2; imSony.MinoltaCamID = (unsigned)table_buf[lid] << 24 | (unsigned)table_buf[lid + 1] << 16 | (unsigned)table_buf[lid + 2] << 8 | (unsigned)table_buf[lid + 3]; if (imSony.MinoltaCamID != 0xffffffff) ilm.CamID = imSony.MinoltaCamID; lid = 0x30 << 2; imgdata.shootinginfo.FocusMode = table_buf[lid + 3]?LIBRAW_SONY_FOCUSMODE_MF:LIBRAW_SONY_FOCUSMODE_AF; free(table_buf); } else if ((tag == 0x0004) && // Minolta CameraSettings7D, big endian (len >= 227)) { table_buf = (uchar *)calloc(len,1); fread(table_buf, len, 1, ifp); lid = 0x0; imgdata.shootinginfo.ExposureMode = (ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1]; lid = 0x0e << 1; imgdata.shootinginfo.FocusMode = (short)table_buf[lid + 1]; switch (imgdata.shootinginfo.FocusMode) { case 0: case 1: imgdata.shootinginfo.FocusMode += 2; break; case 3: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_MF; break; } lid = 0x10 << 1; imgdata.shootinginfo.AFPoint = (ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1]; lid = 0x25 << 1; switch ((ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1]) { case 0: case 1: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 4: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } lid = 0x71 << 1; imgdata.shootinginfo.ImageStabilization = (ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1]; free(table_buf); } else if ((tag == 0x0010) && // CameraInfo strncasecmp(model, "DSLR-A100", 9) && !strncasecmp(make, "SONY", 4) && ((len == 368) || // a700 : CameraInfo (len == 5478) || // a850, a900 : CameraInfo (len == 5506) || // a200, a300, a350 : CameraInfo2 (len == 6118) || // a230, a290, a330, a380, a390 : CameraInfo2 (len == 15360)) // a450, a500, a550, a560, a580 : CameraInfo3 // a33, a35, a55 // NEX-3, NEX-5, NEX-5C, NEX-C3, NEX-VG10E ) { table_buf = (uchar *)calloc(len,1); fread(table_buf, len, 1, ifp); if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) { imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; imCommon.afdata[imCommon.afcount].AFInfoData_order = order; imCommon.afdata[imCommon.afcount].AFInfoData_length = len; imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length); memcpy(imCommon.afdata[imCommon.afcount].AFInfoData, table_buf, imCommon.afdata[imCommon.afcount].AFInfoData_length); imCommon.afcount++; } if (memcmp(table_buf, "\xff\xff\xff\xff\xff\xff\xff\xff", 8) && memcmp(table_buf, "\x00\x00\x00\x00\x00\x00\x00\x00", 8)) { LensDataValid = 1; } switch (len) { case 368: // a700: CameraInfo case 5478: // a850, a900: CameraInfo if ((!dng_writer) || (saneSonyCameraInfo(table_buf[0], table_buf[3], table_buf[2], table_buf[5], table_buf[4], table_buf[7]))) { if (LensDataValid) { if (table_buf[0] | table_buf[3]) ilm.MinFocal = bcd2dec(table_buf[0]) * 100 + bcd2dec(table_buf[3]); if (table_buf[2] | table_buf[5]) ilm.MaxFocal = bcd2dec(table_buf[2]) * 100 + bcd2dec(table_buf[5]); if (table_buf[4]) ilm.MaxAp4MinFocal = bcd2dec(table_buf[4]) / 10.0f; if (table_buf[4]) ilm.MaxAp4MaxFocal = bcd2dec(table_buf[7]) / 10.0f; parseSonyLensFeatures(table_buf[1], table_buf[6]); } imSony.AFPointSelected = table_buf[21]; imgdata.shootinginfo.AFPoint = (ushort)table_buf[25]; if (len == 5478) { imSony.AFMicroAdjValue = table_buf[0x130] - 20; imSony.AFMicroAdjOn = (((table_buf[0x131] & 0x80) == 0x80) ? 1 : 0); imSony.AFMicroAdjRegisteredLenses = table_buf[0x131] & 0x7f; } } break; default: // CameraInfo2 & 3 if ((!dng_writer) || (saneSonyCameraInfo(table_buf[1], table_buf[2], table_buf[3], table_buf[4], table_buf[5], table_buf[6]))) { if ((LensDataValid) && strncasecmp(model, "NEX-5C", 6)) { if (table_buf[1] | table_buf[2]) ilm.MinFocal = bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]); if (table_buf[3] | table_buf[4]) ilm.MaxFocal = bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]); if (table_buf[5]) ilm.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f; if (table_buf[6]) ilm.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f; parseSonyLensFeatures(table_buf[0], table_buf[7]); } if ( // CameraInfo2 (len == 5506) || // a200, a300, a350 (len == 6118)) // a230, a290, a330, a380, a390 { imSony.AFPointSelected = table_buf[0x14]; } else if (!strncasecmp(model, "DSLR-A450", 9) || !strncasecmp(model, "DSLR-A500", 9) || !strncasecmp(model, "DSLR-A550", 9)) { imSony.AFPointSelected = table_buf[0x14]; if (table_buf[0x15]) /* focus mode values translated to values in tag 0x201b */ imgdata.shootinginfo.FocusMode = table_buf[0x15]+1; else imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_MF; imgdata.shootinginfo.AFPoint = (ushort)table_buf[0x18]; } else if (!strncasecmp(model, "SLT-", 4) || !strncasecmp(model, "DSLR-A560", 9) || !strncasecmp(model, "DSLR-A580", 9)) { imSony.AFPointSelected = table_buf[0x1c]; if (table_buf[0x1d]) imgdata.shootinginfo.FocusMode = table_buf[0x1d]+1; else imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_MF; imgdata.shootinginfo.AFPoint = (ushort)table_buf[0x20]; } } } free(table_buf); } else if ((!dng_writer) && ((tag == 0x0020) || (tag == 0xb0280020))) { if (!strncasecmp(model, "DSLR-A100", 9)) // WBInfoA100 { fseek(ifp, 0x49dc, SEEK_CUR); stmread(imgdata.shootinginfo.InternalBodySerial, 13, ifp); } else if ((len == 19154) || // a200 a230 a290 a300 a330 a350 a380 a390 : FocusInfo (len == 19148)) // a700 a850 a900 : FocusInfo { table_buf = (uchar *)calloc(0x0080,1); fread(table_buf, 0x0080, 1, ifp); imgdata.shootinginfo.DriveMode = table_buf[14]; imgdata.shootinginfo.ExposureProgram = table_buf[63]; free(table_buf); fseek (ifp, 0x09bb - 0x0080, SEEK_CUR); // offset 2491 from the start of tag 0x0020 imSony.FocusPosition = (ushort)fgetc(ifp); } else if (len == 20480) // a450 a500 a550 a560 a580 a33 a35 a55 : MoreInfo // NEX-3 NEX-5 NEX-C3 NEX-VG10E : MoreInfo { a = get2(); /*b =*/ get2(); c = get2(); d = get2(); if ((a) && (c == 1)) { fseek(ifp, INT64(d) - 8LL, SEEK_CUR); table_buf = (uchar *)calloc(256,1); fread(table_buf, 256, 1, ifp); imgdata.shootinginfo.DriveMode = table_buf[1]; imgdata.shootinginfo.ExposureProgram = table_buf[2]; imgdata.shootinginfo.MeteringMode = table_buf[3]; switch (table_buf[6]) { case 1: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 2: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } if (strncasecmp(model, "DSLR-A450", 9) && strncasecmp(model, "DSLR-A500", 9) && strncasecmp(model, "DSLR-A550", 9)) { // NEX-3, NEX-5, NEX-5C??, NEX-C3, NEX-VG10(E), a560, a580, a33, a35, a55 imgdata.shootinginfo.FocusMode = table_buf[0x13]; switch (table_buf[0x13]) { case 17: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_AF_S; break; case 18: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_AF_C; break; case 19: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_AF_A; break; case 32: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_MF; break; case 48: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_DMF; break; default: imgdata.shootinginfo.FocusMode = table_buf[0x13]; break; } if (!strncasecmp(model, "DSLR-A560", 9) || !strncasecmp(model, "DSLR-A580", 9) || !strncasecmp(model, "SLT-A33", 7) || !strncasecmp(model, "SLT-A35", 7) || !strncasecmp(model, "SLT-A55", 7) || !strncasecmp(model, "NEX-VG10", 8) || !strncasecmp(model, "NEX-C3", 6)) imSony.FocusPosition = (ushort)table_buf[0x2f]; // FocusPosition2 else // NEX-3, NEX-5, NEX-5C imSony.FocusPosition = (ushort)table_buf[0x2b]; // FocusPosition2 } else // a450 a500 a550 { imSony.FocusPosition = (ushort)table_buf[0x29]; // FocusPosition2 } free(table_buf); } } } else if (tag == 0x0102) { imSony.Quality = get4(); } else if (tag == 0x0104) { imCommon.FlashEC = getreal(type); } else if (tag == 0x0105) // Teleconverter { ilm.TeleconverterID = get4(); } else if (tag == 0x0107) { uitemp = get4(); if (uitemp == 1) imgdata.shootinginfo.ImageStabilization = 0; else if (uitemp == 5) imgdata.shootinginfo.ImageStabilization = 1; else imgdata.shootinginfo.ImageStabilization = uitemp; } else if ((tag == 0xb0280088) && (dng_writer == nonDNG)) { thumb_offset = get4() + base; } else if ((tag == 0xb0280089) && (dng_writer == nonDNG)) { thumb_length = get4(); } else if (((tag == 0x0114) || // CameraSettings (tag == 0xb0280114)) && (len < 256000)) { table_buf = (uchar *)calloc(len,1); fread(table_buf, len, 1, ifp); switch (len) { case 260: // Sony a100, big endian imgdata.shootinginfo.ExposureMode = ((ushort)table_buf[0]) << 8 | ((ushort)table_buf[1]); lid = 0x0a << 1; imgdata.shootinginfo.DriveMode = ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); lid = 0x0c << 1; imgdata.shootinginfo.FocusMode = ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); switch (imgdata.shootinginfo.FocusMode) { case 0: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_AF_S; break; case 1: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_AF_C; break; case 5: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_MF; break; } lid = 0x0d << 1; imSony.AFPointSelected = table_buf[lid + 1]; lid = 0x0e << 1; imSony.AFAreaMode = (uint16_t)table_buf[lid + 1]; lid = 0x12 << 1; imgdata.shootinginfo.MeteringMode = ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); lid = 0x17 << 1; switch ((ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1]) { case 0: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 2: imCommon.ColorSpace = LIBRAW_COLORSPACE_MonochromeGamma; break; case 5: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } break; case 448: // Minolta "DYNAX 5D" and its aliases, big endian lid = 0x0a << 1; imgdata.shootinginfo.ExposureMode = ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); lid = 0x25 << 1; imgdata.shootinginfo.MeteringMode = ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); lid = 0x2f << 1; switch ((ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1]) { case 0: case 1: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 2: imCommon.ColorSpace = LIBRAW_COLORSPACE_MonochromeGamma; break; case 4: case 5: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } lid = 0xbd << 1; imgdata.shootinginfo.ImageStabilization = ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); break; case 280: // a200 a300 a350 a700 case 364: // a850 a900 // CameraSettings and CameraSettings2 are big endian if (table_buf[2] | table_buf[3]) { lid = (((ushort)table_buf[2]) << 8) | ((ushort)table_buf[3]); ilm.CurAp = libraw_powf64l(2.0f, ((float)lid / 8.0f - 1.0f) / 2.0f); } lid = 0x04 << 1; imgdata.shootinginfo.DriveMode = table_buf[lid + 1]; lid = 0x11 << 1; imSony.AFAreaMode = (uint16_t)table_buf[lid + 1]; lid = 0x1b << 1; switch (((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1])) { case 0: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 1: case 5: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } lid = 0x4d << 1; imgdata.shootinginfo.FocusMode = ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); switch (imgdata.shootinginfo.FocusMode) { case 1: case 2: case 3: imgdata.shootinginfo.FocusMode++; break; case 4: imgdata.shootinginfo.FocusMode +=2; break; } if (!imCommon.ColorSpace || (imCommon.ColorSpace == LIBRAW_COLORSPACE_Unknown)) { lid = 0x83 << 1; switch (((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1])) { case 6: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 5: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } } break; case 332: // a230 a290 a330 a380 a390 // CameraSettings and CameraSettings2 are big endian if (table_buf[2] | table_buf[3]) { lid = (((ushort)table_buf[2]) << 8) | ((ushort)table_buf[3]); ilm.CurAp = libraw_powf64l(2.0f, ((float)lid / 8.0f - 1.0f) / 2.0f); } lid = 0x10 << 1; imSony.AFAreaMode = (uint16_t)table_buf[lid + 1]; lid = 0x4d << 1; imgdata.shootinginfo.FocusMode = ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); switch (imgdata.shootinginfo.FocusMode) { case 1: case 2: case 3: imgdata.shootinginfo.FocusMode++; break; case 4: imgdata.shootinginfo.FocusMode +=2; break; } lid = 0x7e << 1; imgdata.shootinginfo.DriveMode = table_buf[lid + 1]; break; case 1536: // a560 a580 a33 a35 a55 NEX-3 NEX-5 NEX-5C NEX-C3 NEX-VG10E case 2048: // a450 a500 a550 // CameraSettings3 are little endian switch (table_buf[0x0e]) { case 1: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; break; case 2: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; } imSony.AFAreaMode = (uint16_t)table_buf[0x24]; imgdata.shootinginfo.DriveMode = table_buf[0x34]; parseSonyLensType2(table_buf[1016], table_buf[1015]); if (ilm.LensMount != LIBRAW_MOUNT_Canon_EF) { switch (table_buf[153]) { case 16: ilm.LensMount = LIBRAW_MOUNT_Minolta_A; break; case 17: ilm.LensMount = LIBRAW_MOUNT_Sony_E; break; } } break; } free(table_buf); } else if ((tag == 0x3000) && (len < 256000)) { table_buf = (uchar *)calloc(len,1); fread(table_buf, len, 1, ifp); if (len >= 0x19) { for (int i = 0; i < 20; i++) imSony.SonyDateTime[i] = table_buf[6 + i]; } if (len >= 0x43) // MetaVersion: (unique_id >= 286) { memcpy (imSony.MetaVersion, table_buf+0x34, 15); imSony.MetaVersion[15] = 0; } free(table_buf); } else if (tag == 0x0116 && len < 256000) { table_buf_0x0116 = (uchar *)calloc(len,1); table_buf_0x0116_len = len; fread(table_buf_0x0116, len, 1, ifp); if (ilm.CamID) { process_Sony_0x0116(table_buf_0x0116, table_buf_0x0116_len, ilm.CamID); free(table_buf_0x0116); table_buf_0x0116_len = 0; } } else if (tag == 0x2008) { imSony.LongExposureNoiseReduction = get4(); } else if (tag == 0x2009) { imSony.HighISONoiseReduction = get2(); } else if (tag == 0x200a) { imSony.HDR[0] = get2(); imSony.HDR[1] = get2(); } else if (tag == 0x2010 && len < 256000) { table_buf_0x2010 = (uchar *)calloc(len,1); table_buf_0x2010_len = len; fread(table_buf_0x2010, len, 1, ifp); if (ilm.CamID) { process_Sony_0x2010(table_buf_0x2010, table_buf_0x2010_len); free(table_buf_0x2010); table_buf_0x2010_len = 0; } } else if (tag == 0x201a) { imSony.ElectronicFrontCurtainShutter = get4(); } else if (tag == 0x201b) { if ((imSony.CameraType != LIBRAW_SONY_DSC) || (imSony.group2010 == LIBRAW_SONY_Tag2010i)) { short t = (short)fgetc(ifp); if (imgdata.shootinginfo.FocusMode != t) { imgdata.shootinginfo.FocusMode = t; } } } else if ((tag == 0x201c) && (len == 1) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_BYTE)) { imSony.AFAreaModeSetting = (uint8_t)fgetc(ifp); } else if ((tag == 0x201d) && (len == 2) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) { imSony.FlexibleSpotPosition[0] = get2(); imSony.FlexibleSpotPosition[1] = get2(); } else if (tag == 0x201e) { if (imSony.CameraType != LIBRAW_SONY_DSC) { imSony.AFPointSelected = imSony.AFPointSelected_0x201e = fgetc(ifp); } } else if (tag == 0x2020) // AFPointsUsed { if (imSony.CameraType != LIBRAW_SONY_DSC) { if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) { imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; imCommon.afdata[imCommon.afcount].AFInfoData_order = order; imCommon.afdata[imCommon.afcount].AFInfoData_length = len; imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length,1); fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); imSony.nAFPointsUsed = short(MIN(imCommon.afdata[imCommon.afcount].AFInfoData_length, sizeof imSony.AFPointsUsed)); memcpy(imSony.AFPointsUsed, imCommon.afdata[imCommon.afcount].AFInfoData, imSony.nAFPointsUsed); imCommon.afcount++; } } } else if (tag == 0x2021) // AFTracking { if ((imSony.CameraType != LIBRAW_SONY_DSC) || (imSony.group2010 == LIBRAW_SONY_Tag2010i)) { imSony.AFTracking = fgetc(ifp); } } else if (tag == 0x2022) // FocalPlaneAFPointsUsed { if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) { imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; imCommon.afdata[imCommon.afcount].AFInfoData_order = order; imCommon.afdata[imCommon.afcount].AFInfoData_length = len; imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length,1); fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); imCommon.afcount++; } } else if (tag == 0x2027) { FORC4 imSony.FocusLocation[c] = get2(); } else if (tag == 0x2028) { if (get2()) { imSony.VariableLowPassFilter = get2(); } } else if (tag == 0x2029) { imSony.RAWFileType = get2(); } else if (tag == 0x202c) { imSony.MeteringMode2 = get2(); } else if (tag == 0x202a) // FocalPlaneAFPointsUsed, newer?? { if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) { imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; imCommon.afdata[imCommon.afcount].AFInfoData_order = order; imCommon.afdata[imCommon.afcount].AFInfoData_length = len; imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length,1); fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); imCommon.afcount++; } } else if (tag == 0x202e) { imSony.RawSizeType = get2(); } else if (tag == 0x202f) { imSony.PixelShiftGroupID = get4(); imSony.PixelShiftGroupPrefix = imSony.PixelShiftGroupID >> 22; imSony.PixelShiftGroupID = ((imSony.PixelShiftGroupID >> 17) & (unsigned)0x1f) * (unsigned)1000000 + ((imSony.PixelShiftGroupID >> 12) & (unsigned)0x1f) * (unsigned)10000 + ((imSony.PixelShiftGroupID >> 6) & (unsigned)0x3f) * (unsigned)100 + (imSony.PixelShiftGroupID & (unsigned)0x3f); imSony.numInPixelShiftGroup = fgetc(ifp); imSony.nShotsInPixelShiftGroup = fgetc(ifp); } else if (tag == 0x9050 && len < 256000) // little endian { table_buf_0x9050 = (uchar *)calloc(len,1); table_buf_0x9050_len = len; fread(table_buf_0x9050, len, 1, ifp); if (ilm.CamID) { process_Sony_0x9050(table_buf_0x9050, table_buf_0x9050_len, ilm.CamID); free(table_buf_0x9050); table_buf_0x9050_len = 0; } } else if (tag == 0x9400 && len < 256000) { table_buf_0x9400 = (uchar *)calloc(len,1); table_buf_0x9400_len = len; fread(table_buf_0x9400, len, 1, ifp); if (ilm.CamID) { process_Sony_0x9400(table_buf_0x9400, table_buf_0x9400_len, unique_id); free(table_buf_0x9400); table_buf_0x9400_len = 0; } } else if (tag == 0x9402 && len < 256000) { table_buf_0x9402 = (uchar *)calloc(len,1); table_buf_0x9402_len = len; fread(table_buf_0x9402, len, 1, ifp); if (ilm.CamID) { process_Sony_0x9402(table_buf_0x9402, table_buf_0x9402_len); free(table_buf_0x9402); table_buf_0x9402_len = 0; } } else if (tag == 0x9403 && len < 256000) { table_buf_0x9403 = (uchar *)calloc(len,1); table_buf_0x9403_len = len; fread(table_buf_0x9403, len, 1, ifp); if (ilm.CamID) { process_Sony_0x9403(table_buf_0x9403, table_buf_0x9403_len); free(table_buf_0x9403); table_buf_0x9403_len = 0; } } else if ((tag == 0x9405) && (len < 256000) && (len > 0x64)) { table_buf = (uchar *)calloc(len,1); fread(table_buf, len, 1, ifp); uc = table_buf[0x0]; if (imCommon.real_ISO < 0.1f) { if ((uc == 0x25) || (uc == 0x3a) || (uc == 0x76) || (uc == 0x7e) || (uc == 0x8b) || (uc == 0x9a) || (uc == 0xb3) || (uc == 0xe1)) { s[0] = SonySubstitution[table_buf[0x04]]; s[1] = SonySubstitution[table_buf[0x05]]; imCommon.real_ISO = 100.0f * libraw_powf64l(2.0f, (16 - ((float)sget2(s)) / 256.0f)); } } free(table_buf); } else if ((tag == 0x9404) && (len < 256000) && (len > 0x21)) { table_buf = (uchar *)calloc(len,1); fread(table_buf, len, 1, ifp); uc = table_buf[0x00]; if (((uc == 0x70) || (uc == 0x8a) || (uc == 0xcd) || (uc == 0xe7) || (uc == 0xea)) && (table_buf[0x03] == 0x08)) { if ((imSony.CameraType == LIBRAW_SONY_ILCA) || (imSony.CameraType == LIBRAW_SONY_SLT)) { imSony.FocusPosition = (ushort)SonySubstitution[table_buf[0x20]]; // FocusPosition2 } } free(table_buf); } else if (tag == 0x9406 && len < 256000) { table_buf_0x9406 = (uchar *)calloc(len,1); table_buf_0x9406_len = len; fread(table_buf_0x9406, len, 1, ifp); if (ilm.CamID) { process_Sony_0x9406(table_buf_0x9406, table_buf_0x9406_len); free(table_buf_0x9406); table_buf_0x9406_len = 0; } } else if (tag == 0x940c && len < 256000) { table_buf_0x940c = (uchar *)calloc(len,1); table_buf_0x940c_len = len; fread(table_buf_0x940c, len, 1, ifp); if (ilm.CamID) { process_Sony_0x940c(table_buf_0x940c, table_buf_0x940c_len); free(table_buf_0x940c); table_buf_0x940c_len = 0; } } else if (tag == 0x940e && len < 256000) { table_buf_0x940e = (uchar *)calloc(len,1); table_buf_0x940e_len = len; fread(table_buf_0x940e, len, 1, ifp); if (ilm.CamID) { process_Sony_0x940e(table_buf_0x940e, table_buf_0x940e_len, ilm.CamID); free(table_buf_0x940e); table_buf_0x940e_len = 0; } } else if ((tag == 0x9416) && (len < 256000) && (len > 0x0076)) { table_buf = (uchar *)calloc(len,1); fread(table_buf, len, 1, ifp); if (imCommon.real_ISO < 0.1f) { s[0] = SonySubstitution[table_buf[0x04]]; s[1] = SonySubstitution[table_buf[0x05]]; imCommon.real_ISO = 100.0f * libraw_powf64l(2.0f, (16 - ((float)sget2(s)) / 256.0f)); } imgdata.shootinginfo.ExposureProgram = SonySubstitution[table_buf[0x35]]; if ((ilm.LensMount != LIBRAW_MOUNT_Canon_EF) && (ilm.LensMount != LIBRAW_MOUNT_Sigma_X3F)) { switch (SonySubstitution[table_buf[0x0048]]) { case 1: case 3: ilm.LensMount = LIBRAW_MOUNT_Minolta_A; break; case 2: ilm.LensMount = LIBRAW_MOUNT_Sony_E; break; } } switch (SonySubstitution[table_buf[0x0049]]) { case 1: ilm.LensFormat = LIBRAW_FORMAT_APSC; break; case 2: ilm.LensFormat = LIBRAW_FORMAT_FF; break; } if (ilm.LensMount == LIBRAW_MOUNT_Sony_E) parseSonyLensType2(SonySubstitution[table_buf[0x4c]], SonySubstitution[table_buf[0x4b]]); free(table_buf); } else if (((tag == 0xb027) || (tag == 0x010c)) && (ilm.LensID == LIBRAW_LENS_NOT_SET)) { ilm.LensID = get4(); if ((ilm.LensID > 0x4900) && (ilm.LensID <= 0x5900)) { ilm.AdapterID = 0x4900; ilm.LensID -= ilm.AdapterID; ilm.LensMount = LIBRAW_MOUNT_Sigma_X3F; strcpy(ilm.Adapter, "MC-11"); } else if ((ilm.LensID > 0xef00) && (ilm.LensID < 0xffff) && (ilm.LensID != 0xff00)) { ilm.AdapterID = 0xef00; ilm.LensID -= ilm.AdapterID; ilm.LensMount = LIBRAW_MOUNT_Canon_EF; } else if (((ilm.LensID != LIBRAW_LENS_NOT_SET) && (ilm.LensID < 0xef00)) || (ilm.LensID == 0xff00)) ilm.LensMount = LIBRAW_MOUNT_Minolta_A; /* if (tag == 0x010c) ilm.CameraMount = LIBRAW_MOUNT_Minolta_A; */ } else if (tag == 0xb02a && len < 256000) // Sony LensSpec { table_buf = (uchar *)calloc(len,1); fread(table_buf, len, 1, ifp); if ((!dng_writer) || (saneSonyCameraInfo(table_buf[1], table_buf[2], table_buf[3], table_buf[4], table_buf[5], table_buf[6]))) { if (table_buf[1] | table_buf[2]) ilm.MinFocal = bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]); if (table_buf[3] | table_buf[4]) ilm.MaxFocal = bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]); if (table_buf[5]) ilm.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f; if (table_buf[6]) ilm.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f; parseSonyLensFeatures(table_buf[0], table_buf[7]); } free(table_buf); } else if ((tag == 0xb02b) && !imgdata.sizes.raw_inset_crops[0].cwidth && (len == 2)) { imgdata.sizes.raw_inset_crops[0].cheight = get4(); imgdata.sizes.raw_inset_crops[0].cwidth = get4(); } else if (tag == 0xb041) { imgdata.shootinginfo.ExposureMode = get2(); } else if ((tag == 0xb043) && (len == 1) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) { imSony.AFAreaMode = get2(); } } class checked_buffer_t { public: // create with internal storage checked_buffer_t(short ord, int size) : _order(ord), storage(size+64) { _data = storage.data(); _len = size; } checked_buffer_t(short ord, unsigned char *dd, int ss): _order(ord), _data(dd),_len(ss){} ushort sget2(int offset) { checkoffset(offset + 2); return libraw_sget2_static(_order, _data + offset); } void checkoffset(int off) { if (off >= _len) throw LIBRAW_EXCEPTION_IO_EOF; } unsigned char operator [] (int idx) { checkoffset(idx); return _data[idx]; } unsigned sget4(int offset) { checkoffset(offset+4); return libraw_sget4_static(_order, _data + offset); } double sgetreal(int type, int offset) { int sz = libraw_tagtype_dataunit_bytes(type); checkoffset(offset + sz); return libraw_sgetreal_static(_order, type, _data + offset); } unsigned char *data() { return _data; } int tiff_sget(unsigned save, INT64 *tag_offset, unsigned *tag_id, unsigned *tag_type, INT64 *tag_dataoffset, unsigned *tag_datalen, int *tag_dataunitlen) { if ((((*tag_offset) + 12) > _len) || (*tag_offset < 0)) { // abnormal, tag buffer overrun return -1; } int pos = *tag_offset; *tag_id = sget2(pos); pos += 2; *tag_type = sget2(pos); pos += 2; *tag_datalen = sget4(pos); pos += 4; *tag_dataunitlen = libraw_tagtype_dataunit_bytes(*tag_type); if ((*tag_datalen * (*tag_dataunitlen)) > 4) { *tag_dataoffset = sget4(pos) - save; if ((*tag_dataoffset + *tag_datalen) > _len) { // abnormal, tag data buffer overrun return -2; } } else *tag_dataoffset = *tag_offset + 8; *tag_offset += 12; return 0; } private: short _order; unsigned char *_data; int _len; std::vector storage; }; void LibRaw::parseSonySR2(uchar *_cbuf_SR2, unsigned SR2SubIFDOffset, unsigned SR2SubIFDLength, unsigned dng_writer) { unsigned c; unsigned entries, tag_id, tag_type, tag_datalen; INT64 tag_offset, tag_dataoffset; int TagProcessed; int tag_dataunitlen; float num; int i; int WBCTC_count; try { checked_buffer_t cbuf_SR2(order, _cbuf_SR2, SR2SubIFDLength); entries = cbuf_SR2.sget2(0); if (entries > 1000) return; tag_offset = 2; WBCTC_count = 0; while (entries--) { if (cbuf_SR2.tiff_sget(SR2SubIFDOffset, &tag_offset, &tag_id, &tag_type, &tag_dataoffset, &tag_datalen, &tag_dataunitlen) == 0) { TagProcessed = 0; if (dng_writer == nonDNG) { switch (tag_id) { case 0x7300: FORC4 cblack[c] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); TagProcessed = 1; break; case 0x7303: FORC4 cam_mul[GRBG_2_RGBG(c)] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); TagProcessed = 1; break; case 0x7310: FORC4 cblack[RGGB_2_RGBG(c)] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); i = cblack[3]; FORC3 if (i > (int)cblack[c]) i = cblack[c]; FORC4 cblack[c] -= i; black = i; TagProcessed = 1; break; case 0x7313: FORC4 cam_mul[RGGB_2_RGBG(c)] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); TagProcessed = 1; break; case 0x74a0: ilm.MaxAp4MaxFocal = cbuf_SR2.sgetreal(tag_type, tag_dataoffset); TagProcessed = 1; break; case 0x74a1: ilm.MaxAp4MinFocal = cbuf_SR2.sgetreal(tag_type, tag_dataoffset); TagProcessed = 1; break; case 0x74a2: ilm.MaxFocal = cbuf_SR2.sgetreal(tag_type, tag_dataoffset); TagProcessed = 1; break; case 0x74a3: ilm.MinFocal = cbuf_SR2.sgetreal(tag_type, tag_dataoffset); TagProcessed = 1; break; case 0x7800: for (i = 0; i < 3; i++) { num = 0.0; for (c = 0; c < 3; c++) { imgdata.color.ccm[i][c] = (float)((short)cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * (i * 3 + c))); num += imgdata.color.ccm[i][c]; } if (num > 0.01) FORC3 imgdata.color.ccm[i][c] = imgdata.color.ccm[i][c] / num; } TagProcessed = 1; break; case 0x787f: if (tag_datalen == 3) { FORC3 imgdata.color.linear_max[c] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); imgdata.color.linear_max[3] = imgdata.color.linear_max[1]; } else if (tag_datalen == 1) { imgdata.color.linear_max[0] = imgdata.color.linear_max[1] = imgdata.color.linear_max[2] = imgdata.color.linear_max[3] = cbuf_SR2.sget2(tag_dataoffset); } TagProcessed = 1; break; } } if (!TagProcessed) { if ((tag_id >= 0x7480) && (tag_id <= 0x7486)) { i = tag_id - 0x7480; if (Sony_SR2_wb_list[i] > 255) { if (WBCTC_count < 64) { icWBCCTC[WBCTC_count][0] = Sony_SR2_wb_list[i]; FORC3 icWBCCTC[WBCTC_count][c + 1] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); icWBCCTC[WBCTC_count][4] = icWBCCTC[WBCTC_count][2]; } WBCTC_count++; } else { FORC3 icWBC[Sony_SR2_wb_list[i]][c] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); icWBC[Sony_SR2_wb_list[i]][3] = icWBC[Sony_SR2_wb_list[i]][1]; } } else if ((tag_id >= 0x7820) && (tag_id <= 0x782d)) { i = tag_id - 0x7820; if (Sony_SR2_wb_list1[i] > 255) { if (WBCTC_count < 64) { icWBCCTC[WBCTC_count][0] = Sony_SR2_wb_list1[i]; FORC3 icWBCCTC[WBCTC_count][c + 1] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); icWBCCTC[WBCTC_count][4] = icWBCCTC[WBCTC_count][2]; if (Sony_SR2_wb_list1[i] == 3200) { FORC3 icWBC[LIBRAW_WBI_StudioTungsten][c] = icWBCCTC[WBCTC_count][c + 1]; icWBC[LIBRAW_WBI_StudioTungsten][3] = icWBC[LIBRAW_WBI_StudioTungsten][1]; } } WBCTC_count++; } else { FORC3 icWBC[Sony_SR2_wb_list1[i]][c] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); icWBC[Sony_SR2_wb_list1[i]][3] = icWBC[Sony_SR2_wb_list1[i]][1]; } } else if (tag_id == 0x7302) { FORC4 icWBC[LIBRAW_WBI_Auto][GRBG_2_RGBG(c)] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); } else if (tag_id == 0x7312) { FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); } } } } } catch (...) { return; } } void LibRaw::parseSonySRF(unsigned len) { if ((len > 0xfffff) || (len == 0)) return; INT64 save = ftell(ifp); INT64 offset = 0x0310c0 - save; /* for non-DNG this value normally is 0x8ddc */ if (len < offset || offset < 0) return; try { INT64 decrypt_len = offset >> 2; /* master key offset value is the next un-encrypted metadata field after SRF0 */ unsigned i, nWB; unsigned MasterKey, SRF2Key=0; INT64 srf_offset, tag_offset, tag_dataoffset; int tag_dataunitlen; //uchar *srf_buf; ushort entries; unsigned tag_id, tag_type, tag_datalen; //srf_buf = (uchar *)malloc(len+64); checked_buffer_t srf_buf(order, len); fread(srf_buf.data(), len, 1, ifp); offset += srf_buf[offset] << 2; /* master key is stored in big endian */ MasterKey = ((unsigned)srf_buf[offset] << 24) | ((unsigned)srf_buf[offset + 1] << 16) | ((unsigned)srf_buf[offset + 2] << 8) | (unsigned)srf_buf[offset + 3]; /* skip SRF0 */ srf_offset = 0; entries = srf_buf.sget2(srf_offset); if (entries > 1000) goto restore_after_parseSonySRF; offset = srf_offset + 2; srf_offset = srf_buf.sget4(offset + 12 * entries) - save; /* SRF0 ends with SRF1 abs. position */ /* get SRF1, it has fixed 40 bytes length and contains keys to decode metadata * and raw data */ if (srf_offset < 0 || decrypt_len < srf_offset / 4) goto restore_after_parseSonySRF; sony_decrypt((unsigned *)(srf_buf.data() + srf_offset), decrypt_len - srf_offset / 4, 1, MasterKey); entries = srf_buf.sget2(srf_offset); if (entries > 1000) goto restore_after_parseSonySRF; offset = srf_offset + 2; tag_offset = offset; while (entries--) { if (tiff_sget(save, srf_buf.data(), len, &tag_offset, &tag_id, &tag_type, &tag_dataoffset, &tag_datalen, &tag_dataunitlen) == 0) { if (tag_id == 0x0000) { SRF2Key = srf_buf.sget4(tag_dataoffset); } else if (tag_id == 0x0001) { /*RawDataKey =*/ srf_buf.sget4(tag_dataoffset); } } else goto restore_after_parseSonySRF; } offset = tag_offset; /* get SRF2 */ srf_offset = srf_buf.sget4(offset) - save; /* SRFn ends with SRFn+1 position */ if (srf_offset < 0 || decrypt_len < srf_offset / 4) goto restore_after_parseSonySRF; sony_decrypt((unsigned *)(srf_buf.data() + srf_offset), decrypt_len - srf_offset / 4, 1, SRF2Key); entries = srf_buf.sget2(srf_offset); if (entries > 1000) goto restore_after_parseSonySRF; offset = srf_offset + 2; tag_offset = offset; while (entries--) { if (srf_buf.tiff_sget(save, &tag_offset, &tag_id, &tag_type, &tag_dataoffset, &tag_datalen, &tag_dataunitlen) == 0) { if ((tag_id >= 0x00c0) && (tag_id <= 0x00ce)) { i = (tag_id - 0x00c0) % 3; nWB = (tag_id - 0x00c0) / 3; icWBC[Sony_SRF_wb_list[nWB]][i] = srf_buf.sget4(tag_dataoffset); if (i == 1) { icWBC[Sony_SRF_wb_list[nWB]][3] = icWBC[Sony_SRF_wb_list[nWB]][i]; } } else if ((tag_id >= 0x00d0) && (tag_id <= 0x00d2)) { i = (tag_id - 0x00d0) % 3; cam_mul[i] = srf_buf.sget4(tag_dataoffset); if (i == 1) { cam_mul[3] = cam_mul[i]; } } else switch (tag_id) { /* 0x0002 SRF6Offset 0x0003 SRFDataOffset (?) 0x0004 RawDataOffset 0x0005 RawDataLength */ case 0x0043: ilm.MaxAp4MaxFocal = srf_buf.sgetreal(tag_type, tag_dataoffset); break; case 0x0044: ilm.MaxAp4MinFocal = srf_buf.sgetreal(tag_type, tag_dataoffset); break; case 0x0045: ilm.MinFocal = srf_buf.sgetreal(tag_type, tag_dataoffset); break; case 0x0046: ilm.MaxFocal = srf_buf.sgetreal(tag_type, tag_dataoffset); break; } } else goto restore_after_parseSonySRF; } offset = tag_offset; restore_after_parseSonySRF:; } catch (...) // srf_buf can raise IO_EOF exception, catch it and return usual way { fseek(ifp, save, SEEK_SET); return; } fseek(ifp, save, SEEK_SET); } LibRaw-0.21.4/src/metadata/tiff.cpp000066400000000000000000002224561477673233700170170ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" #include "../../internal/libraw_cameraids.h" int LibRaw::parse_tiff_ifd(int base) { unsigned entries, tag, type, len, plen = 16, save, utmp; int ifd, use_cm = 0, cfa, i, j, c, ima_len = 0; char *cbuf, *cp; uchar cfa_pat[16], cfa_pc[] = {0, 1, 2, 3}, tab[256]; double fm[3][4], cc[4][4], cm[4][3], cam_xyz[4][3], num; double ab[] = {1, 1, 1, 1}, asn[] = {0, 0, 0, 0}, xyz[] = {1, 1, 1}; unsigned sony_curve[] = {0, 0, 0, 0, 0, 4095}; unsigned *buf, sony_offset = 0, sony_length = 0, sony_key = 0; struct jhead jh; ushort *rafdata; if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) return 1; ifd = tiff_nifds++; for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) cc[j][i] = i == j; if (libraw_internal_data.unpacker_data.ifd0_offset == -1LL) libraw_internal_data.unpacker_data.ifd0_offset = base; entries = get2(); if (entries > 512) return 1; INT64 fsize = ifp->size(); while (entries--) { tiff_get(base, &tag, &type, &len, &save); INT64 savepos = ftell(ifp); if (len > 8 && savepos + len > 2 * fsize) { fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! continue; } if (callbacks.exif_cb) { callbacks.exif_cb(callbacks.exifparser_data, tag | (is_pana_raw ? 0x30000 : ((ifd + 1) << 20)), type, len, order, ifp, base); fseek(ifp, savepos, SEEK_SET); } if (!is_pana_raw) { /* processing of EXIF tags that collide w/ PanasonicRaw tags */ switch (tag) { case 0x0001: if (len == 4) is_pana_raw = get4(); break; case 0x000b: /* 11, Std. EXIF Software tag */ fgets(software, 64, ifp); if (!strncmp(software, "Adobe", 5) || !strncmp(software, "dcraw", 5) || !strncmp(software, "UFRaw", 5) || !strncmp(software, "Bibble", 6) || !strcmp(software, "Digital Photo Professional")) is_raw = 0; break; case 0x001c: /* 28, safeguard, probably not needed */ case 0x001d: /* 29, safeguard, probably not needed */ case 0x001e: /* 30, safeguard, probably not needed */ cblack[tag - 0x001c] = get2(); cblack[3] = cblack[1]; break; case 0x0111: /* 273, StripOffset */ if (len > 1 && len < 16384) { off_t sav = ftell(ifp); tiff_ifd[ifd].strip_offsets = (int *)calloc(len, sizeof(int)); tiff_ifd[ifd].strip_offsets_count = len; for (int ii = 0; ii < (int)len; ii++) tiff_ifd[ifd].strip_offsets[ii] = get4() + base; fseek(ifp, sav, SEEK_SET); // restore position } /* fallback */ case 0x0201: /* 513, JpegIFOffset */ case 0xf007: // 61447 tiff_ifd[ifd].offset = get4() + base; if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) { fseek(ifp, tiff_ifd[ifd].offset, SEEK_SET); if (ljpeg_start(&jh, 1)) { if (!dng_version && !strcasecmp(make, "SONY") && tiff_ifd[ifd].phint == 32803 && tiff_ifd[ifd].comp == 7) // Sony/lossless compressed IFD { tiff_ifd[ifd].comp = 6; tiff_ifd[ifd].bps = jh.bits; tiff_ifd[ifd].samples = 1; } else { tiff_ifd[ifd].comp = 6; tiff_ifd[ifd].bps = jh.bits; tiff_ifd[ifd].t_width = jh.wide; tiff_ifd[ifd].t_height = jh.high; tiff_ifd[ifd].samples = jh.clrs; if (!(jh.sraw || (jh.clrs & 1))) tiff_ifd[ifd].t_width *= jh.clrs; if ((tiff_ifd[ifd].t_width > 4 * tiff_ifd[ifd].t_height) & ~jh.clrs) { tiff_ifd[ifd].t_width /= 2; tiff_ifd[ifd].t_height *= 2; } i = order; parse_tiff(tiff_ifd[ifd].offset + 12); order = i; } } } break; } } else { /* processing Panasonic-specific "PanasonicRaw" tags */ switch (tag) { case 0x0004: /* 4, SensorTopBorder */ imgdata.sizes.raw_inset_crops[0].ctop = get2(); break; case 0x000a: /* 10, BitsPerSample */ pana_bpp = get2(); pana_bpp = LIM(pana_bpp, 8, 16); break; case 0x000b: /* 11, Compression */ imPana.Compression = get2(); break; case 0x000e: /* 14, LinearityLimitRed */ case 0x000f: /* 15, LinearityLimitGreen */ case 0x0010: /* 16, LinearityLimitBlue */ imgdata.color.linear_max[tag - 14] = get2(); if (imgdata.color.linear_max[tag - 14] == 16383) imgdata.color.linear_max[tag - 14] -= 64; if (imgdata.color.linear_max[tag - 14] == 4095) imgdata.color.linear_max[tag - 14] -= 16; if (tag == 0x000f) // 15, LinearityLimitGreen imgdata.color.linear_max[3] = imgdata.color.linear_max[1]; break; case 0x0013: /* 19, WBInfo */ if ((i = get2()) > 0x100) break; for (c = 0; c < i; c++) { if ((j = get2()) < 0x100) { if (j >= 0) { icWBC[j][0] = get2(); icWBC[j][2] = get2(); icWBC[j][1] = icWBC[j][3] = 0x100; } } else // light source out of EXIF numbers range get4(); } break; case 0x0018: /* 24, HighISOMultiplierRed */ case 0x0019: /* 25, HighISOMultiplierGreen */ case 0x001a: /* 26, HighISOMultiplierBlue */ imPana.HighISOMultiplier[tag - 0x0018] = get2(); break; case 0x001c: /* 28, BlackLevelRed */ case 0x001d: /* 29, BlackLevelGreen */ case 0x001e: /* 30, BlackLevelBlue */ pana_black[tag - 0x001c] = get2(); break; case 0x002d: /* 45, RawFormat */ /* pana_encoding: tag 0x002d (45dec) not used - DMC-LX1/FZ30/FZ50/L1/LX1/LX2 2 - RAW DMC-FZ8/FZ18 3 - RAW DMC-L10 4 - RW2 for most other models, including G9 in "pixel shift off" mode and YUNEEC CGO4 (must add 15 to black levels for RawFormat == 4) 5 - RW2 DC-GH5s; G9 in "pixel shift on" mode 6 - RW2 DC-S1, DC-S1R in "pixel shift off" mode 7 - RW2 DC-S1R (probably DC-S1 too) in "pixel shift on" mode */ pana_encoding = get2(); break; case 0x002f: /* 47, CropTop */ imgdata.sizes.raw_inset_crops[0].ctop = get2(); break; case 0x0030: /* 48, CropLeft */ imgdata.sizes.raw_inset_crops[0].cleft = get2(); break; case 0x0031: /* 49, CropBottom */ imgdata.sizes.raw_inset_crops[0].cheight = get2() - imgdata.sizes.raw_inset_crops[0].ctop; break; case 0x0032: /* 50, CropRight */ imgdata.sizes.raw_inset_crops[0].cwidth = get2() - imgdata.sizes.raw_inset_crops[0].cleft; break; case 0x0037: /* 55, ISO if ISO in 0x8827 & ISO in 0x0017 == 65535 */ if (iso_speed == 65535) iso_speed = get4(); break; case 0x011c: /* 284, Gamma */ { int n = get2(); if (n >= 1024) imPana.gamma = (float)n / 1024.0f; else if (n >= 256) imPana.gamma = (float)n / 256.0f; else imPana.gamma = (float)n / 100.0f; } break; case 0x0120: /* 288, CameraIFD, contains tags 0x1xxx, 0x2xxx, 0x3xxx */ { unsigned sorder = order; unsigned long sbase = base; base = ftell(ifp); order = get2(); fseek(ifp, 2, SEEK_CUR); fseek(ifp, INT64(get4()) - 8LL, SEEK_CUR); parse_tiff_ifd(base); base = sbase; order = sorder; } break; case 0x0121: /* 289, Multishot, 0 is Off, 65536 is Pixel Shift */ imPana.Multishot = get4(); break; case 0x1001: if (imPana.Multishot == 0) { imPana.Multishot = get4(); if (imPana.Multishot) imPana.Multishot += 65535; } break; case 0x1100: imPana.FocusStepNear = get2(); break; case 0x1101: imPana.FocusStepCount = get2(); break; case 0x1105: imPana.ZoomPosition = get4(); break; case 0x1201: if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) { imPana.LensManufacturer = fgetc(ifp); } else if (type == 258) { imPana.LensManufacturer = get4(); if (imPana.LensManufacturer >= 257) { ilm.LensMount = LIBRAW_MOUNT_LPS_L; ilm.LensFormat = LIBRAW_FORMAT_FF; } } break; case 0x1202: if (ilm.LensMount == LIBRAW_MOUNT_LPS_L) { if ((utmp = get2())) ilm.LensID = utmp; } else if ((imPana.LensManufacturer != 0xff) && (imPana.LensManufacturer != 0xffffffff)) { if ((utmp = (fgetc(ifp) << 8) | fgetc(ifp))) ilm.LensID = (imPana.LensManufacturer << 16) + utmp; } break; case 0x1203: /* 4611, FocalLengthIn35mmFormat, contained in 0x0120 CameraIFD */ if (imgdata.lens.FocalLengthIn35mmFormat < 0.65f) imgdata.lens.FocalLengthIn35mmFormat = get2(); break; case 0x2009: /* 8201, contained in 0x0120 CameraIFD */ if ((pana_encoding == 4) || (pana_encoding == 5)) { i = MIN(8, len); int permut[8] = {3, 2, 1, 0, 3 + 4, 2 + 4, 1 + 4, 0 + 4}; imPana.BlackLevelDim = len; for (j = 0; j < i; j++) { imPana.BlackLevel[permut[j]] = (float)(get2()) / (float)(powf(2.f, 14.f - pana_bpp)); } } break; case 0x3420: /* 13344, WB_RedLevelAuto, contained in 0x0120 CameraIFD */ icWBC[LIBRAW_WBI_Auto][0] = get2(); icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] = 1024.0f; break; case 0x3421: /* 13345, WB_BlueLevelAuto, contained in 0x0120 CameraIFD */ icWBC[LIBRAW_WBI_Auto][2] = get2(); break; case 0x0002: /* 2, ImageWidth */ tiff_ifd[ifd].t_width = getint(type); break; case 0x0003: /* 3, ImageHeight */ tiff_ifd[ifd].t_height = getint(type); break; case 0x0005: /* 5, SensorLeftBorder */ width = get2(); imgdata.sizes.raw_inset_crops[0].cleft = width; break; case 0x0006: /* 6, SensorBottomBorder */ height = get2(); imgdata.sizes.raw_inset_crops[0].cheight = height - imgdata.sizes.raw_inset_crops[0].ctop; break; case 0x0007: /* 7, SensorRightBorder */ i = get2(); width += i; imgdata.sizes.raw_inset_crops[0].cwidth = i - imgdata.sizes.raw_inset_crops[0].cleft; break; case 0x0009: /* 9, CFAPattern */ if ((i = get2())) filters = i; break; case 0x0011: /* 17, RedBalance */ case 0x0012: /* 18, BlueBalance */ if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) && len == 1) cam_mul[(tag - 0x0011) * 2] = get2() / 256.0; break; case 0x0017: /* 23, ISO */ if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) iso_speed = get2(); break; case 0x0024: /* 36, WBRedLevel */ case 0x0025: /* 37, WBGreenLevel */ case 0x0026: /* 38, WBBlueLevel */ cam_mul[tag - 0x0024] = get2(); break; case 0x0027: /* 39, WBInfo2 */ if ((i = get2()) > 0x100) break; for (c = 0; c < i; c++) { if ((j = get2()) < 0x100) { if(j >= 0) { icWBC[j][0] = get2(); icWBC[j][1] = icWBC[j][3] = get2(); icWBC[j][2] = get2(); if (c == 1 && i > 6 && cam_mul[0] <= 0.001f) for (int q = 0; q < 4; q++) cam_mul[q] = icWBC[j][q]; } } else fseek(ifp, 6, SEEK_CUR); } break; case 0x002e: /* 46, JpgFromRaw */ if ((type != LIBRAW_EXIFTAG_TYPE_UNDEFINED) || (fgetc(ifp) != 0xff) || (fgetc(ifp) != 0xd8)) break; thumb_offset = ftell(ifp) - 2; thumb_length = len; break; case 0x0118: /* 280, Panasonic RW2 offset */ if (type != LIBRAW_EXIFTAG_TYPE_LONG) break; load_raw = &LibRaw::panasonic_load_raw; load_flags = 0x2008; case 0x0111: /* 273, StripOffset */ if (len > 1 && len < 16384) { off_t sav = ftell(ifp); tiff_ifd[ifd].strip_offsets = (int *)calloc(len, sizeof(int)); tiff_ifd[ifd].strip_offsets_count = len; for (int ii = 0; ii < (int)len; ii++) tiff_ifd[ifd].strip_offsets[ii] = get4() + base; fseek(ifp, sav, SEEK_SET); // restore position } /* fallthrough */ tiff_ifd[ifd].offset = get4() + base; if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) { fseek(ifp, tiff_ifd[ifd].offset, SEEK_SET); if (ljpeg_start(&jh, 1)) { tiff_ifd[ifd].comp = 6; tiff_ifd[ifd].t_width = jh.wide; tiff_ifd[ifd].t_height = jh.high; tiff_ifd[ifd].bps = jh.bits; tiff_ifd[ifd].samples = jh.clrs; if (!(jh.sraw || (jh.clrs & 1))) tiff_ifd[ifd].t_width *= jh.clrs; if ((tiff_ifd[ifd].t_width > 4 * tiff_ifd[ifd].t_height) & ~jh.clrs) { tiff_ifd[ifd].t_width /= 2; tiff_ifd[ifd].t_height *= 2; } i = order; parse_tiff(tiff_ifd[ifd].offset + 12); order = i; } } break; } } /* processing of Panasonic-specific tags finished */ switch (tag) { /* processing of general EXIF tags */ case 0xf000: /* 61440, Fuji HS10 table */ fseek(ifp, get4() + base, SEEK_SET); parse_tiff_ifd(base); break; case 0x00fe: /* NewSubfileType */ tiff_ifd[ifd].newsubfiletype = getreal(type); break; case 0x0100: /* 256, ImageWidth */ case 0xf001: /* 61441, Fuji RAF RawImageFullWidth */ tiff_ifd[ifd].t_width = getint(type); break; case 0x0101: /* 257, ImageHeight */ case 0xf002: /* 61442, Fuji RAF RawImageFullHeight */ tiff_ifd[ifd].t_height = getint(type); break; case 0x0102: /* 258, BitsPerSample */ case 0xf003: /* 61443, Fuji RAF 0xf003 */ if(!tiff_ifd[ifd].samples || tag != 0x0102) // ??? already set by tag 0x115 tiff_ifd[ifd].samples = len & 7; tiff_ifd[ifd].bps = getint(type); if (tiff_bps < (unsigned)tiff_ifd[ifd].bps) tiff_bps = tiff_ifd[ifd].bps; break; case 0xf006: /* 61446, Fuji RAF 0xf006 */ raw_height = 0; if (tiff_ifd[ifd].bps > 12) break; load_raw = &LibRaw::packed_load_raw; load_flags = get4() ? 24 : 80; break; case 0x0103: /* 259, Compression */ /* 262 = Kodak 262 32767 = Sony ARW Compressed 32769 = Packed RAW 32770 = Samsung SRW Compressed 32772 = Samsung SRW Compressed 2 32867 = Kodak KDC Compressed 34713 = Nikon NEF Compressed 65000 = Kodak DCR Compressed 65535 = Pentax PEF Compressed */ tiff_ifd[ifd].comp = getint(type); break; case 0x0106: /* 262, PhotometricInterpretation */ tiff_ifd[ifd].phint = get2(); break; case 0x010e: /* 270, ImageDescription */ fread(desc, 512, 1, ifp); break; case 0x010f: /* 271, Make */ fgets(make, 64, ifp); break; case 0x0110: /* 272, Model */ if (!strncmp(make, "Hasselblad", 10) && model[0] && (imHassy.format != LIBRAW_HF_Imacon)) break; fgets(model, 64, ifp); break; case 0x0116: // 278 tiff_ifd[ifd].rows_per_strip = getint(type); break; case 0x0112: /* 274, Orientation */ tiff_ifd[ifd].t_flip = "50132467"[get2() & 7] - '0'; break; case 0x0115: /* 277, SamplesPerPixel */ tiff_ifd[ifd].samples = getint(type) & 7; break; case 0x0152: /* Extrasamples */ tiff_ifd[ifd].extrasamples = (getint(type) & 0xff) + 1024; break; case 0x0117: /* 279, StripByteCounts */ if (len > 1 && len < 16384) { off_t sav = ftell(ifp); tiff_ifd[ifd].strip_byte_counts = (int *)calloc(len, sizeof(int)); tiff_ifd[ifd].strip_byte_counts_count = len; for (int ii = 0; ii < (int)len; ii++) tiff_ifd[ifd].strip_byte_counts[ii] = get4(); fseek(ifp, sav, SEEK_SET); // restore position } /* fallback */ case 0x0202: // 514 case 0xf008: // 61448 tiff_ifd[ifd].bytes = get4(); break; case 0xf00e: // 61454, FujiFilm "As Shot" FORC3 cam_mul[GRBG_2_RGBG(c)] = getint(type); break; case 0x0131: /* 305, Software */ fgets(software, 64, ifp); if (!strncmp(software, "Adobe", 5) || !strncmp(software, "dcraw", 5) || !strncmp(software, "UFRaw", 5) || !strncmp(software, "Bibble", 6) || !strcmp(software, "Digital Photo Professional")) is_raw = 0; break; case 0x0132: /* 306, DateTime */ get_timestamp(0); break; case 0x013b: /* 315, Artist */ fread(artist, 64, 1, ifp); break; case 0x013d: // 317 tiff_ifd[ifd].predictor = getint(type); break; case 0x0142: /* 322, TileWidth */ tiff_ifd[ifd].t_tile_width = getint(type); break; case 0x0143: /* 323, TileLength */ tiff_ifd[ifd].t_tile_length = getint(type); break; case 0x0144: /* 324, TileOffsets */ tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4(); if (len == 1) tiff_ifd[ifd].t_tile_width = tiff_ifd[ifd].t_tile_length = 0; if (len == 4) { load_raw = &LibRaw::sinar_4shot_load_raw; is_raw = 5; } break; case 0x0145: // 325 tiff_ifd[ifd].bytes = len > 1 ? ftell(ifp) : get4(); break; case 0x014a: /* 330, SubIFDs */ if (!strcmp(model, "DSLR-A100") && tiff_ifd[ifd].t_width == 3872) { load_raw = &LibRaw::sony_arw_load_raw; data_offset = get4() + base; ifd++; if (ifd >= int(sizeof tiff_ifd / sizeof tiff_ifd[0])) throw LIBRAW_EXCEPTION_IO_CORRUPT; break; } if (!strncmp(make, "Hasselblad", 10) && libraw_internal_data.unpacker_data.hasselblad_parser_flag) { fseek(ifp, ftell(ifp) + 4, SEEK_SET); fseek(ifp, get4() + base, SEEK_SET); parse_tiff_ifd(base); break; } if (len > 1000) len = 1000; /* 1000 SubIFDs is enough */ while (len--) { i = ftell(ifp); fseek(ifp, get4() + base, SEEK_SET); if (parse_tiff_ifd(base)) break; fseek(ifp, i + 4, SEEK_SET); } break; case 0x0153: // 339 tiff_ifd[ifd].sample_format = getint(type); break; case 0x0190: // 400 strcpy(make, "Sarnoff"); maximum = 0xfff; break; case 0x02bc: // 700 if ((tagtypeIs(LIBRAW_EXIFTAG_TYPE_BYTE) || tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII) || tagtypeIs(LIBRAW_EXIFTAG_TYPE_SBYTE) || tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary)) && (len > 1) && (len < 5100000)) { xmpdata = (char *)calloc(xmplen = len + 1,1); unsigned br = fread(xmpdata,1, len, ifp); xmpdata[br] = 0; } break; case 0x7000: imSony.SonyRawFileType = get2(); break; case 0x7010: // 28688 FORC4 sony_curve[c + 1] = get2() >> 2 & 0xfff; for (i = 0; i < 5; i++) for (j = sony_curve[i] + 1; j <= (int)sony_curve[i + 1]; j++) curve[j] = curve[j - 1] + (1 << i); break; case 0x7200: // 29184, Sony SR2Private sony_offset = get4(); break; case 0x7201: // 29185, Sony SR2Private sony_length = get4(); break; case 0x7221: // 29217, Sony SR2Private sony_key = get4(); break; case 0x7250: // 29264, Sony SR2Private parse_minolta(ftell(ifp)); raw_width = 0; break; case 0x7303: // 29443, Sony SR2SubIFD FORC4 cam_mul[GRBG_2_RGBG(c)] = get2(); break; case 0x7313: // 29459, Sony SR2SubIFD FORC4 cam_mul[RGGB_2_RGBG(c)] = get2(); break; case 0x7310: // 29456, Sony SR2SubIFD FORC4 cblack[RGGB_2_RGBG(c)] = get2(); i = cblack[3]; FORC3 if (i > (int)cblack[c]) i = cblack[c]; FORC4 cblack[c] -= i; black = i; break; case 0x827d: /* 33405, Model2 */ /* for Kodak ProBack 645 PB645x-yyyy 'x' is: 'M' for Mamiya 645 'C' for Contax 645 'H' for Hasselblad H-series */ fgets(model2, 64, ifp); break; case 0x828d: /* 33421, CFARepeatPatternDim */ if (get2() == 6 && get2() == 6) tiff_ifd[ifd].t_filters = filters = 9; break; case 0x828e: /* 33422, CFAPattern */ if (filters == 9) { FORC(36)((char *)xtrans)[c] = fgetc(ifp) & 3; break; } case 0xfd09: /* 64777, Kodak P-series */ if (len == 36) { tiff_ifd[ifd].t_filters = filters = 9; colors = 3; FORC(36)((char *)xtrans)[c] = fgetc(ifp) & 3; } else if (len > 0) { if ((plen = len) > 16) plen = 16; fread(cfa_pat, 1, plen, ifp); for (colors = cfa = i = 0; i < (int)plen && colors < 4; i++) { if (cfa_pat[i] > 31) continue; // Skip wrong data colors += !(cfa & (1 << cfa_pat[i])); cfa |= 1 << cfa_pat[i]; } if (cfa == 070) memcpy(cfa_pc, "\003\004\005", 3); /* CMY */ if (cfa == 072) memcpy(cfa_pc, "\005\003\004\001", 4); /* GMCY */ goto guess_cfa_pc; } break; case 0x8290: // 33424 case 0xfe00: // 65024 fseek(ifp, get4() + base, SEEK_SET); parse_kodak_ifd(base); break; case 0x829a: /* 33434, ExposureTime */ tiff_ifd[ifd].t_shutter = shutter = getreal(type); break; case 0x829d: /* 33437, FNumber */ aperture = getreal(type); break; case 0x9400: imCommon.exifAmbientTemperature = getreal(type); if ((imCommon.CameraTemperature > -273.15f) && ((OlyID == OlyID_TG_5) || (OlyID == OlyID_TG_6))) imCommon.CameraTemperature += imCommon.exifAmbientTemperature; break; case 0x9401: imCommon.exifHumidity = getreal(type); break; case 0x9402: imCommon.exifPressure = getreal(type); break; case 0x9403: imCommon.exifWaterDepth = getreal(type); break; case 0x9404: imCommon.exifAcceleration = getreal(type); break; case 0x9405: imCommon.exifCameraElevationAngle = getreal(type); break; case 0xa405: // FocalLengthIn35mmFormat imgdata.lens.FocalLengthIn35mmFormat = get2(); break; case 0xa431: // BodySerialNumber case 0xc62f: stmread(imgdata.shootinginfo.BodySerial, len, ifp); break; case 0xa432: // LensInfo, 42034dec, Lens Specification per EXIF standard imgdata.lens.MinFocal = getreal(type); imgdata.lens.MaxFocal = getreal(type); imgdata.lens.MaxAp4MinFocal = getreal(type); imgdata.lens.MaxAp4MaxFocal = getreal(type); break; case 0xa435: // LensSerialNumber stmread(imgdata.lens.LensSerial, len, ifp); break; case 0xc630: // DNG LensInfo, Lens Specification per EXIF standard imgdata.lens.MinFocal = getreal(type); imgdata.lens.MaxFocal = getreal(type); imgdata.lens.MaxAp4MinFocal = getreal(type); imgdata.lens.MaxAp4MaxFocal = getreal(type); break; case 0xa420: /* 42016, ImageUniqueID */ stmread(imgdata.color.ImageUniqueID, len, ifp); break; case 0xc65d: /* 50781, RawDataUniqueID */ imgdata.color.RawDataUniqueID[16] = 0; fread(imgdata.color.RawDataUniqueID, 1, 16, ifp); break; case 0xa433: // LensMake stmread(imgdata.lens.LensMake, len, ifp); break; case 0xa434: // LensModel stmread(imgdata.lens.Lens, len, ifp); if (!strncmp(imgdata.lens.Lens, "----", 4)) imgdata.lens.Lens[0] = 0; break; case 0x9205: imgdata.lens.EXIF_MaxAp = libraw_powf64l(2.0f, (getreal(type) / 2.0f)); break; case 0x8602: /* 34306, Leaf white balance */ FORC4 { int q = get2(); if (q) cam_mul[GRGB_2_RGBG(c)] = 4096.0 / q; } break; case 0x8603: /* 34307, Leaf CatchLight color matrix */ fread(software, 1, 7, ifp); if (strncmp(software, "MATRIX", 6)) break; colors = 4; for (raw_color = i = 0; i < 3; i++) { FORC4 fscanf(ifp, "%f", &rgb_cam[i][GRGB_2_RGBG(c)]); if (!use_camera_wb) continue; num = 0; FORC4 num += rgb_cam[i][c]; FORC4 rgb_cam[i][c] /= MAX(1, num); } break; case 0x8606: /* 34310, Leaf metadata */ parse_mos(ftell(ifp)); case 0x85ff: // 34303 strcpy(make, "Leaf"); break; case 0x8769: /* 34665, EXIF tag */ fseek(ifp, get4() + base, SEEK_SET); parse_exif(base); break; case 0x8825: /* 34853, GPSInfo tag */ { unsigned pos; fseek(ifp, pos = (get4() + base), SEEK_SET); parse_gps(base); fseek(ifp, pos, SEEK_SET); parse_gps_libraw(base); } break; case 0x8773: /* 34675, InterColorProfile */ case 0xc68f: /* 50831, AsShotICCProfile */ profile_offset = ftell(ifp); profile_length = len; break; case 0x9102: /* 37122, CompressedBitsPerPixel */ kodak_cbpp = get4(); break; case 0x920a: /* 37386, FocalLength */ focal_len = getreal(type); break; case 0x9211: /* 37393, ImageNumber */ shot_order = getint(type); break; case 0x9215: /* 37397, ExposureIndex */ imCommon.exifExposureIndex = getreal(type); break; case 0x9218: /* 37400, old Kodak KDC tag */ for (raw_color = i = 0; i < 3; i++) { getreal(type); FORC3 rgb_cam[i][c] = getreal(type); } break; case 0xa010: // 40976 strip_offset = get4(); switch (tiff_ifd[ifd].comp) { case 0x8002: // 32770 load_raw = &LibRaw::samsung_load_raw; break; case 0x8004: // 32772 load_raw = &LibRaw::samsung2_load_raw; break; case 0x8005: // 32773 load_raw = &LibRaw::samsung3_load_raw; break; } break; case 0xb4c3: /* 46275, Imacon tags */ imHassy.format = LIBRAW_HF_Imacon; strcpy(make, "Imacon"); data_offset = ftell(ifp); ima_len = len; break; case 0xb4c7: // 46279 if (!ima_len) break; fseek(ifp, 38, SEEK_CUR); case 0xb4c2: // 46274 fseek(ifp, 40, SEEK_CUR); raw_width = get4(); raw_height = get4(); left_margin = get4() & 7; width = raw_width - left_margin - (get4() & 7); top_margin = get4() & 7; height = raw_height - top_margin - (get4() & 7); if (raw_width == 7262 && ima_len == 234317952) { height = 5412; width = 7216; left_margin = 7; filters = 0; } else if (raw_width == 7262) { height = 5444; width = 7244; left_margin = 7; } fseek(ifp, 52, SEEK_CUR); FORC3 cam_mul[c] = getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); fseek(ifp, 114, SEEK_CUR); flip = (get2() >> 7) * 90; if (width * (height * 6l) == ima_len) { if (flip % 180 == 90) SWAP(width, height); raw_width = width; raw_height = height; left_margin = top_margin = filters = flip = 0; } c = unsigned(height) * unsigned(width) / 1000000; if (c == 32) c--; sprintf(model, "Ixpress %d-Mp", c); load_raw = &LibRaw::imacon_full_load_raw; if (filters) { if (left_margin & 1) filters = 0x61616161; load_raw = &LibRaw::unpacked_load_raw; } maximum = 0xffff; break; case 0xc516: /* 50454, Sinar tag */ case 0xc517: // 50455 if (len < 1 || len > 2560000 || !(cbuf = (char *)malloc(len))) break; if (fread(cbuf, 1, len, ifp) != (int)len) throw LIBRAW_EXCEPTION_IO_CORRUPT; // cbuf to be free'ed in recycle cbuf[len - 1] = 0; for (cp = cbuf - 1; cp && cp < cbuf + len; cp = strchr(cp, '\n')) if (!strncmp(++cp, "Neutral ", 8)) sscanf(cp + 8, "%f %f %f", cam_mul, cam_mul + 1, cam_mul + 2); free(cbuf); break; case 0xc51a: // 50458 if (!make[0]) strcpy(make, "Hasselblad"); break; case 0xc51b: /* 50459, Hasselblad tag */ if (!libraw_internal_data.unpacker_data.hasselblad_parser_flag) { libraw_internal_data.unpacker_data.hasselblad_parser_flag = 1; i = order; j = ftell(ifp); c = tiff_nifds; order = get2(); fseek(ifp, j + (get2(), get4()), SEEK_SET); parse_tiff_ifd(j); maximum = 0xffff; tiff_nifds = c; order = i; break; } case 0xc612: /* 50706, DNGVersion */ FORC4 dng_version = (dng_version << 8) + fgetc(ifp); if (!make[0]) strcpy(make, "DNG"); is_raw = 1; break; case 0xc614: /* 50708, UniqueCameraModel */ stmread(imgdata.color.UniqueCameraModel, len, ifp); if (model[0]) break; strncpy(make, imgdata.color.UniqueCameraModel, MIN(len, sizeof(imgdata.color.UniqueCameraModel))); if ((cp = strchr(make, ' '))) { strcpy(model, cp + 1); *cp = 0; } break; case 0xc616: /* 50710, CFAPlaneColor */ if (filters == 9) break; if (len > 4) len = 4; colors = len; fread(cfa_pc, 1, colors, ifp); guess_cfa_pc: FORCC tab[cfa_pc[c]] = c; cdesc[c] = 0; for (i = 16; i--;) filters = filters << 2 | tab[cfa_pat[i % plen]]; filters -= !filters; tiff_ifd[ifd].t_filters = filters; break; case 0xc617: /* 50711, CFALayout */ if (get2() == 2) tiff_ifd[ifd].t_fuji_width = fuji_width = 1; break; case 0x0123: // 291 case 0xc618: /* 50712, LinearizationTable */ tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_LINTABLE; tiff_ifd[ifd].lineartable_offset = ftell(ifp); tiff_ifd[ifd].lineartable_len = len; linear_table(len); break; case 0xc619: /* 50713, BlackLevelRepeatDim */ tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK; tiff_ifd[ifd].dng_levels.dng_fcblack[4] = tiff_ifd[ifd].dng_levels.dng_cblack[4] = cblack[4] = get2(); tiff_ifd[ifd].dng_levels.dng_fcblack[5] = tiff_ifd[ifd].dng_levels.dng_cblack[5] = cblack[5] = get2(); if (cblack[4] * cblack[5] > (LIBRAW_CBLACK_SIZE - 7)) // Use last cblack item as DNG black level count tiff_ifd[ifd].dng_levels.dng_fcblack[4] = tiff_ifd[ifd].dng_levels.dng_fcblack[5] = tiff_ifd[ifd].dng_levels.dng_cblack[4] = tiff_ifd[ifd].dng_levels.dng_cblack[5] = cblack[4] = cblack[5] = 1; break; case 0xf00c: if (imFuji.RAFDataGeneration != 4096) { unsigned fwb[4]; FORC4 fwb[c] = get4(); if (fwb[3] < 0x100) { FORC3 icWBC[fwb[3]][GRBG_2_RGBG(c)] = fwb[c]; icWBC[fwb[3]][3] = icWBC[fwb[3]][1]; if ((fwb[3] == 17) && // Tungsten WB (libraw_internal_data.unpacker_data.lenRAFData > 3) && (libraw_internal_data.unpacker_data.lenRAFData < 10240000)) { INT64 f_save = ftell(ifp); rafdata = (ushort *)calloc( sizeof(ushort) * libraw_internal_data.unpacker_data.lenRAFData,1); fseek(ifp, libraw_internal_data.unpacker_data.posRAFData, SEEK_SET); fread(rafdata, sizeof(ushort), libraw_internal_data.unpacker_data.lenRAFData, ifp); fseek(ifp, f_save, SEEK_SET); uchar *PrivateMknBuf = (uchar *)rafdata; int PrivateMknLength = libraw_internal_data.unpacker_data.lenRAFData << 1; for (int pos = 0; pos < PrivateMknLength - 16; pos++) { if (!memcmp(PrivateMknBuf + pos, "TSNERDTS", 8)) // STDRENST { imFuji.isTSNERDTS = 1; break; } } int fj; // 31? (fj<<1)-0x3c : 34? (fj<<1)-0x4e : undef int is34 = 0; if ((imFuji.RAFDataVersion == 0x0260) || // X-Pro3, GFX 100S (imFuji.RAFDataVersion == 0x0261) || // X100V, GFX 50S II (imFuji.RAFDataVersion == 0x0262) || // X-T4 (imFuji.RAFDataVersion == 0x0263) || // X-H2S (imFuji.RAFDataVersion == 0x0264) || // X-S10 (imFuji.RAFDataVersion == 0x0265) || // X-E4 (imFuji.RAFDataVersion == 0x0266) || // X-T30 II !strcmp(model, "X-Pro3") || !strcmp(model, "GFX 100S") || !strcmp(model, "GFX100S") || !strcmp(model, "GFX 50S II") || !strcmp(model, "GFX50S II") || !strcmp(model, "X100V") || !strcmp(model, "X-T4") || !strcmp(model, "X-H2S") || !strcmp(model, "X-E4") || !strcmp(model, "X-T30 II") || !strcmp(model, "X-S10")) // is34 cameras have 34 CCT values instead of 31, manual still claims 2500 to 10000 K // aligned 3000 K to Incandescent, as it is usual w/ other Fujifilm cameras is34 = 1; for (int fi = 0; fi < int(libraw_internal_data.unpacker_data.lenRAFData - 3); fi++) // looking for Tungsten WB { if ((fwb[0] == rafdata[fi]) && (fwb[1] == rafdata[fi + 1]) && (fwb[2] == rafdata[fi + 2])) // found Tungsten WB { if (fi > 14 && rafdata[fi - 15] != fwb[0]) // 15 is offset of Tungsten WB from the first // preset, Fine Weather WB continue; if (fi >= 15) { for (int wb_ind = 0, ofst = fi - 15; wb_ind < (int)Fuji_wb_list1.size(); wb_ind++, ofst += 3) { icWBC[Fuji_wb_list1[wb_ind]][1] = icWBC[Fuji_wb_list1[wb_ind]][3] = rafdata[ofst]; icWBC[Fuji_wb_list1[wb_ind]][0] = rafdata[ofst + 1]; icWBC[Fuji_wb_list1[wb_ind]][2] = rafdata[ofst + 2]; } } if (is34) fi += 24; fi += 96; for (fj = fi; fj < (fi + 15); fj += 3) // looking for the end of the WB table { if (fj > libraw_internal_data.unpacker_data.lenRAFData - 3) break; if (rafdata[fj] != rafdata[fi]) { fj -= 93; if (is34) fj -= 9; //printf ("wb start in DNG: 0x%04x\n", fj*2-0x4e); for (int iCCT = 0, ofst = fj; iCCT < 31 && ofst < libraw_internal_data.unpacker_data.lenRAFData - 3; iCCT++, ofst += 3) { icWBCCTC[iCCT][0] = FujiCCT_K[iCCT]; icWBCCTC[iCCT][1] = rafdata[ofst + 1]; icWBCCTC[iCCT][2] = icWBCCTC[iCCT][4] = rafdata[ofst]; icWBCCTC[iCCT][3] = rafdata[ofst + 2]; } break; } } free(rafdata); break; } } } } FORC4 fwb[c] = get4(); if (fwb[3] < 0x100) { FORC3 icWBC[fwb[3]][GRBG_2_RGBG(c)] = fwb[c]; icWBC[fwb[3]][3] = icWBC[fwb[3]][1]; } } break; case 0xf00d: if (imFuji.RAFDataGeneration != 4096) { FORC3 icWBC[LIBRAW_WBI_Auto][GRBG_2_RGBG(c)] = getint(type); icWBC[LIBRAW_WBI_Auto][3] = icWBC[LIBRAW_WBI_Auto][1]; } break; case 0xc615: /* 50709, LocalizedCameraModel */ stmread(imgdata.color.LocalizedCameraModel, len, ifp); break; case 0xf00a: // 61450 cblack[4] = cblack[5] = MIN(sqrt((double)len), 64); case 0xc61a: /* 50714, BlackLevel */ if (tiff_ifd[ifd].samples > 1 && tiff_ifd[ifd].samples == (int)len) // LinearDNG, per-channel black { tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK; for (i = 0; i < 4 && i < (int)len; i++) { tiff_ifd[ifd].dng_levels.dng_fcblack[i] = getreal(type); tiff_ifd[ifd].dng_levels.dng_cblack[i] = cblack[i] = tiff_ifd[ifd].dng_levels.dng_fcblack[i] + 0.5; } // Record len in last cblack field tiff_ifd[ifd].dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1] = len; tiff_ifd[ifd].dng_levels.dng_fblack = tiff_ifd[ifd].dng_levels.dng_black = black = 0; } else if (tiff_ifd[ifd].samples > 1 // Linear DNG w repeat dim && (tiff_ifd[ifd].samples * cblack[4] * cblack[5] == len)) { tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK; tiff_ifd[ifd].dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1] = cblack[LIBRAW_CBLACK_SIZE - 1] = len; for (i = 0; i < (int)len && i < LIBRAW_CBLACK_SIZE - 7; i++) { tiff_ifd[ifd].dng_levels.dng_fcblack[i + 6] = getreal(type); tiff_ifd[ifd].dng_levels.dng_cblack[i + 6] = cblack[i + 6] = tiff_ifd[ifd].dng_levels.dng_fcblack[i + 6] + 0.5; } } else if ((cblack[4] * cblack[5] < 2) && len == 1) { tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK; tiff_ifd[ifd].dng_levels.dng_fblack = getreal(type); black = tiff_ifd[ifd].dng_levels.dng_black = tiff_ifd[ifd].dng_levels.dng_fblack; } else if (cblack[4] * cblack[5] <= len) { FORC(int(cblack[4] * cblack[5])) { tiff_ifd[ifd].dng_levels.dng_fcblack[6 + c] = getreal(type); cblack[6 + c] = tiff_ifd[ifd].dng_levels.dng_fcblack[6 + c]; } black = 0; FORC4 cblack[c] = 0; if (tag == 0xc61a) { tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK; FORC(int(cblack[4] * cblack[5])) tiff_ifd[ifd].dng_levels.dng_cblack[6 + c] = cblack[6 + c]; tiff_ifd[ifd].dng_levels.dng_fblack = 0; tiff_ifd[ifd].dng_levels.dng_black = 0; FORC4 tiff_ifd[ifd].dng_levels.dng_fcblack[c] = tiff_ifd[ifd].dng_levels.dng_cblack[c] = 0; } } break; case 0xc61b: /* 50715, BlackLevelDeltaH */ case 0xc61c: /* 50716, BlackLevelDeltaV */ for (num = i = 0; i < (int)len && i < 65536; i++) num += getreal(type); if (len > 0) { black += num / len + 0.5; tiff_ifd[ifd].dng_levels.dng_fblack += num / float(len); tiff_ifd[ifd].dng_levels.dng_black += num / len + 0.5; tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK; } break; case 0xc61d: /* 50717, WhiteLevel */ tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_WHITE; tiff_ifd[ifd].dng_levels.dng_whitelevel[0] = maximum = getint(type); if (tiff_ifd[ifd].samples > 1) // Linear DNG case for (i = 1; i < 4 && i < (int)len; i++) tiff_ifd[ifd].dng_levels.dng_whitelevel[i] = getint(type); break; case 0xc61e: /* DefaultScale */ { float q1 = getreal(type); float q2 = getreal(type); if (q1 > 0.00001f && q2 > 0.00001f) { pixel_aspect = q1 / q2; if (pixel_aspect > 0.995 && pixel_aspect < 1.005) pixel_aspect = 1.0; } } break; case 0xc61f: /* 50719, DefaultCropOrigin */ if (len == 2) { tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_CROPORIGIN; tiff_ifd[ifd].dng_levels.default_crop[0] = getreal(type); tiff_ifd[ifd].dng_levels.default_crop[1] = getreal(type); if (!strncasecmp(make, "SONY", 4)) { imgdata.sizes.raw_inset_crops[0].cleft = tiff_ifd[ifd].dng_levels.default_crop[0]; imgdata.sizes.raw_inset_crops[0].ctop = tiff_ifd[ifd].dng_levels.default_crop[1]; } } break; case 0xc620: /* 50720, DefaultCropSize */ if (len == 2) { tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_CROPSIZE; tiff_ifd[ifd].dng_levels.default_crop[2] = getreal(type); tiff_ifd[ifd].dng_levels.default_crop[3] = getreal(type); if (!strncasecmp(make, "SONY", 4)) { imgdata.sizes.raw_inset_crops[0].cwidth = tiff_ifd[ifd].dng_levels.default_crop[2]; imgdata.sizes.raw_inset_crops[0].cheight = tiff_ifd[ifd].dng_levels.default_crop[3]; } } break; case 0xc7b5: /* 51125 DefaultUserCrop */ if (len == 4) { int cnt = 0; FORC4 { float v = getreal(type); if (v >= 0.f && v <= 1.f) { tiff_ifd[ifd].dng_levels.user_crop[c] = v; cnt++; } } if(cnt == 4 // valid values && tiff_ifd[ifd].dng_levels.user_crop[0] < tiff_ifd[ifd].dng_levels.user_crop[2] // top < bottom && tiff_ifd[ifd].dng_levels.user_crop[1] < tiff_ifd[ifd].dng_levels.user_crop[3] // left < right ) tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_USERCROP; } break; case 0x74c7: if ((len == 2) && !strncasecmp(make, "SONY", 4)) { imgdata.sizes.raw_inset_crops[0].cleft = get4(); imgdata.sizes.raw_inset_crops[0].ctop = get4(); } break; case 0x74c8: if ((len == 2) && !strncasecmp(make, "SONY", 4)) { imgdata.sizes.raw_inset_crops[0].cwidth = get4(); imgdata.sizes.raw_inset_crops[0].cheight = get4(); } break; case 0xc65a: // 50778 tiff_ifd[ifd].dng_color[0].illuminant = get2(); tiff_ifd[ifd].dng_color[0].parsedfields |= LIBRAW_DNGFM_ILLUMINANT; break; case 0xc65b: // 50779 tiff_ifd[ifd].dng_color[1].illuminant = get2(); tiff_ifd[ifd].dng_color[1].parsedfields |= LIBRAW_DNGFM_ILLUMINANT; break; case 0xc621: /* 50721, ColorMatrix1 */ case 0xc622: /* 50722, ColorMatrix2 */ { int chan = (len == 9) ? 3 : (len == 12 ? 4 : 0); i = tag == 0xc621 ? 0 : 1; if (chan) { tiff_ifd[ifd].dng_color[i].parsedfields |= LIBRAW_DNGFM_COLORMATRIX; imHassy.nIFD_CM[i] = ifd; } FORC(chan) for (j = 0; j < 3; j++) { tiff_ifd[ifd].dng_color[i].colormatrix[c][j] = cm[c][j] = getreal(type); } use_cm = 1; } break; case 0xc714: /* ForwardMatrix1 */ case 0xc715: /* ForwardMatrix2 */ { int chan = (len == 9) ? 3 : (len == 12 ? 4 : 0); i = tag == 0xc714 ? 0 : 1; if (chan) tiff_ifd[ifd].dng_color[i].parsedfields |= LIBRAW_DNGFM_FORWARDMATRIX; for (j = 0; j < 3; j++) FORC(chan) { tiff_ifd[ifd].dng_color[i].forwardmatrix[j][c] = fm[j][c] = getreal(type); } } break; case 0xc623: /* 50723, CameraCalibration1 */ case 0xc624: /* 50724, CameraCalibration2 */ { int chan = (len == 9) ? 3 : (len == 16 ? 4 : 0); j = tag == 0xc623 ? 0 : 1; if (chan) tiff_ifd[ifd].dng_color[j].parsedfields |= LIBRAW_DNGFM_CALIBRATION; for (i = 0; i < chan; i++) FORC(chan) { tiff_ifd[ifd].dng_color[j].calibration[i][c] = cc[i][c] = getreal(type); } } break; case 0xc627: /* 50727, AnalogBalance */ if (len >= 3) tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_ANALOGBALANCE; for (c = 0; c < (int)len && c < 4; c++) { tiff_ifd[ifd].dng_levels.analogbalance[c] = ab[c] = getreal(type); } break; case 0xc628: /* 50728, AsShotNeutral */ if (len >= 3) tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_ASSHOTNEUTRAL; for (c = 0; c < (int)len && c < 4; c++) tiff_ifd[ifd].dng_levels.asshotneutral[c] = asn[c] = getreal(type); break; case 0xc629: /* 50729, AsShotWhiteXY */ xyz[0] = getreal(type); xyz[1] = getreal(type); xyz[2] = 1 - xyz[0] - xyz[1]; FORC3 xyz[c] /= LibRaw_constants::d65_white[c]; break; case 0xc62a: /* DNG: 50730 BaselineExposure */ tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BASELINEEXPOSURE; tiff_ifd[ifd].dng_levels.baseline_exposure = getreal(type); break; case 0xc62e: /* DNG: 50734 LinearResponseLimit */ tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_LINEARRESPONSELIMIT; tiff_ifd[ifd].dng_levels.LinearResponseLimit = getreal(type); break; case 0xc634: /* 50740 : DNG Adobe, DNG Pentax, Sony SR2, DNG Private */ { char mbuf[64]; INT64 curr_pos, start_pos = ftell(ifp); unsigned MakN_order, m_sorder = order; unsigned MakN_length; unsigned pos_in_original_raw; fread(mbuf, 1, 6, ifp); if (!strcmp(mbuf, "Adobe")) { order = 0x4d4d; // Adobe header is always in "MM" / big endian curr_pos = start_pos + 6; while (curr_pos + 8 - start_pos <= len) { fread(mbuf, 1, 4, ifp); curr_pos += 8; if (!strncmp(mbuf, "Pano", 4)) { // PanasonicRaw, yes, they use "Pano" as signature parseAdobePanoMakernote(); } if (!strncmp(mbuf, "MakN", 4)) { MakN_length = get4(); MakN_order = get2(); pos_in_original_raw = get4(); order = MakN_order; INT64 save_pos = ifp->tell(); parse_makernote_0xc634(curr_pos + 6 - pos_in_original_raw, 0, AdobeDNG); curr_pos = save_pos + MakN_length - 6; fseek(ifp, curr_pos, SEEK_SET); fread(mbuf, 1, 4, ifp); curr_pos += 8; if (!strncmp(mbuf, "Pano ", 4)) { parseAdobePanoMakernote(); } if (!strncmp(mbuf, "RAF ", 4)) { // Fujifilm Raw, AdobeRAF parseAdobeRAFMakernote(); } if (!strncmp(mbuf, "SR2 ", 4)) { order = 0x4d4d; MakN_length = get4(); MakN_order = get2(); pos_in_original_raw = get4(); order = MakN_order; unsigned *buf_SR2; unsigned SR2SubIFDOffset = 0; unsigned SR2SubIFDLength = 0; unsigned SR2SubIFDKey = 0; { int _base = curr_pos + 6 - pos_in_original_raw; unsigned _entries, _tag, _type, _len, _save; _entries = get2(); while (_entries--) { tiff_get(_base, &_tag, &_type, &_len, &_save); if (_tag == 0x7200) { SR2SubIFDOffset = get4(); } else if (_tag == 0x7201) { SR2SubIFDLength = get4(); } else if (_tag == 0x7221) { SR2SubIFDKey = get4(); } fseek(ifp, _save, SEEK_SET); } } if (SR2SubIFDLength && (SR2SubIFDLength < 10240000) && (buf_SR2 = (unsigned *)calloc(SR2SubIFDLength + 1024,1))) { // 1024b for safety fseek(ifp, SR2SubIFDOffset + base, SEEK_SET); fread(buf_SR2, SR2SubIFDLength, 1, ifp); sony_decrypt(buf_SR2, SR2SubIFDLength / 4, 1, SR2SubIFDKey); parseSonySR2((uchar *)buf_SR2, SR2SubIFDOffset, SR2SubIFDLength, AdobeDNG); free(buf_SR2); } } /* SR2 processed */ break; } } } else { fread(mbuf + 6, 1, 2, ifp); if (!strcmp(mbuf, "RICOH") && ((sget2((uchar *)mbuf + 6) == 0x4949) || (sget2((uchar *)mbuf + 6) == 0x4d4d))) { is_PentaxRicohMakernotes = 1; } if (!strcmp(mbuf, "PENTAX ") || !strcmp(mbuf, "SAMSUNG") || is_PentaxRicohMakernotes) { fseek(ifp, start_pos, SEEK_SET); parse_makernote_0xc634(base, 0, CameraDNG); } } fseek(ifp, start_pos, SEEK_SET); order = m_sorder; } if (dng_version) { break; } parse_minolta(j = get4() + base); fseek(ifp, j, SEEK_SET); parse_tiff_ifd(base); break; case 0xc640: // 50752 read_shorts(cr2_slice, 3); break; case 0xc68b: /* 50827, OriginalRawFileName */ stmread(imgdata.color.OriginalRawFileName, len, ifp); break; case 0xc68d: /* 50829 ActiveArea */ tiff_ifd[ifd].t_tm = top_margin = getint(type); tiff_ifd[ifd].t_lm = left_margin = getint(type); tiff_ifd[ifd].t_vheight = height = getint(type) - top_margin; tiff_ifd[ifd].t_vwidth = width = getint(type) - left_margin; break; case 0xc68e: /* 50830 MaskedAreas */ for (i = 0; i < (int)len && i < 32; i++) ((int *)mask)[i] = getint(type); black = 0; break; case 0xc71a: /* 50970, PreviewColorSpace */ tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_PREVIEWCS; tiff_ifd[ifd].dng_levels.preview_colorspace = getint(type); break; case 0xc740: /* 51008, OpcodeList1 */ tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_OPCODE1; break; case 0xc741: /* 51009, OpcodeList2 */ tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_OPCODE2; tiff_ifd[ifd].opcode2_offset = meta_offset = ftell(ifp); break; case 0xc74e: /* 51022, OpcodeList3 */ tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_OPCODE3; break; case 0xfd04: /* 64772, Kodak P-series */ if (len < 13) break; fseek(ifp, 16, SEEK_CUR); data_offset = get4(); fseek(ifp, 28, SEEK_CUR); data_offset += get4(); load_raw = &LibRaw::packed_load_raw; break; case 0xfe02: // 65026 if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII)) fgets(model2, 64, ifp); } fseek(ifp, save, SEEK_SET); } if (sony_length && sony_length < 10240000 && (buf = (unsigned *)calloc(sony_length, 1))) { fseek(ifp, sony_offset, SEEK_SET); fread(buf, sony_length, 1, ifp); sony_decrypt(buf, sony_length / 4, 1, sony_key); parseSonySR2((uchar *)buf, sony_offset, sony_length, nonDNG); free(buf); } for (i = 0; i < colors && i < 4; i++) FORCC cc[i][c] *= ab[i]; if (use_cm) { FORCC for (i = 0; i < 3; i++) for (cam_xyz[c][i] = j = 0; j < colors; j++) cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i]; cam_xyz_coeff(cmatrix, cam_xyz); } if (asn[0]) { cam_mul[3] = 0; FORCC if (fabs(asn[c]) > 0.0001) cam_mul[c] = 1 / asn[c]; } if (!use_cm) FORCC if (fabs(cc[c][c]) > 0.0001) pre_mul[c] /= cc[c][c]; return 0; } int LibRaw::parse_tiff(int _base) { INT64 base = _base; int doff; fseek(ifp, base, SEEK_SET); order = get2(); if (order != 0x4949 && order != 0x4d4d) return 0; get2(); while ((doff = get4())) { INT64 doff64 = doff; if (doff64 + base > ifp->size()) break; fseek(ifp, doff64 + base, SEEK_SET); if (parse_tiff_ifd(_base)) break; } return 1; } struct ifd_size_t { int ifdi; INT64 databits; }; int ifd_size_t_cmp(const void *a, const void *b) { if (!a || !b) return 0; const ifd_size_t *ai = (ifd_size_t *)a; const ifd_size_t *bi = (ifd_size_t *)b; return bi->databits > ai->databits ? 1 : (bi->databits < ai->databits ? -1 : 0); } static LibRaw_internal_thumbnail_formats tiff2thumbformat(int _comp, int _phint, int _bps, const char *_make); void LibRaw::apply_tiff() { int max_samp = 0, ties = 0, raw = -1, thm = -1, i; unsigned long long ns, os; struct jhead jh; thumb_misc = 16; if (thumb_offset) { fseek(ifp, thumb_offset, SEEK_SET); if (ljpeg_start(&jh, 1)) { if ((unsigned)jh.bits < 17 && (unsigned)jh.wide < 0x10000 && (unsigned)jh.high < 0x10000) { thumb_misc = jh.bits; thumb_width = jh.wide; thumb_height = jh.high; } } } for (i = tiff_nifds; i--;) { if (tiff_ifd[i].t_shutter) shutter = tiff_ifd[i].t_shutter; tiff_ifd[i].t_shutter = shutter; } if (dng_version) { int ifdc = 0; for (i = 0; i < (int)tiff_nifds; i++) { if (tiff_ifd[i].t_width < 1 || tiff_ifd[i].t_width > 65535 || tiff_ifd[i].t_height < 1 || tiff_ifd[i].t_height > 65535) continue; /* wrong image dimensions */ int samp = tiff_ifd[i].samples; if (samp == 2) samp = 1; // Fuji 2-frame max_samp = LIM(MAX(max_samp, samp), 1, 3); // max_samp is needed for thumbnail selection below if ( // Check phint only for RAW subfiletype (tiff_ifd[i].newsubfiletype == 16 || tiff_ifd[i].newsubfiletype == 0 || (tiff_ifd[i].newsubfiletype & 0xffff) == 1) && (tiff_ifd[i].phint != 32803 && tiff_ifd[i].phint != 34892) ) continue; if ((tiff_ifd[i].newsubfiletype == 0) // main image // Enhanced demosaiced: || (tiff_ifd[i].newsubfiletype == 16 && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_ADD_ENHANCED)) // Preview: 0x1 or 0x10001 || ((tiff_ifd[i].newsubfiletype & 0xffff) == 1 && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_ADD_PREVIEWS)) // Transparency mask: 0x4 || ((tiff_ifd[i].newsubfiletype & 0xffff) == 4 && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_ADD_MASKS))) { // Add this IFD to dng_frames libraw_internal_data.unpacker_data.dng_frames[ifdc] = ((tiff_ifd[i].newsubfiletype & 0xffff) << 16) | ((i << 8) & 0xff00); ifdc++; // Fuji SuperCCD: second frame: if ((tiff_ifd[i].newsubfiletype == 0) && tiff_ifd[i].samples == 2) { libraw_internal_data.unpacker_data.dng_frames[ifdc] = ((tiff_ifd[i].newsubfiletype & 0xffff) << 16) | ((i << 8) & 0xff00) | 1; ifdc++; } } } if (ifdc) { if (ifdc > 1 && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_PREFER_LARGEST_IMAGE)) { ifd_size_t arr[LIBRAW_IFD_MAXCOUNT * 2]; memset(arr, 0, sizeof(arr)); for (int q = 0; q < ifdc && q < LIBRAW_IFD_MAXCOUNT * 2; q++) { int ifdidx = (libraw_internal_data.unpacker_data.dng_frames[q] >> 8) & 0xff; arr[q].ifdi = libraw_internal_data.unpacker_data.dng_frames[q]; arr[q].databits = tiff_ifd[ifdidx].t_width * tiff_ifd[ifdidx].t_height * tiff_ifd[ifdidx].samples * tiff_ifd[ifdidx].bps + (0x100 - (arr[q].ifdi & 0xff)); // add inverted frame # to ensure same // sort order for similar sized frames. if (tiff_ifd[ifdidx].phint == 4) arr[q].databits /= 4; // Force lower bit count for Transp. mask images } qsort(arr, MIN(ifdc, LIBRAW_IFD_MAXCOUNT * 2), sizeof(arr[0]), ifd_size_t_cmp); for (int q = 0; q < ifdc && q < LIBRAW_IFD_MAXCOUNT * 2; q++) libraw_internal_data.unpacker_data.dng_frames[q] = arr[q].ifdi; } int idx = LIM((int)shot_select, 0, ifdc - 1); i = (libraw_internal_data.unpacker_data.dng_frames[idx] >> 8) & 0xff; // extract frame# back raw_width = tiff_ifd[i].t_width; raw_height = tiff_ifd[i].t_height; tiff_bps = tiff_ifd[i].bps; tiff_compress = tiff_ifd[i].comp; tiff_sampleformat = tiff_ifd[i].sample_format; data_offset = tiff_ifd[i].offset; data_size = tiff_ifd[i].bytes; tiff_flip = tiff_ifd[i].t_flip; tiff_samples = tiff_ifd[i].samples; tile_width = tiff_ifd[i].t_tile_width; tile_length = tiff_ifd[i].t_tile_length; fuji_width = tiff_ifd[i].t_fuji_width; if (tiff_samples != 2) /* special case: Fuji SuperCCD */ { if (tiff_ifd[i].phint == 34892) filters = 0; else if (i > 0 && tiff_ifd[i].phint == 32803 && tiff_ifd[0].phint == 32803 && !tiff_ifd[i].t_filters && tiff_ifd[0].t_filters) filters = tiff_ifd[0].t_filters; else filters = tiff_ifd[i].t_filters; width = tiff_ifd[i].t_vwidth; height = tiff_ifd[i].t_vheight; top_margin = tiff_ifd[i].t_tm; left_margin = tiff_ifd[i].t_lm; shutter = tiff_ifd[i].t_shutter; if (tiff_ifd[i].dng_levels.dng_whitelevel[0]) maximum = tiff_ifd[i].dng_levels.dng_whitelevel[0]; else if (tiff_ifd[i].sample_format <= 2 && tiff_bps > 0 && tiff_bps < 32) // SampleFormat: 0-default(1), 1 - Uint, 2 - Int maximum = (1 << tiff_bps) - 1; else if (tiff_ifd[i].sample_format == 3) maximum = 1; // Defaults for FP } raw = i; is_raw = ifdc; } else is_raw = 0; } else { // Fix for broken Sony bps tag if (!strncasecmp(make, "Sony", 4)) { for (i = 0; i < (int)tiff_nifds; i++) { if (tiff_ifd[i].bps > 33 && tiff_ifd[i].samples == 1) { int bps = 14; // default if (tiff_ifd[i].dng_levels.dng_whitelevel[0] > 0) { for(int c = 0,j=1; c < 16; c++, j<<=1) if (j > (int)tiff_ifd[i].dng_levels.dng_whitelevel[0]) { bps = c; break; } } tiff_ifd[i].bps = bps; } } } for (i = 0; i < (int)tiff_nifds; i++) { if (tiff_ifd[i].t_width < 1 || tiff_ifd[i].t_width > 65535 || tiff_ifd[i].t_height < 1 || tiff_ifd[i].t_height > 65535) continue; /* wrong image dimensions */ if (max_samp < tiff_ifd[i].samples) max_samp = tiff_ifd[i].samples; if (max_samp > 3) max_samp = 3; os = unsigned(raw_width) * unsigned(raw_height); ns = unsigned(tiff_ifd[i].t_width) * unsigned(tiff_ifd[i].t_height); if (tiff_bps) { os *= tiff_bps; ns *= tiff_ifd[i].bps; } /* too complex if below, so separate if to skip RGB+Alpha TIFFs*/ if (tiff_ifd[i].phint == 2 && tiff_ifd[i].extrasamples > 0 && tiff_ifd[i].samples > 3) continue; // SKIP RGB+Alpha IFDs if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) && unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 && (unsigned)tiff_ifd[i].bps < 33 && (unsigned)tiff_ifd[i].samples < 13 && ns && ((ns > os && (ties = 1)) || (ns == os && (int)shot_select == ties++))) { raw_width = tiff_ifd[i].t_width; raw_height = tiff_ifd[i].t_height; tiff_bps = tiff_ifd[i].bps; tiff_compress = tiff_ifd[i].comp; tiff_sampleformat = tiff_ifd[i].sample_format; data_offset = tiff_ifd[i].offset; data_size = tiff_ifd[i].bytes; tiff_flip = tiff_ifd[i].t_flip; tiff_samples = tiff_ifd[i].samples; tile_width = tiff_ifd[i].t_tile_width; tile_length = tiff_ifd[i].t_tile_length; shutter = tiff_ifd[i].t_shutter; raw = i; } } if (is_raw == 1 && ties) is_raw = ties; } if (is_NikonTransfer && raw >= 0) { if (tiff_ifd[raw].bps == 16) { if (tiff_compress == 1) { if ((raw_width * raw_height * 3) == (tiff_ifd[raw].bytes << 1)) { tiff_bps = tiff_ifd[raw].bps = 12; } else { tiff_bps = tiff_ifd[raw].bps = 14; } } } else if (tiff_ifd[raw].bps == 8) { if (tiff_compress == 1) { is_NikonTransfer = 2; // 8-bit debayered TIFF, like CoolScan NEFs imgdata.rawparams.coolscan_nef_gamma = 2.2f; } } } if (!tile_width) tile_width = INT_MAX; if (!tile_length) tile_length = INT_MAX; for (i = tiff_nifds; i--;) if (tiff_ifd[i].t_flip) tiff_flip = tiff_ifd[i].t_flip; #if 0 if (raw < 0 && is_raw) is_raw = 0; #endif if (raw >= 0 && !load_raw) switch (tiff_compress) { case 32767: if (!dng_version && INT64(tiff_ifd[raw].bytes) == INT64(raw_width) * INT64(raw_height)) { tiff_bps = 14; load_raw = &LibRaw::sony_arw2_load_raw; break; } if (!dng_version && !strncasecmp(make, "Sony", 4) && INT64(tiff_ifd[raw].bytes) == INT64(raw_width) * INT64(raw_height) * 2LL) { tiff_bps = 14; load_raw = &LibRaw::unpacked_load_raw; break; } if (INT64(tiff_ifd[raw].bytes) * 8LL != INT64(raw_width) * INT64(raw_height) * INT64(tiff_bps)) { raw_height += 8; load_raw = &LibRaw::sony_arw_load_raw; break; } load_flags = 79; case 32769: load_flags++; case 32770: case 32773: goto slr; case 0: case 1: if (dng_version && tiff_sampleformat == 3 && (tiff_bps > 8 && (tiff_bps % 8 == 0) && (tiff_bps <= 32))) // only 16,24, and 32 are allowed { load_raw = &LibRaw::uncompressed_fp_dng_load_raw; break; } // Sony 14-bit uncompressed if (!dng_version && !strncasecmp(make, "Sony", 4) && INT64(tiff_ifd[raw].bytes) == INT64(raw_width) * INT64(raw_height) * 2LL) { tiff_bps = 14; load_raw = &LibRaw::unpacked_load_raw; break; } if (!dng_version && !strncasecmp(make, "Sony", 4) && tiff_ifd[raw].samples == 4 && INT64(tiff_ifd[raw].bytes) == INT64(raw_width) * INT64(raw_height) * 8LL) // Sony ARQ { // maybe to detect ARQ with the following: // if (tiff_ifd[raw].phint == 32892) tiff_bps = 14; tiff_samples = 4; load_raw = &LibRaw::sony_arq_load_raw; filters = 0; strcpy(cdesc, "RGBG"); break; } if (!strncasecmp(make, "Nikon", 5) && (!strncmp(software, "Nikon Scan", 10) || (is_NikonTransfer == 2) || strcasestr(model, "COOLSCAN"))) { load_raw = &LibRaw::nikon_coolscan_load_raw; raw_color = 1; colors = (tiff_samples == 3) ? 3 : 1; filters = 0; break; } if ((!strncmp(make, "OLYMPUS", 7) || !strncmp(make, "OM Digi", 7) || (!strncasecmp(make, "CLAUSS", 6) && !strncasecmp(model, "piX 5oo", 7))) && // 0x5330303539 works here (INT64(tiff_ifd[raw].bytes) * 2ULL == INT64(raw_width) * INT64(raw_height) * 3ULL)) load_flags = 24; if (!dng_version && INT64(tiff_ifd[raw].bytes) * 5ULL == INT64(raw_width) * INT64(raw_height) * 8ULL) { load_flags = 81; tiff_bps = 12; } slr: switch (tiff_bps) { case 8: load_raw = &LibRaw::eight_bit_load_raw; break; case 12: if (tiff_ifd[raw].phint == 2) load_flags = 6; if (!strncasecmp(make, "NIKON", 5) && !strncasecmp(model, "COOLPIX A1000", 13) && data_size == raw_width * raw_height * 2u) load_raw = &LibRaw::unpacked_load_raw; else load_raw = &LibRaw::packed_load_raw; break; case 14: load_flags = 0; case 16: load_raw = &LibRaw::unpacked_load_raw; if ((!strncmp(make, "OLYMPUS", 7) || !strncmp(make, "OM Digi", 7) || (!strncasecmp(make, "CLAUSS", 6) && !strncasecmp(model, "piX 5oo", 7))) && // 0x5330303539 works here (INT64(tiff_ifd[raw].bytes) * 7LL > INT64(raw_width) * INT64(raw_height))) load_raw = &LibRaw::olympus_load_raw; } break; case 6: case 7: case 99: if (!dng_version && tiff_compress == 6 && !strcasecmp(make, "SONY")) load_raw = &LibRaw::sony_ljpeg_load_raw; else load_raw = &LibRaw::lossless_jpeg_load_raw; break; case 262: load_raw = &LibRaw::kodak_262_load_raw; break; case 34713: if ((INT64(raw_width) + 9LL) / 10LL * 16LL * INT64(raw_height) == INT64(tiff_ifd[raw].bytes)) { load_raw = &LibRaw::packed_load_raw; load_flags = 1; } else if (INT64(raw_width) * INT64(raw_height) * 3LL == INT64(tiff_ifd[raw].bytes) * 2LL) { load_raw = &LibRaw::packed_load_raw; if (model[0] == 'N') load_flags = 80; } else if (INT64(raw_width) * INT64(raw_height) * 3LL == INT64(tiff_ifd[raw].bytes)) { load_raw = &LibRaw::nikon_yuv_load_raw; gamma_curve(1 / 2.4, 12.92, 1, 4095); memset(cblack, 0, sizeof cblack); filters = 0; } else if (INT64(raw_width) * INT64(raw_height) * 2LL == INT64(tiff_ifd[raw].bytes)) { load_raw = &LibRaw::unpacked_load_raw; load_flags = 4; order = 0x4d4d; } #if 0 /* Never used because of same condition above, but need to recheck */ else if (INT64(raw_width) * INT64(raw_height) * 3LL == INT64(tiff_ifd[raw].bytes) * 2LL) { load_raw = &LibRaw::packed_load_raw; load_flags = 80; } #endif else if (tiff_ifd[raw].rows_per_strip && tiff_ifd[raw].strip_offsets_count && tiff_ifd[raw].strip_offsets_count == tiff_ifd[raw].strip_byte_counts_count) { int fit = 1; for (int q = 0; q < tiff_ifd[raw].strip_byte_counts_count - 1; q++) // all but last if (INT64(tiff_ifd[raw].strip_byte_counts[q]) * 2LL != INT64(tiff_ifd[raw].rows_per_strip) * INT64(raw_width) * 3LL) { fit = 0; break; } if (fit) load_raw = &LibRaw::nikon_load_striped_packed_raw; else load_raw = &LibRaw::nikon_load_raw; // fallback } else if ((((INT64(raw_width) * 3LL / 2LL) + 15LL) / 16LL) * 16LL * INT64(raw_height) == INT64(tiff_ifd[raw].bytes)) { load_raw = &LibRaw::nikon_load_padded_packed_raw; load_flags = (((INT64(raw_width) * 3ULL / 2ULL) + 15ULL) / 16ULL) * 16ULL; // bytes per row } else if (!strncmp(model, "NIKON Z 9", 9) && tiff_ifd[raw].offset) { INT64 pos = ftell(ifp); unsigned char cmp[] = "CONTACT_INTOPIX"; // 15 unsigned char buf[16]; fseek(ifp, INT64(tiff_ifd[raw].offset) + 6LL, SEEK_SET); fread(buf, 1, 16, ifp); fseek(ifp, pos, SEEK_SET); if(!memcmp(buf,cmp,15)) load_raw = &LibRaw::nikon_he_load_raw_placeholder; else load_raw = &LibRaw::nikon_load_raw; } else load_raw = &LibRaw::nikon_load_raw; break; case 65535: load_raw = &LibRaw::pentax_load_raw; break; case 65000: switch (tiff_ifd[raw].phint) { case 2: load_raw = &LibRaw::kodak_rgb_load_raw; filters = 0; break; case 6: load_raw = &LibRaw::kodak_ycbcr_load_raw; filters = 0; break; case 32803: load_raw = &LibRaw::kodak_65000_load_raw; } case 32867: case 34892: break; case 8: break; #ifdef USE_GPRSDK case 9: if (dng_version) break; /* Compression=9 supported for dng if we compiled with GPR SDK */ /* Else: fallthrough */ #endif default: is_raw = 0; } if (!dng_version) { if (((tiff_samples == 3 && tiff_ifd[raw].bytes && !(tiff_bps == 16 && !strncmp(make, "Leaf", 4)) && // Allow Leaf/16bit/3color files tiff_bps != 14 && (tiff_compress & -16) != 32768) || (tiff_bps == 8 && strncmp(make, "Phase", 5) && strncmp(make, "Leaf", 4) && !strcasestr(make, "Kodak") && !strstr(model2, "DEBUG RAW"))) && !strcasestr(model, "COOLSCAN") && strncmp(software, "Nikon Scan", 10) && is_NikonTransfer != 2) is_raw = 0; if (is_raw && raw >= 0 && tiff_ifd[raw].phint == 2 && tiff_ifd[raw].extrasamples > 0 && tiff_ifd[raw].samples > 3) is_raw = 0; // SKIP RGB+Alpha IFDs } INT64 fsizecheck = 0ULL; if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_ALL_VENDORS) fsizecheck = ifp->size(); else if ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_KNOWN_VENDORS) && !strncasecmp(make,"Ricoh",5)) fsizecheck = ifp->size(); for (i = 0; i < (int)tiff_nifds; i++) if (i != raw && (tiff_ifd[i].samples == max_samp || (tiff_ifd[i].comp == 7 && tiff_ifd[i].samples == 1)) /* Allow 1-bps JPEGs */ && tiff_ifd[i].bps > 0 && tiff_ifd[i].bps < 33 && tiff_ifd[i].phint != 32803 && tiff_ifd[i].phint != 34892 && unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 && tiff_ifd[i].comp != 34892) { if (fsizecheck > 0LL) { bool ok = true; if (tiff_ifd[i].strip_byte_counts_count && tiff_ifd[i].strip_offsets_count) for (int s = 0; s < MIN(tiff_ifd[i].strip_byte_counts_count, tiff_ifd[i].strip_offsets_count); s++) { if (tiff_ifd[i].strip_offsets[s] + tiff_ifd[i].strip_byte_counts[s] > fsizecheck) { ok = false; break; } } else if (tiff_ifd[i].bytes > 0) if (tiff_ifd[i].offset + tiff_ifd[i].bytes > fsizecheck) ok = false; if(!ok) continue; } if ( (INT64(tiff_ifd[i].t_width) * INT64(tiff_ifd[i].t_height) / INT64(SQR(tiff_ifd[i].bps) + 1)) > (INT64(thumb_width) * INT64(thumb_height) / INT64(SQR(thumb_misc) + 1)) ) { thumb_width = tiff_ifd[i].t_width; thumb_height = tiff_ifd[i].t_height; thumb_offset = tiff_ifd[i].offset; thumb_length = tiff_ifd[i].bytes; thumb_misc = tiff_ifd[i].bps; thm = i; } if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT && tiff_ifd[i].bytes > 0) { bool already = false; for(int idx = 0; idx < imgdata.thumbs_list.thumbcount ; idx++) if (imgdata.thumbs_list.thumblist[idx].toffset == tiff_ifd[i].offset) { already = true; break; } if (!already) { int idx = imgdata.thumbs_list.thumbcount; imgdata.thumbs_list.thumblist[idx].tformat = tiff2thumbformat(tiff_ifd[i].comp, tiff_ifd[i].phint, tiff_ifd[i].bps, make); imgdata.thumbs_list.thumblist[idx].twidth = tiff_ifd[i].t_width; imgdata.thumbs_list.thumblist[idx].theight = tiff_ifd[i].t_height; imgdata.thumbs_list.thumblist[idx].tflip = tiff_ifd[i].t_flip; imgdata.thumbs_list.thumblist[idx].tlength = tiff_ifd[i].bytes; imgdata.thumbs_list.thumblist[idx].tmisc = tiff_ifd[i].bps | (tiff_ifd[i].samples << 5); imgdata.thumbs_list.thumblist[idx].toffset = tiff_ifd[i].offset; imgdata.thumbs_list.thumbcount++; } } } if (thm >= 0) { thumb_misc |= tiff_ifd[thm].samples << 5; thumb_format = tiff2thumbformat(tiff_ifd[thm].comp, tiff_ifd[thm].phint, tiff_ifd[thm].bps, make); } } static LibRaw_internal_thumbnail_formats tiff2thumbformat(int _comp, int _phint, int _bps, const char *_make) { switch (_comp) { case 0: return LIBRAW_INTERNAL_THUMBNAIL_LAYER; case 1: if (_bps <= 8) return LIBRAW_INTERNAL_THUMBNAIL_PPM; else if (!strncmp(_make, "Imacon", 6)) return LIBRAW_INTERNAL_THUMBNAIL_PPM16; else return LIBRAW_INTERNAL_THUMBNAIL_KODAK_THUMB; case 65000: return _phint == 6 ? LIBRAW_INTERNAL_THUMBNAIL_KODAK_YCBCR : LIBRAW_INTERNAL_THUMBNAIL_KODAK_RGB; } return LIBRAW_INTERNAL_THUMBNAIL_JPEG; // default } LibRaw-0.21.4/src/postprocessing/000077500000000000000000000000001477673233700166525ustar00rootroot00000000000000LibRaw-0.21.4/src/postprocessing/aspect_ratio.cpp000066400000000000000000000064161477673233700220420ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" void LibRaw::fuji_rotate() { int i, row, col; double step; float r, c, fr, fc; unsigned ur, uc; ushort wide, high, (*img)[4], (*pix)[4]; if (!fuji_width) return; fuji_width = (fuji_width - 1 + shrink) >> shrink; step = sqrt(0.5); wide = fuji_width / step; high = (height - fuji_width) / step; // All real fuji/rotated images are small, so check against max_raw_memory_mb here is safe if (INT64(wide) * INT64(high) * INT64(sizeof(*img)) > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) throw LIBRAW_EXCEPTION_TOOBIG; img = (ushort(*)[4])calloc(high, wide * sizeof *img); RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE, 0, 2); for (row = 0; row < high; row++) for (col = 0; col < wide; col++) { ur = r = fuji_width + (row - col) * step; uc = c = (row + col) * step; if (ur > (unsigned)height - 2 || uc > (unsigned)width - 2) continue; fr = r - ur; fc = c - uc; pix = image + ur * width + uc; for (i = 0; i < colors; i++) img[row * wide + col][i] = (pix[0][i] * (1 - fc) + pix[1][i] * fc) * (1 - fr) + (pix[width][i] * (1 - fc) + pix[width + 1][i] * fc) * fr; } free(image); width = wide; height = high; image = img; fuji_width = 0; RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE, 1, 2); } void LibRaw::stretch() { ushort newdim, (*img)[4], *pix0, *pix1; int row, col, c; double rc, frac; if (pixel_aspect == 1) return; RUN_CALLBACK(LIBRAW_PROGRESS_STRETCH, 0, 2); if (pixel_aspect < 1) { newdim = height / pixel_aspect + 0.5; img = (ushort(*)[4])calloc(width, newdim * sizeof *img); for (rc = row = 0; row < newdim; row++, rc += pixel_aspect) { frac = rc - (c = rc); pix0 = pix1 = image[c * width]; if (c + 1 < height) pix1 += width * 4; for (col = 0; col < width; col++, pix0 += 4, pix1 += 4) FORCC img[row * width + col][c] = pix0[c] * (1 - frac) + pix1[c] * frac + 0.5; } height = newdim; } else { newdim = width * pixel_aspect + 0.5; img = (ushort(*)[4])calloc(height, newdim * sizeof *img); for (rc = col = 0; col < newdim; col++, rc += 1 / pixel_aspect) { frac = rc - (c = rc); pix0 = pix1 = image[c]; if (c + 1 < width) pix1 += 4; for (row = 0; row < height; row++, pix0 += width * 4, pix1 += width * 4) FORCC img[row * newdim + col][c] = pix0[c] * (1 - frac) + pix1[c] * frac + 0.5; } width = newdim; } free(image); image = img; RUN_CALLBACK(LIBRAW_PROGRESS_STRETCH, 1, 2); } LibRaw-0.21.4/src/postprocessing/dcraw_process.cpp000066400000000000000000000145021477673233700222160ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" int LibRaw::dcraw_process(void) { int quality, i; int iterations = -1, dcb_enhance = 1, noiserd = 0; float preser = 0; float expos = 1.0; CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW); // CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE); try { int no_crop = 1; if (~O.cropbox[2] && ~O.cropbox[3]) no_crop = 0; libraw_decoder_info_t di; get_decoder_info(&di); bool is_bayer = (imgdata.idata.filters || P1.colors == 1); int subtract_inline = !O.bad_pixels && !O.dark_frame && is_bayer && !IO.zero_is_bad; int rc = raw2image_ex(subtract_inline); // allocate imgdata.image and copy data! if (rc != LIBRAW_SUCCESS) return rc; // Adjust sizes int save_4color = O.four_color_rgb; if (IO.zero_is_bad) { remove_zeroes(); SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES); } if (O.bad_pixels && no_crop) { bad_pixels(O.bad_pixels); SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS); } if (O.dark_frame && no_crop) { subtract(O.dark_frame); SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME); } /* pre subtract black callback: check for it above to disable subtract * inline */ if (callbacks.pre_subtractblack_cb) (callbacks.pre_subtractblack_cb)(this); quality = 2 + !IO.fuji_width; if (O.user_qual >= 0) quality = O.user_qual; if (!subtract_inline || !C.data_maximum) { adjust_bl(); subtract_black_internal(); } if (!(di.decoder_flags & LIBRAW_DECODER_FIXEDMAXC)) adjust_maximum(); if (O.user_sat > 0) C.maximum = O.user_sat; if (P1.is_foveon) { if (load_raw == &LibRaw::x3f_load_raw) { // Filter out zeroes for (int q = 0; q < S.height * S.width; q++) { for (int c = 0; c < 4; c++) if ((short)imgdata.image[q][c] < 0) imgdata.image[q][c] = 0; } } SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE); } if (O.green_matching && !O.half_size) { green_matching(); } if (callbacks.pre_scalecolors_cb) (callbacks.pre_scalecolors_cb)(this); if (!O.no_auto_scale) { scale_colors(); SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS); } if (callbacks.pre_preinterpolate_cb) (callbacks.pre_preinterpolate_cb)(this); pre_interpolate(); SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE); if (O.dcb_iterations >= 0) iterations = O.dcb_iterations; if (O.dcb_enhance_fl >= 0) dcb_enhance = O.dcb_enhance_fl; if (O.fbdd_noiserd >= 0) noiserd = O.fbdd_noiserd; /* pre-exposure correction callback */ if (O.exp_correc > 0) { expos = O.exp_shift; preser = O.exp_preser; exp_bef(expos, preser); } if (callbacks.pre_interpolate_cb) (callbacks.pre_interpolate_cb)(this); /* post-exposure correction fallback */ if (P1.filters && !O.no_interpolation) { if (noiserd > 0 && P1.colors == 3 && P1.filters > 1000) fbdd(noiserd); if (P1.filters > 1000 && callbacks.interpolate_bayer_cb) (callbacks.interpolate_bayer_cb)(this); else if (P1.filters == 9 && callbacks.interpolate_xtrans_cb) (callbacks.interpolate_xtrans_cb)(this); else if (quality == 0) lin_interpolate(); else if (quality == 1 || P1.colors > 3) vng_interpolate(); else if (quality == 2 && P1.filters > 1000) ppg_interpolate(); else if (P1.filters == LIBRAW_XTRANS) { // Fuji X-Trans xtrans_interpolate(quality > 2 ? 3 : 1); } else if (quality == 3) ahd_interpolate(); // really don't need it here due to fallback op else if (quality == 4) dcb(iterations, dcb_enhance); else if (quality == 11) dht_interpolate(); else if (quality == 12) aahd_interpolate(); // fallback to AHD else { ahd_interpolate(); imgdata.process_warnings |= LIBRAW_WARN_FALLBACK_TO_AHD; } SET_PROC_FLAG(LIBRAW_PROGRESS_INTERPOLATE); } if (IO.mix_green) { for (P1.colors = 3, i = 0; i < S.height * S.width; i++) imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1; SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN); } if (callbacks.post_interpolate_cb) (callbacks.post_interpolate_cb)(this); else if (!P1.is_foveon && P1.colors == 3 && O.med_passes > 0) { median_filter(); SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER); } if (O.highlight == 2) { blend_highlights(); SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS); } if (O.highlight > 2) { recover_highlights(); SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS); } if (O.use_fuji_rotate) { fuji_rotate(); SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE); } if (!libraw_internal_data.output_data.histogram) { libraw_internal_data.output_data.histogram = (int(*)[LIBRAW_HISTOGRAM_SIZE])calloc(1, sizeof(*libraw_internal_data.output_data.histogram) * 4); } #ifndef NO_LCMS if (O.camera_profile) { apply_profile(O.camera_profile, O.output_profile); SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE); } #endif if (callbacks.pre_converttorgb_cb) (callbacks.pre_converttorgb_cb)(this); convert_to_rgb(); SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB); if (callbacks.post_converttorgb_cb) (callbacks.post_converttorgb_cb)(this); if (O.use_fuji_rotate) { stretch(); SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH); } O.four_color_rgb = save_4color; // also, restore return 0; } catch (const std::bad_alloc&) { recycle(); return LIBRAW_UNSUFFICIENT_MEMORY; } catch (const LibRaw_exceptions& err) { EXCEPTION_HANDLER(err); } } LibRaw-0.21.4/src/postprocessing/mem_image.cpp000066400000000000000000000162341477673233700213040ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" libraw_processed_image_t *LibRaw::dcraw_make_mem_thumb(int *errcode) { if (!T.thumb) { if (!ID.toffset && !(imgdata.thumbnail.tlength > 0 && load_raw == &LibRaw::broadcom_load_raw) // RPi ) { if (errcode) *errcode = LIBRAW_NO_THUMBNAIL; } else { if (errcode) *errcode = LIBRAW_OUT_OF_ORDER_CALL; } return NULL; } if (T.tlength < 64u) { if (errcode) *errcode = EINVAL; return NULL; } if (INT64(T.tlength) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) { if (errcode) *errcode = LIBRAW_TOO_BIG; return NULL; } if (T.tformat == LIBRAW_THUMBNAIL_BITMAP) { libraw_processed_image_t *ret = (libraw_processed_image_t *)::malloc( sizeof(libraw_processed_image_t) + T.tlength); if (!ret) { if (errcode) *errcode = ENOMEM; return NULL; } memset(ret, 0, sizeof(libraw_processed_image_t)); ret->type = LIBRAW_IMAGE_BITMAP; ret->height = T.theight; ret->width = T.twidth; if (T.tcolors > 0 && T.tcolors < 4) ret->colors = T.tcolors; else ret->colors = 3; // defaults ret->bits = 8; ret->data_size = T.tlength; memmove(ret->data, T.thumb, T.tlength); if (errcode) *errcode = 0; return ret; } else if (T.tformat == LIBRAW_THUMBNAIL_JPEG) { ushort exif[5]; int mk_exif = 0; if (strcmp(T.thumb + 6, "Exif")) mk_exif = 1; int dsize = T.tlength + mk_exif * (sizeof(exif) + sizeof(tiff_hdr)); libraw_processed_image_t *ret = (libraw_processed_image_t *)::malloc( sizeof(libraw_processed_image_t) + dsize); if (!ret) { if (errcode) *errcode = ENOMEM; return NULL; } memset(ret, 0, sizeof(libraw_processed_image_t)); ret->type = LIBRAW_IMAGE_JPEG; ret->data_size = dsize; ret->data[0] = 0xff; ret->data[1] = 0xd8; if (mk_exif) { struct tiff_hdr th; memcpy(exif, "\xff\xe1 Exif\0\0", 10); exif[1] = htons(8 + sizeof th); memmove(ret->data + 2, exif, sizeof(exif)); tiff_head(&th, 0); memmove(ret->data + (2 + sizeof(exif)), &th, sizeof(th)); memmove(ret->data + (2 + sizeof(exif) + sizeof(th)), T.thumb + 2, T.tlength - 2); } else { memmove(ret->data + 2, T.thumb + 2, T.tlength - 2); } if (errcode) *errcode = 0; return ret; } else { if (errcode) *errcode = LIBRAW_UNSUPPORTED_THUMBNAIL; return NULL; } } // jlb // macros for copying pixels to either BGR or RGB formats #define FORBGR for (c = P1.colors - 1; c >= 0; c--) #define FORRGB for (c = 0; c < P1.colors; c++) void LibRaw::get_mem_image_format(int *width, int *height, int *colors, int *bps) const { *width = S.width; *height = S.height; if (imgdata.progress_flags < LIBRAW_PROGRESS_FUJI_ROTATE) { if (O.use_fuji_rotate) { if (IO.fuji_width) { int fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink; *width = (ushort)(fuji_width / sqrt(0.5)); *height = (ushort)((*height - fuji_width) / sqrt(0.5)); } else { if (S.pixel_aspect < 0.995) *height = (ushort)(*height / S.pixel_aspect + 0.5); if (S.pixel_aspect > 1.005) *width = (ushort)(*width * S.pixel_aspect + 0.5); } } } if (S.flip & 4) { std::swap(*width, *height); } *colors = P1.colors; *bps = O.output_bps; } int LibRaw::copy_mem_image(void *scan0, int stride, int bgr) { // the image memory pointed to by scan0 is assumed to be in the format // returned by get_mem_image_format if ((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) < LIBRAW_PROGRESS_PRE_INTERPOLATE) return LIBRAW_OUT_OF_ORDER_CALL; if (libraw_internal_data.output_data.histogram) { int perc, val, total, t_white = 0x2000, c; perc = S.width * S.height * O.auto_bright_thr; if (IO.fuji_width) perc /= 2; if (!((O.highlight & ~2) || O.no_auto_bright)) for (t_white = c = 0; c < P1.colors; c++) { for (val = 0x2000, total = 0; --val > 32;) if ((total += libraw_internal_data.output_data.histogram[c][val]) > perc) break; if (t_white < val) t_white = val; } gamma_curve(O.gamm[0], O.gamm[1], 2, (t_white << 3) / O.bright); } int s_iheight = S.iheight; int s_iwidth = S.iwidth; int s_width = S.width; int s_hwight = S.height; S.iheight = S.height; S.iwidth = S.width; if (S.flip & 4) SWAP(S.height, S.width); uchar *ppm; ushort *ppm2; int c, row, col, soff, rstep, cstep; soff = flip_index(0, 0); cstep = flip_index(0, 1) - soff; rstep = flip_index(1, 0) - flip_index(0, S.width); for (row = 0; row < S.height; row++, soff += rstep) { uchar *bufp = ((uchar *)scan0) + row * stride; ppm2 = (ushort *)(ppm = bufp); // keep trivial decisions in the outer loop for speed if (bgr) { if (O.output_bps == 8) { for (col = 0; col < S.width; col++, soff += cstep) FORBGR *ppm++ = imgdata.color.curve[imgdata.image[soff][c]] >> 8; } else { for (col = 0; col < S.width; col++, soff += cstep) FORBGR *ppm2++ = imgdata.color.curve[imgdata.image[soff][c]]; } } else { if (O.output_bps == 8) { for (col = 0; col < S.width; col++, soff += cstep) FORRGB *ppm++ = imgdata.color.curve[imgdata.image[soff][c]] >> 8; } else { for (col = 0; col < S.width; col++, soff += cstep) FORRGB *ppm2++ = imgdata.color.curve[imgdata.image[soff][c]]; } } // bufp += stride; // go to the next line } S.iheight = s_iheight; S.iwidth = s_iwidth; S.width = s_width; S.height = s_hwight; return 0; } #undef FORBGR #undef FORRGB libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *errcode) { int width, height, colors, bps; get_mem_image_format(&width, &height, &colors, &bps); int stride = width * (bps / 8) * colors; unsigned ds = height * stride; libraw_processed_image_t *ret = (libraw_processed_image_t *)::malloc( sizeof(libraw_processed_image_t) + ds); if (!ret) { if (errcode) *errcode = ENOMEM; return NULL; } memset(ret, 0, sizeof(libraw_processed_image_t)); // metadata init ret->type = LIBRAW_IMAGE_BITMAP; ret->height = height; ret->width = width; ret->colors = colors; ret->bits = bps; ret->data_size = ds; copy_mem_image(ret->data, stride, 0); return ret; } void LibRaw::dcraw_clear_mem(libraw_processed_image_t *p) { if (p) ::free(p); } LibRaw-0.21.4/src/postprocessing/postprocessing_aux.cpp000066400000000000000000000324271477673233700233250ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" void LibRaw::hat_transform(float *temp, float *base, int st, int size, int sc) { int i; for (i = 0; i < sc; i++) temp[i] = 2 * base[st * i] + base[st * (sc - i)] + base[st * (i + sc)]; for (; i + sc < size; i++) temp[i] = 2 * base[st * i] + base[st * (i - sc)] + base[st * (i + sc)]; for (; i < size; i++) temp[i] = 2 * base[st * i] + base[st * (i - sc)] + base[st * (2 * size - 2 - (i + sc))]; } #if !defined(LIBRAW_USE_OPENMP) void LibRaw::wavelet_denoise() { float *fimg = 0, *temp, thold, mul[2], avg, diff; int scale = 1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2]; ushort *window[4]; static const float noise[] = {0.8002f, 0.2735f, 0.1202f, 0.0585f, 0.0291f, 0.0152f, 0.0080f, 0.0044f}; if (iwidth < 65 || iheight < 65) return; while (maximum << scale < 0x10000) scale++; maximum <<= --scale; black <<= scale; FORC4 cblack[c] <<= scale; if ((size = iheight * iwidth) < 0x15550000) fimg = (float *)malloc((size * 3 + iheight + iwidth + 128) * sizeof *fimg); temp = fimg + size * 3; if ((nc = colors) == 3 && filters) nc++; FORC(nc) { /* denoise R,G1,B,G3 individually */ for (i = 0; i < size; i++) fimg[i] = 256 * sqrt((double)(image[i][c] << scale)); for (hpass = lev = 0; lev < 5; lev++) { lpass = size * ((lev & 1) + 1); for (row = 0; row < iheight; row++) { hat_transform(temp, fimg + hpass + row * iwidth, 1, iwidth, 1 << lev); for (col = 0; col < iwidth; col++) fimg[lpass + row * iwidth + col] = temp[col] * 0.25; } for (col = 0; col < iwidth; col++) { hat_transform(temp, fimg + lpass + col, iwidth, iheight, 1 << lev); for (row = 0; row < iheight; row++) fimg[lpass + row * iwidth + col] = temp[row] * 0.25; } thold = threshold * noise[lev]; for (i = 0; i < size; i++) { fimg[hpass + i] -= fimg[lpass + i]; if (fimg[hpass + i] < -thold) fimg[hpass + i] += thold; else if (fimg[hpass + i] > thold) fimg[hpass + i] -= thold; else fimg[hpass + i] = 0; if (hpass) fimg[i] += fimg[hpass + i]; } hpass = lpass; } for (i = 0; i < size; i++) image[i][c] = CLIP(SQR(fimg[i] + fimg[lpass + i]) / 0x10000); } if (filters && colors == 3) { /* pull G1 and G3 closer together */ for (row = 0; row < 2; row++) { mul[row] = 0.125 * pre_mul[FC(row + 1, 0) | 1] / pre_mul[FC(row, 0) | 1]; blk[row] = cblack[FC(row, 0) | 1]; } for (i = 0; i < 4; i++) window[i] = (ushort *)fimg + width * i; for (wlast = -1, row = 1; row < height - 1; row++) { while (wlast < row + 1) { for (wlast++, i = 0; i < 4; i++) window[(i + 3) & 3] = window[i]; for (col = FC(wlast, 1) & 1; col < width; col += 2) window[2][col] = BAYER(wlast, col); } thold = threshold / 512; for (col = (FC(row, 0) & 1) + 1; col < width - 1; col += 2) { avg = (window[0][col - 1] + window[0][col + 1] + window[2][col - 1] + window[2][col + 1] - blk[~row & 1] * 4) * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5; avg = avg < 0 ? 0 : sqrt(avg); diff = sqrt((double)BAYER(row, col)) - avg; if (diff < -thold) diff += thold; else if (diff > thold) diff -= thold; else diff = 0; BAYER(row, col) = CLIP(SQR(avg + diff) + 0.5); } } } free(fimg); } #else /* LIBRAW_USE_OPENMP */ void LibRaw::wavelet_denoise() { float *fimg = 0, *temp, thold, mul[2], avg, diff; int scale = 1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2]; ushort *window[4]; static const float noise[] = {0.8002, 0.2735, 0.1202, 0.0585, 0.0291, 0.0152, 0.0080, 0.0044}; if (iwidth < 65 || iheight < 65) return; while (maximum << scale < 0x10000) scale++; maximum <<= --scale; black <<= scale; FORC4 cblack[c] <<= scale; if ((size = iheight * iwidth) < 0x15550000) fimg = (float *)malloc((size * 3 + iheight + iwidth) * sizeof *fimg); temp = fimg + size * 3; if ((nc = colors) == 3 && filters) nc++; #pragma omp parallel default(shared) private( \ i, col, row, thold, lev, lpass, hpass, temp, c) firstprivate(scale, size) { temp = (float *)malloc((iheight + iwidth) * sizeof *fimg); FORC(nc) { /* denoise R,G1,B,G3 individually */ #pragma omp for for (i = 0; i < size; i++) fimg[i] = 256 * sqrt((double)(image[i][c] << scale)); for (hpass = lev = 0; lev < 5; lev++) { lpass = size * ((lev & 1) + 1); #pragma omp for for (row = 0; row < iheight; row++) { hat_transform(temp, fimg + hpass + row * iwidth, 1, iwidth, 1 << lev); for (col = 0; col < iwidth; col++) fimg[lpass + row * iwidth + col] = temp[col] * 0.25; } #pragma omp for for (col = 0; col < iwidth; col++) { hat_transform(temp, fimg + lpass + col, iwidth, iheight, 1 << lev); for (row = 0; row < iheight; row++) fimg[lpass + row * iwidth + col] = temp[row] * 0.25; } thold = threshold * noise[lev]; #pragma omp for for (i = 0; i < size; i++) { fimg[hpass + i] -= fimg[lpass + i]; if (fimg[hpass + i] < -thold) fimg[hpass + i] += thold; else if (fimg[hpass + i] > thold) fimg[hpass + i] -= thold; else fimg[hpass + i] = 0; if (hpass) fimg[i] += fimg[hpass + i]; } hpass = lpass; } #pragma omp for for (i = 0; i < size; i++) image[i][c] = CLIP(SQR(fimg[i] + fimg[lpass + i]) / 0x10000); } free(temp); } /* end omp parallel */ /* the following loops are hard to parallelize, no idea yes, * problem is wlast which is carrying dependency * second part should be easier, but did not yet get it right. */ if (filters && colors == 3) { /* pull G1 and G3 closer together */ for (row = 0; row < 2; row++) { mul[row] = 0.125 * pre_mul[FC(row + 1, 0) | 1] / pre_mul[FC(row, 0) | 1]; blk[row] = cblack[FC(row, 0) | 1]; } for (i = 0; i < 4; i++) window[i] = (ushort *)fimg + width * i; for (wlast = -1, row = 1; row < height - 1; row++) { while (wlast < row + 1) { for (wlast++, i = 0; i < 4; i++) window[(i + 3) & 3] = window[i]; for (col = FC(wlast, 1) & 1; col < width; col += 2) window[2][col] = BAYER(wlast, col); } thold = threshold / 512; for (col = (FC(row, 0) & 1) + 1; col < width - 1; col += 2) { avg = (window[0][col - 1] + window[0][col + 1] + window[2][col - 1] + window[2][col + 1] - blk[~row & 1] * 4) * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5; avg = avg < 0 ? 0 : sqrt(avg); diff = sqrt((double)BAYER(row, col)) - avg; if (diff < -thold) diff += thold; else if (diff > thold) diff -= thold; else diff = 0; BAYER(row, col) = CLIP(SQR(avg + diff) + 0.5); } } } free(fimg); } #endif void LibRaw::median_filter() { ushort(*pix)[4]; int pass, c, i, j, k, med[9]; static const uchar opt[] = /* Optimal 9-element median search */ {1, 2, 4, 5, 7, 8, 0, 1, 3, 4, 6, 7, 1, 2, 4, 5, 7, 8, 0, 3, 5, 8, 4, 7, 3, 6, 1, 4, 2, 5, 4, 7, 4, 2, 6, 4, 4, 2}; for (pass = 1; pass <= med_passes; pass++) { RUN_CALLBACK(LIBRAW_PROGRESS_MEDIAN_FILTER, pass - 1, med_passes); for (c = 0; c < 3; c += 2) { for (pix = image; pix < image + width * height; pix++) pix[0][3] = pix[0][c]; for (pix = image + width; pix < image + width * (height - 1); pix++) { if ((pix - image + 1) % width < 2) continue; for (k = 0, i = -width; i <= width; i += width) for (j = i - 1; j <= i + 1; j++) med[k++] = pix[j][3] - pix[j][1]; for (i = 0; i < int(sizeof opt); i += 2) if (med[opt[i]] > med[opt[i + 1]]) SWAP(med[opt[i]], med[opt[i + 1]]); pix[0][c] = CLIP(med[4] + pix[0][1]); } } } } void LibRaw::blend_highlights() { int clip = INT_MAX, row, col, c, i, j; static const float trans[2][4][4] = { {{1, 1, 1}, {1.7320508f, -1.7320508f, 0}, {-1, -1, 2}}, {{1, 1, 1, 1}, {1, -1, 1, -1}, {1, 1, -1, -1}, {1, -1, -1, 1}}}; static const float itrans[2][4][4] = { {{1, 0.8660254f, -0.5}, {1, -0.8660254f, -0.5}, {1, 0, 1}}, {{1, 1, 1, 1}, {1, -1, 1, -1}, {1, 1, -1, -1}, {1, -1, -1, 1}}}; float cam[2][4], lab[2][4], sum[2], chratio; if ((unsigned)(colors - 3) > 1) return; RUN_CALLBACK(LIBRAW_PROGRESS_HIGHLIGHTS, 0, 2); FORCC if (clip > (i = 65535 * pre_mul[c])) clip = i; for (row = 0; row < height; row++) for (col = 0; col < width; col++) { FORCC if (image[row * width + col][c] > clip) break; if (c == colors) continue; FORCC { cam[0][c] = image[row * width + col][c]; cam[1][c] = MIN(cam[0][c], clip); } for (i = 0; i < 2; i++) { FORCC for (lab[i][c] = j = 0; j < colors; j++) lab[i][c] += trans[colors - 3][c][j] * cam[i][j]; for (sum[i] = 0, c = 1; c < colors; c++) sum[i] += SQR(lab[i][c]); } chratio = sqrt(sum[1] / sum[0]); for (c = 1; c < colors; c++) lab[0][c] *= chratio; FORCC for (cam[0][c] = j = 0; j < colors; j++) cam[0][c] += itrans[colors - 3][c][j] * lab[0][j]; FORCC image[row * width + col][c] = cam[0][c] / colors; } RUN_CALLBACK(LIBRAW_PROGRESS_HIGHLIGHTS, 1, 2); } #define SCALE (4 >> shrink) void LibRaw::recover_highlights() { float *map, sum, wgt, grow; int hsat[4], count, spread, change, val, i; unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x; ushort *pixel; static const signed char dir[8][2] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}}; grow = pow(2.0, 4 - highlight); FORC(unsigned(colors)) hsat[c] = 32000 * pre_mul[c]; FORC(unsigned(colors)) if(hsat[c]<1) return; for (kc = 0, c = 1; c < (unsigned)colors; c++) if (pre_mul[kc] < pre_mul[c]) kc = c; high = height / SCALE; wide = width / SCALE; map = (float *)calloc(high, wide * sizeof *map); FORC(unsigned(colors)) if (c != kc) { RUN_CALLBACK(LIBRAW_PROGRESS_HIGHLIGHTS, c - 1, colors - 1); memset(map, 0, high * wide * sizeof *map); for (mrow = 0; mrow < high; mrow++) for (mcol = 0; mcol < wide; mcol++) { sum = wgt = count = 0; for (row = mrow * SCALE; row < (mrow + 1) * SCALE; row++) for (col = mcol * SCALE; col < (mcol + 1) * SCALE; col++) { pixel = image[row * width + col]; if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) { sum += pixel[c]; wgt += pixel[kc]; count++; } } if (count == SCALE * SCALE) map[mrow * wide + mcol] = sum / wgt; } for (spread = 32 / grow; spread--;) { for (mrow = 0; mrow < high; mrow++) for (mcol = 0; mcol < wide; mcol++) { if (map[mrow * wide + mcol]) continue; sum = count = 0; for (d = 0; d < 8; d++) { y = mrow + dir[d][0]; x = mcol + dir[d][1]; if (y < high && x < wide && map[y * wide + x] > 0) { sum += (1 + (d & 1)) * map[y * wide + x]; count += 1 + (d & 1); } } if (count > 3) map[mrow * wide + mcol] = -(sum + grow) / (count + grow); } for (change = i = 0; i < int(high * wide); i++) if (map[i] < 0) { map[i] = -map[i]; change = 1; } if (!change) break; } for (i = 0; i < int(high * wide); i++) if (map[i] == 0) map[i] = 1; for (mrow = 0; mrow < high; mrow++) for (mcol = 0; mcol < wide; mcol++) { for (row = mrow * SCALE; row < (mrow + 1) * SCALE; row++) for (col = mcol * SCALE; col < (mcol + 1) * SCALE; col++) { pixel = image[row * width + col]; if (pixel[c] / hsat[c] > 1) { val = pixel[kc] * map[mrow * wide + mcol]; if (pixel[c] < val) pixel[c] = CLIP(val); } } } } free(map); } #undef SCALE LibRaw-0.21.4/src/postprocessing/postprocessing_ph.cpp000066400000000000000000000020131477673233700231230ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * Placeholder functions to build LibRaw w/o postprocessing tools 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 "../../internal/libraw_cxx_defs.h" int LibRaw::dcraw_process(void) { return LIBRAW_NOT_IMPLEMENTED; } void LibRaw::fuji_rotate() {} void LibRaw::convert_to_rgb_loop(float /*out_cam*/ [3][4]) {} libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *) { return NULL; } libraw_processed_image_t *LibRaw::dcraw_make_mem_thumb(int *){ return NULL;} void LibRaw::lin_interpolate_loop(int * /*code*/, int /*size*/) {} void LibRaw::scale_colors_loop(float /*scale_mul*/[4]) {} LibRaw-0.21.4/src/postprocessing/postprocessing_utils.cpp000066400000000000000000000131111477673233700236550ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" #define TBLN 65535 void LibRaw::exp_bef(float shift, float smooth) { // params limits if (shift > 8) shift = 8; if (shift < 0.25) shift = 0.25; if (smooth < 0.0) smooth = 0.0; if (smooth > 1.0) smooth = 1.0; unsigned short *lut = (ushort *)malloc((TBLN + 1) * sizeof(unsigned short)); if (shift <= 1.0) { for (int i = 0; i <= TBLN; i++) lut[i] = (unsigned short)((float)i * shift); } else { float x1, x2, y1, y2; float cstops = log(shift) / log(2.0f); float room = cstops * 2; float roomlin = powf(2.0f, room); x2 = (float)TBLN; x1 = (x2 + 1) / roomlin - 1; y1 = x1 * shift; y2 = x2 * (1 + (1 - smooth) * (shift - 1)); float sq3x = powf(x1 * x1 * x2, 1.0f / 3.0f); float B = (y2 - y1 + shift * (3 * x1 - 3.0f * sq3x)) / (x2 + 2.0f * x1 - 3.0f * sq3x); float A = (shift - B) * 3.0f * powf(x1 * x1, 1.0f / 3.0f); float CC = y2 - A * powf(x2, 1.0f / 3.0f) - B * x2; for (int i = 0; i <= TBLN; i++) { float X = (float)i; float Y = A * powf(X, 1.0f / 3.0f) + B * X + CC; if (i < x1) lut[i] = (unsigned short)((float)i * shift); else lut[i] = Y < 0 ? 0 : (Y > TBLN ? TBLN : (unsigned short)(Y)); } } for (int i = 0; i < S.height * S.width; i++) { imgdata.image[i][0] = lut[imgdata.image[i][0]]; imgdata.image[i][1] = lut[imgdata.image[i][1]]; imgdata.image[i][2] = lut[imgdata.image[i][2]]; imgdata.image[i][3] = lut[imgdata.image[i][3]]; } if (C.data_maximum <= TBLN) C.data_maximum = lut[C.data_maximum]; if (C.maximum <= TBLN) C.maximum = lut[C.maximum]; free(lut); } void LibRaw::convert_to_rgb_loop(float out_cam[3][4]) { int row, col, c; float out[3]; ushort *img; memset(libraw_internal_data.output_data.histogram, 0, sizeof(int) * LIBRAW_HISTOGRAM_SIZE * 4); if (libraw_internal_data.internal_output_params.raw_color) { for (img = imgdata.image[0], row = 0; row < S.height; row++) { for (col = 0; col < S.width; col++, img += 4) { for (c = 0; c < imgdata.idata.colors; c++) { libraw_internal_data.output_data.histogram[c][img[c] >> 3]++; } } } } else if (imgdata.idata.colors == 3) { for (img = imgdata.image[0], row = 0; row < S.height; row++) { for (col = 0; col < S.width; col++, img += 4) { out[0] = out_cam[0][0] * img[0] + out_cam[0][1] * img[1] + out_cam[0][2] * img[2]; out[1] = out_cam[1][0] * img[0] + out_cam[1][1] * img[1] + out_cam[1][2] * img[2]; out[2] = out_cam[2][0] * img[0] + out_cam[2][1] * img[1] + out_cam[2][2] * img[2]; img[0] = CLIP((int)out[0]); img[1] = CLIP((int)out[1]); img[2] = CLIP((int)out[2]); libraw_internal_data.output_data.histogram[0][img[0] >> 3]++; libraw_internal_data.output_data.histogram[1][img[1] >> 3]++; libraw_internal_data.output_data.histogram[2][img[2] >> 3]++; } } } else if (imgdata.idata.colors == 4) { for (img = imgdata.image[0], row = 0; row < S.height; row++) { for (col = 0; col < S.width; col++, img += 4) { out[0] = out_cam[0][0] * img[0] + out_cam[0][1] * img[1] + out_cam[0][2] * img[2] + out_cam[0][3] * img[3]; out[1] = out_cam[1][0] * img[0] + out_cam[1][1] * img[1] + out_cam[1][2] * img[2] + out_cam[1][3] * img[3]; out[2] = out_cam[2][0] * img[0] + out_cam[2][1] * img[1] + out_cam[2][2] * img[2] + out_cam[2][3] * img[3]; img[0] = CLIP((int)out[0]); img[1] = CLIP((int)out[1]); img[2] = CLIP((int)out[2]); libraw_internal_data.output_data.histogram[0][img[0] >> 3]++; libraw_internal_data.output_data.histogram[1][img[1] >> 3]++; libraw_internal_data.output_data.histogram[2][img[2] >> 3]++; libraw_internal_data.output_data.histogram[3][img[3] >> 3]++; } } } } void LibRaw::scale_colors_loop(float scale_mul[4]) { unsigned size = S.iheight * S.iwidth; if (C.cblack[4] && C.cblack[5]) { int val; for (unsigned i = 0; i < size; i++) { for (unsigned c = 0; c < 4; c++) { if (!(val = imgdata.image[i][c])) continue; val -= C.cblack[6 + i / S.iwidth % C.cblack[4] * C.cblack[5] + i % S.iwidth % C.cblack[5]]; val -= C.cblack[c]; val *= scale_mul[c]; imgdata.image[i][c] = CLIP(val); } } } else if (C.cblack[0] || C.cblack[1] || C.cblack[2] || C.cblack[3]) { for (unsigned i = 0; i < size; i++) { for (unsigned c = 0; c < 4; c++) { int val = imgdata.image[i][c]; if (!val) continue; val -= C.cblack[c]; val *= scale_mul[c]; imgdata.image[i][c] = CLIP(val); } } } else // BL is zero { for (unsigned i = 0; i < size; i++) { for (unsigned c = 0; c < 4; c++) { int val = imgdata.image[i][c]; val *= scale_mul[c]; imgdata.image[i][c] = CLIP(val); } } } } LibRaw-0.21.4/src/postprocessing/postprocessing_utils_dcrdefs.cpp000066400000000000000000000250371477673233700253610ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" void LibRaw::convert_to_rgb() { float out_cam[3][4]; double num, inverse[3][3]; static const double(*out_rgb[])[3] = { LibRaw_constants::rgb_rgb, LibRaw_constants::adobe_rgb, LibRaw_constants::wide_rgb, LibRaw_constants::prophoto_rgb, LibRaw_constants::xyz_rgb, LibRaw_constants::aces_rgb, LibRaw_constants::dcip3d65_rgb, LibRaw_constants::rec2020_rgb}; static const char *name[] = {"sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ", "ACES", "DCI-P3 D65", "Rec. 2020"}; static const unsigned phead[] = { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0, 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d}; unsigned pbody[] = {10, 0x63707274, 0, 36, /* cprt */ 0x64657363, 0, 60, /* desc, len is strlen(longest_string) + 12 */ 0x77747074, 0, 20, /* wtpt */ 0x626b7074, 0, 20, /* bkpt */ 0x72545243, 0, 14, /* rTRC */ 0x67545243, 0, 14, /* gTRC */ 0x62545243, 0, 14, /* bTRC */ 0x7258595a, 0, 20, /* rXYZ */ 0x6758595a, 0, 20, /* gXYZ */ 0x6258595a, 0, 20}; /* bXYZ */ static const unsigned pwhite[] = {0xf351, 0x10000, 0x116cc}; unsigned pcurve[] = {0x63757276, 0, 1, 0x1000000}; RUN_CALLBACK(LIBRAW_PROGRESS_CONVERT_RGB, 0, 2); gamma_curve(gamm[0], gamm[1], 0, 0); memcpy(out_cam, rgb_cam, sizeof out_cam); raw_color |= colors == 1 || output_color < 1 || output_color > 8; if (!raw_color) { size_t prof_desc_len; std::vector prof_desc; int i, j, k; prof_desc_len = snprintf(NULL, 0, "%s gamma %g toe slope %g", name[output_color - 1], floorf(1000.f / gamm[0] + .5f) / 1000.f, floorf(gamm[1] * 1000.0f + .5f) / 1000.f) + 1; prof_desc.resize(prof_desc_len); sprintf(prof_desc.data(), "%s gamma %g toe slope %g", name[output_color - 1], floorf(1000.f / gamm[0] + .5f) / 1000.f, floorf(gamm[1] * 1000.0f + .5f) / 1000.f); oprof = (unsigned *)calloc(phead[0], 1); memcpy(oprof, phead, sizeof phead); if (output_color == 5) oprof[4] = oprof[5]; oprof[0] = 132 + 12 * pbody[0]; for (i = 0; i < (int)pbody[0]; i++) { oprof[oprof[0] / 4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874; pbody[i * 3 + 2] = oprof[0]; oprof[0] += (pbody[i * 3 + 3] + 3) & -4; } memcpy(oprof + 32, pbody, sizeof pbody); oprof[pbody[5] / 4 + 2] = unsigned(prof_desc_len + 1); memcpy((char *)oprof + pbody[8] + 8, pwhite, sizeof pwhite); pcurve[3] = (short)(256 / gamm[5] + 0.5) << 16; for (i = 4; i < 7; i++) memcpy((char *)oprof + pbody[i * 3 + 2], pcurve, sizeof pcurve); pseudoinverse((double(*)[3])out_rgb[output_color - 1], inverse, 3); for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) { for (num = k = 0; k < 3; k++) num += LibRaw_constants::xyzd50_srgb[i][k] * inverse[j][k]; oprof[pbody[j * 3 + 23] / 4 + i + 2] = num * 0x10000 + 0.5; } for (i = 0; i < (int)phead[0] / 4; i++) oprof[i] = htonl(oprof[i]); strcpy((char *)oprof + pbody[2] + 8, "auto-generated by dcraw"); if (pbody[5] + 12 + prof_desc.size() < phead[0]) strcpy((char *)oprof + pbody[5] + 12, prof_desc.data()); for (i = 0; i < 3; i++) for (j = 0; j < colors; j++) for (out_cam[i][j] = k = 0; k < 3; k++) out_cam[i][j] += out_rgb[output_color - 1][i][k] * rgb_cam[k][j]; } convert_to_rgb_loop(out_cam); if (colors == 4 && output_color) colors = 3; RUN_CALLBACK(LIBRAW_PROGRESS_CONVERT_RGB, 1, 2); } void LibRaw::scale_colors() { unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8]; int val; double dsum[8], dmin, dmax; float scale_mul[4], fr, fc; ushort *img = 0, *pix; RUN_CALLBACK(LIBRAW_PROGRESS_SCALE_COLORS, 0, 2); if (user_mul[0]) memcpy(pre_mul, user_mul, sizeof pre_mul); if (use_auto_wb || (use_camera_wb && (cam_mul[0] < -0.5 // LibRaw 0.19 and older: fallback to auto only if cam_mul[0] is set to -1 || (cam_mul[0] <= 0.00001f // New default: fallback to auto if no cam_mul parsed from metadata && !(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CAMERAWB_FALLBACK_TO_DAYLIGHT)) ))) { memset(dsum, 0, sizeof dsum); bottom = MIN(greybox[1] + greybox[3], height); right = MIN(greybox[0] + greybox[2], width); for (row = greybox[1]; row < bottom; row += 8) for (col = greybox[0]; col < right; col += 8) { memset(sum, 0, sizeof sum); for (y = row; y < row + 8 && y < bottom; y++) for (x = col; x < col + 8 && x < right; x++) FORC4 { if (filters) { c = fcol(y, x); val = BAYER2(y, x); } else val = image[y * width + x][c]; if (val > (int)maximum - 25) goto skip_block; if ((val -= cblack[c]) < 0) val = 0; sum[c] += val; sum[c + 4]++; if (filters) break; } FORC(8) dsum[c] += sum[c]; skip_block:; } FORC4 if (dsum[c]) pre_mul[c] = dsum[c + 4] / dsum[c]; } if (use_camera_wb && cam_mul[0] > 0.00001f) { memset(sum, 0, sizeof sum); for (row = 0; row < 8; row++) for (col = 0; col < 8; col++) { c = FC(row, col); if ((val = white[row][col] - cblack[c]) > 0) sum[c] += val; sum[c + 4]++; } if (imgdata.color.as_shot_wb_applied) { // Nikon sRAW: camera WB already applied: pre_mul[0] = pre_mul[1] = pre_mul[2] = pre_mul[3] = 1.0; } else if (sum[0] && sum[1] && sum[2] && sum[3]) FORC4 pre_mul[c] = (float)sum[c + 4] / sum[c]; else if (cam_mul[0] > 0.00001f && cam_mul[2] > 0.00001f) memcpy(pre_mul, cam_mul, sizeof pre_mul); else { imgdata.process_warnings |= LIBRAW_WARN_BAD_CAMERA_WB; } } // Nikon sRAW, daylight if (imgdata.color.as_shot_wb_applied && !use_camera_wb && !use_auto_wb && cam_mul[0] > 0.00001f && cam_mul[1] > 0.00001f && cam_mul[2] > 0.00001f) { for (c = 0; c < 3; c++) pre_mul[c] /= cam_mul[c]; } if (pre_mul[1] == 0) pre_mul[1] = 1; if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1; if (threshold) wavelet_denoise(); maximum -= black; for (dmin = DBL_MAX, dmax = c = 0; c < 4; c++) { if (dmin > pre_mul[c]) dmin = pre_mul[c]; if (dmax < pre_mul[c]) dmax = pre_mul[c]; } if (!highlight) dmax = dmin; if (dmax > 0.00001 && maximum > 0) FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum; else FORC4 scale_mul[c] = 1.0; if (filters > 1000 && (cblack[4] + 1) / 2 == 1 && (cblack[5] + 1) / 2 == 1) { FORC4 cblack[FC(c / 2, c % 2)] += cblack[6 + c / 2 % cblack[4] * cblack[5] + c % 2 % cblack[5]]; cblack[4] = cblack[5] = 0; } size = iheight * iwidth; scale_colors_loop(scale_mul); if ((aber[0] != 1 || aber[2] != 1) && colors == 3) { for (c = 0; c < 4; c += 2) { if (aber[c] == 1) continue; img = (ushort *)malloc(size * sizeof *img); for (i = 0; i < size; i++) img[i] = image[i][c]; for (row = 0; row < iheight; row++) { ur = fr = (row - iheight * 0.5) * aber[c] + iheight * 0.5; if (ur > (unsigned)iheight - 2) continue; fr -= ur; for (col = 0; col < iwidth; col++) { uc = fc = (col - iwidth * 0.5) * aber[c] + iwidth * 0.5; if (uc > (unsigned)iwidth - 2) continue; fc -= uc; pix = img + ur * iwidth + uc; image[row * iwidth + col][c] = (pix[0] * (1 - fc) + pix[1] * fc) * (1 - fr) + (pix[iwidth] * (1 - fc) + pix[iwidth + 1] * fc) * fr; } } free(img); } } RUN_CALLBACK(LIBRAW_PROGRESS_SCALE_COLORS, 1, 2); } // green equilibration void LibRaw::green_matching() { int i, j; double m1, m2, c1, c2; int o1_1, o1_2, o1_3, o1_4; int o2_1, o2_2, o2_3, o2_4; ushort(*img)[4]; const int margin = 3; int oj = 2, oi = 2; float f; const float thr = 0.01f; if (half_size || shrink) return; if (FC(oj, oi) != 3) oj++; if (FC(oj, oi) != 3) oi++; if (FC(oj, oi) != 3) oj--; img = (ushort(*)[4])calloc(height * width, sizeof *image); memcpy(img, image, height * width * sizeof *image); for (j = oj; j < height - margin; j += 2) for (i = oi; i < width - margin; i += 2) { o1_1 = img[(j - 1) * width + i - 1][1]; o1_2 = img[(j - 1) * width + i + 1][1]; o1_3 = img[(j + 1) * width + i - 1][1]; o1_4 = img[(j + 1) * width + i + 1][1]; o2_1 = img[(j - 2) * width + i][3]; o2_2 = img[(j + 2) * width + i][3]; o2_3 = img[j * width + i - 2][3]; o2_4 = img[j * width + i + 2][3]; m1 = (o1_1 + o1_2 + o1_3 + o1_4) / 4.0; m2 = (o2_1 + o2_2 + o2_3 + o2_4) / 4.0; c1 = (abs(o1_1 - o1_2) + abs(o1_1 - o1_3) + abs(o1_1 - o1_4) + abs(o1_2 - o1_3) + abs(o1_3 - o1_4) + abs(o1_2 - o1_4)) / 6.0; c2 = (abs(o2_1 - o2_2) + abs(o2_1 - o2_3) + abs(o2_1 - o2_4) + abs(o2_2 - o2_3) + abs(o2_3 - o2_4) + abs(o2_2 - o2_4)) / 6.0; if ((img[j * width + i][3] < maximum * 0.95) && (c1 < maximum * thr) && (c2 < maximum * thr)) { f = image[j * width + i][3] * m1 / m2; image[j * width + i][3] = f > 0xffff ? 0xffff : f; } } free(img); } LibRaw-0.21.4/src/preprocessing/000077500000000000000000000000001477673233700164535ustar00rootroot00000000000000LibRaw-0.21.4/src/preprocessing/ext_preprocess.cpp000066400000000000000000000063261477673233700222330ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_fileio_defs.h" /* Search from the current directory up to the root looking for a ".badpixels" file, and fix those pixels now. */ void LibRaw::bad_pixels(const char *cfname) { FILE *fp = NULL; char *cp, line[128]; int time, row, col, r, c, rad, tot, n; if (!filters) return; RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS, 0, 2); if (cfname) fp = fopen(cfname, "r"); if (!fp) { imgdata.process_warnings |= LIBRAW_WARN_NO_BADPIXELMAP; return; } while (fgets(line, 128, fp)) { cp = strchr(line, '#'); if (cp) *cp = 0; if (sscanf(line, "%d %d %d", &col, &row, &time) != 3) continue; if ((unsigned)col >= width || (unsigned)row >= height) continue; if (time > timestamp) continue; for (tot = n = 0, rad = 1; rad < 3 && n == 0; rad++) for (r = row - rad; r <= row + rad; r++) for (c = col - rad; c <= col + rad; c++) if ((unsigned)r < height && (unsigned)c < width && (r != row || c != col) && fcol(r, c) == fcol(row, col)) { tot += BAYER2(r, c); n++; } if (n > 0) BAYER2(row, col) = tot / n; } fclose(fp); RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS, 1, 2); } void LibRaw::subtract(const char *fname) { FILE *fp; int dim[3] = {0, 0, 0}, comment = 0, number = 0, error = 0, nd = 0, c, row, col; RUN_CALLBACK(LIBRAW_PROGRESS_DARK_FRAME, 0, 2); if (!(fp = fopen(fname, "rb"))) { imgdata.process_warnings |= LIBRAW_WARN_BAD_DARKFRAME_FILE; return; } if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1; while (!error && nd < 3 && (c = fgetc(fp)) != EOF) { if (c == '#') comment = 1; if (c == '\n') comment = 0; if (comment) continue; if (isdigit(c)) number = 1; if (number) { if (isdigit(c)) dim[nd] = dim[nd] * 10 + c - '0'; else if (isspace(c)) { number = 0; nd++; } else error = 1; } } if (error || nd < 3) { fclose(fp); return; } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) { imgdata.process_warnings |= LIBRAW_WARN_BAD_DARKFRAME_DIM; fclose(fp); return; } std::vector pixel(width, 0); for (row = 0; row < height; row++) { fread(pixel.data(), 2, width, fp); for (col = 0; col < width; col++) BAYER(row, col) = MAX(BAYER(row, col) - ntohs(pixel[col]), 0); } fclose(fp); memset(cblack, 0, sizeof cblack); black = 0; RUN_CALLBACK(LIBRAW_PROGRESS_DARK_FRAME, 1, 2); } LibRaw-0.21.4/src/preprocessing/preprocessing_ph.cpp000066400000000000000000000014731477673233700225360ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * Placeholder functions to build LibRaw w/o postprocessing and preprocessing calls 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 "../../internal/libraw_cxx_defs.h" void LibRaw::copy_fuji_uncropped(unsigned short /*cblack*/[4], unsigned short * /*dmaxp*/) {} void LibRaw::copy_bayer(unsigned short /*cblack*/[4], unsigned short * /*dmaxp*/){} void LibRaw::raw2image_start(){} LibRaw-0.21.4/src/preprocessing/raw2image.cpp000066400000000000000000000412071477673233700210410ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" void LibRaw::raw2image_start() { // restore color,sizes and internal data into raw_image fields memmove(&imgdata.color, &imgdata.rawdata.color, sizeof(imgdata.color)); memmove(&imgdata.sizes, &imgdata.rawdata.sizes, sizeof(imgdata.sizes)); memmove(&imgdata.idata, &imgdata.rawdata.iparams, sizeof(imgdata.idata)); memmove(&libraw_internal_data.internal_output_params, &imgdata.rawdata.ioparams, sizeof(libraw_internal_data.internal_output_params)); if (O.user_flip >= 0) S.flip = O.user_flip; switch ((S.flip + 3600) % 360) { case 270: S.flip = 5; break; case 180: S.flip = 3; break; case 90: S.flip = 6; break; } // adjust for half mode! IO.shrink = !imgdata.rawdata.color4_image && !imgdata.rawdata.color3_image && !imgdata.rawdata.float4_image && !imgdata.rawdata.float3_image && P1.filters && (O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1))); S.iheight = (S.height + IO.shrink) >> IO.shrink; S.iwidth = (S.width + IO.shrink) >> IO.shrink; } int LibRaw::raw2image(void) { CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW); try { raw2image_start(); if (is_phaseone_compressed() && imgdata.rawdata.raw_alloc) { phase_one_allocate_tempbuffer(); int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc, imgdata.rawdata.raw_image); if (rc == 0) rc = phase_one_correct(); if (rc != 0) { phase_one_free_tempbuffer(); return rc; } } // free and re-allocate image bitmap if (imgdata.image) { imgdata.image = (ushort(*)[4])realloc( imgdata.image, S.iheight * S.iwidth * sizeof(*imgdata.image)); memset(imgdata.image, 0, S.iheight * S.iwidth * sizeof(*imgdata.image)); } else imgdata.image = (ushort(*)[4])calloc(S.iheight * S.iwidth, sizeof(*imgdata.image)); libraw_decoder_info_t decoder_info; get_decoder_info(&decoder_info); // Copy area size int copyheight = MAX(0, MIN(int(S.height), int(S.raw_height) - int(S.top_margin))); int copywidth = MAX(0, MIN(int(S.width), int(S.raw_width) - int(S.left_margin))); // Move saved bitmap to imgdata.image if ((imgdata.idata.filters || P1.colors == 1) && imgdata.rawdata.raw_image) { if (IO.fuji_width) { unsigned r, c; int row, col; for (row = 0; row < S.raw_height - S.top_margin * 2; row++) { for (col = 0; col < IO.fuji_width << int(!libraw_internal_data.unpacker_data.fuji_layout); col++) { if (libraw_internal_data.unpacker_data.fuji_layout) { r = IO.fuji_width - 1 - col + (row >> 1); c = col + ((row + 1) >> 1); } else { r = IO.fuji_width - 1 + row - (col >> 1); c = row + ((col + 1) >> 1); } if (r < S.height && c < S.width && col + int(S.left_margin) < int(S.raw_width)) imgdata.image[((r) >> IO.shrink) * S.iwidth + ((c) >> IO.shrink)] [FC(r, c)] = imgdata.rawdata .raw_image[(row + S.top_margin) * S.raw_pitch / 2 + (col + S.left_margin)]; } } } else { int row, col; for (row = 0; row < copyheight; row++) for (col = 0; col < copywidth; col++) imgdata.image[((row) >> IO.shrink) * S.iwidth + ((col) >> IO.shrink)][fcol(row, col)] = imgdata.rawdata .raw_image[(row + S.top_margin) * S.raw_pitch / 2 + (col + S.left_margin)]; } } else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY) { if (imgdata.rawdata.color4_image) { if (S.width * 8u == S.raw_pitch && S.height == S.raw_height) memmove(imgdata.image, imgdata.rawdata.color4_image, S.width * S.height * sizeof(*imgdata.image)); else { for (int row = 0; row < copyheight; row++) memmove(&imgdata.image[row * S.width], &imgdata.rawdata .color4_image[(row + S.top_margin) * S.raw_pitch / 8 + S.left_margin], copywidth * sizeof(*imgdata.image)); } } else if (imgdata.rawdata.color3_image) { unsigned char *c3image = (unsigned char *)imgdata.rawdata.color3_image; for (int row = 0; row < copyheight; row++) { ushort(*srcrow)[3] = (ushort(*)[3]) & c3image[(row + S.top_margin) * S.raw_pitch]; ushort(*dstrow)[4] = (ushort(*)[4]) & imgdata.image[row * S.width]; for (int col = 0; col < copywidth; col++) { for (int c = 0; c < 3; c++) dstrow[col][c] = srcrow[S.left_margin + col][c]; dstrow[col][3] = 0; } } } else { // legacy decoder, but no data? throw LIBRAW_EXCEPTION_DECODE_RAW; } } // Free PhaseOne separate copy allocated at function start if (is_phaseone_compressed()) { phase_one_free_tempbuffer(); } // hack - clear later flags! if (load_raw == &LibRaw::canon_600_load_raw && S.width < S.raw_width) { canon_600_correct(); } imgdata.progress_flags = LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN | LIBRAW_PROGRESS_RAW2_IMAGE | LIBRAW_PROGRESS_IDENTIFY | LIBRAW_PROGRESS_SIZE_ADJUST | LIBRAW_PROGRESS_LOAD_RAW; return 0; } catch (const std::bad_alloc&) { EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); } catch (const LibRaw_exceptions& err) { EXCEPTION_HANDLER(err); } } void LibRaw::copy_fuji_uncropped(unsigned short cblack[4], unsigned short *dmaxp) { #if defined(LIBRAW_USE_OPENMP) #pragma omp parallel for schedule(dynamic) default(none) firstprivate(cblack) shared(dmaxp) #endif for (int row = 0; row < int(S.raw_height) - int(S.top_margin) * 2; row++) { int col; unsigned short ldmax = 0; for (col = 0; col < IO.fuji_width << int(!libraw_internal_data.unpacker_data.fuji_layout) && col + int(S.left_margin) < int(S.raw_width); col++) { unsigned r, c; if (libraw_internal_data.unpacker_data.fuji_layout) { r = IO.fuji_width - 1 - col + (row >> 1); c = col + ((row + 1) >> 1); } else { r = IO.fuji_width - 1 + row - (col >> 1); c = row + ((col + 1) >> 1); } if (r < S.height && c < S.width) { unsigned short val = imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 + (col + S.left_margin)]; int cc = FC(r, c); if (val > cblack[cc]) { val -= cblack[cc]; if (val > ldmax) ldmax = val; } else val = 0; imgdata.image[((r) >> IO.shrink) * S.iwidth + ((c) >> IO.shrink)][cc] = val; } } #if defined(LIBRAW_USE_OPENMP) #pragma omp critical(dataupdate) #endif { if (*dmaxp < ldmax) *dmaxp = ldmax; } } } void LibRaw::copy_bayer(unsigned short cblack[4], unsigned short *dmaxp) { // Both cropped and uncropped int maxHeight = MIN(int(S.height),int(S.raw_height)-int(S.top_margin)); #if defined(LIBRAW_USE_OPENMP) #pragma omp parallel for schedule(dynamic) default(none) shared(dmaxp) firstprivate(cblack, maxHeight) #endif for (int row = 0; row < maxHeight ; row++) { int col; unsigned short ldmax = 0; for (col = 0; col < S.width && col + S.left_margin < S.raw_width; col++) { unsigned short val = imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 + (col + S.left_margin)]; int cc = fcol(row, col); if (val > cblack[cc]) { val -= cblack[cc]; if (val > ldmax) ldmax = val; } else val = 0; imgdata.image[((row) >> IO.shrink) * S.iwidth + ((col) >> IO.shrink)][cc] = val; } #if defined(LIBRAW_USE_OPENMP) #pragma omp critical(dataupdate) #endif { if (*dmaxp < ldmax) *dmaxp = ldmax; } } } int LibRaw::raw2image_ex(int do_subtract_black) { CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW); try { raw2image_start(); // Compressed P1 files with bl data! if (is_phaseone_compressed() && imgdata.rawdata.raw_alloc) { phase_one_allocate_tempbuffer(); int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc, imgdata.rawdata.raw_image); if (rc == 0) rc = phase_one_correct(); if (rc != 0) { phase_one_free_tempbuffer(); return rc; } } // process cropping int do_crop = 0; if (~O.cropbox[2] && ~O.cropbox[3]) { int crop[4], c, filt; for (int q = 0; q < 4; q++) { crop[q] = O.cropbox[q]; if (crop[q] < 0) crop[q] = 0; } if (IO.fuji_width && imgdata.idata.filters >= 1000) { crop[0] = (crop[0] / 4) * 4; crop[1] = (crop[1] / 4) * 4; if (!libraw_internal_data.unpacker_data.fuji_layout) { crop[2] *= sqrt(2.0); crop[3] /= sqrt(2.0); } crop[2] = (crop[2] / 4 + 1) * 4; crop[3] = (crop[3] / 4 + 1) * 4; } else if (imgdata.idata.filters == 1) { crop[0] = (crop[0] / 16) * 16; crop[1] = (crop[1] / 16) * 16; } else if (imgdata.idata.filters == LIBRAW_XTRANS) { crop[0] = (crop[0] / 6) * 6; crop[1] = (crop[1] / 6) * 6; } do_crop = 1; crop[2] = MIN(crop[2], (signed)S.width - crop[0]); crop[3] = MIN(crop[3], (signed)S.height - crop[1]); if (crop[2] <= 0 || crop[3] <= 0) throw LIBRAW_EXCEPTION_BAD_CROP; // adjust sizes! S.left_margin += crop[0]; S.top_margin += crop[1]; S.width = crop[2]; S.height = crop[3]; S.iheight = (S.height + IO.shrink) >> IO.shrink; S.iwidth = (S.width + IO.shrink) >> IO.shrink; if (!IO.fuji_width && imgdata.idata.filters && imgdata.idata.filters >= 1000) { for (filt = c = 0; c < 16; c++) filt |= FC((c >> 1) + (crop[1]), (c & 1) + (crop[0])) << c * 2; imgdata.idata.filters = filt; } } int alloc_width = S.iwidth; int alloc_height = S.iheight; if (IO.fuji_width && do_crop) { int IO_fw = S.width >> int(!libraw_internal_data.unpacker_data.fuji_layout); int t_alloc_width = (S.height >> libraw_internal_data.unpacker_data.fuji_layout) + IO_fw; int t_alloc_height = t_alloc_width - 1; alloc_height = (t_alloc_height + IO.shrink) >> IO.shrink; alloc_width = (t_alloc_width + IO.shrink) >> IO.shrink; } int alloc_sz = alloc_width * alloc_height; if (imgdata.image) { imgdata.image = (ushort(*)[4])realloc(imgdata.image, alloc_sz * sizeof(*imgdata.image)); memset(imgdata.image, 0, alloc_sz * sizeof(*imgdata.image)); } else imgdata.image = (ushort(*)[4])calloc(alloc_sz, sizeof(*imgdata.image)); libraw_decoder_info_t decoder_info; get_decoder_info(&decoder_info); // Adjust black levels unsigned short cblack[4] = {0, 0, 0, 0}; unsigned short dmax = 0; if (do_subtract_black) { adjust_bl(); for (int i = 0; i < 4; i++) cblack[i] = (unsigned short)C.cblack[i]; } // Max area size to definitely not overrun in/out buffers int copyheight = MAX(0, MIN(int(S.height), int(S.raw_height) - int(S.top_margin))); int copywidth = MAX(0, MIN(int(S.width), int(S.raw_width) - int(S.left_margin))); // Move saved bitmap to imgdata.image if ((imgdata.idata.filters || P1.colors == 1) && imgdata.rawdata.raw_image) { if (IO.fuji_width) { if (do_crop) { IO.fuji_width = S.width >> int(!libraw_internal_data.unpacker_data.fuji_layout); int IO_fwidth = (S.height >> int(libraw_internal_data.unpacker_data.fuji_layout)) + IO.fuji_width; int IO_fheight = IO_fwidth - 1; int row, col; for (row = 0; row < S.height; row++) { for (col = 0; col < S.width; col++) { int r, c; if (libraw_internal_data.unpacker_data.fuji_layout) { r = IO.fuji_width - 1 - col + (row >> 1); c = col + ((row + 1) >> 1); } else { r = IO.fuji_width - 1 + row - (col >> 1); c = row + ((col + 1) >> 1); } unsigned short val = imgdata.rawdata .raw_image[(row + S.top_margin) * S.raw_pitch / 2 + (col + S.left_margin)]; int cc = FCF(row, col); if (val > cblack[cc]) { val -= cblack[cc]; if (dmax < val) dmax = val; } else val = 0; imgdata.image[((r) >> IO.shrink) * alloc_width + ((c) >> IO.shrink)][cc] = val; } } S.height = IO_fheight; S.width = IO_fwidth; S.iheight = (S.height + IO.shrink) >> IO.shrink; S.iwidth = (S.width + IO.shrink) >> IO.shrink; S.raw_height -= 2 * S.top_margin; } else { copy_fuji_uncropped(cblack, &dmax); } } // end Fuji else { copy_bayer(cblack, &dmax); } } else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY) { if (imgdata.rawdata.color4_image) { if (S.raw_pitch != S.width * 8u || S.height != S.raw_height) { for (int row = 0; row < copyheight; row++) memmove(&imgdata.image[row * S.width], &imgdata.rawdata .color4_image[(row + S.top_margin) * S.raw_pitch / 8 + S.left_margin], copywidth * sizeof(*imgdata.image)); } else { // legacy is always 4channel and not shrinked! memmove(imgdata.image, imgdata.rawdata.color4_image, S.width*copyheight * sizeof(*imgdata.image)); } } else if (imgdata.rawdata.color3_image) { unsigned char *c3image = (unsigned char *)imgdata.rawdata.color3_image; for (int row = 0; row < copyheight; row++) { ushort(*srcrow)[3] = (ushort(*)[3]) & c3image[(row + S.top_margin) * S.raw_pitch]; ushort(*dstrow)[4] = (ushort(*)[4]) & imgdata.image[row * S.width]; for (int col = 0; col < copywidth; col++) { for (int c = 0; c < 3; c++) dstrow[col][c] = srcrow[S.left_margin + col][c]; dstrow[col][3] = 0; } } } else { // legacy decoder, but no data? throw LIBRAW_EXCEPTION_DECODE_RAW; } } // Free PhaseOne separate copy allocated at function start if (is_phaseone_compressed()) { phase_one_free_tempbuffer(); } if (load_raw == &LibRaw::canon_600_load_raw && S.width < S.raw_width) { canon_600_correct(); } if (do_subtract_black) { C.data_maximum = (int)dmax; C.maximum -= C.black; // ZERO(C.cblack); C.cblack[0] = C.cblack[1] = C.cblack[2] = C.cblack[3] = 0; C.black = 0; } // hack - clear later flags! imgdata.progress_flags = LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN | LIBRAW_PROGRESS_RAW2_IMAGE | LIBRAW_PROGRESS_IDENTIFY | LIBRAW_PROGRESS_SIZE_ADJUST | LIBRAW_PROGRESS_LOAD_RAW; return 0; } catch (const LibRaw_exceptions& err) { EXCEPTION_HANDLER(err); } } LibRaw-0.21.4/src/preprocessing/subtract_black.cpp000066400000000000000000000045701477673233700221500ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" int LibRaw::subtract_black() { adjust_bl(); return subtract_black_internal(); } int LibRaw::subtract_black_internal() { CHECK_ORDER_LOW(LIBRAW_PROGRESS_RAW2_IMAGE); try { if (!is_phaseone_compressed() && (C.cblack[0] || C.cblack[1] || C.cblack[2] || C.cblack[3] || (C.cblack[4] && C.cblack[5]))) { int cblk[4], i; for (i = 0; i < 4; i++) cblk[i] = C.cblack[i]; int size = S.iheight * S.iwidth; int dmax = 0; if (C.cblack[4] && C.cblack[5]) { for (unsigned q = 0; q < (unsigned)size; q++) { for (unsigned c = 0; c < 4; c++) { int val = imgdata.image[q][c]; val -= C.cblack[6 + q / S.iwidth % C.cblack[4] * C.cblack[5] + q % S.iwidth % C.cblack[5]]; val -= cblk[c]; imgdata.image[q][c] = CLIP(val); if (dmax < val) dmax = val; } } } else { for (unsigned q = 0; q < (unsigned)size; q++) { for (unsigned c = 0; c < 4; c++) { int val = imgdata.image[q][c]; val -= cblk[c]; imgdata.image[q][c] = CLIP(val); if (dmax < val) dmax = val; } } } C.data_maximum = dmax & 0xffff; C.maximum -= C.black; ZERO(C.cblack); // Yeah, we used cblack[6+] values too! C.black = 0; } else { // Nothing to Do, maximum is already calculated, black level is 0, so no // change only calculate channel maximum; int idx; ushort *p = (ushort *)imgdata.image; int dmax = 0; for (idx = 0; idx < S.iheight * S.iwidth * 4; idx++) if (dmax < p[idx]) dmax = p[idx]; C.data_maximum = dmax; } return 0; } catch (const LibRaw_exceptions& err) { EXCEPTION_HANDLER(err); } } LibRaw-0.21.4/src/tables/000077500000000000000000000000001477673233700150425ustar00rootroot00000000000000LibRaw-0.21.4/src/tables/cameralist.cpp000066400000000000000000000704271477673233700177040ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" #ifdef USE_RAWSPEED /* we need separate file for that */ #include "../../RawSpeed/rawspeed_xmldata.cpp" const int RAWSPEED_DATA_COUNT = (sizeof(_rawspeed_data_xml) / sizeof(_rawspeed_data_xml[0])); #endif // clang-format off // Supported cameras: static const char *static_camera_list[] = { "Adobe Digital Negative (DNG)", "AgfaPhoto DC-833m", "Alcatel 5035D", "Apple iPad Pro", "Apple iPhone SE", "Apple iPhone 6s", "Apple iPhone 6 plus", "Apple iPhone 7", "Apple iPhone 7 plus", "Apple iPhone 8", "Apple iPhone 8 plus", "Apple iPhone X", "Apple iPhone 12 Pro", "Apple iPhone 12 Pro Max", "Apple iPhone 13 Pro", "Apple QuickTake 100", "Apple QuickTake 150", "Apple QuickTake 200", #ifdef LIBRAW_OLD_VIDEO_SUPPORT "ARRI ALEXA", "ARRI ALEXA65", "ARRI ALEXA LF", "ARRI ALEXA XT", "ARRI ALEXA SXT", #endif "ASUS ZenPhone4", "ASUS ZenPhone6", "AutelRobotics XB015", "AutelRobotics XT705 (EVO II)", "AVT F-080C", "AVT F-145C", "AVT F-201C", "AVT F-510C", "AVT F-810C", "Baumer TXG14", "BlackMagic Cinema Camera", "BlackMagic Micro Cinema Camera", "BlackMagic Pocket Cinema Camera", "BlackMagic Production Camera 4k", "BlackMagic URSA", "BlackMagic URSA Mini 4k", "BlackMagic URSA Mini 4.6k", "BlackMagic URSA Mini Pro 4.6k", "BQ Aquarius U", "Canon PowerShot 600", "Canon PowerShot A5", "Canon PowerShot A5 Zoom", "Canon PowerShot A50", "Canon PowerShot A410 (CHDK hack)", "Canon PowerShot A460 (CHDK hack)", "Canon PowerShot A470 (CHDK hack)", "Canon PowerShot A480 (CHDK hack)", "Canon PowerShot A530 (CHDK hack)", "Canon PowerShot A540 (CHDK hack)", "Canon PowerShot A550 (CHDK hack)", "Canon PowerShot A560 (CHDK hack)", "Canon PowerShot A570 IS (CHDK hack)", "Canon PowerShot A590 IS (CHDK hack)", "Canon PowerShot A610 (CHDK hack)", "Canon PowerShot A620 (CHDK hack)", "Canon PowerShot A630 (CHDK hack)", "Canon PowerShot A640 (CHDK hack)", "Canon PowerShot A650 IS (CHDK hack)", "Canon PowerShot A710 IS (CHDK hack)", "Canon PowerShot A720 IS (CHDK hack)", "Canon PowerShot A3300 IS (CHDK hack)", "Canon PowerShot D10 (CHDK hack)", "Canon PowerShot ELPH 130 IS / IXUS 140 / IXY 110F (CHDK hack)", "Canon PowerShot ELPH 160 / IXUS 160 (CHDK hack)", "Canon PowerShot Pro70", "Canon PowerShot Pro90 IS", "Canon PowerShot Pro1", "Canon PowerShot G1", "Canon PowerShot G1 X", "Canon PowerShot G1 X Mark II", "Canon PowerShot G1 X Mark III", "Canon PowerShot G2", "Canon PowerShot G3", "Canon PowerShot G3 X", "Canon PowerShot G5", "Canon PowerShot G5 X", "Canon PowerShot G5 X Mark II", "Canon PowerShot G6", "Canon PowerShot G7 (CHDK hack)", "Canon PowerShot G7 X", "Canon PowerShot G7 X Mark II", "Canon PowerShot G7 X Mark III", "Canon PowerShot G9", "Canon PowerShot G9 X", "Canon PowerShot G9 X Mark II", "Canon PowerShot G10", "Canon PowerShot G11", "Canon PowerShot G12", "Canon PowerShot G15", "Canon PowerShot G16", "Canon PowerShot S2 IS (CHDK hack)", "Canon PowerShot S3 IS (CHDK hack)", "Canon PowerShot S5 IS (CHDK hack)", "Canon PowerShot SD300 / IXUS 40 / IXY Digital 50 (CHDK hack)", "Canon PowerShot SD750 / IXUS 75 / IXY Digital 90 (CHDK hack)", "Canon PowerShot SD900 / Digital IXUS 900 Ti / IXY Digital 1000 (CHDK hack)", "Canon PowerShot SD950 IS / Digital IXUS 960 IS / IXY Digital 2000 IS (CHDK hack)", "Canon PowerShot SD1200 IS / Digital IXUS 95 IS / IXY Digital 110 IS (CHDK hack)", "Canon PowerShot S30", "Canon PowerShot S40", "Canon PowerShot S45", "Canon PowerShot S50", "Canon PowerShot S60", "Canon PowerShot S70", "Canon PowerShot S90", "Canon PowerShot S95", "Canon PowerShot S100", "Canon PowerShot S110", "Canon PowerShot S120", "Canon PowerShot SX1 IS", "Canon PowerShot SX40 HS (CHDK hack, CR2)", "Canon PowerShot SX50 HS", "Canon PowerShot SX60 HS", "Canon PowerShot SX70 HS", "Canon PowerShot SX100 IS (CHDK hack)", "Canon PowerShot SX110 IS (CHDK hack)", "Canon PowerShot SX120 IS (CHDK hack)", "Canon PowerShot SX130 IS (CHDK hack)", "Canon PowerShot SX160 IS (CHDK hack)", "Canon PowerShot SX220 HS (CHDK hack)", "Canon PowerShot SX510 HS (CHDK hack)", "Canon PowerShot SX710 HS (CHDK hack)", "Canon PowerShot SX10 IS (CHDK hack)", "Canon PowerShot SX20 IS (CHDK hack)", "Canon PowerShot SX30 IS (CHDK hack)", "Canon EOS R", "Canon EOS RP", "Canon EOS R3", "Canon EOS R5", "Canon EOS R6", "Canon EOS R7", "Canon EOS R10", "Canon EOS D30", "Canon EOS D60", "Canon EOS 5DS", "Canon EOS 5DS R", "Canon EOS 5D", "Canon EOS 5D Mark II", "Canon EOS 5D Mark III", "Canon EOS 5D Mark IV", "Canon EOS 6D", "Canon EOS 6D Mark II", "Canon EOS 7D", "Canon EOS 7D Mark II", "Canon EOS 10D", "Canon EOS 20D", "Canon EOS 20Da", "Canon EOS 30D", "Canon EOS 40D", "Canon EOS 50D", "Canon EOS 60D", "Canon EOS 60Da", "Canon EOS 70D", "Canon EOS 77D / 9000D", "Canon EOS 80D", "Canon EOS 90D", "Canon EOS 100D / Rebel SL1 / Kiss X7", "Canon EOS 200D / Rebel SL2 / Kiss X9", "Canon EOS 250D / 200D II / Rebel SL3 / Kiss X10", "Canon EOS 300D / Digital Rebel / Kiss Digital", "Canon EOS 350D / Digital Rebel XT / Kiss Digital N", "Canon EOS 400D / Digital Rebel XTi / Kiss Digital X", "Canon EOS 450D / Digital Rebel XSi / Kiss X2", "Canon EOS 500D / Rebel T1i / Kiss X3", "Canon EOS 550D / Rebel T2i / Kiss X4", "Canon EOS 600D / Rebel T3i / Kiss X5", "Canon EOS 650D / Rebel T4i / Kiss X6i", "Canon EOS 700D / Rebel T5i / Kiss X7i", "Canon EOS 750D / Rebel T6i / Kiss X8i", "Canon EOS 760D / Rebel T6S / 8000D", "Canon EOS 800D / Rebel T7i / Kiss X9i", "Canon EOS 850D / Rebel T8i / Kiss X10i", "Canon EOS 1000D / Digital Rebel XS / Kiss F", "Canon EOS 1100D / Rebel T3 / Kiss X50", "Canon EOS 1200D / Kiss X70 / REBEL T5 / Hi", "Canon EOS 1300D / Rebel T6 / Kiss X80", "Canon EOS 1500D / 2000D / Rebel T7 / Kiss X90", "Canon EOS 3000D / 4000D / Rebel T100", #ifdef LIBRAW_OLD_VIDEO_SUPPORT "Canon EOS C500", #endif "Canon EOS D2000", "Canon EOS M", "Canon EOS M2", "Canon EOS M3", "Canon EOS M5", "Canon EOS M6", "Canon EOS M6 Mark II", "Canon EOS M10", "Canon EOS M50 / Kiss M", "Canon EOS M50 Mark II", "Canon EOS M100", "Canon EOS M200", "Canon EOS-1D C", "Canon EOS-1D X", "Canon EOS-1D X Mark II", "Canon EOS-1D X Mark III", "Canon EOS-1D", "Canon EOS-1D Mark II", "Canon EOS-1D Mark II N", "Canon EOS-1D Mark III", "Canon EOS-1D Mark IV", "Canon EOS-1Ds", "Canon EOS-1Ds Mark II", "Canon EOS-1Ds Mark III", "Casio QV-2000UX (secret menu hack)", "Casio QV-3000EX (secret menu hack)", "Casio QV-3500EX (secret menu hack)", "Casio QV-4000 (secret menu hack)", "Casio QV-5700 (secret menu hack)", "Casio QV-R41", "Casio QV-R51", "Casio QV-R61", "Casio EX-F1", "Casio EX-FC300S", "Casio EX-FC400S", "Casio EX-FH20", "Casio EX-FH25", "Casio EX-FH100", "Casio EX-S20 / M20", "Casio EX-S100", "Casio EX-Z4", "Casio EX-Z50", "Casio EX-Z500", "Casio EX-Z55", "Casio EX-Z60", "Casio EX-Z75", "Casio EX-Z750", "Casio EX-Z8", "Casio EX-Z850", "Casio EX-Z1050", "Casio EX-ZR100", "Casio EX-Z1080", "Casio EX-ZR700", "Casio EX-ZR710", "Casio EX-ZR750", "Casio EX-ZR800", "Casio EX-ZR850", "Casio EX-ZR1000", "Casio EX-ZR1100", "Casio EX-ZR1200", "Casio EX-ZR1300", "Casio EX-ZR1500", "Casio EX-ZR3000", "Casio EX-ZR3100", "Casio EX-ZR3200", "Casio EX-ZR3500", "Casio EX-ZR3600", "Casio EX-ZR3700", "Casio EX-ZR4000 / 5000", "Casio EX-ZR4100 / 5100", "Casio EX-100", "Casio EX-100F", "Casio EX-100PRO", "Casio EX-10", "Casio EX-P505 (secret menu hack)", "Casio EX-P600 (secret menu hack)", "Casio EX-P700 (secret menu hack)", "CLAUSS pix500", "Contax N Digital", "Creative PC-CAM 600", "Digital Bolex D16", "Digital Bolex D16M", "DJI 4384x3288", "DJI Mavic Air", "DJI Mavic Air2", "DJI Mavic Air 2S", "DJI Mavic Mini2", "DJI Mavic 3", "DJI Osmo Action", "DJI Pocket", "DJI Phantom4 Pro/Pro+", "DJI Zenmuse X5", "DJI Zenmuse X5R", "DXO One", "Epson R-D1", "Epson R-D1s", "Epson R-D1x", "Eyedeas E1", "Foculus 531C", "FujiFilm DBP for GX680 / DX-2000", "FujiFilm E550", "FujiFilm E900", "FujiFilm F500EXR / F505EXR", "FujiFilm F550EXR", "FujiFilm F600EXR / F605EXR", "FujiFilm F700", "FujiFilm F710", "FujiFilm F770EXR / F775EXR", "FujiFilm F800EXR", "FujiFilm F810", "FujiFilm F900EXR", "FujiFilm S2Pro", "FujiFilm S3Pro", "FujiFilm S5Pro", "FujiFilm S20Pro", "FujiFilm S1", "FujiFilm S100FS", "FujiFilm S5000", "FujiFilm S5100 / S5500", "FujiFilm S5200 / S5600", "FujiFilm S6000fd / S6500fd", "FujiFilm S7000", "FujiFilm S9000 / S9500", "FujiFilm S9100 / S9600", "FujiFilm S200EXR / S205EXR", "FujiFilm SL1000", "FujiFilm HS10/HS11", "FujiFilm HS20EXR / HS22EXR", "FujiFilm HS30EXR / HS33EXR / HS35EXR", "FujiFilm HS50EXR", "FujiFilm GFX 50S", "FujiFilm GFX 50S II", "FujiFilm GFX 50R", "FujiFilm GFX 100", "FujiFilm GFX 100S", "FujiFilm X-Pro1", "FujiFilm X-Pro2", "FujiFilm X-Pro3", "FujiFilm X-S1", "FujiFilm XQ1", "FujiFilm XQ2", "FujiFilm X100", "FujiFilm X100F", "FujiFilm X100S", "FujiFilm X100T", "FujiFilm X100V", "FujiFilm X10", "FujiFilm X20", "FujiFilm X30", "FujiFilm X70", "FujiFilm X-A1", "FujiFilm X-A2", "FujiFilm X-A3", "FujiFilm X-A5", "FujiFilm X-A7", "FujiFilm X-A10", "FujiFilm X-A20", "FujiFilm X-E1", "FujiFilm X-E2", "FujiFilm X-E2S", "FujiFilm X-E3", "FujiFilm X-E4", "FujiFilm X-M1", "FujiFilm XF1", "FujiFilm XF10", "FujiFilm X-H1", "FujiFilm X-H2S", "FujiFilm X-T1", "FujiFilm X-S10", "FujiFilm X-T1 Graphite Silver", "FujiFilm X-T2", "FujiFilm X-T3", "FujiFilm X-T4", "FujiFilm X-T10", "FujiFilm X-T20", "FujiFilm X-T30", "FujiFilm X-T30 II", "FujiFilm X-T100", "FujiFilm X-T200", "FujiFilm IS-1", "Gione E7", "GITUP GIT2", "GITUP GIT2P", "GITUP G3 DUO (16:9 mode only)", "Google Pixel", "Google Pixel XL", "Google Pixel 3a", "Google Pixel 4 XL", "Google Pixel 4a (5G)", "Google Pixel 5", #ifdef USE_GPRSDK "GoPro Fusion", "GoPro HERO5", "GoPro HERO6", "GoPro HERO7", "GoPro HERO8", "GoPro HERO9", "GoPro HERO10", #endif "Hasselblad H2D-22", "Hasselblad H2D-39", "Hasselblad H3DII-22", "Hasselblad H3DII-31", "Hasselblad H3DII-39", "Hasselblad H3DII-50", "Hasselblad H3D-22", "Hasselblad H3D-31", "Hasselblad H3D-39", "Hasselblad H4D-60", "Hasselblad H4D-50", "Hasselblad H4D-40", "Hasselblad H4D-31", "Hasselblad H5D-60", "Hasselblad H5D-50", "Hasselblad H5D-50c", "Hasselblad H5D-40", "Hasselblad H6D-100c", "Hasselblad A6D-100c", // Aerial camera "Hasselblad CFV", "Hasselblad CFV-50", "Hasselblad CFV II 50C", "Hasselblad CFH", "Hasselblad CF-22", "Hasselblad CF-31", "Hasselblad CF-39", "Hasselblad V96C", "Hasselblad L1D-20c (DJI Mavic 2 Pro)", "Hasselblad Lusso", "Hasselblad Lunar", "Hasselblad True Zoom", "Hasselblad Stellar", "Hasselblad Stellar II", "Hasselblad HV", "Hasselblad X1D", "Hasselblad X1D II 50C", "HTC UltraPixel", "HTC MyTouch 4G", "HTC One (A9)", "HTC One (M9)", "HTC 10", "HTC U12", "Huawei P8 Lite (PRA-LX1)", "Huawei P9 (EVA-L09/AL00)", "Huawei P10 (VTR-L09)", "Huawei P10+ (VKY-L09)", "Huawei P10 Lite (WAS-LX1A)", "Huawei P20 (EML-L09)", "Huawei P20 Lite (ANE-LX1)", "Huawei P20 Pro (CLT-L29/L09)", "Huawei P30 Pro (VOG-L29)", "Huawei Honor6a", "Huawei Honor7a pro", "Huawei Honor8 (FRD-L09)", "Huawei Honor9", "Huawei Honor10", "Huawei Honor20", "Huawei Honor View 10 (BKL-L09)", "Huawei Honor View 20 (PCT-L29)", "Huawei Honor 20 Pro (YAL-L41)", "Huawei Mate8 (NXT-L29)", "Huawei Mate10 (BLA-L29)", "Huawei Mate20 Pro (LYA-L29)", "Huawei Mate20 Lite (SNE-LX1)", "Imacon Ixpress 96, 96C", "Imacon Ixpress 384, 384C (single shot only)", "Imacon Ixpress 132C", "Imacon Ixpress 528C (single shot only)", "ISG 2020x1520", "Ikonoskop A-Cam dII Panchromatic", "Ikonoskop A-Cam dII", "Kandao QooCam 8K", "Kinefinity KineMINI", "Kinefinity KineRAW Mini", "Kinefinity KineRAW S35", "Kodak DC20", "Kodak DC25", "Kodak DC40", "Kodak DC50", "Kodak DC120", "Kodak DCS200", "Kodak DCS315C", "Kodak DCS330C", "Kodak DCS420", "Kodak DCS460", "Kodak DCS460M", "Kodak DCS520C", "Kodak DCS560C", "Kodak DCS620C", "Kodak DCS620X", "Kodak DCS660C", "Kodak DCS660M", "Kodak DCS720X", "Kodak DCS760C", "Kodak DCS760M", "Kodak EOSDCS1", "Kodak EOSDCS3", "Kodak NC2000", "Kodak ProBack", "Kodak PB645C", "Kodak PB645H", "Kodak PB645M", "Kodak DCS Pro 14n", "Kodak DCS Pro 14nx", "Kodak DCS Pro SLR/c", "Kodak DCS Pro SLR/n", "Kodak C330", "Kodak C603", "Kodak P850", "Kodak P880", "Kodak PIXPRO AZ901", "Kodak PIXPRO S-1", "Kodak Z980", "Kodak Z981", "Kodak Z990", "Kodak Z1015", "Kodak KAI-0340", "Konica KD-400Z", "Konica KD-510Z", "Leaf AFi 5", "Leaf AFi 6", "Leaf AFi 7", "Leaf AFi-II 6", "Leaf AFi-II 7", "Leaf AFi-II 10", "Leaf AFi-II 10R", "Leaf Aptus-II 5", "Leaf Aptus-II 6", "Leaf Aptus-II 7", "Leaf Aptus-II 8", "Leaf Aptus-II 10", "Leaf Aptus-II 12", "Leaf Aptus-II 12R", "Leaf Aptus 17", "Leaf Aptus 22", "Leaf Aptus 54S", "Leaf Aptus 65", "Leaf Aptus 65S", "Leaf Aptus 75", "Leaf Aptus 75S", "Leaf Cantare", "Leaf Cantare XY", "Leaf CatchLight", "Leaf CMost", "Leaf Credo 40", "Leaf Credo 50", "Leaf Credo 60", "Leaf Credo 80", "Leaf DCB-II", "Leaf Valeo 6", "Leaf Valeo 11", "Leaf Valeo 17", "Leaf Valeo 17wi", "Leaf Valeo 22", "Leaf Valeo 22wi", "Leaf Volare", "Lenovo a820", "Leica C (Typ 112)", "Leica CL", "Leica C-Lux / CAM-DC25", "Leica Digilux 2", "Leica Digilux 3", "Leica Digital-Modul-R", "Leica D-LUX2", "Leica D-LUX3", "Leica D-LUX4", "Leica D-LUX5", "Leica D-LUX6", "Leica D-LUX7", "Leica D-Lux (Typ 109)", "Leica M8", "Leica M8.2", "Leica M9", "Leica M10", "Leica M10-D", "Leica M10-P", "Leica M10-R", "Leica M10 Monochrom", "Leica M11", "Leica M (Typ 240)", "Leica M (Typ 262)", "Leica Monochrom (Typ 240)", "Leica Monochrom (Typ 246)", "Leica M-D (Typ 262)", "Leica M-E", "Leica M-P", "Leica R8", "Leica Q (Typ 116)", "Leica Q-P", "Leica Q2", "Leica Q2 Monochrom", "Leica S", "Leica S2", "Leica S3", "Leica S (Typ 007)", "Leica SL (Typ 601)", "Leica SL2", "Leica SL2-S", "Leica T (Typ 701)", "Leica TL", "Leica TL2", "Leica X1", "Leica X (Typ 113)", "Leica X2", "Leica X-E (Typ 102)", "Leica X-U (Typ 113)", "Leica V-LUX1", "Leica V-LUX2", "Leica V-LUX3", "Leica V-LUX4", "Leica V-LUX5", "Leica V-Lux (Typ 114)", "Leica X VARIO (Typ 107)", "LG G3", "LG G4", "LG G5 (H850)", "LG G6", "LG V20 (F800K)", "LG V20 (H910)", "LG VS995", "Logitech Fotoman Pixtura", "Mamiya ZD", "Matrix 4608x3288", "Meizy MX4", "Micron 2010", "Minolta RD175 / Agfa ActionCam", "Minolta DiMAGE 5", "Minolta DiMAGE 7", "Minolta DiMAGE 7i", "Minolta DiMAGE 7Hi", "Minolta DiMAGE A1", "Minolta DiMAGE A2", "Minolta DiMAGE A200", "Minolta DiMAGE G400", "Minolta DiMAGE G500", "Minolta DiMAGE G530", "Minolta DiMAGE G600", "Minolta DiMAGE Z2", "Minolta Alpha/Dynax/Maxxum 5D", "Minolta Alpha/Dynax/Maxxum 7D", "Motorola PIXL", "Motorola Moto G (5S)", "Motorola Moto G7 Play", "Nikon D1", "Nikon D1H", "Nikon D1X", "Nikon D2H", "Nikon D2Hs", "Nikon D2X", "Nikon D2Xs", "Nikon D3", "Nikon D3s", "Nikon D3X", "Nikon D4", "Nikon D4s", "Nikon D40", "Nikon D40X", "Nikon D5", "Nikon D50", "Nikon D6", "Nikon D60", "Nikon D70", "Nikon D70s", "Nikon D80", "Nikon D90", "Nikon D100", "Nikon D200", "Nikon D300", "Nikon D300s", "Nikon D500", "Nikon D600", "Nikon D610", "Nikon D700", "Nikon D750", "Nikon D780", "Nikon D800", "Nikon D800E", "Nikon D810", "Nikon D810A", "Nikon D850", "Nikon D3000", "Nikon D3100", "Nikon D3200", "Nikon D3300", "Nikon D3400", "Nikon D3500", "Nikon D5000", "Nikon D5100", "Nikon D5200", "Nikon D5300", "Nikon D5500", "Nikon D5600", "Nikon D7000", "Nikon D7100", "Nikon D7200", "Nikon D7500", "Nikon Df", "Nikon Z 5", "Nikon Z 6", "Nikon Z 6 II", "Nikon Z 7", "Nikon Z 7 II", "Nikon Z 9 (HE/HE* formats are not supported yet)", "Nikon Z 50", "Nikon Z fc", "Nikon 1 AW1", "Nikon 1 J1", "Nikon 1 J2", "Nikon 1 J3", "Nikon 1 J4", "Nikon 1 J5", "Nikon 1 S1", "Nikon 1 S2", "Nikon 1 V1", "Nikon 1 V2", "Nikon 1 V3", "Nikon Coolpix 700 (\"DIAG RAW\" hack)", "Nikon Coolpix 800 (\"DIAG RAW\" hack)", "Nikon Coolpix 880 (\"DIAG RAW\" hack)", "Nikon Coolpix 900 (\"DIAG RAW\" hack)", "Nikon Coolpix 950 (\"DIAG RAW\" hack)", "Nikon Coolpix 990 (\"DIAG RAW\" hack)", "Nikon Coolpix 995 (\"DIAG RAW\" hack)", "Nikon Coolpix 2100 (\"DIAG RAW\" hack)", "Nikon Coolpix 2500 (\"DIAG RAW\" hack)", "Nikon Coolpix 3200 (\"DIAG RAW\" hack)", "Nikon Coolpix 3700 (\"DIAG RAW\" hack)", "Nikon Coolpix 4300 (\"DIAG RAW\" hack)", "Nikon Coolpix 4500 (\"DIAG RAW\" hack)", "Nikon Coolpix 5000", "Nikon Coolpix 5400", "Nikon Coolpix 5700", "Nikon Coolpix 8400", "Nikon Coolpix 8700", "Nikon Coolpix 8800", "Nikon Coolpix A", "Nikon Coolpix A1000", "Nikon Coolpix B700", "Nikon Coolpix P330", "Nikon Coolpix P340", "Nikon Coolpix P950", "Nikon Coolpix P6000", "Nikon Coolpix P1000", "Nikon Coolpix P7000", "Nikon Coolpix P7100", "Nikon Coolpix P7700", "Nikon Coolpix P7800", "Nikon Coolpix S6 (\"DIAG RAW\" hack)", "Nikon Coolscan NEF", "Nokia 7 Plus", "Nokia 8.3 5G", "Nokia 9", "Nokia N95", "Nokia X2", "Nokia 1200x1600", "Nokia Lumia 930", "Nokia Lumia 950 XL", "Nokia Lumia 1020", "Nokia Lumia 1520", "Olympus AIR A01", "Olympus C-3030Z", "Olympus C-5050Z", "Olympus C-5060WZ", "Olympus C-7070WZ", "Olympus C-70Z / C-7000Z", "Olympus C-740UZ", "Olympus C-770UZ", "Olympus C-8080WZ", "Olympus X200 / D-560Z / C-350Z", "Olympus E-1", "Olympus E-3", "Olympus E-5", "Olympus E-10", "Olympus E-20 / E-20N / E-20P", "Olympus E-30", "Olympus E-300", "Olympus E-330", "Olympus E-400", "Olympus E-410", "Olympus E-420", "Olympus E-450", "Olympus E-500", "Olympus E-510", "Olympus E-520", "Olympus E-600", "Olympus E-620", "Olympus E-P1", "Olympus E-P2", "Olympus E-P3", "Olympus E-P5", "Olympus E-P7", "Olympus E-PL1", "Olympus E-PL1s", "Olympus E-PL2", "Olympus E-PL3", "Olympus E-PL5", "Olympus E-PL6", "Olympus E-PL7", "Olympus E-PL8", "Olympus E-PL9", "Olympus E-PL10", "Olympus E-PM1", "Olympus E-PM2", "Olympus E-M1", "Olympus E-M1 Mark II", "Olympus E-M1 Mark III", "Olympus E-M1X", "Olympus E-M10", "Olympus E-M10 Mark II", "Olympus E-M10 Mark III", "Olympus E-M10 Mark IV", "Olympus E-M5", "Olympus E-M5 Mark II", "Olympus E-M5 Mark III", "Olympus Pen-F", "Olympus SP-310", "Olympus SP-320", "Olympus SP-350", "Olympus SP-500UZ", "Olympus SP-510UZ", "Olympus SP-550UZ", "Olympus SP-560UZ", "Olympus SP-565UZ", "Olympus SP-570UZ", "Olympus Stylus 1", "Olympus Stylus 1s", "Olympus SH-2", "Olympus SH-3", "Olympus TG-4", "Olympus TG-5", "Olympus TG-6", "Olympus XZ-1", "Olympus XZ-2", "Olympus XZ-10", "OM Digital Solutions OM-1", "OmniVision 4688", "OmniVision OV5647", "OmniVision OV5648", "OmniVision OV8850", "OmniVision 13860", "OnePlus 6 (A6003)", "OnePlus 6T", "OnePlus 7 Pro (GM1913)", "OnePlus 8 Pro (IN2023)", "OnePlus One", "OnePlus A3303", "OnePlus A5000", "Panasonic DMC-CM1", "Panasonic DMC-FZ8", "Panasonic DMC-FZ18", "Panasonic DMC-FZ28", "Panasonic DMC-FZ30", "Panasonic DMC-FZ35 / FZ38", "Panasonic DMC-FZ40 / FZ42 / FZ45", "Panasonic DMC-FZ50", "Panasonic DMC-FZ70 / FZ72", "Panasonic DC-FZ80 / FZ81 / FZ82 / FZ83 / FZ85", "Panasonic DMC-FZ100", "Panasonic DMC-FZ150", "Panasonic DMC-FZ200", "Panasonic DMC-FZ300 / FZ330", "Panasonic DMC-FZ1000", "Panasonic DC-FZ1000 II / FZ1000M2 / DC-FZ10002", "Panasonic DMC-FZ2000 / FZ2500 / FZH1", "Panasonic DMC-FX150 / FX180", "Panasonic DMC-G1", "Panasonic DMC-G10", "Panasonic DMC-G2", "Panasonic DMC-G3", "Panasonic DMC-G5", "Panasonic DMC-G6", "Panasonic DMC-G7 / G70", "Panasonic DMC-G8 / G80 / G81 / G85", "Panasonic DC-G9", "Panasonic DC-G90 / G95 / G91 / G99", "Panasonic DC-G100 / G110", "Panasonic DMC-GF1", "Panasonic DMC-GF2", "Panasonic DMC-GF3", "Panasonic DMC-GF5", "Panasonic DMC-GF6", "Panasonic DMC-GF7", "Panasonic DC-GF10 / GF90", "Panasonic DMC-GH1", "Panasonic DMC-GH2", "Panasonic DMC-GH3", "Panasonic DMC-GH4", "Panasonic AG-GH4", "Panasonic DC-GH5", "Panasonic DC-GH5S", "Panasonic DC-GH5 Mark II", "Panasonic DMC-GM1", "Panasonic DMC-GM1s", "Panasonic DMC-GM5", "Panasonic DMC-GX1", "Panasonic DMC-GX7", "Panasonic DMC-GX8", "Panasonic DC-GX9 / GX7mkIII", "Panasonic DMC-GX80 / GX85, DMC-GX7mkII", "Panasonic DC-GX800 / GX850, DC-GF9", "Panasonic DMC-L1", "Panasonic DMC-L10", "Panasonic DMC-LC1", "Panasonic DMC-LF1", "Panasonic DMC-LX1", "Panasonic DMC-LX2", "Panasonic DMC-LX3", "Panasonic DMC-LX5", "Panasonic DMC-LX7", "Panasonic DMC-LX9 / LX10 / LX15", "Panasonic DMC-LX100", "Panasonic DC-LX100M2", "Panasonic DC-S1", "Panasonic DC-S1H", "Panasonic DC-S1R", "Panasonic DC-S5", "Panasonic DMC-ZS40, DMC-TZ60 / TZ61", "Panasonic DMC-ZS50, DMC-TZ70 / TZ71", "Panasonic DMC-ZS60, DMC-TZ80 / TZ81 / TZ82 / TZ85", "Panasonic DC-ZS70, DC-TZ90 / TZ91 / TZ92 / TZ93", "Panasonic DC-ZS80, DC-TZ95 / TZ96 / TZ97", "Panasonic DMC-ZS100 / ZS110, DMC-TZ100 / TZ101 / TZ110, DMC-TX1", "Panasonic DC-ZS200 / ZS220, DC-TZ200 / TZ202 / TZ220, DC-TX2", "PARROT Anafi", "PARROT Bebop 2", "PARROT Bebop Drone", "Pentax *ist D", "Pentax *ist DL", "Pentax *ist DL2", "Pentax *ist DS", "Pentax *ist DS2", "Pentax K10D", "Pentax K20D", "Pentax K100D", "Pentax K100D Super", "Pentax K110D", "Pentax K200D", "Pentax K2000/K-m", "Pentax KP", "Pentax K-x", "Pentax K-r", "Pentax K-01", "Pentax K-1", "Pentax K-1 Mark II", "Pentax K-3", "Pentax K-3 Mark II", "Pentax K-3 Mark III", "Pentax K-30", "Pentax K-5", "Pentax K-5 II", "Pentax K-5 IIs", "Pentax K-50", "Pentax K-500", "Pentax K-7", "Pentax K-70", "Pentax K-S1", "Pentax K-S2", "Pentax MX-1", "Pentax Q", "Pentax Q7", "Pentax Q10", "Pentax QS-1", "Pentax Optio S (secret menu or hack)", "Pentax Optio S4 (secret menu or hack)", "Pentax Optio 33WR (secret menu or hack)", "Pentax Optio 750Z (secret menu or hack)", "Pentax 645D", "Pentax 645Z", "PhaseOne IQ140", "PhaseOne IQ150", "PhaseOne IQ160", "PhaseOne IQ180", "PhaseOne IQ180 IR", "PhaseOne IQ250", "PhaseOne IQ260", "PhaseOne IQ260 Achromatic", "PhaseOne IQ280", "PhaseOne IQ3 50MP", "PhaseOne IQ3 60MP", "PhaseOne IQ3 80MP", "PhaseOne IQ3 100MP", "PhaseOne IQ3 100MP Trichromatic", "PhaseOne IQ4 150MP", "PhaseOne LightPhase", "PhaseOne Achromatic+", "PhaseOne H 10", "PhaseOne H 20", "PhaseOne H 25", "PhaseOne P 20", "PhaseOne P 20+", "PhaseOne P 21", "PhaseOne P 25", "PhaseOne P 25+", "PhaseOne P 30", "PhaseOne P 30+", "PhaseOne P 40+", "PhaseOne P 45", "PhaseOne P 45+", "PhaseOne P 65", "PhaseOne P 65+", "Photron BC2-HD", "Pixelink A782", #ifdef USE_X3FTOOLS "Polaroid x530", #endif "RaspberryPi Camera", "RaspberryPi Camera V2", #ifdef USE_6BY9RPI "RaspberryPi HQ Camera", #endif "Ricoh GR", "Realme 3 Pro", "Ricoh GR II", "Ricoh GR III", "Ricoh GR IIIx", "Ricoh GR Digital", "Ricoh GR Digital II", "Ricoh GR Digital III", "Ricoh GR Digital IV", "Ricoh Caplio GX100", "Ricoh Caplio GX200", "Ricoh GXR Mount A12", "Ricoh GXR GR Lens A12 50mm F2.5 Macro", "Ricoh GXR GR Lens A12 28mm F2.5", "Ricoh GXR Ricoh Lens A16 24-85mm F3.5-5.5", "Ricoh GXR Ricoh Lens S10 24-72mm F2.5-4.4 VC", "Ricoh GXR Ricoh Lens P10 28-300 mm F3.5-5.6 VC", #ifdef LIBRAW_OLD_VIDEO_SUPPORT #ifndef NO_JASPER "Redcode R3D format", #endif #endif "Rollei d530flex", "RoverShot 3320af", "Samsung EX1 / TL500", "Samsung EX2F", "Samsung GX-1L", "Samsung GX-1S", "Samsung GX10", "Samsung GX20", "Samsung Galaxy Nexus", "Samsung Galaxy Note 9", "Samsung Galaxy NX (EK-GN120)", "Samsung Galaxy S3", "Samsung Galaxy S6 (SM-G920F)", "Samsung Galaxy S7", "Samsung Galaxy S7 Edge", "Samsung Galaxy S8 (SM-G950U)", "Samsung Galaxy S9 (SM-G960F)", "Samsung Galaxy S9+ (SM-G965U / 965F)", "Samsung Galaxy S10 (SM-G973F)", "Samsung Galaxy S10+ (SM-G975U)", "Samsung NX1", "Samsung NX5", "Samsung NX10", "Samsung NX11", "Samsung NX100", "Samsung NX1000", "Samsung NX1100", "Samsung NX20", "Samsung NX200", "Samsung NX210", "Samsung NX2000", "Samsung NX30", "Samsung NX300", "Samsung NX300M", "Samsung NX3000", "Samsung NX500", "Samsung NX mini / NXF1", "Samsung Pro815", "Samsung WB550 / WB560 / HZ15W", "Samsung WB2000 / TL350", "Samsung WB5000 / HZ25W", "Samsung S85 (hacked)", "Samsung S850 (hacked)", "Sarnoff 4096x5440", "Seitz 6x17", "Seitz Roundshot D3", "Seitz Roundshot D2X", "Seitz Roundshot D2Xs", "Sigma fp", #ifdef USE_X3FTOOLS "Sigma SD9 (raw decode only)", "Sigma SD10 (raw decode only)", "Sigma SD14 (raw decode only)", "Sigma SD15 (raw decode only)", "Sigma SD1", "Sigma SD1 Merrill", "Sigma DP1", "Sigma DP1 Merrill", "Sigma DP1S", "Sigma DP1X", "Sigma DP2", "Sigma DP2 Merrill", "Sigma DP2S", "Sigma DP2X", "Sigma DP3 Merrill", "Sigma dp0 Quattro", "Sigma dp1 Quattro", "Sigma dp2 Quattro", "Sigma dp3 Quattro", "Sigma sd Quattro", "Sigma sd Quattro H", #else "Sigma dp0 Quattro (DNG only)", "Sigma dp1 Quattro (DNG only)", "Sigma dp2 Quattro (DNG only)", "Sigma dp3 Quattro (DNG only)", "Sigma sd Quattro (DNG only)", "Sigma sd Quattro H (DNG only)", #endif "Sinar eMotion 22", "Sinar eMotion 54", "Sinar eSpirit 65", "Sinar eMotion 75", "Sinar eVolution 75", "Sinar 3072x2048 (Sinarback 23)", "Sinar 4080x4080 (Sinarback 44)", "Sinar 4080x5440", "Sinar STI format", "Sinar Sinarback 54", "SMaL Ultra-Pocket 3", "SMaL Ultra-Pocket 4", "SMaL Ultra-Pocket 5", "Sony ILCE-1 (A1)", "Sony ILCE-7 (A7)", "Sony ILCE-7M2 (A7 II)", "Sony ILCE-7M3 (A7 III)", "Sony ILCE-7M4 (A7 IV)", "Sony ILCE-7C (A7C)", "Sony ILCE-7R (A7R)", "Sony ILCE-7RM2 (A7R II)", "Sony ILCE-7RM3 (A7R III)", "Sony ILCE-7RM3A (A7R IIIA)", "Sony ILCE-7RM4 (A7R IV)", "Sony ILCE-7RM4A (A7R IVA)", "Sony ILCE-7S (A7S)", "Sony ILCE-7SM2 (A7S II)", "Sony ILCE-7SM3 (A7S III)", "Sony ILCE-9 (A9)", "Sony ILCE-9M2 (A9 II)", "Sony ILCA-68 (A68)", "Sony ILCA-77M2 (A77-II)", "Sony ILCA-99M2 (A99-II)", "Sony ILCE-3000 / 3500", "Sony ILCE-5000", "Sony ILCE-5100", "Sony ILCE-6000", "Sony ILCE-6100", "Sony ILCE-6300", "Sony ILCE-6400", "Sony ILCE-6500", "Sony ILCE-6600", "Sony ILCE-QX1", "Sony DSC-F828", "Sony DSC-HX95", "Sony DSC-HX99", "Sony DSC-R1", "Sony DSC-RX0", "Sony DSC-RX0 II", "Sony DSC-RX1", "Sony DSC-RX1R", "Sony DSC-RX1R II", "Sony DSC-RX10", "Sony DSC-RX10 II", "Sony DSC-RX10 III", "Sony DSC-RX10 IV", "Sony DSC-RX100", "Sony DSC-RX100 II", "Sony DSC-RX100 III", "Sony DSC-RX100 IV", "Sony DSC-RX100 V", "Sony DSC-RX100 VA", "Sony DSC-RX100 VI", "Sony DSC-RX100 VII", "Sony DSC-V3", "Sony DSLR-A100", "Sony DSLR-A200", "Sony DSLR-A230", "Sony DSLR-A290", "Sony DSLR-A300", "Sony DSLR-A330", "Sony DSLR-A350", "Sony DSLR-A380 / A390", "Sony DSLR-A450", "Sony DSLR-A500", "Sony DSLR-A550", "Sony DSLR-A560", "Sony DSLR-A580", "Sony DSLR-A700", "Sony DSLR-A850", "Sony DSLR-A900", "Sony NEX-3", "Sony NEX-3N", "Sony NEX-5", "Sony NEX-5N", "Sony NEX-5R", "Sony NEX-5T", "Sony NEX-6", "Sony NEX-7", "Sony NEX-C3", "Sony NEX-F3", "Sony NEX-VG20", "Sony NEX-VG30", "Sony NEX-VG900", "Sony SLT-A33", "Sony SLT-A35", "Sony SLT-A37", "Sony SLT-A55(V)", "Sony SLT-A57", "Sony SLT-A58", "Sony SLT-A65(V)", "Sony SLT-A77(V)", "Sony SLT-A99(V)", "Sony XCD-SX910CR", "Sony IMX135-mipi 13mp", "Sony IMX135-QCOM", "Sony IMX072-mipi", "Sony IMX214", "Sony IMX219", "Sony IMX230", "Sony IMX298-mipi 16mp", "Sony IMX219-mipi 8mp", "Sony Xperia 5 II (XQ-AS52)", "Sony Xperia L", "Sony Xperia 1 III", "Sony ZV-1 (DCZV1/B)", "Sony ZV-E10", "STV680 VGA", "PtGrey GRAS-50S5C", "JaiPulnix BB-500CL", "JaiPulnix BB-500GE", "SVS SVS625CL", "Vivo X51 5G (V2006)", "Yi M1", "YUNEEC CGO3", "YUNEEC CGO3P", "YUNEEC CGO4", "Xiaomi MI3", "Xiaomi MI 8", "Xiaomi MI 9 Lite", "Xiaomi MI MAX", "Xiaomi POCO M3", "Xiaomi RedMi Note3 Pro", "Xiaomi RedMi Note7", "Xiaomi RedMi Note 8T", "Xiaomi FIMI X8SE", "Xiaoyi YIAC3 (YI 4k)", "Zeiss ZX1", "Zenit M", NULL }; // clang-format on const char **LibRaw::cameraList() { return static_camera_list; } int LibRaw::cameraCount() { return (sizeof(static_camera_list) / sizeof(static_camera_list[0])) - 1; } LibRaw-0.21.4/src/tables/colorconst.cpp000066400000000000000000000042271477673233700177400ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" const double LibRaw_constants::xyz_rgb[3][3] = { {0.4124564, 0.3575761, 0.1804375}, {0.2126729, 0.7151522, 0.0721750}, {0.0193339, 0.1191920, 0.9503041}}; const float LibRaw_constants::d65_white[3] = {0.95047f, 1.0f, 1.08883f}; const double LibRaw_constants::xyzd50_srgb[3][3] = { {0.436083, 0.385083, 0.143055}, {0.222507, 0.716888, 0.060608}, {0.013930, 0.097097, 0.714022}}; const double LibRaw_constants::rgb_rgb[3][3] = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; const double LibRaw_constants::adobe_rgb[3][3] = { {0.715146, 0.284856, 0.000000}, {0.000000, 1.000000, 0.000000}, {0.000000, 0.041166, 0.958839}}; const double LibRaw_constants::wide_rgb[3][3] = { {0.593087, 0.404710, 0.002206}, {0.095413, 0.843149, 0.061439}, {0.011621, 0.069091, 0.919288}}; const double LibRaw_constants::prophoto_rgb[3][3] = { {0.529317, 0.330092, 0.140588}, {0.098368, 0.873465, 0.028169}, {0.016879, 0.117663, 0.865457}}; const double LibRaw_constants::aces_rgb[3][3] = { // Coffin's values (commented out) are not adapted from ACES "D60-like" WP to D65 // {0.432996, 0.375380, 0.189317}, // {0.089427, 0.816523, 0.102989}, // {0.019165, 0.118150, 0.941914}}; {0.43968015, 0.38295299, 0.17736686}, {0.08978964, 0.81343316, 0.09677734}, {0.01754827, 0.11156156, 0.87089017}}; const double LibRaw_constants::dcip3d65_rgb[3][3] = { {0.822488, 0.177511, 0.000000}, {0.033200, 0.966800, 0.000000}, {0.017089, 0.072411, 0.910499}}; const double LibRaw_constants::rec2020_rgb[3][3] = { {0.627452, 0.329249, 0.043299}, {0.069109, 0.919531, 0.011360}, {0.016398, 0.088030, 0.895572}}; LibRaw-0.21.4/src/tables/colordata.cpp000066400000000000000000002767461477673233700175440ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" /* All matrices are from Adobe DNG Converter unless otherwise noted. */ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, int internal_only) { // clang-format off static const struct { unsigned m_idx; const char *prefix; int t_black, t_maximum, trans[12]; } table[] = { { LIBRAW_CAMERAMAKER_Agfa, "DC-833m", 0, 0, { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Apple, "QuickTake", 0, 0, { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Broadcom, "RPi IMX219", 66, 0x3ff, { 5302,1083,-728,-5320,14112,1699,-863,2371,5136 } }, /* LibRaw */ { LIBRAW_CAMERAMAKER_Broadcom, "RPi OV5647", 16, 0x3ff, { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Broadcom, "Pi", 16, 0x3ff, { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ #ifdef USE_6BY9RPI // this code normalizes model to LIBRAW_CAMERAMAKER_RaspberryPi { LIBRAW_CAMERAMAKER_RaspberryPi, "RP_imx477", 0, 0, // Do not set black, it is set at parser to 256 or 64 { 5603, -1351, -600, -2872, 11180, 2132, 600, 453, 5821 } }, /* PyDNG */ { LIBRAW_CAMERAMAKER_RaspberryPi, "RP_imx", 66, 0x3ff, { 5302,1083,-728,-5320,14112,1699,-863,2371,5136 } }, /* LibRaw */ { LIBRAW_CAMERAMAKER_RaspberryPi, "ov5647", 16, 0x3ff, { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ #endif { LIBRAW_CAMERAMAKER_Canon, "EOS D30", 0, 0, { 9900,-2771,-1324,-7072,14229,3140,-2790,3344,8861 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS D60", 0, 0xfa0, { 6211,-1358,-896,-8557,15766,3012,-3001,3507,8567 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 5DS", 0, 0x3c96, // same CMs: 5DS, "5DS R" */ { 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 } }, // v.2 { LIBRAW_CAMERAMAKER_Canon, "EOS 5D Mark IV", 0, 0, { 6446,-366,-864,-4436,12204,2513,-952,2496,6348 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 5D Mark III", 0, 0x3c80, { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 5D Mark II", 0, 0x3cf0, { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 5D", 0, 0xe6c, { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 6D Mark II", 0, 0x38de, { 6875,-970,-932,-4691,12459,2501,-874,1953,5809 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 6D", 0, 0x3c82, { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 77D", 0, 0, { 7377,-742,-998,-4235,11981,2549,-673,1918,5538 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 7D Mark II", 0, 0x3510, { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 7D", 0, 0x3510, { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 850D", 0, 0, { 9079,-1923,-1236,-4677,12454,2492,-922,2319,5565}}, { LIBRAW_CAMERAMAKER_Canon, "EOS 800D", 0, 0, { 6970,-512,-968,-4425,12161,2553,-739,1982,5601 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 80D", 0, 0, { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 10D", 0, 0xfa0, { 8250,-2044,-1127,-8092,15606,2664,-2893,3453,8348 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 250D", 0, 0, { 9079,-1923,-1236,-4677,12454,2492,-922,2319,5565 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 200D", 0, 0, { 7377,-742,-998,-4235,11981,2549,-673,1918,5538 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 20Da", 0, 0, { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 20D", 0, 0xfff, { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 30D", 0, 0, { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 40D", 0, 0x3f60, { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 50D", 0, 0x3d93, { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 60Da", 0, 0x2ff7, { 17492,-7240,-2023,-1791,10323,1701,-186,1329,5406 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 60D", 0, 0x2ff7, { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 70D", 0, 0x3bc7, { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 100D", 0, 0x350f, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 300D", 0, 0xfa0, { 8250,-2044,-1127,-8092,15606,2664,-2893,3453,8348 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 350D", 0, 0xfff, { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 3000D", 0, 0, { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 400D", 0, 0xe8e, { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 450D", 0, 0x390d, { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 500D", 0, 0x3479, { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 550D", 0, 0x3dd7, { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 600D", 0, 0x3510, { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 650D", 0, 0x354d, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 750D", 0, 0x3c00, { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 760D", 0, 0x3c00, { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 700D", 0, 0x3c00, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 90D", 0, 0, { 11498, -3759, -1516, -5073, 12954, 2349, -892, 1867, 6118}}, { LIBRAW_CAMERAMAKER_Canon, "EOS 1000D", 0, 0xe43, { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 1100D", 0, 0x3510, { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 1200D", 0, 0x37c2, { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 1300D", 0, 0x37c2, { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS 1500D", 0, 0, { 8300,-2110,-1120,-4917,12694,2482,-938,2141,5666 } }, // v.2 { LIBRAW_CAMERAMAKER_Canon, "EOS RP", 0, 0, { 8608,-2097,-1178,-5425,13265,2383,-1149,2238,5680 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS R3", 0, 0, { 9423,-2839,-1195,-4532,12377,2415,-483,1374,5276 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS R5", 0, 0, { 9766,-2953,-1254,-4276,12116,2433,-437,1336,5131 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS R6", 0, 0, { 8293,-1611,-1132,-4759,12711,2275,-1013,2415,5509 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS R7", 0, 0, { 10424, -3138, -1300, -4221, 11938, 2584, -547, 1658, 6183 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS R10", 0, 0, { 9269, -2012, -1107, -3990, 11762, 2527, -569, 2093, 4913 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS R", 0, 0, { 8293,-1789,-1094,-5025,12925,2327,-1199,2769,6108 } }, // v.2 { LIBRAW_CAMERAMAKER_Canon, "EOS M6 Mark II", 0, 0, { 11498,-3759,-1516,-5073,12954,2349,-892,1867,6118 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS M6", 0, 0, { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS M50 Mark II", 0, 0, { 10463,-2173,-1437,-4856,12635,2482,-1216,2915,7237 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS M50", 0, 0, { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS M5", 0, 0, { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS M3", 0, 0, { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS M200", 0, 0, { 10463,-2173,-1437,-4856,12635,2482,-1216,2915,7237 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS M2", 0, 0, { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS M100", 0, 0, { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS M10", 0, 0, { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS M", 0, 0, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS-1Ds Mark III", 0, 0x3bb0, { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS-1Ds Mark II", 0, 0xe80, { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark IV", 0, 0x3bb0, { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark III", 0, 0x3bb0, { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark II N", 0, 0xe80, { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark II", 0, 0xe80, { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS-1Ds", 0, 0xe20, { 3925,4060,-1739,-8973,16552,2545,-3287,3945,8243 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS-1D C", 0, 0x3c4e, { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS-1D X Mark III", 0, 0, { 8971, -2022, -1242, -5405, 13249, 2380, -1280, 2483, 6072}}, { LIBRAW_CAMERAMAKER_Canon, "EOS-1D X Mark II", 0, 0x3c4e, { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS-1D X", 0, 0x3c4e, { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS-1D", 0, 0xe20, { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS C500", 853, 0, { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Canon, "IXUS 160", 0, 0, { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } }, /* DJC */ {LIBRAW_CAMERAMAKER_Canon, "PowerShot 600", 0, 0, { -3822,10019,1311,4085,-157,3386,-5341,10829,4812,-1969,10969,1126 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot A3300 IS", 0, 0, { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Canon, "PowerShot A460", 0, 0, { 6493,-2338,-885,-1589,5934,697,-445,1368,2543 } }, // CHDK { LIBRAW_CAMERAMAKER_Canon, "PowerShot A470", 0, 0, { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Canon, "PowerShot A530", 0, 0, { 7252,-2405,-1223,-2102,6560,523,-112,704,3007 } }, // CHDK { LIBRAW_CAMERAMAKER_Canon, "PowerShot A50", 0, 0, { -6233,10706,1825,3260,821,3980,-6512,10745,6287,-2539,12232,262 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot A5", 0, 0, { -5707,10308,2002,2662,1829,4139,-6265,11063,6033,-2659,11911,593 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot A610", 0, 0, { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Canon, "PowerShot A620", 0, 0, { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Canon, "PowerShot A630", 0, 0, { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Canon, "PowerShot A640", 0, 0, { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Canon, "PowerShot A650 IS", 0, 0, { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Canon, "PowerShot A720 IS", 0, 0, { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Canon, "PowerShot D10", 127, 0, { 14052,-5229,-1156,-1325,9420,2252,-498,1957,4116 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Canon, "PowerShot G10", 0, 0, { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G11", 0, 0, { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G12", 0, 0, { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G15", 0, 0, { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G16", 0, 0, { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1 X Mark III", 0, 0, { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1 X Mark II", 0, 0, { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1 X", 0, 0, { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1", 0, 0, { -5686,10300,2223,4725,-1157,4383,-6128,10783,6163,-2688,12093,604 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G2", 0, 0, { 9194,-2787,-1059,-8098,15657,2608,-2610,3064,7867 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G3 X", 0, 0, { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G3", 0, 0, { 9326,-2882,-1084,-7940,15447,2677,-2620,3090,7740 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G5 X Mark II",0, 0, { 11629, -5713, -914, -2706, 11090, 1842, -206, 1225, 5515 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G5 X",0, 0, { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G5", 0, 0, { 9869,-2972,-942,-7314,15098,2369,-1898,2536,7282 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G6", 0, 0, { 9876,-3774,-871,-7613,14807,3071,-1448,1305,7485 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G7 X Mark III", 0, 0, { 11629, -5713, -914, -2706, 11090, 1842, -206, 1225, 5515 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G7 X Mark II", 0, 0, { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G7 X", 0, 0, { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G9 X Mark II", 0, 0, { 10056,-4131,-944,-2576,11143,1625,-238,1294,5179 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G9 X",0, 0, { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot G9", 0, 0, { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot S2 IS", 0, 0, { 5477,-1435,-992,-1868,6639,510,-58,792,2670 } }, // CHDK { LIBRAW_CAMERAMAKER_Canon, "PowerShot S3 IS", 0, 0, { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Canon, "PowerShot S30", 0, 0, { 10744,-3813,-1142,-7962,15966,2075,-2492,2805,7744 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot S40", 0, 0, { 8606,-2573,-949,-8237,15489,2974,-2649,3076,9100 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot S45", 0, 0, // + { 8251,-2410,-964,-8047,15430,2823,-2380,2824,8119 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot S50", 0, 0, { 8979,-2658,-871,-7721,15500,2357,-1773,2366,6634 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot S60", 0, 0, { 8794,-2482,-797,-7804,15403,2572,-1422,1996,7083 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot S70", 0, 0, { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot S90", 0, 0, { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot S95", 0, 0, { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot S120", 0, 0, { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot S110", 0, 0, { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot S100", 0, 0, { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot SD300", 0, 0, { 6526,-1720,-1075,-1390,5945,602,-90,820,2380 } }, // CHDK { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX1 IS", 0, 0, { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX20 IS", 0, 0, { 8275,-2904,-1260,-128,5305,505,51,481,2450 } }, // CHDK { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX30 IS", 0, 0, { 13014,-4698,-1026,-2001,9615,2386,-164,1423,3759 } }, // CHDK { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX40 HS", 0, 0, { 54480,-17404,-8039,-7505,44044,1136,-580,7158,11891 } }, // CHDK { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX50 HS", 0, 0, { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX60 HS", 0, 0, { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX70 HS", 0, 0, { 18285,-8907,-1951,-1845,10688,1323,364,1101,5139 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX110 IS", 0, 0, { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX120 IS", 0, 0, { 7286,-2242,-1047,41,4401,457,269,684,1864 } }, // CHDK { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX220 HS", 0, 0, { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX710 HS", 0, 0, { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot Pro1", 0, 0, { 10062,-3522,-1000,-7643,15117,2730,-765,817,7322 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot Pro70", 34, 0, { -5106,10695,1576,3820,53,4566,-6497,10736,6701,-3336,11887,1394 } }, { LIBRAW_CAMERAMAKER_Canon, "PowerShot Pro90", 0, 0, { -5912,10768,2288,4612,-989,4333,-6153,10897,5944,-2907,12288,624 } }, { LIBRAW_CAMERAMAKER_Casio, "EX-F1", 0, 0, { 9084,-2016,-848,-6711,14351,2570,-1059,1725,6135 } }, { LIBRAW_CAMERAMAKER_Casio, "EX-FH100", 0, 0, { 12771,-4179,-1558,-2149,10938,1375,-453,1751,4494 } }, { LIBRAW_CAMERAMAKER_Casio, "EX-S20", 0, 0, { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Casio, "EX-Z750", 0, 0, { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Casio, "EX-Z10", 128, 0xfff, { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } }, /* DJC */ { LIBRAW_CAMERAMAKER_CINE, "650", 0, 0, { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, { LIBRAW_CAMERAMAKER_CINE, "660", 0, 0, { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, { LIBRAW_CAMERAMAKER_CINE, "", 0, 0, /* empty camera name*/ { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } }, { LIBRAW_CAMERAMAKER_Contax, "N Digital", 0, 0xf1e, { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } }, { LIBRAW_CAMERAMAKER_DXO, "ONE", 0, 0, { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, { LIBRAW_CAMERAMAKER_Epson, "R-D1", 0, 0, // same CMs: R-D1, R-D1s, R-D1x { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "DBP for GX680", -128, 0x0fff, { 12741,-4916,-1420,-8510,16791,1715,-1767,2302,7771 } }, /* temp, copy from S2Pro */ { LIBRAW_CAMERAMAKER_Fujifilm, "E550", 0, 0, { 11044,-3888,-1120,-7248,15167,2208,-1531,2276,8069 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "E900", 0, 0, { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "F5", 0, 0, // F500EXR/F505EXR; F550EXR { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "F6", 0, 0, // F600EXR/F605EXR; F660EXR { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "F77", 0, 0xfe9, // F770EXR/F775EXR { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "F7", 0, 0, // same CMs: F700, F710EXR { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "F810", 0, 0, { 11044,-3888,-1120,-7248,15167,2208,-1531,2276,8069 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "F8", 0, 0, // F800EXR { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "F900EXR", 0, 0, { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "GFX 100", 0, 0, // same CMs: "GFX 100", "GFX 100S"/"GFX100S", "GFX 100 IR" { 16212,-8423,-1583,-4336,12583,1937,-195,726,6199 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "GFX 50", 0, 0, // same CMs: "GFX 50S", "GFX 50R", "GFX 50S II" { 11756,-4754,-874,-3056,11045,2305,-381,1457,6006 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "HS10", 0, 0xf68, { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "HS2", 0, 0, // HS20EXR/HS22EXR { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "HS3", 0, 0, // HS30EXR/HS33EXR/HS35EXR { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "HS50EXR", 0, 0, { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "IS-1", 0, 0, { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "IS Pro", 0, 0, { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S5000", 0, 0, { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S5100", 0, 0, { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S5200", 0, 0, // S5200/S5600 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S6", 0, 0, // S6000fd/S6500fd { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S7000", 0, 0, { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S9000", 0, 0, // S9000/S9500 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S9100", 0, 0, // S9100/S9600 { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S100FS", -514, 0, { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S20Pro", 0, 0, { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S20", -512, 0x3fff, // S200EXR/S205EXR { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "SL1000", 0, 0, { 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S1", 0, 0, { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S2Pro", -128, 0, { 12741,-4916,-1420,-8510,16791,1715,-1767,2302,7771 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S3Pro", 0, 0, { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "S5Pro", 0, 0, { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X100F", 0, 0, { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X100S", 0, 0, { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X100T", 0, 0, { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X100V", 0, 0, { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X100", 0, 0, { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X10", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X20", 0, 0, { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X30", 0, 0, { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X70", 0, 0, { 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "XF10", 0, 0, { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "XF1", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "XQ", 0, 0, // same CMs: XQ1, XQ2 { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-Pro1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-Pro2", 0, 0, { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-Pro3", 0, 0, { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-A10", 0, 0, { 11540,-4999,-991,-2949,10963,2278,-382,1049,5605} }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-A20", 0, 0, { 11540,-4999,-991,-2949,10963,2278,-382,1049,5605} }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-A1", 0, 0, { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-A2", 0, 0, { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-A3", 0, 0, { 12407,-5222,-1086,-2971,11116,2120,-294,1029,5284 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-A5", 0, 0, { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-A7", 0, 0, { 15055,-7391,-1274,-4062,12071,2238,-610,1217,6147 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-E1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-E2S", 0, 0, { 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-E2", 0, 0, { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-E3", 0, 0, { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-E4", 0, 0, { 13426, -6334, -1177, -4244, 12136, 2371, -580, 1303, 5980 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-H1", 0, 0, { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-H2S", 0, 0, { 12836, -5909, -1032, -3087, 11132, 2236, -35, 872, 5330 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-M1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-S10", 0, 0, { 13426,-6334,-1177,-4244,12136,2371,-580,1303,5980 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-S1", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-T100", 0, 0, { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-T1", 0, 0, /* same CMs: X-T1, "X-T1IR", "X-T1 IR", X-T10 */ { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-T200", 0, 0, { 15055,-7391,-1274,-4062,12071,2238,-610,1217,6147 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-T2", 0, 0, // same CMs: X-T2, X-T20 { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-T3", 0, 0, // same CMs: X-T3, X-T30, "X-T30 II" { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, // v.2 { LIBRAW_CAMERAMAKER_Fujifilm, "X-T4", 0, 0, { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, { LIBRAW_CAMERAMAKER_GITUP, "G3DUO", 130, 62000, { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, { LIBRAW_CAMERAMAKER_GITUP, "GIT2P", 4160, 0, { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, { LIBRAW_CAMERAMAKER_GITUP, "GIT2", 3200, 0, { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, { LIBRAW_CAMERAMAKER_GoPro, "HERO5 Black", 0, 0, { 10344,-4210,-620,-2315,10625,1948,93,1058,5541 } }, {LIBRAW_CAMERAMAKER_Hasselblad, "L1D-20c", 0, 0, { 7310, -2746, -646, -2991, 10847, 2469, 163, 585, 6324}}, { LIBRAW_CAMERAMAKER_Hasselblad, "16-Uncoated-3FR", 0, 0, { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, { LIBRAW_CAMERAMAKER_Hasselblad, "16-Uncoated-FFF", 0, 0, { 8068, -2959, -108, -5788, 13608, 2389, -1002, 2237, 8162}}, { LIBRAW_CAMERAMAKER_Hasselblad, "16-Uncoated", 0, 0, { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, { LIBRAW_CAMERAMAKER_Hasselblad, "22-Uncoated-3FR", 0, 0, { 8523, -3257, -280, -5078, 13458, 1743, -1449, 2961, 7809}}, { LIBRAW_CAMERAMAKER_Hasselblad, "22-Uncoated-FFF", 0, 0, { 8068, -2959, -108, -5788, 13608, 2389, -1002, 2237, 8162}}, { LIBRAW_CAMERAMAKER_Hasselblad, "22-Uncoated", 0, 0, { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, {LIBRAW_CAMERAMAKER_Hasselblad, "31-Uncoated-FFF", 0, 0, { 5155, -1201, 200, -5841, 13197, 2950, -1101, 2317, 6988}}, {LIBRAW_CAMERAMAKER_Hasselblad, "31-Uncoated", 0, 0, { 5458, -1448, 145, -4479, 12338, 2401, -1659, 3086, 6710}}, {LIBRAW_CAMERAMAKER_Hasselblad, "39-Uncoated-3FR", 0, 0, { 3904, -100, 262, -4318, 12407, 2128, -1598, 3594, 6233}}, {LIBRAW_CAMERAMAKER_Hasselblad, "39-Uncoated-FFF", 0, 0, { 4739, -932, 295, -4829, 12220, 2952, -1027, 2341, 7083}}, {LIBRAW_CAMERAMAKER_Hasselblad, "39-Uncoated", 0, 0, { 3894, -110, 287, -4672, 12610, 2295, -2092, 4100, 6196}}, { LIBRAW_CAMERAMAKER_Hasselblad, "39-Coated-3FR", 0, 0, { 5427, -1147, 173, -3834, 12073, 1969, -1444, 3320, 5621}}, { LIBRAW_CAMERAMAKER_Hasselblad, "39-Coated-FFF", 0, 0, { 5323, -1233, 399, -4926, 12362, 2894, -856, 2471, 5961}}, { LIBRAW_CAMERAMAKER_Hasselblad, "39-Coated", 0, 0, { 3857, 452, -46, -6008, 14477, 1596, -2627, 4481, 5718}}, {LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated5-3FR", 0, 0, { 7014, -2067, -540, -4821, 13016, 1980, -1663, 3089, 6940}}, {LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated5-FFF", 0, 0, { 5963, -1357, -172, -5439, 12762, 3007, -964, 2222, 7172}}, {LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated5", 0, 0, { 6159, -1402, -177, -5439, 12762, 3007, -955, 2200, 7104}}, { LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated-3FR", 0, 0, { 6550, -1681, -399, -4626, 12598, 2257, -1807, 3354, 6486}}, { LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated-FFF", 0, 0, { 6041, -1375, -174, -5439, 10000, 3007, -930, 2145, 6923}}, { LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated", 0, 0, { 6159, -1402, -177, -5439, 12762, 3007, -955, 2200, 7104}}, { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated5-3FR", 0, 0, { 5707, -693, -382, -4285, 12669, 1773, -1615, 3519, 5410}}, { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated5-FFF", 0, 0, { 5263, -612, 39, -4950, 12426, 2843, -935, 2423, 5941}}, { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated5", 0, 0, { 5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442}}, { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated-3FR", 0, 0, { 5656, -659, -346, -3923, 12305, 1790, -1602, 3509, 5442}}, { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated-FFF", 0, 0, { 5280, -614, 39, -4950, 12426, 2843, -939, 2434, 5968}}, { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated", 0, 0, { 5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442}}, { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5-II-3FR", 0, 0, { 10887, -6152, 1034, -3564, 12412, 4224, 63, 626, 10123}}, { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5-II-FFF", 0, 0, { 4932, -835, 141, -4878, 11868, 3437, -1138, 1961, 7067}}, { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5-II", 0, 0, { 8737, -4937, 830, -2860, 9961, 3390, 51, 502, 8124}}, { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5", 0, 0, { 4932,-835,141,-4878,11868,3437,-1138,1961,7067 } }, { LIBRAW_CAMERAMAKER_Hasselblad, "60-Coated-3FR", 0, 0, { 9296, 336, -1088, -6442, 14323, 2289, -1433, 2942, 5756}}, { LIBRAW_CAMERAMAKER_Hasselblad, "60-Coated", 0, 0, { 9662, -684, -279, -4903, 12293, 2950, -344, 1669, 6024}}, { LIBRAW_CAMERAMAKER_Hasselblad, "100-17-Coated5", 0, 0, { 5110, -1357, -308, -5573, 12835, 3077, -1279, 2025, 7010}}, { LIBRAW_CAMERAMAKER_HTC, "One A9", 64, 1023, { 101,-20,-2,-11,145,41,-24,1,56 } }, /* this is FM1 transposed */ { LIBRAW_CAMERAMAKER_Imacon, "Ixpress", 0, 0, { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Kodak, "NC2000", 0, 0, // AP Nikon { 13891,-6055,-803,-465,9919,642,2121,82,1291 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS315C", -8, 0, { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS330C", -8, 0, { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS420", 0, 0, { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS46", 0, 0, // same CM as EOSDCS1 and DCS465 DB { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS520C", -178, 0, // same CamID: DCS520C, "EOS D2000C" { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS560C", -177, 0, // same CamID: DCS560C, "EOS D6000C" { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS620C", -177, 0, { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS620X", -176, 0, { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS660C", -173, 0, { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS720X", 0, 0, { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS760C", 0, 0, { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS Pro SLR", 0, 0, { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS Pro 14nx", 0, 0, { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, { LIBRAW_CAMERAMAKER_Kodak, "DCS Pro 14", 0, 0, // same CamID: "DCS Pro 14N", "Photo Control Camerz ZDS 14" { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } }, { LIBRAW_CAMERAMAKER_Kodak, "EOSDCS1", 0, 0, { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, { LIBRAW_CAMERAMAKER_Kodak, "EOSDCS3", 0, 0, { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } }, { LIBRAW_CAMERAMAKER_Kodak, "ProBack645", 0, 0, { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } }, { LIBRAW_CAMERAMAKER_Kodak, "ProBack", 0, 0, { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } }, {LIBRAW_CAMERAMAKER_Kodak, "PIXPRO AZ901", 0, 0, // dng { 21875, -8006, -2558, 634, 8194, 1104, 1535, 951, 6969}}, { LIBRAW_CAMERAMAKER_Kodak, "P712", 0, 3963, { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } }, { LIBRAW_CAMERAMAKER_Kodak, "P850", 0, 3964, { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } }, { LIBRAW_CAMERAMAKER_Kodak, "P880", 0, 3963, { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } }, { LIBRAW_CAMERAMAKER_Kodak, "Z980", 0, 0, { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } }, { LIBRAW_CAMERAMAKER_Kodak, "Z981", 0, 0, { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } }, { LIBRAW_CAMERAMAKER_Kodak, "Z990", 0, 0xfed, { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } }, { LIBRAW_CAMERAMAKER_Kodak, "Z1015", 0, 0xef1, { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } }, {LIBRAW_CAMERAMAKER_Leaf, "AFi 54S", 0, 0, { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, {LIBRAW_CAMERAMAKER_Leaf, "AFi 65S", 0, 0, { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, {LIBRAW_CAMERAMAKER_Leaf, "AFi 75S", 0, 0, { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, {LIBRAW_CAMERAMAKER_Leaf, "Aptus 17", 0, 0, { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, {LIBRAW_CAMERAMAKER_Leaf, "Aptus 22", 0, 0, { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, {LIBRAW_CAMERAMAKER_Leaf, "Aptus 54S", 0, 0, { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, {LIBRAW_CAMERAMAKER_Leaf, "Aptus 65S", 0, 0, { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, {LIBRAW_CAMERAMAKER_Leaf, "Aptus 65", 0, 0, { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, {LIBRAW_CAMERAMAKER_Leaf, "Aptus 75S", 0, 0, { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, {LIBRAW_CAMERAMAKER_Leaf, "Aptus 75", 0, 0, { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, {LIBRAW_CAMERAMAKER_Leaf, "C-Most", 0, 0, { 3952, 2188, 449, -6701, 14584, 2275, -4536, 7349, 6535}}, {LIBRAW_CAMERAMAKER_Leaf, "Credo 40", 0, 0, { 8035, 435, -962, -6001, 13872, 2320, -1159, 3065, 5434}}, {LIBRAW_CAMERAMAKER_Leaf, "Credo 50", 0, 0, // emb { 10325, 845, -604, -4113, 13385, 481, -1791, 4163, 6924}}, {LIBRAW_CAMERAMAKER_Leaf, "Credo 60", 0, 0, { 8035, 435, -962, -6001, 13872, 2320, -1159, 3065, 5434}}, {LIBRAW_CAMERAMAKER_Leaf, "Credo 80", 0, 0, { 6294, 686, -712, -5435, 13417, 2211, -1006, 2435, 5042}}, {LIBRAW_CAMERAMAKER_Leaf, "Valeo 11", 0, 0, { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, {LIBRAW_CAMERAMAKER_Leaf, "Valeo 17", 0, 0, { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, {LIBRAW_CAMERAMAKER_Leaf, "Valeo 22", 0, 0, { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, {LIBRAW_CAMERAMAKER_Leaf, "Valeo 6", 0, 0, { 3952, 2188, 449, -6701, 14584, 2275, -4536, 7349, 6535}}, // { LIBRAW_CAMERAMAKER_Leaf, "AFi-II 6", 0, 0, { LIBRAW_CAMERAMAKER_Leaf, "AFi-II 7", 0, 0, { 7691,-108,-339,-6185,13627,2833,-2046,3899,5952 } }, { LIBRAW_CAMERAMAKER_Leaf, "AFi-II 10", 0, 0, { 6719,1147,-148,-6929,14061,3176,-1781,3343,5424 } }, { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 5", 0, 0, { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } }, { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 6", 0, 0, { 7989,-113,-352,-6185,13627,2833,-2028,3866,5901 } }, { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 7", 0, 0, { 8209,-116,-362,-6185,13627,2833,-1962,3740,5709 } }, { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 8", 0, 0, { 7361,1257,-163,-6929,14061,3176,-1839,3454,5603 } }, { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 10R", 0, 0, { 7167,1224,-158,-6929,14061,3176,-1826,3429,5562 } }, { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 10", 0, 0, { 7527,1285,-166,-6929,14061,3176,-1995,3747,6077 } }, // { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 12R", 0, 0, { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 12", 0, 0, { 7361,1257,-163,-6929,14061,3176,-1695,3182,5162 } }, { LIBRAW_CAMERAMAKER_Leica, "CL", 0, 0, { 7743,-2896,-921,-4211,12271,2169,-697,1562,5491 } }, { LIBRAW_CAMERAMAKER_Leica, "M8", 0, 0, { 7675,-2196,-305,-5860,14119,1856,-2425,4006,6578 } }, { LIBRAW_CAMERAMAKER_Leica, "M9", 0, 0, { 6687,-1751,-291,-3556,11373,2492,-548,2204,7146 } }, { LIBRAW_CAMERAMAKER_Leica, "M10", 0, 0, // same CMs: M10, M10-D, M10-P { 9090,-3342,-740,-4006,13456,493,-569,2266,6871 } }, { LIBRAW_CAMERAMAKER_Leica, "M (Typ 2", 0, 0, // same CMs: "M (Typ 240)", "M (Typ 262)", "M-D (Typ 262)" { 7199,-2140,-712,-4005,13327,649,-810,2521,6673 } }, { LIBRAW_CAMERAMAKER_Leica, "Q (Typ 116)", 0, 0, { 10068,-4043,-1068,-5319,14268,1044,-765,1701,6522 } }, { LIBRAW_CAMERAMAKER_Leica, "Q2", 0, 0, { 12312,-5440,-1307,-6408,15499,824,-1075,1677,7220 } }, { LIBRAW_CAMERAMAKER_Leica, "SL (Typ 601)", 0, 0, { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } }, { LIBRAW_CAMERAMAKER_Leica, "S (Typ 007)", 0, 0, { 6063,-2234,-231,-5210,13787,1500,-1043,2866,6997 } }, { LIBRAW_CAMERAMAKER_Leica, "S2", 0, 0, { 5627,-721,-447,-4423,12456,2192,-1048,2948,7379 } }, { LIBRAW_CAMERAMAKER_Leica, "S3", 0, 0, // { 5147,-1464,-318,-5374,13263,2325,-1425,2918,6450 } }, { 5092,-1630,-470,-6313,14297,2170,-1603,3135,5982 } }, {LIBRAW_CAMERAMAKER_Leica, "S", 0, 0, // same CMs: "S-E (Typ 006)", "S (Typ 006)" { 5749,-1072,-382,-4274,12432,2048,-1166,3104,7105 } }, { LIBRAW_CAMERAMAKER_Leica, "TL2", 0, 0, { 6375,-2062,-732,-4878,12838,2262,-877,1705,6204 } }, { LIBRAW_CAMERAMAKER_Leica, "T", 0, 0, // same CMs: TL, "T (Typ 701)" { 6295,-1679,-475,-5586,13046,2837,-1410,1889,7075 } }, { LIBRAW_CAMERAMAKER_Leica, "X2", 0, 0, { 8336,-2853,-699,-4425,11989,2760,-954,1625,6396 } }, { LIBRAW_CAMERAMAKER_Leica, "X1", 0, 0, { 9055,-2611,-666,-4906,12652,2519,-555,1384,7417 } }, { LIBRAW_CAMERAMAKER_Leica, "X", 0, 0, /* same CMs: "X (Typ 113)", "X-U (Typ 113)", XV, "X Vario (Typ 107)" */ { 9062,-3198,-828,-4065,11772,2603,-761,1468,6458 } }, { LIBRAW_CAMERAMAKER_Mamiya,"ZD", 0, 0, { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } }, { LIBRAW_CAMERAMAKER_Micron, "2010", 110, 0, { 16695,-3761,-2151,155,9682,163,3433,951,4904 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE 5", 0, 0xf7d, { 9117,-3063,-973,-7949,15763,2306,-2752,3136,8093 } }, { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE 7Hi", 0, 0xf7d, { 11555,-4064,-1256,-7903,15633,2409,-2811,3320,7358 } }, { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE 7i", 0, 0xf7d, { 11050,-3791,-1199,-7875,15585,2434,-2797,3359,7560 } }, { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE 7", 0, 0xf7d, { 9258,-2879,-1008,-8076,15847,2351,-2806,3280,7821 } }, { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE A1", 0, 0xf8b, { 9274,-2548,-1167,-8220,16324,1943,-2273,2721,8340 } }, { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE A200", 0, 0, { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } }, { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE A2", 0, 0xf8f, { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } }, { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE Z2", 0, 0, { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Minolta, "DG-5D", 0, 0xffb, // same CamID: "ALPHA 5D", "DYNAX 5D", "MAXXUM 5D", "Alpha Sweet Digital" { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } }, { LIBRAW_CAMERAMAKER_Minolta, "DG-7D", 0, 0xffb, // same CamID: "ALPHA 7D", "DYNAX 7D", "MAXXUM 7D" { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } }, { LIBRAW_CAMERAMAKER_Motorola, "PIXL", 0, 0, { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Nikon, "1 AW1", 0, 0, { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, { LIBRAW_CAMERAMAKER_Nikon, "1 J3", 0, 0, { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, { LIBRAW_CAMERAMAKER_Nikon, "1 J4", 0, 0, { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, { LIBRAW_CAMERAMAKER_Nikon, "1 J5", 0, 0, { 7520,-2518,-645,-3844,12102,1945,-913,2249,6835 } }, { LIBRAW_CAMERAMAKER_Nikon, "1 S2", -200, 0, { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } }, { LIBRAW_CAMERAMAKER_Nikon, "1 V2", 0, 0, { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, { LIBRAW_CAMERAMAKER_Nikon, "1 V3", -200, 0, { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, { LIBRAW_CAMERAMAKER_Nikon, "1 ", 0, 0, /* same CMs: "1 J1", "1 J2", "1 S1", "1 V1" */ { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 2100", 0, 0, // a.k.a. E2100 { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711 } }, /* DJC, copied from Z2, new white balance */ { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 2500", 0, 0, // a.k.a. E2500, possibly same CM as for E5000 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 3200", 0, 0, // a.k.a. E3200 { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 4300", 0, 0, // a.k.a. E4300 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } }, /* DJC, copied from Minolta DiMAGE Z2 */ { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 4500", 0, 0, // a.k.a. E4500, possibly same CM as for E5000 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 5000", 0, 0, // a.k.a. E5000 { -6678,12805,2248,5725,-499,3375,-5903,10713,6034,-270,9976,134 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 5400", 0, 0, // a.k.a. E5400 { 9349,-2988,-1001,-7918,15766,2266,-2097,2680,6839 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 5700", 0, 0, // a.k.a. E5700 { -6475,12496,2428,5409,-16,3180,-5965,10912,5866,-177,9918,248 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 8400", 0, 0, // a.k.a. E8400 { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 8700", 0, 0, // a.k.a. E8700 { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 8800", 0, 0, // a.k.a. E8800 { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 700", 0, 0x3dd, // a.k.a. E700 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 800", 0, 0x3dd, // a.k.a. E800 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 950", 0, 0x3dd, // a.k.a. E950 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 995", 0, 0, // a.k.a. E995 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, /* DJC, copied from E5000 */ { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX A1000", 0, 0, { 10601,-3487,-1127,-2931,11443,1676,-587,1740,5278 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX B700", 0, 0, { 14387,-6014,-1299,-1357,9975,1616,467,1047,4744 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX A", 0, 0, { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P1000", 0, 0, { 14294,-6116,-1333,-1628,10219,1637,-14,1158,5022 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P6000", 0, 0, { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P7000", 0, 0, { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P7100", 0, 0, { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P7700", -3200, 0, // same CamID: "COOLPIX P7700", "COOLPIX Deneb" { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P7800", -3200, 0, // same CamID: "COOLPIX P7800", "COOLPIX Kalon" { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P330", -200, 0, { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P340", -200, 0, { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, { LIBRAW_CAMERAMAKER_Nikon, "Coolpix P950", 0, 0, { 13307, -5641, -1290, -2048, 10581, 1689, -64, 1222, 5176}}, { LIBRAW_CAMERAMAKER_Nikon, "D3000", 0, 0, { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, { LIBRAW_CAMERAMAKER_Nikon, "D3100", 0, 0, { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } }, { LIBRAW_CAMERAMAKER_Nikon, "D3200", 0, 0xfb9, { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } }, { LIBRAW_CAMERAMAKER_Nikon, "D3300", 0, 0, { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, { LIBRAW_CAMERAMAKER_Nikon, "D3400", 0, 0, { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, { LIBRAW_CAMERAMAKER_Nikon, "D3500", 0, 0, { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } }, { LIBRAW_CAMERAMAKER_Nikon, "D5000", 0, 0xf00, { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } }, { LIBRAW_CAMERAMAKER_Nikon, "D5100", 0, 0x3de6, { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, { LIBRAW_CAMERAMAKER_Nikon, "D5200", 0, 0, { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, { LIBRAW_CAMERAMAKER_Nikon, "D5300", 0, 0, { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, { LIBRAW_CAMERAMAKER_Nikon, "D5500", 0, 0, { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } }, { LIBRAW_CAMERAMAKER_Nikon, "D5600", 0, 0, { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } }, { LIBRAW_CAMERAMAKER_Nikon, "D7000", 0, 0, { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, { LIBRAW_CAMERAMAKER_Nikon, "D7100", 0, 0, { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, { LIBRAW_CAMERAMAKER_Nikon, "D7200", 0, 0, { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, { LIBRAW_CAMERAMAKER_Nikon, "D7500", 0, 0, { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } }, { LIBRAW_CAMERAMAKER_Nikon, "D100", 0, 0, { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } }, { LIBRAW_CAMERAMAKER_Nikon, "D200", 0, 0xfbc, { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } }, { LIBRAW_CAMERAMAKER_Nikon, "D300", 0, 0, // same CMs: D300, D300s { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } }, { LIBRAW_CAMERAMAKER_Nikon, "D500", 0, 0, { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } }, { LIBRAW_CAMERAMAKER_Nikon, "D600", 0, 0x3e07, { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, { LIBRAW_CAMERAMAKER_Nikon, "D610",0, 0, { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, { LIBRAW_CAMERAMAKER_Nikon, "D700", 0, 0, { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, { LIBRAW_CAMERAMAKER_Nikon, "D750", -600, 0, { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } }, { LIBRAW_CAMERAMAKER_Nikon, "D780", -600, 0, { 9943,-3269,-839,-5323,13269,2259,-1198,2083,7557 } }, { LIBRAW_CAMERAMAKER_Nikon, "D800", 0, 0, // same CMs: D800, D800E { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } }, { LIBRAW_CAMERAMAKER_Nikon, "D810A", 0, 0, { 11973,-5685,-888,-1965,10326,1901,-115,1123,7169 } }, { LIBRAW_CAMERAMAKER_Nikon, "D810", 0, 0, { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } }, { LIBRAW_CAMERAMAKER_Nikon, "D850", 0, 0, { 10405,-3755,-1270,-5461,13787,1793,-1040,2015,6785 } }, { LIBRAW_CAMERAMAKER_Nikon, "D40X", 0, 0, { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } }, { LIBRAW_CAMERAMAKER_Nikon, "D40", 0, 0, { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } }, { LIBRAW_CAMERAMAKER_Nikon, "D50", 0, 0, { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, { LIBRAW_CAMERAMAKER_Nikon, "D60", 0, 0, { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, { LIBRAW_CAMERAMAKER_Nikon, "D70", 0, 0, // same CMs: D70, D70s { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, { LIBRAW_CAMERAMAKER_Nikon, "D80", 0, 0, { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } }, { LIBRAW_CAMERAMAKER_Nikon, "D90", 0, 0xf00, { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } }, { LIBRAW_CAMERAMAKER_Nikon, "D1H", 0, 0, { 7659,-2238,-935,-8942,16969,2004,-2701,3051,8690 } }, { LIBRAW_CAMERAMAKER_Nikon, "D1X", 0, 0, { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } }, { LIBRAW_CAMERAMAKER_Nikon, "D1", 0, 0, // { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } }, /* multiplied by 2.218750, 1.0, 1.148438 */ { 7637,-2199,-974,-9109,17099,2043,-2822,3306,8372 } }, { LIBRAW_CAMERAMAKER_Nikon, "D2H", 0, 0, // same CMs: D2H, D2Hs { 5733,-911,-629,-7967,15987,2055,-3050,4013,7048 } }, { LIBRAW_CAMERAMAKER_Nikon, "D2X", 0, 0, // same CMs: D2X, D2Xs { 10231,-2768,-1254,-8302,15900,2551,-797,681,7148 } }, { LIBRAW_CAMERAMAKER_Nikon, "D3S", 0, 0, { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } }, { LIBRAW_CAMERAMAKER_Nikon, "D3X", 0, 0, { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } }, { LIBRAW_CAMERAMAKER_Nikon, "D3", 0, 0, { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, { LIBRAW_CAMERAMAKER_Nikon, "D4", 0, 0, // same CMs: D4, D4S (and Df) { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, { LIBRAW_CAMERAMAKER_Nikon, "D5", 0, 0, { 9200,-3522,-992,-5755,13803,2117,-753,1486,6338 } }, { LIBRAW_CAMERAMAKER_Nikon, "D6", 0, 0, { 9028,-3423,-1035,-6321,14265,2217,-1013,1683,6928 } }, { LIBRAW_CAMERAMAKER_Nikon, "Df", 0, 0, { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, { LIBRAW_CAMERAMAKER_Nikon, "Z 50", 0, 0, { 11640,-4829,-1079,-5107,13006,2325,-972,1711,7380 } }, { LIBRAW_CAMERAMAKER_Nikon, "Z 5", 0, 0, { 8695,-2558,-648,-5015,12711,2575,-1279,2215,7514 } }, { LIBRAW_CAMERAMAKER_Nikon, "Z 6", 0, 0, { 9943,-3269,-839,-5323,13269,2259,-1198,2083,7557 } }, // 'Z 6'(v.2), 'Z 6_2' { LIBRAW_CAMERAMAKER_Nikon, "Z 7", 0, 0, { 13705,-6004,-1400,-5464,13568,2062,-940,1706,7618 } }, // 'Z 7'(v.2), 'Z 7_2' { LIBRAW_CAMERAMAKER_Nikon, "Z 9", 0, 0, { 13389,-6049,-1441,-4544,12757,1969,229,498,7390 } }, { LIBRAW_CAMERAMAKER_Nikon, "Z fc", 0, 0, { 11640,-4829,-1079,-5107,13006,2325,-972,1711,7380 } }, { LIBRAW_CAMERAMAKER_Olympus, "AIR A01", 0, 0xfe1, { 8992,-3093,-639,-2563,10721,2122,-437,1270,5473 } }, { LIBRAW_CAMERAMAKER_Olympus, "C-5050Z", 0, 0, { 10633,-3234,-1285,-7460,15570,1967,-1917,2510,6299 } }, { LIBRAW_CAMERAMAKER_Olympus, "C-5060WZ", 0, 0, { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } }, { LIBRAW_CAMERAMAKER_Olympus, "C-7070WZ", 0, 0, { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } }, { LIBRAW_CAMERAMAKER_Olympus, "C-7000Z", 0, 0, { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } }, { LIBRAW_CAMERAMAKER_Olympus, "C-8080WZ", 0, 0, { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-300", 0, 0, { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-330", 0, 0, { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-400", 0, 0, { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-410", 0, 0xf6a, { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-420", 0, 0xfd7, { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-450", 0, 0xfd2, { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-500", 0, 0, { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-510", 0, 0xf6a, { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-520", 0, 0xfd2, { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-600", 0, 0xfaf, { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-620", 0, 0xfaf, { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-10", 0, 0x3ff, { 12970,-4703,-1433,-7466,15843,1644,-2191,2451,6668 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-20", 0, 0x3ff, // model is "E-20,E-20N,E-20P" { 13414,-4950,-1517,-7166,15293,1960,-2325,2664,7212 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-30", 0, 0xfbc, { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-1", 0, 0, { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-3", 0, 0xf99, { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-5", 0, 0xeec, { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-P1", 0, 0xffd, { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-P2", 0, 0xffd, { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-P3", 0, 0, { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-P5", 0, 0, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-P7", 0, 0, { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-PL10", 0, 0, { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-PL1s", 0, 0, { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-PL1", 0, 0, { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-PL2", 0, 0xcf3, { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-PL3", 0, 0, { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-PL5", 0, 0xfcb, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-PL6", 0, 0, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-PL7", 0, 0, { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-PL8", 0, 0, { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-PL9", 0, 0, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-PM1", 0, 0, { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-PM2", 0, 0, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-M10 Mark IV", 0, 0, { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-M10", 0, 0, // Same CMs: E-M10, E-M10 Mark II, E-M10 Mark III; "CLAUSS piX 5oo" { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-M1X", 0, 0, { 11896,-5110,-1076,-3181,11378,2048,-519,1224,5166 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-M1 Mark III", 0, 0, { 11896,-5110,-1076,-3181,11378,2048,-519,1224,5166 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-M1 Mark II", 0, 0, { 9383,-3170,-763,-2457,10702,2020,-384,1236,5552 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-M1", 0, 0, { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-M5 Mark III", 0, 0, { 11896,-5110,-1076,-3181,11378,2048,-519,1224,5166 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-M5 Mark II", 0, 0, { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } }, { LIBRAW_CAMERAMAKER_Olympus, "E-M5", 0, 0xfe1, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { LIBRAW_CAMERAMAKER_Olympus, "PEN-F",0, 0, { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } }, { LIBRAW_CAMERAMAKER_Olympus, "SH-2", 0, 0, // same CamID: SH-2, SH-3 { 10156,-3425,-1077,-2611,11177,1624,-385,1592,5080 } }, { LIBRAW_CAMERAMAKER_Olympus, "SP-350", 0, 0, { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } }, { LIBRAW_CAMERAMAKER_Olympus, "SP-3", 0, 0, // Same CMs: SP310, SP320 { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } }, { LIBRAW_CAMERAMAKER_Olympus, "SP-500UZ", 0, 0xfff, { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } }, { LIBRAW_CAMERAMAKER_Olympus, "SP-510UZ", 0, 0xffe, { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } }, { LIBRAW_CAMERAMAKER_Olympus, "SP-550UZ", 0, 0xffe, { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } }, { LIBRAW_CAMERAMAKER_Olympus, "SP-560UZ", 0, 0xff9, { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } }, { LIBRAW_CAMERAMAKER_Olympus, "SP-565UZ", 0, 0, { 11856,-4469,-1159,-4814,12368,2756,-993,1779,5589 } }, { LIBRAW_CAMERAMAKER_Olympus, "SP-570UZ", 0, 0, { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } }, { LIBRAW_CAMERAMAKER_Olympus, "STYLUS 1",0, 0, // Olympus "STYLUS 1 and STYLUS 1s have the same CamID, cameras are slightly different { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } }, { LIBRAW_CAMERAMAKER_Olympus, "TG-4", 0, 0, { 11426,-4159,-1126,-2066,10678,1593,-120,1327,4998 } }, { LIBRAW_CAMERAMAKER_Olympus, "TG-", 0, 0, // same CMs: TG-5, TG-6 { 10899,-3833,-1082,-2112,10736,1575,-267,1452,5269 } }, { LIBRAW_CAMERAMAKER_Olympus, "XZ-10", 0, 0, { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, { LIBRAW_CAMERAMAKER_Olympus, "XZ-1", 0, 0, { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } }, { LIBRAW_CAMERAMAKER_Olympus, "XZ-2", 0, 0, { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, { LIBRAW_CAMERAMAKER_Olympus, "OM-1", 0, 0, { 9488, -3984, -714, -2887, 10945, 2229, -137, 960, 5786 } }, { LIBRAW_CAMERAMAKER_OmniVison, "", 16, 0x3ff, { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Pentax, "*istDL2", 0, 0, { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, { LIBRAW_CAMERAMAKER_Pentax, "*istDL", 0, 0, { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } }, { LIBRAW_CAMERAMAKER_Pentax, "*istDS2", 0, 0, { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, { LIBRAW_CAMERAMAKER_Pentax, "*istDS", 0, 0, { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } }, { LIBRAW_CAMERAMAKER_Pentax, "*istD", 0, 0, { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-01", 0, 0, { 8134,-2728,-645,-4365,11987,2694,-838,1509,6498 } }, { LIBRAW_CAMERAMAKER_Pentax, "K10D", 0, 0, { 9679,-2965,-811,-8622,16514,2182,-975,883,9793 } }, { LIBRAW_CAMERAMAKER_Pentax, "K1", 0, 0, // same CMs: K100D, "K100D Super", K110D { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } }, { LIBRAW_CAMERAMAKER_Pentax, "K20D", 0, 0, { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } }, { LIBRAW_CAMERAMAKER_Pentax, "K200D", 0, 0, { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-m", 0, 0, { 9730,-2989,-970,-8527,16258,2381,-1060,970,8362 } }, { LIBRAW_CAMERAMAKER_Pentax, "KP", 0, 0, { 7825,-2160,-1403,-4841,13555,1349,-1559,2449,5814 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-x", 0, 0, { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-r", 0, 0, { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-1", 0, 0, // same CMs: K-1, "K-1 Mark II" { 8596,-2981,-639,-4202,12046,2431,-685,1424,6122 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-30", 0, 0, { 8134,-2728,-645,-4365,11987,2694,-838,1509,6498 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-3 Mark III", 0, 0, { 9251, -3817, -1069, -4627, 12667, 2175, -798, 1660, 5633 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-3", 0, 0, // same CMs: K-3, "K-3 II" { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-500", 0, 0, { 8109,-2740,-608,-4593,12175,2731,-1006,1515,6545 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-50", 0, 0, { 8109,-2740,-608,-4593,12175,2731,-1006,1515,6545 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-5 II", 0, 0, // same CMs: "K-5 II" and "K-5 IIs" { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-5", 0, 0, { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-70", 0, 0, { 8766,-3149,-747,-3976,11943,2292,-517,1259,5552 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-7", 0, 0, { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } }, { LIBRAW_CAMERAMAKER_Pentax, "KP", 0, 0, { 8617,-3228,-1034,-4674,12821,2044,-803,1577,5728 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-S1", 0, 0, { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } }, { LIBRAW_CAMERAMAKER_Pentax, "K-S2", 0, 0, { 8662,-3280,-798,-3928,11771,2444,-586,1232,6054 } }, { LIBRAW_CAMERAMAKER_Pentax, "Q-S1", 0, 0, { 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } }, { LIBRAW_CAMERAMAKER_Pentax, "Q7", 0, 0, { 10901,-3938,-1025,-2743,11210,1738,-823,1805,5344 } }, { LIBRAW_CAMERAMAKER_Pentax, "Q10", 0, 0, { 11562,-4183,-1172,-2357,10919,1641,-582,1726,5112 } }, { LIBRAW_CAMERAMAKER_Pentax, "Q", 0, 0, { 11731,-4169,-1267,-2015,10727,1473,-217,1492,4870 } }, { LIBRAW_CAMERAMAKER_Pentax, "MX-1", 0, 0, { 9296,-3146,-888,-2860,11287,1783,-618,1698,5151 } }, { LIBRAW_CAMERAMAKER_Pentax, "645D", 0, 0x3e00, { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } }, { LIBRAW_CAMERAMAKER_Pentax, "645Z", 0, 0, { 9519,-3591,-664,-4074,11725,2671,-624,1501,6653 } }, {LIBRAW_CAMERAMAKER_Panasonic, "DC-S1R", 0, 0, { 11822,-5321,-1249,-5958,15114,766,-614,1264,7043 } }, {LIBRAW_CAMERAMAKER_Panasonic, "DC-S1H", 0, 0, { 9397,-3719,-805,-5425,13326,2309,-972,1715,6034 } }, {LIBRAW_CAMERAMAKER_Panasonic, "DC-S1", 0, 0, { 9744,-3905,-779,-4899,12807,2324,-798,1630,5827 } }, {LIBRAW_CAMERAMAKER_Panasonic, "DC-S5", 0, 0, { 9744,-3905,-779,-4899,12807,2324,-798,1630,5827 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-CM1", -15, 0, // same CMs: DMC-CM1, DMC-CM10 { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-FZ1000M2", -15, 0, { 9803,-4185,-992,-4066,12578,1628,-838,1824,5288 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ1000", -15, 0, { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ2500", -15, 0, { 7386,-2443,-743,-3437,11864,1757,-608,1660,4766 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ100", -15, 0xfff, { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ150", -15, 0xfff, { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ200", -15, 0xfff, { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ300", -15, 0xfff, { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ18", 0, 0, { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ28", -15, 0xf96, { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ30", 0, 0xf94, { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ35", -15, 0, { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ40", -15, 0, { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ50", 0, 0, { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ70", -15, 0, { 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-FZ80", -15, 0, { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ8", 0, 0xf7f, { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-L10", -15, 0xf96, { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-L1", 0, 0xf7f, { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LC1", 0, 0, { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LF1", -15, 0, { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-LX100M2", -15, 0, { 8585,-3127,-833,-4005,12250,1953,-650,1494,4862 } }, // v.2 { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX100", -15, 0, { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX1", 0, 0xf7f, { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX2", 0, 0, { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX3", -15, 0, { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX5", -15, 0, { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX7", -15, 0, { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX9", -15, 0, { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FX150", -15, 0xfff, { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-G99", -15, 0, { 9657,-3963,-748,-3361,11378,2258,-568,1415,5158 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-G100", -15, 0, { 8370,-2869,-710,-3389,11372,2298,-640,1599,4887 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G10", 0, 0, { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G1", -15, 0xf94, { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G2", -15, 0xf3c, { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G3", -15, 0xfff, { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G5", -15, 0xfff, { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G6", -15, 0xfff, { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G7", -15, 0xfff, { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G8", -15, 0xfff, { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-G9", -15, 0, { 7685,-2375,-634,-3687,11700,2249,-748,1546,5111 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GH1", -15, 0xf92, { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GH2", -15, 0xf95, { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GH3", -15, 0, { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GH4", -15, 0, { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-GH5s", -15, 0, { 6929,-2355,-708,-4192,12534,1828,-1097,1989,5195 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-GH5M2", 0, 0, { 9300, -3659, -755, -2981, 10988, 2287, -190, 1077, 5016 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-GH5", -15, 0, { 7641,-2336,-605,-3218,11299,2187,-485,1338,5121 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GM1", -15, 0, { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GM5", -15, 0, { 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-GF10", -15, 0, { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF1", -15, 0xf92, { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF2", -15, 0xfff, { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF3", -15, 0xfff, { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF5", -15, 0xfff, { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF6", -15, 0, { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF7", -15, 0, { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF8", -15, 0, { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-GF9", -15, 0, { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GX85", -15, 0, { 7771,-3020,-629,-4029,11950,2345,-821,1977,6119 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GX1", -15, 0, { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GX7", -15,0, { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GX8", -15,0, { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-GX9", -15, 0, { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-ZS100", -15, 0, { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-ZS200", -15, 0, { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-ZS40", -15, 0, { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-ZS50", -15, 0, { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-ZS60", -15, 0, { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-ZS70", -15, 0, { 9052,-3117,-883,-3045,11346,1927,-205,1520,4730 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-ZS80", -15, 0, { 12194,-5340,-1329,-3035,11394,1858,-50,1418,5219 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "H20", 0, 0, { 3906,1422,-467,-9953,18472,1365,-3307,4496,6406 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "H25", 0, 0, { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "IQ4 150MP", 0, 0, { 6644, -2257, -804, -6459, 14562, 2019, -1221, 1876, 6411}}, { LIBRAW_CAMERAMAKER_PhaseOne, "IQ140", 0, 0, { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "IQ150", 0, 0, {10325,845,-604,-4113,13385,481,-1791,4163,6924}}, /* temp */ /* emb */ // { 3984,0,0,0,10000,0,0,0,7666 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "IQ160", 0, 0, { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "IQ180", 0, 0, { 6294,686,-712,-5435,13417,2211,-1006,2435,5042 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "IQ250",0, 0, // {3984,0,0,0,10000,0,0,0,7666}}, {10325,845,-604,-4113,13385,481,-1791,4163,6924}}, /* emb */ { LIBRAW_CAMERAMAKER_PhaseOne, "IQ260", 0, 0, { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "IQ280", 0, 0, { 6294,686,-712,-5435,13417,2211,-1006,2435,5042 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "IQ3 100MP", 0, 0, // {2423,0,0,0,9901,0,0,0,7989}}, { 10999,354,-742,-4590,13342,937,-1060,2166,8120} }, /* emb */ { LIBRAW_CAMERAMAKER_PhaseOne, "IQ3 50MP", 0, 0, // { 3984,0,0,0,10000,0,0,0,7666 } }, {10058,1079,-587,-4135,12903,944,-916,2726,7480}}, /* emb */ { LIBRAW_CAMERAMAKER_PhaseOne, "IQ3 60MP", 0, 0, { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "IQ3 80MP", 0, 0, { 6294,686,-712,-5435,13417,2211,-1006,2435,5042 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "P21", 0, 0, { 6516,-2050,-507,-8217,16703,1479,-3492,4741,8489 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "P30", 0, 0, { 4516,-244,-36,-7020,14976,2174,-3206,4670,7087 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "P40", 0, 0, { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "P45", 0, 0, { 5053,-24,-117,-5685,14077,1703,-2619,4491,5850 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "P65", 0, 0, { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, { LIBRAW_CAMERAMAKER_PhaseOne, "P2", 0, 0, { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } }, { LIBRAW_CAMERAMAKER_Photron, "BC2-HD", 0, 0, { 14603,-4122,-528,-1810,9794,2017,-297,2763,5936 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Polaroid, "x530", 0, 0, { 13458,-2556,-510,-5444,15081,205,0,0,12120 } }, { LIBRAW_CAMERAMAKER_RED, "One", 704, 0xffff, { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Ricoh, "S10 24-72mm F2.5-4.4 VC", 0, 0, { 10531,-4043,-878,-2038,10270,2052,-107,895,4577 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GR A12 50mm F2.5 MACRO", 0, 0, { 8849,-2560,-689,-5092,12831,2520,-507,1280,7104 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GR DIGITAL 2", 0, 0, { 8846,-2704,-729,-5265,12708,2871,-1471,1955,6218 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GR DIGITAL 3", 0, 0, { 8170,-2496,-655,-5147,13056,2312,-1367,1859,5265 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GR DIGITAL 4", 0, 0, { 8771,-3151,-837,-3097,11015,2389,-703,1343,4924 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GR III", 0, 0, { 6127,-1777,-585,-5913,13699,2428,-1088,1780,6017 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GR II", 0, 0, { 5329,-1459,-390,-5407,12930,2768,-1119,1772,6046 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GR", 0, 0, { 5329,-1459,-390,-5407,12930,2768,-1119,1772,6046 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GX200", 0, 0, { 8040,-2368,-626,-4659,12543,2363,-1125,1581,5660 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GXR Mount A12", 0, 0, { 7834,-2182,-739,-5453,13409,2241,-952,2005,6620 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GXR A12 50mm", 0, 0, { 8849,-2560,-689,-5092,12831,2520,-507,1280,7104 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GXR A12 28mm", 0, 0, { 10228,-3159,-933,-5304,13158,2371,-943,1873,6685 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GXR A16", 0, 0, { 7837,-2538,-730,-4370,12184,2461,-868,1648,5830 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GXR P10", 0, 0, { 13168,-5128,-1663,-3006,11569,1611,-373,1244,4907 } }, { LIBRAW_CAMERAMAKER_Ricoh, "GXR S10", 0, 0, { 8963,-2926,-754,-4881,12921,2164,-1464,1944,4901 } }, { LIBRAW_CAMERAMAKER_Samsung, "EX1", 0, 0x3e00, { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } }, { LIBRAW_CAMERAMAKER_Samsung, "EX2F", 0, 0x7ff, { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } }, // { LIBRAW_CAMERAMAKER_Samsung, "GX20", 0, 0, // { 23213,-14575,-4840,-7077,16564,316,385,-1656,9398 } }, // Adobe DNG // { 27717,-17403,-5779,-8450,19778,377,459,1978,11221 } }, // Samsung DNG // { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } }, // Adobe DCP // { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S6 Edge Rear Camera", 0, 0, // { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S6 Rear Camera", 0, 0, { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S6", 0, 0, // same CMs: "Galaxy S6", "Galaxy S6 Edge" { 13699,-5767,-1384,-4449,13879,499,-467,1691,5892 } }, // { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S7 Edge Rear Camera", 0, 0, // { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S7 Rear Camera", 0, 0, { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S7", 0, 0, // same CMs: "Galaxy S7", "Galaxy S7 Edge" { 9927,-3704,-1024,-3935,12758,1257,-389,1512,4993 } }, // { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S8+ Rear Camera", 0, 0, // { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S8 Rear Camera", 0, 0, { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S8", 0, 0, // same CMs: "Galaxy S8", "Galaxy S8+" { 9927,-3704,-1024,-3935,12758,1257,-389,1512,4993 } }, // { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S9+ Rear Camera", 0, 0, // { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S9 Rear Camera", 0, 0, { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S9", 0, 0, // same CMs: "Galaxy S9", "Galaxy S9+" { 13292,-6142,-1268,-4095,12890,1283,-557,1930,5163 } }, // { LIBRAW_CAMERAMAKER_Samsung, "Galaxy Note 9 Rear Telephoto Camera", 0, 0, { LIBRAW_CAMERAMAKER_Samsung, "Galaxy Note 9 Rear Camera", 0, 0, { 13292,-6142,-1268,-4095,12890,1283,-557,1930,5163 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX U", 0, 0, { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX3300", 0, 0, { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX3000", 0, 0, { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX30", 0, 0, // same CMs: NX30, NX300, NX300M { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX2000", 0, 0, { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX2", 0, 0xfff, // same CMs: NX20, NX200, NX210 { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX1000", 0, 0, { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX1100", 0, 0, { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX11", 0, 0, { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX10", 0, 0, // same CMs: NX10, NX100 { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX500", 0, 0, { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX5", 0, 0, { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX1", 0, 0, { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } }, { LIBRAW_CAMERAMAKER_Samsung, "NX mini", 0, 0, { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } }, { LIBRAW_CAMERAMAKER_Samsung, "WB2000", 0, 0xfff, { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } }, { LIBRAW_CAMERAMAKER_Samsung, "WB5000", 0, 0, { 7675, -2195, -305, -5860, 14118, 1857, -2425, 4007, 6578}}, { LIBRAW_CAMERAMAKER_Samsung, "S85", 0, 0, { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } }, /* DJC */ // Foveon: LibRaw color data { LIBRAW_CAMERAMAKER_Sigma, "dp0 Quattro", 2047, 0, { 13801,-3390,-1016,5535,3802,877,1848,4245,3730 } }, { LIBRAW_CAMERAMAKER_Sigma, "dp1 Quattro", 2047, 0, { 13801,-3390,-1016,5535,3802,877,1848,4245,3730 } }, { LIBRAW_CAMERAMAKER_Sigma, "dp2 Quattro", 2047, 0, { 13801,-3390,-1016,5535,3802,877,1848,4245,3730 } }, { LIBRAW_CAMERAMAKER_Sigma, "dp3 Quattro", 2047, 0, { 13801,-3390,-1016,5535,3802,877,1848,4245,3730 } }, { LIBRAW_CAMERAMAKER_Sigma, "sd Quattro H", 256, 0, { 1295,108,-311,256,828,-65,-28,750,254 } }, /* temp */ { LIBRAW_CAMERAMAKER_Sigma, "sd Quattro", 2047, 0, { 1295,108,-311,256,828,-65,-28,750,254 } }, /* temp */ { LIBRAW_CAMERAMAKER_Sigma, "SD9", 15, 4095, { 13564,-2537,-751,-5465,15154,194,-67,116,10425 } }, { LIBRAW_CAMERAMAKER_Sigma, "SD10", 15, 16383, { 6787,-1682,575,-3091,8357,160,217,-369,12314 } }, { LIBRAW_CAMERAMAKER_Sigma, "SD14", 15, 16383, { 13589,-2509,-739,-5440,15104,193,-61,105,10554 } }, { LIBRAW_CAMERAMAKER_Sigma, "SD15", 15, 4095, { 13556,-2537,-730,-5462,15144,195,-61,106,10577 } }, // Merrills + SD1 { LIBRAW_CAMERAMAKER_Sigma, "SD1", 31, 4095, { 5133,-1895,-353,4978,744,144,3837,3069,2777 } }, /* LibRaw */ { LIBRAW_CAMERAMAKER_Sigma, "DP1 Merrill", 31, 4095, { 5133,-1895,-353,4978,744,144,3837,3069,2777 } }, /* LibRaw */ { LIBRAW_CAMERAMAKER_Sigma, "DP2 Merrill", 31, 4095, { 5133,-1895,-353,4978,744,144,3837,3069,2777 } }, /* LibRaw */ { LIBRAW_CAMERAMAKER_Sigma, "DP3 Merrill", 31, 4095, { 5133,-1895,-353,4978,744,144,3837,3069,2777 } }, /* LibRaw */ // Sigma DP (non-Merrill Versions) { LIBRAW_CAMERAMAKER_Sigma, "DP1X", 0, 4095, { 13704,-2452,-857,-5413,15073,186,-89,151,9820 } }, { LIBRAW_CAMERAMAKER_Sigma, "DP1", 0, 4095, { 12774,-2591,-394,-5333,14676,207,15,-21,12127 } }, { LIBRAW_CAMERAMAKER_Sigma, "DP", 0, 4095, // { 7401,-1169,-567,2059,3769,1510,664,3367,5328 } }, { 13100,-3638,-847,6855,2369,580,2723,3218,3251 } }, /* LibRaw */ { LIBRAW_CAMERAMAKER_Sinar, "", 0, 0, { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Sony, "DSC-F828", 0, 0, { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-R1", 0, 0, { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-V3", 0, 0, { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-HX9", -800, 0, // same CMs: DSC-HX95, DSC-HX99 { 13076,-5686,-1481,-4027,12851,1251,-167,725,4937 } }, { LIBRAW_CAMERAMAKER_Sony, "ZV-1", -800, 0, { 8280,-2987,-703,-3531,11645,2133,-550,1542,5312 } }, { LIBRAW_CAMERAMAKER_Sony, "ZV-E10", 0, 0, { 6355,-2067,-490,-3653,11542,2400,-406,1258,5506 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-RX100M7", -800, 0, {10315, -4390, -937, -4859, 12734, 2365, -734, 1537, 5997 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-RX100M6", -800, 0, { 7325,-2321,-596,-3494,11674,2055,-668,1562,5031 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-RX100M5A", -800, 0, { 11176,-4700,-965,-4004,12184,2032,-763,1726,5876 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-RX100M", -800, 0, // same CMs: DSC-RX100M2, DSC-RX100M3, DSC-RX100M4, DSC-RX100M5 { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-RX100", 0, 0, { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-RX10M4", -800, 0, { 7699,-2566,-629,-2967,11270,1928,-378,1286,4807 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-RX10",0, 0, // same CMs: DSC-RX10, DSC-RX10M2, DSC-RX10M3 { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-RX1RM2", 0, 0, { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-RX1R", 0, 0, { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-RX1", 0, 0, { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-RX0", -800, 0, // same CMs: DSC-RX0, DSC-RX0M2 { 9396,-3507,-843,-2497,11111,1572,-343,1355,5089 } }, { LIBRAW_CAMERAMAKER_Sony, "DSLR-A100", 0, 0xfeb, { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } }, { LIBRAW_CAMERAMAKER_Sony, "DSLR-A290", 0, 0, { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, { LIBRAW_CAMERAMAKER_Sony, "DSLR-A2", 0, 0, // same CMs: DSLR-A200, DSLR-A230 { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, { LIBRAW_CAMERAMAKER_Sony, "DSLR-A300", 0, 0, { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, { LIBRAW_CAMERAMAKER_Sony, "DSLR-A330", 0, 0, { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } }, { LIBRAW_CAMERAMAKER_Sony, "DSLR-A3", 0, 0, // same CMs: DSLR-A350, DSLR-A380, DSLR-A390 { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, { LIBRAW_CAMERAMAKER_Sony, "DSLR-A450", 0, 0, // close to 16596 if arw is 14-bit { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, { LIBRAW_CAMERAMAKER_Sony, "DSLR-A580", 0, 16596, { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }, { LIBRAW_CAMERAMAKER_Sony, "DSLR-A500", 0, 16596, { 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } }, { LIBRAW_CAMERAMAKER_Sony, "DSLR-A5", 0, 16596, // same CMs: DSLR-A550, DSLR-A560 { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, { LIBRAW_CAMERAMAKER_Sony, "DSLR-A700", 0, 0, { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }, { LIBRAW_CAMERAMAKER_Sony, "DSLR-A850", 0, 0, { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } }, { LIBRAW_CAMERAMAKER_Sony, "DSLR-A900", 0, 0, { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCA-68", 0, 0, { 6435,-1903,-536,-4722,12449,2550,-663,1363,6517 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCA-77M2", 0, 0, { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCA-99M2", 0, 0, { 6660,-1918,-471,-4613,12398,2485,-649,1433,6447 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-1", 0, 0, { 8161, -2947, -739, -4811, 12668, 2389, -437, 1229, 6524}}, { LIBRAW_CAMERAMAKER_Sony, "ILCE-7RM4", 0, 0, // same CMs: ILCE-7RM4, ILCE-7RM4A { 7662, -2686,-660,-5240, 12965,2530, -796, 1508, 6167 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-7RM3", 0, 0, // same CMs: ILCE-7RM3, ILCE-7RM3A { 6640,-1847,-503,-5238,13010,2474,-993,1673,6527 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-7RM2", 0, 0, { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-7R", 0, 0, { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-7SM3", 0, 0, { 6912,-2127,-469,-4470,12175,2587,-398,1478,6492 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-7S", 0, 0, // same CMs: ILCE-7S, ILCE-7SM2 { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-7C", 0, 0, { 7374,-2389,-551,-5435,13162,2519,-1006,1795,6552 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-7M4", 0, 0, { 7460,-2365,-588,-5687,13442,2474,-624,1156,6584 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-7M3", 0, 0, { 7374,-2389,-551,-5435,13162,2519,-1006,1795,6552 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-7", 0, 0, // same CMs: ILCE-7, ILCE-7M2 { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-9", 0, 0, // same CMs: ILCE-9, ILCE-9M2 { 6389,-1703,-378,-4562,12265,2587,-670,1489,6550 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-6100", 0, 0, { 7657,-2847,-607,-4083,11966,2389,-684,1418,5844 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-6300", 0, 0, { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-6400", 0, 0, { 7657,-2847,-607,-4083,11966,2389,-684,1418,5844 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-6500", 0, 0, { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-6600", 0, 0, { 7657,-2847,-607,-4083,11966,2389,-684,1418,5844 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE", 0, 0, // same CMs: ILCE-3000, ILCE-5000, ILCE-5100, ILCE-6000, ILCE-QX1 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, { LIBRAW_CAMERAMAKER_Sony, "ILME-FX3", 0, 0, { 6912, -2127, -469, -4470, 12175, 2587, -398, 1478, 6492 } }, { LIBRAW_CAMERAMAKER_Sony, "NEX-5N", 0, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, { LIBRAW_CAMERAMAKER_Sony, "NEX-5R", 0, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { LIBRAW_CAMERAMAKER_Sony, "NEX-5T", 0, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { LIBRAW_CAMERAMAKER_Sony, "NEX-5", 0, 0, { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, { LIBRAW_CAMERAMAKER_Sony, "NEX-3N", 0, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { LIBRAW_CAMERAMAKER_Sony, "NEX-3", 0, 0, { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, { LIBRAW_CAMERAMAKER_Sony, "NEX-6", 0, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { LIBRAW_CAMERAMAKER_Sony, "NEX-7", 0, 0, { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, { LIBRAW_CAMERAMAKER_Sony, "NEX-VG30", 0, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { LIBRAW_CAMERAMAKER_Sony, "NEX-VG900", 0, 0, { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, { LIBRAW_CAMERAMAKER_Sony, "NEX", 0, 0, // same CMs: NEX-C3, NEX-F3, NEX-VG20 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, { LIBRAW_CAMERAMAKER_Sony, "SLT-A33", 0, 0, { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } }, { LIBRAW_CAMERAMAKER_Sony, "SLT-A35", 0, 0, { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } }, { LIBRAW_CAMERAMAKER_Sony, "SLT-A37", 0, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, { LIBRAW_CAMERAMAKER_Sony, "SLT-A55", 0, 0, { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }, { LIBRAW_CAMERAMAKER_Sony, "SLT-A5", 0, 0, // same CMs: SLT-A57, SLT-A58 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, { LIBRAW_CAMERAMAKER_Sony, "SLT-A65", 0, 0, { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, { LIBRAW_CAMERAMAKER_Sony, "SLT-A77", 0, 0, { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, { LIBRAW_CAMERAMAKER_Sony, "SLT-A99", 0, 0, { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, { LIBRAW_CAMERAMAKER_Sony, "MODEL-NAME", 0, 0, { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, { LIBRAW_CAMERAMAKER_YI, "M1", 0, 0, { 7712,-2059,-653,-3882,11494,2726,-710,1332,5958 } }, }; // clang-format on double cam_xyz[4][3]; //char name[130]; int i, j; if (colors > 4 || colors < 1) return 1; int bl4 = (cblack[0] + cblack[1] + cblack[2] + cblack[3]) / 4, bl64 = 0; if (cblack[4] * cblack[5] > 0) { for (unsigned c = 0; c < 4096 && c < cblack[4] * cblack[5]; c++) bl64 += cblack[c + 6]; bl64 /= cblack[4] * cblack[5]; } int rblack = black + bl4 + bl64; for (i = 0; i < int(sizeof table / sizeof *table); i++) { if (table[i].m_idx == make_idx) { size_t l = strlen(table[i].prefix); if (!l || !strncasecmp(t_model, table[i].prefix, l)) { if (!dng_version) { if (table[i].t_black > 0) { black = (ushort)table[i].t_black; memset(cblack, 0, sizeof(cblack)); } else if (table[i].t_black < 0 && rblack == 0) { black = (ushort)(-table[i].t_black); memset(cblack, 0, sizeof(cblack)); } if (table[i].t_maximum) maximum = (ushort)table[i].t_maximum; } if (table[i].trans[0]) { for (raw_color = j = 0; j < 12; j++) if (internal_only) imgdata.color.cam_xyz[j / 3][j % 3] = table[i].trans[j] / 10000.f; else ((double *)cam_xyz)[j] = imgdata.color.cam_xyz[j / 3][j % 3] = table[i].trans[j] / 10000.f; if (!internal_only) cam_xyz_coeff(rgb_cam, cam_xyz); } return 1; // CM found } } } return 0; // CM not found } void LibRaw::simple_coeff(int index) { static const float table[][12] = { /* index 0 -- all Foveon cameras */ {1.4032f, -0.2231f, -0.1016f, -0.5263f, 1.4816f, 0.017f, -0.0112f, 0.0183f, 0.9113f}, /* index 1 -- Kodak DC20 and DC25 */ {2.25f, 0.75f, -1.75f, -0.25f, -0.25f, 0.75f, 0.75f, -0.25f, -0.25f, -1.75f, 0.75f, 2.25f}, /* index 2 -- Logitech Fotoman Pixtura */ {1.893f, -0.418f, -0.476f, -0.495f, 1.773f, -0.278f, -1.017f, -0.655f, 2.672f}, /* index 3 -- Nikon E880, E900, and E990 */ {-1.936280f, 1.800443f, -1.448486f, 2.584324f, 1.405365f, -0.524955f, -0.289090f, 0.408680f, -1.204965f, 1.082304f, 2.941367f, -1.818705f}}; int i, c; for (raw_color = i = 0; i < 3; i++) FORCC rgb_cam[i][c] = table[index][i * MIN(colors,4) + c]; } LibRaw-0.21.4/src/tables/wblists.cpp000066400000000000000000000174421477673233700172450ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/dcraw_defs.h" #define _ARR_SZ(a) (sizeof(a)/sizeof(a[0])) static const int _tagtype_dataunit_bytes [20] = { 1, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4, 2, 8, 8, 8, 8, 8 }; libraw_static_table_t LibRaw::tagtype_dataunit_bytes(_tagtype_dataunit_bytes, _ARR_SZ(_tagtype_dataunit_bytes)); int libraw_tagtype_dataunit_bytes(int tagtype) { return _tagtype_dataunit_bytes[((unsigned)tagtype < _ARR_SZ(_tagtype_dataunit_bytes)) ? tagtype : 0]; } static const int _Canon_wbi2std[] = { // Canon WB index to standard indexes // std. number wbi - Canon number LIBRAW_WBI_Auto, // 0 LIBRAW_WBI_Daylight, // 1 LIBRAW_WBI_Cloudy, // 2 LIBRAW_WBI_Tungsten, // 3 LIBRAW_WBI_Fluorescent, // 4 LIBRAW_WBI_Flash, // 5 LIBRAW_WBI_Custom, // 6 LIBRAW_WBI_BW, // 7 LIBRAW_WBI_Shade, // 8 LIBRAW_WBI_Kelvin, // 9 LIBRAW_WBI_PC_Set1, // 10 LIBRAW_WBI_PC_Set2, // 11 LIBRAW_WBI_PC_Set3, // 12 LIBRAW_WBI_Unknown, // 13, unlucky number "13", not used LIBRAW_WBI_FluorescentHigh, // 14 LIBRAW_WBI_Custom1, // 15 LIBRAW_WBI_Custom2, // 16 LIBRAW_WBI_Underwater, // 17, last one for older PowerShot models LIBRAW_WBI_Custom3, // 18 LIBRAW_WBI_Custom4, // 19 LIBRAW_WBI_PC_Set4, // 20 LIBRAW_WBI_PC_Set5, // 21 LIBRAW_WBI_Unknown, // 22 LIBRAW_WBI_Auto1 // 23 }; libraw_static_table_t LibRaw::Canon_wbi2std(_Canon_wbi2std, _ARR_SZ(_Canon_wbi2std)); static const int _Canon_KeyIsZero_Len2048_linenums_2_StdWBi[] = { // Appendix A: G2, S30, S40; G3, G5, S45, S50 LIBRAW_WBI_Custom1, LIBRAW_WBI_Custom2, LIBRAW_WBI_Daylight, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Tungsten, LIBRAW_WBI_Fluorescent, LIBRAW_WBI_Unknown, // ? FluorescentHigh, Shade, Custom, Kelvin LIBRAW_WBI_Flash }; libraw_static_table_t LibRaw::Canon_KeyIsZero_Len2048_linenums_2_StdWBi(_Canon_KeyIsZero_Len2048_linenums_2_StdWBi, _ARR_SZ(_Canon_KeyIsZero_Len2048_linenums_2_StdWBi)); static const int _Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi[] = { // G6, S60, S70; offset +16 LIBRAW_WBI_Custom1, LIBRAW_WBI_Custom2, LIBRAW_WBI_Daylight, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Tungsten, LIBRAW_WBI_Fluorescent, LIBRAW_WBI_FluorescentHigh, // LIBRAW_WBI_Unknown, // ? FluorescentHigh, Shade, Custom, Kelvin LIBRAW_WBI_Unknown, LIBRAW_WBI_Underwater, // LIBRAW_WBI_Unknown, LIBRAW_WBI_Unknown, LIBRAW_WBI_Flash }; libraw_static_table_t LibRaw::Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi(_Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi, _ARR_SZ(_Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi)); static const int _Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi[] = { // Pro1; offset +8 LIBRAW_WBI_Custom1, LIBRAW_WBI_Custom2, LIBRAW_WBI_Daylight, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Tungsten, LIBRAW_WBI_Fluorescent, LIBRAW_WBI_Unknown, LIBRAW_WBI_Flash, // LIBRAW_WBI_Unknown, LIBRAW_WBI_Unknown, LIBRAW_WBI_Unknown, LIBRAW_WBI_Unknown // LIBRAW_WBI_Flash }; libraw_static_table_t LibRaw::Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi(_Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi, _ARR_SZ(_Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi)); static const int _Canon_G9_linenums_2_StdWBi[] = { LIBRAW_WBI_Auto, LIBRAW_WBI_Daylight, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Tungsten, LIBRAW_WBI_Fluorescent, LIBRAW_WBI_FluorescentHigh, LIBRAW_WBI_Flash, LIBRAW_WBI_Underwater, LIBRAW_WBI_Custom1, LIBRAW_WBI_Custom2 }; libraw_static_table_t LibRaw::Canon_G9_linenums_2_StdWBi(_Canon_G9_linenums_2_StdWBi, _ARR_SZ(_Canon_G9_linenums_2_StdWBi)); static const int _Canon_D30_linenums_2_StdWBi[] = { LIBRAW_WBI_Daylight, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Tungsten, LIBRAW_WBI_Fluorescent, LIBRAW_WBI_Flash, LIBRAW_WBI_Custom }; libraw_static_table_t LibRaw::Canon_D30_linenums_2_StdWBi(_Canon_D30_linenums_2_StdWBi, _ARR_SZ(_Canon_D30_linenums_2_StdWBi)); static const int _Fuji_wb_list1[] = { LIBRAW_WBI_FineWeather, LIBRAW_WBI_Shade, LIBRAW_WBI_FL_D, LIBRAW_WBI_FL_N, LIBRAW_WBI_FL_W, LIBRAW_WBI_Tungsten }; libraw_static_table_t LibRaw::Fuji_wb_list1(_Fuji_wb_list1, _ARR_SZ(_Fuji_wb_list1)); static const int _FujiCCT_K[31] = { 2500, 2550, 2650, 2700, 2800, 2850, 2950, 3000, 3100, 3200, 3300, 3400, 3600, 3700, 3800, 4000, 4200, 4300, 4500, 4800, 5000, 5300, 5600, 5900, 6300, 6700, 7100, 7700, 8300, 9100, 10000 }; libraw_static_table_t LibRaw::FujiCCT_K(_FujiCCT_K, _ARR_SZ(_FujiCCT_K)); static const int _Fuji_wb_list2[] = { LIBRAW_WBI_Auto, 0, LIBRAW_WBI_Custom, 6, LIBRAW_WBI_FineWeather, 1, LIBRAW_WBI_Shade, 8, LIBRAW_WBI_FL_D, 10, LIBRAW_WBI_FL_N, 11, LIBRAW_WBI_FL_W, 12, LIBRAW_WBI_Tungsten, 2, LIBRAW_WBI_Underwater, 35, LIBRAW_WBI_Ill_A, 82, LIBRAW_WBI_D65, 83 }; libraw_static_table_t LibRaw::Fuji_wb_list2(_Fuji_wb_list2, _ARR_SZ(_Fuji_wb_list2)); static const int _Pentax_wb_list1[] = { LIBRAW_WBI_Daylight, LIBRAW_WBI_Shade, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Tungsten, LIBRAW_WBI_FL_D, LIBRAW_WBI_FL_N, LIBRAW_WBI_FL_W, LIBRAW_WBI_Flash }; libraw_static_table_t LibRaw::Pentax_wb_list1(_Pentax_wb_list1, _ARR_SZ(_Pentax_wb_list1)); static const int _Pentax_wb_list2[] = { LIBRAW_WBI_Daylight, LIBRAW_WBI_Shade, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Tungsten, LIBRAW_WBI_FL_D, LIBRAW_WBI_FL_N, LIBRAW_WBI_FL_W, LIBRAW_WBI_Flash, LIBRAW_WBI_FL_L }; libraw_static_table_t LibRaw::Pentax_wb_list2(_Pentax_wb_list2, _ARR_SZ(_Pentax_wb_list2)); static const int _Oly_wb_list1[] = { LIBRAW_WBI_Shade, LIBRAW_WBI_Cloudy, LIBRAW_WBI_FineWeather, LIBRAW_WBI_Tungsten, LIBRAW_WBI_Sunset, LIBRAW_WBI_FL_D, LIBRAW_WBI_FL_N, LIBRAW_WBI_FL_W, LIBRAW_WBI_FL_WW }; libraw_static_table_t LibRaw::Oly_wb_list1(_Oly_wb_list1, _ARR_SZ(_Oly_wb_list1)); static const int _Oly_wb_list2[] = { LIBRAW_WBI_Auto, 0, LIBRAW_WBI_Tungsten, 3000, 0x100, 3300, 0x100, 3600, 0x100, 3900, LIBRAW_WBI_FL_W, 4000, 0x100, 4300, LIBRAW_WBI_FL_D, 4500, 0x100, 4800, LIBRAW_WBI_FineWeather, 5300, LIBRAW_WBI_Cloudy, 6000, LIBRAW_WBI_FL_N, 6600, LIBRAW_WBI_Shade, 7500, LIBRAW_WBI_Custom1, 0, LIBRAW_WBI_Custom2, 0, LIBRAW_WBI_Custom3, 0, LIBRAW_WBI_Custom4, 0 }; libraw_static_table_t LibRaw::Oly_wb_list2(_Oly_wb_list2, _ARR_SZ(_Oly_wb_list2)); static const int _Sony_SRF_wb_list[] = { LIBRAW_WBI_Daylight, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Fluorescent, LIBRAW_WBI_Tungsten, LIBRAW_WBI_Flash }; libraw_static_table_t LibRaw::Sony_SRF_wb_list(_Sony_SRF_wb_list, _ARR_SZ(_Sony_SRF_wb_list)); static const int _Sony_SR2_wb_list[] = { LIBRAW_WBI_Daylight, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Tungsten, LIBRAW_WBI_Flash, 4500, LIBRAW_WBI_Unknown, LIBRAW_WBI_Fluorescent }; libraw_static_table_t LibRaw::Sony_SR2_wb_list(_Sony_SR2_wb_list, _ARR_SZ(_Sony_SR2_wb_list)); static const int _Sony_SR2_wb_list1[] = { LIBRAW_WBI_Daylight, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Tungsten, LIBRAW_WBI_Flash, 4500, LIBRAW_WBI_Shade, LIBRAW_WBI_FL_W, LIBRAW_WBI_FL_N, LIBRAW_WBI_FL_D, LIBRAW_WBI_FL_L, 8500, 6000, 3200, 2500 }; libraw_static_table_t LibRaw::Sony_SR2_wb_list1(_Sony_SR2_wb_list1, _ARR_SZ(_Sony_SR2_wb_list1)); LibRaw-0.21.4/src/utils/000077500000000000000000000000001477673233700147305ustar00rootroot00000000000000LibRaw-0.21.4/src/utils/curves.cpp000066400000000000000000000100641477673233700167440ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" void LibRaw::cubic_spline(const int *x_, const int *y_, const int len) { float **A, *b, *c, *d, *x, *y; int i, j; A = (float **)calloc(((2 * len + 4) * sizeof **A + sizeof *A), 2 * len); if (!A) return; A[0] = (float *)(A + 2 * len); for (i = 1; i < 2 * len; i++) A[i] = A[0] + 2 * len * i; y = len + (x = i + (d = i + (c = i + (b = A[0] + i * i)))); for (i = 0; i < len; i++) { x[i] = x_[i] / 65535.0; y[i] = y_[i] / 65535.0; } for (i = len - 1; i > 0; i--) { float _div = x[i] - x[i - 1]; if (fabs(_div) < 1.0e-15) _div = 1; b[i] = (y[i] - y[i - 1]) / _div; d[i - 1] = _div; } for (i = 1; i < len - 1; i++) { A[i][i] = 2 * (d[i - 1] + d[i]); if (i > 1) { A[i][i - 1] = d[i - 1]; A[i - 1][i] = d[i - 1]; } A[i][len - 1] = 6 * (b[i + 1] - b[i]); } for (i = 1; i < len - 2; i++) { float v = A[i + 1][i] / A[i][i]; for (j = 1; j <= len - 1; j++) A[i + 1][j] -= v * A[i][j]; } for (i = len - 2; i > 0; i--) { float acc = 0; for (j = i; j <= len - 2; j++) acc += A[i][j] * c[j]; c[i] = (A[i][len - 1] - acc) / A[i][i]; } for (i = 0; i < 0x10000; i++) { float x_out = (float)(i / 65535.0); float y_out = 0; for (j = 0; j < len - 1; j++) { if (x[j] <= x_out && x_out <= x[j + 1]) { float v = x_out - x[j]; y_out = y[j] + ((y[j + 1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j + 1] * d[j]) / 6) * v + (c[j] * 0.5) * v * v + ((c[j + 1] - c[j]) / (6 * d[j])) * v * v * v; } } curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 : (ushort)(y_out * 65535.0 + 0.5)); } free(A); } void LibRaw::gamma_curve(double pwr, double ts, int mode, int imax) { int i; double g[6], bnd[2] = {0, 0}, r; g[0] = pwr; g[1] = ts; g[2] = g[3] = g[4] = 0; bnd[g[1] >= 1] = 1; if (g[1] && (g[1] - 1) * (g[0] - 1) <= 0) { for (i = 0; i < 48; i++) { g[2] = (bnd[0] + bnd[1]) / 2; if (g[0]) bnd[(pow(g[2] / g[1], -g[0]) - 1) / g[0] - 1 / g[2] > -1] = g[2]; else bnd[g[2] / exp(1 - 1 / g[2]) < g[1]] = g[2]; } g[3] = g[2] / g[1]; if (g[0]) g[4] = g[2] * (1 / g[0] - 1); } if (g[0]) g[5] = 1 / (g[1] * SQR(g[3]) / 2 - g[4] * (1 - g[3]) + (1 - pow(g[3], 1 + g[0])) * (1 + g[4]) / (1 + g[0])) - 1; else g[5] = 1 / (g[1] * SQR(g[3]) / 2 + 1 - g[2] - g[3] - g[2] * g[3] * (log(g[3]) - 1)) - 1; if (!mode--) { memcpy(gamm, g, sizeof gamm); return; } for (i = 0; i < 0x10000; i++) { curve[i] = 0xffff; if ((r = (double)i / imax) < 1) curve[i] = 0x10000 * (mode ? (r < g[3] ? r * g[1] : (g[0] ? pow(r, g[0]) * (1 + g[4]) - g[4] : log(r) * g[2] + 1)) : (r < g[2] ? r / g[1] : (g[0] ? pow((r + g[4]) / (1 + g[4]), 1 / g[0]) : exp((r - 1) / g[2])))); } } void LibRaw::linear_table(unsigned len) { int i; if (len > 0x10000) len = 0x10000; else if (len < 1) return; read_shorts(curve, len); for (i = len; i < 0x10000; i++) curve[i] = curve[i - 1]; maximum = curve[len < 0x1000 ? 0xfff : len - 1]; } LibRaw-0.21.4/src/utils/decoder_info.cpp000066400000000000000000000323241477673233700200600ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" const char *LibRaw::unpack_function_name() { libraw_decoder_info_t decoder_info; get_decoder_info(&decoder_info); return decoder_info.decoder_name; } int LibRaw::get_decoder_info(libraw_decoder_info_t *d_info) { if (!d_info) return LIBRAW_UNSPECIFIED_ERROR; d_info->decoder_name = 0; d_info->decoder_flags = 0; if (!load_raw) return LIBRAW_OUT_OF_ORDER_CALL; // dcraw.c names order if (load_raw == &LibRaw::android_tight_load_raw) { d_info->decoder_name = "android_tight_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::android_loose_load_raw) { d_info->decoder_name = "android_loose_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::vc5_dng_load_raw_placeholder) { d_info->decoder_name = "vc5_dng_load_raw_placeholder()"; #ifndef USE_GPRSDK d_info->decoder_flags = LIBRAW_DECODER_UNSUPPORTED_FORMAT; #endif } else if (load_raw == &LibRaw::canon_600_load_raw) { d_info->decoder_name = "canon_600_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::fuji_compressed_load_raw) { d_info->decoder_name = "fuji_compressed_load_raw()"; } else if (load_raw == &LibRaw::fuji_14bit_load_raw) { d_info->decoder_name = "fuji_14bit_load_raw()"; } else if (load_raw == &LibRaw::canon_load_raw) { d_info->decoder_name = "canon_load_raw()"; } else if (load_raw == &LibRaw::lossless_jpeg_load_raw) { d_info->decoder_name = "lossless_jpeg_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3; } else if (load_raw == &LibRaw::canon_sraw_load_raw) { d_info->decoder_name = "canon_sraw_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED3; } else if (load_raw == &LibRaw::crxLoadRaw) { d_info->decoder_name = "crxLoadRaw()"; } else if (load_raw == &LibRaw::lossless_dng_load_raw) { d_info->decoder_name = "lossless_dng_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3 | LIBRAW_DECODER_ADOBECOPYPIXEL; } else if (load_raw == &LibRaw::packed_dng_load_raw) { d_info->decoder_name = "packed_dng_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3 | LIBRAW_DECODER_ADOBECOPYPIXEL; } else if (load_raw == &LibRaw::pentax_load_raw) { d_info->decoder_name = "pentax_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3; } else if (load_raw == &LibRaw::nikon_load_raw) { d_info->decoder_name = "nikon_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED3; } else if (load_raw == &LibRaw::nikon_coolscan_load_raw) { d_info->decoder_name = "nikon_coolscan_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::nikon_he_load_raw_placeholder) { d_info->decoder_name = "nikon_he_load_raw_placeholder()"; d_info->decoder_flags = LIBRAW_DECODER_UNSUPPORTED_FORMAT; } else if (load_raw == &LibRaw::nikon_load_sraw) { d_info->decoder_name = "nikon_load_sraw()"; d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::nikon_yuv_load_raw) { d_info->decoder_name = "nikon_load_yuv_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::rollei_load_raw) { // UNTESTED d_info->decoder_name = "rollei_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::phase_one_load_raw) { d_info->decoder_name = "phase_one_load_raw()"; } else if (load_raw == &LibRaw::phase_one_load_raw_c) { d_info->decoder_name = "phase_one_load_raw_c()"; d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED3; /* FIXME: need to make sure correction not applied*/ } else if (load_raw == &LibRaw::phase_one_load_raw_s) { d_info->decoder_name = "phase_one_load_raw_s()"; } else if (load_raw == &LibRaw::hasselblad_load_raw) { d_info->decoder_name = "hasselblad_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED3; /* FIXME: need to make sure correction not applied*/ } else if (load_raw == &LibRaw::leaf_hdr_load_raw) { d_info->decoder_name = "leaf_hdr_load_raw()"; } else if (load_raw == &LibRaw::unpacked_load_raw) { d_info->decoder_name = "unpacked_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_FLATDATA; } else if (load_raw == &LibRaw::unpacked_load_raw_reversed) { d_info->decoder_name = "unpacked_load_raw_reversed()"; d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::sinar_4shot_load_raw) { // UNTESTED d_info->decoder_name = "sinar_4shot_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_SINAR4SHOT; } else if (load_raw == &LibRaw::imacon_full_load_raw) { d_info->decoder_name = "imacon_full_load_raw()"; } else if (load_raw == &LibRaw::hasselblad_full_load_raw) { d_info->decoder_name = "hasselblad_full_load_raw()"; } else if (load_raw == &LibRaw::packed_load_raw) { d_info->decoder_name = "packed_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3; } else if (load_raw == &LibRaw::broadcom_load_raw) { // UNTESTED d_info->decoder_name = "broadcom_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::nokia_load_raw) { // UNTESTED d_info->decoder_name = "nokia_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; } #ifdef LIBRAW_OLD_VIDEO_SUPPORT else if (load_raw == &LibRaw::canon_rmf_load_raw) { // UNTESTED d_info->decoder_name = "canon_rmf_load_raw()"; } #endif else if (load_raw == &LibRaw::panasonic_load_raw) { d_info->decoder_name = "panasonic_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED; } else if (load_raw == &LibRaw::panasonicC6_load_raw) { d_info->decoder_name = "panasonicC6_load_raw()"; /* FIXME: No rawspeed3: not sure it handles 12-bit data too */ } else if (load_raw == &LibRaw::panasonicC7_load_raw) { d_info->decoder_name = "panasonicC7_load_raw()"; } else if (load_raw == &LibRaw::olympus_load_raw) { d_info->decoder_name = "olympus_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3;; } else if (load_raw == &LibRaw::minolta_rd175_load_raw) { // UNTESTED d_info->decoder_name = "minolta_rd175_load_raw()"; } else if (load_raw == &LibRaw::quicktake_100_load_raw) { // UNTESTED d_info->decoder_name = "quicktake_100_load_raw()"; } else if (load_raw == &LibRaw::kodak_radc_load_raw) { d_info->decoder_name = "kodak_radc_load_raw()"; } else if (load_raw == &LibRaw::kodak_jpeg_load_raw) { // UNTESTED + RBAYER d_info->decoder_name = "kodak_jpeg_load_raw()"; } else if (load_raw == &LibRaw::lossy_dng_load_raw) { // Check rbayer d_info->decoder_name = "lossy_dng_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_HASCURVE; } else if (load_raw == &LibRaw::kodak_dc120_load_raw) { d_info->decoder_name = "kodak_dc120_load_raw()"; } else if (load_raw == &LibRaw::eight_bit_load_raw) { d_info->decoder_name = "eight_bit_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::kodak_c330_load_raw) { d_info->decoder_name = "kodak_yrgb_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::kodak_c603_load_raw) { d_info->decoder_name = "kodak_yrgb_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::kodak_262_load_raw) { d_info->decoder_name = "kodak_262_load_raw()"; // UNTESTED! d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::kodak_65000_load_raw) { d_info->decoder_name = "kodak_65000_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_HASCURVE; } else if (load_raw == &LibRaw::kodak_ycbcr_load_raw) { // UNTESTED d_info->decoder_name = "kodak_ycbcr_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::kodak_rgb_load_raw) { // UNTESTED d_info->decoder_name = "kodak_rgb_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::sony_load_raw) { d_info->decoder_name = "sony_load_raw()"; } else if (load_raw == &LibRaw::sony_ljpeg_load_raw) { d_info->decoder_name = "sony_ljpeg_load_raw()"; } else if (load_raw == &LibRaw::sony_arw_load_raw) { d_info->decoder_name = "sony_arw_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3; } else if (load_raw == &LibRaw::sony_arw2_load_raw) { d_info->decoder_name = "sony_arw2_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3 | LIBRAW_DECODER_SONYARW2; } else if (load_raw == &LibRaw::sony_arq_load_raw) { d_info->decoder_name = "sony_arq_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_LEGACY_WITH_MARGINS | LIBRAW_DECODER_FLATDATA | LIBRAW_DECODER_FLAT_BG2_SWAPPED; } else if (load_raw == &LibRaw::samsung_load_raw) { d_info->decoder_name = "samsung_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3; } else if (load_raw == &LibRaw::samsung2_load_raw) { d_info->decoder_name = "samsung2_load_raw()"; } else if (load_raw == &LibRaw::samsung3_load_raw) { d_info->decoder_name = "samsung3_load_raw()"; } else if (load_raw == &LibRaw::smal_v6_load_raw) { // UNTESTED d_info->decoder_name = "smal_v6_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; } else if (load_raw == &LibRaw::smal_v9_load_raw) { // UNTESTED d_info->decoder_name = "smal_v9_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; } #ifdef LIBRAW_OLD_VIDEO_SUPPORT else if (load_raw == &LibRaw::redcine_load_raw) { d_info->decoder_name = "redcine_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_HASCURVE; } #endif else if (load_raw == &LibRaw::x3f_load_raw) { d_info->decoder_name = "x3f_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_OWNALLOC | LIBRAW_DECODER_FIXEDMAXC | LIBRAW_DECODER_LEGACY_WITH_MARGINS; } else if (load_raw == &LibRaw::pentax_4shot_load_raw) { d_info->decoder_name = "pentax_4shot_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_OWNALLOC; } else if (load_raw == &LibRaw::deflate_dng_load_raw) { d_info->decoder_name = "deflate_dng_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_OWNALLOC; } else if (load_raw == &LibRaw::uncompressed_fp_dng_load_raw) { d_info->decoder_name = "uncompressed_fp_dng_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_OWNALLOC; } else if (load_raw == &LibRaw::nikon_load_striped_packed_raw) { d_info->decoder_name = "nikon_load_striped_packed_raw()"; } else if (load_raw == &LibRaw::nikon_load_padded_packed_raw) { d_info->decoder_name = "nikon_load_padded_packed_raw()"; } else if (load_raw == &LibRaw::nikon_14bit_load_raw) { d_info->decoder_name = "nikon_14bit_load_raw()"; } /* -- added 07/02/18 -- */ else if (load_raw == &LibRaw::unpacked_load_raw_fuji_f700s20) { d_info->decoder_name = "unpacked_load_raw_fuji_f700s20()"; } else if (load_raw == &LibRaw::unpacked_load_raw_FujiDBP) { d_info->decoder_name = "unpacked_load_raw_FujiDBP()"; } #ifdef USE_6BY9RPI else if (load_raw == &LibRaw::rpi_load_raw8) { d_info->decoder_name = "rpi_load_raw8"; } else if (load_raw == &LibRaw::rpi_load_raw12) { d_info->decoder_name = "rpi_load_raw12"; } else if (load_raw == &LibRaw::rpi_load_raw14) { d_info->decoder_name = "rpi_load_raw14"; } else if (load_raw == &LibRaw::rpi_load_raw16) { d_info->decoder_name = "rpi_load_raw16"; } #endif else { d_info->decoder_name = "Unknown unpack function"; d_info->decoder_flags = LIBRAW_DECODER_NOTSET; } return LIBRAW_SUCCESS; } LibRaw-0.21.4/src/utils/init_close_utils.cpp000066400000000000000000000257331477673233700210160ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../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 CameraMetaDataLR *camerameta = make_camera_metadata(); // May be NULL in case of exception in // make_camera_metadata() _rawspeed_camerameta = static_cast(camerameta); #endif callbacks.data_cb = (flags & LIBRAW_OPTIONS_NO_DATAERR_CALLBACK) ? NULL : &default_data_callback; callbacks.exif_cb = NULL; // no default callback 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.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) { CameraMetaDataLR *cmeta = static_cast(_rawspeed_camerameta); delete cmeta; _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; _exitflag = 0; #ifdef USE_RAWSPEED if (_rawspeed_decoder) { RawSpeed::RawDecoder *d = static_cast(_rawspeed_decoder); delete d; } _rawspeed_decoder = 0; #endif #ifdef USE_RAWSPEED3 if (_rawspeed3_handle) rawspeed3_release(_rawspeed3_handle); #endif #ifdef USE_DNGSDK if (dngnegative) { dng_negative *ng = (dng_negative *)dngnegative; delete ng; dngnegative = 0; } if(dngimage) { dng_image *dimage = (dng_image*)dngimage; delete dimage; 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(); } LibRaw-0.21.4/src/utils/open.cpp000066400000000000000000001326351477673233700164070ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" #include "../../internal/libraw_cameraids.h" #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM int LibRaw::open_file(const char *fname, INT64 max_buf_size) { int big = 0; if (max_buf_size == LIBRAW_OPEN_BIGFILE) big = 1; else if (max_buf_size == LIBRAW_OPEN_FILE) big = 0; else { #ifndef LIBRAW_WIN32_CALLS struct stat st; if (stat(fname, &st)) return LIBRAW_IO_ERROR; big = (st.st_size > max_buf_size) ? 1 : 0; #else struct _stati64 st; if (_stati64(fname, &st)) return LIBRAW_IO_ERROR; big = (st.st_size > max_buf_size) ? 1 : 0; #endif } LibRaw_abstract_datastream *stream; try { if (big) stream = new LibRaw_bigfile_datastream(fname); else stream = new LibRaw_file_datastream(fname); } catch (const std::bad_alloc& ) { recycle(); return LIBRAW_UNSUFFICIENT_MEMORY; } if (!stream->valid()) { delete stream; return LIBRAW_IO_ERROR; } ID.input_internal = 0; // preserve from deletion on error int ret = open_datastream(stream); if (ret == LIBRAW_SUCCESS) { ID.input_internal = 1; // flag to delete datastream on recycle } else { delete stream; ID.input_internal = 0; } return ret; } #if defined(WIN32) || defined(_WIN32) #ifndef LIBRAW_WIN32_UNICODEPATHS int LibRaw::open_file(const wchar_t *, INT64) { return LIBRAW_NOT_IMPLEMENTED; } #else int LibRaw::open_file(const wchar_t *fname, INT64 max_buf_size) { int big = 0; if (max_buf_size == LIBRAW_OPEN_BIGFILE) big = 1; else if (max_buf_size == LIBRAW_OPEN_FILE) big = 0; else { struct _stati64 st; if (_wstati64(fname, &st)) return LIBRAW_IO_ERROR; big = (st.st_size > max_buf_size) ? 1 : 0; } LibRaw_abstract_datastream *stream; try { if (big) stream = new LibRaw_bigfile_datastream(fname); else stream = new LibRaw_file_datastream(fname); } catch (const std::bad_alloc&) { recycle(); return LIBRAW_UNSUFFICIENT_MEMORY; } if (!stream->valid()) { delete stream; return LIBRAW_IO_ERROR; } ID.input_internal = 0; // preserve from deletion on error int ret = open_datastream(stream); if (ret == LIBRAW_SUCCESS) { ID.input_internal = 1; // flag to delete datastream on recycle } else { delete stream; ID.input_internal = 0; } return ret; } #endif #endif #else /* LIBRAW_NO_IOSTREAMS_DATASTREAM*/ int LibRaw::libraw_openfile_tail(LibRaw_abstract_datastream *stream) { if (!stream->valid()) { delete stream; return LIBRAW_IO_ERROR; } ID.input_internal = 0; // preserve from deletion on error int ret = open_datastream(stream); if (ret == LIBRAW_SUCCESS) { ID.input_internal = 1; // flag to delete datastream on recycle } else { delete stream; ID.input_internal = 0; } return ret; } int LibRaw::open_file(const char *fname) { LibRaw_abstract_datastream *stream; try { #ifdef LIBRAW_WIN32_CALLS stream = new LibRaw_bigfile_buffered_datastream(fname); #else stream = new LibRaw_bigfile_datastream(fname); #endif } catch (const std::bad_alloc&) { recycle(); return LIBRAW_UNSUFFICIENT_MEMORY; } if ((stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE) && (stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE)) { delete stream; return LIBRAW_TOO_BIG; } return libraw_openfile_tail(stream); } #if defined(WIN32) || defined(_WIN32) #ifndef LIBRAW_WIN32_UNICODEPATHS int LibRaw::open_file(const wchar_t *) { return LIBRAW_NOT_IMPLEMENTED; } #else int LibRaw::open_file(const wchar_t *fname) { LibRaw_abstract_datastream *stream; try { #ifdef LIBRAW_WIN32_CALLS stream = new LibRaw_bigfile_buffered_datastream(fname); #else stream = new LibRaw_bigfile_datastream(fname); #endif } catch (const std::bad_alloc&) { recycle(); return LIBRAW_UNSUFFICIENT_MEMORY; } if ((stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) && (stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE)) { delete stream; return LIBRAW_TOO_BIG; } return libraw_openfile_tail(stream); } #endif #endif #endif int LibRaw::open_buffer(const void *buffer, size_t size) { // this stream will close on recycle() if (!buffer || buffer == (const void *)-1) return LIBRAW_IO_ERROR; if ((size > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) && (size > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE)) return LIBRAW_TOO_BIG; LibRaw_buffer_datastream *stream; try { stream = new LibRaw_buffer_datastream(buffer, size); } catch (const std::bad_alloc& ) { recycle(); return LIBRAW_UNSUFFICIENT_MEMORY; } if (!stream->valid()) { delete stream; return LIBRAW_IO_ERROR; } ID.input_internal = 0; // preserve from deletion on error int ret = open_datastream(stream); if (ret == LIBRAW_SUCCESS) { ID.input_internal = 1; // flag to delete datastream on recycle } else { delete stream; ID.input_internal = 0; } return ret; } int LibRaw::open_bayer(const unsigned char *buffer, unsigned datalen, ushort _raw_width, ushort _raw_height, ushort _left_margin, ushort _top_margin, ushort _right_margin, ushort _bottom_margin, unsigned char procflags, unsigned char bayer_pattern, unsigned unused_bits, unsigned otherflags, unsigned black_level) { // this stream will close on recycle() if (!buffer || buffer == (const void *)-1) return LIBRAW_IO_ERROR; LibRaw_buffer_datastream *stream; try { stream = new LibRaw_buffer_datastream(buffer, datalen); } catch (const std::bad_alloc& ) { recycle(); return LIBRAW_UNSUFFICIENT_MEMORY; } if (!stream->valid()) { delete stream; return LIBRAW_IO_ERROR; } ID.input = stream; SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN); // From identify initdata(); strcpy(imgdata.idata.make, "BayerDump"); snprintf(imgdata.idata.model, sizeof(imgdata.idata.model) - 1, "%u x %u pixels", _raw_width, _raw_height); S.flip = procflags >> 2; libraw_internal_data.internal_output_params.zero_is_bad = procflags & 2; libraw_internal_data.unpacker_data.data_offset = 0; S.raw_width = _raw_width; S.raw_height = _raw_height; S.left_margin = _left_margin; S.top_margin = _top_margin; S.width = S.raw_width - S.left_margin - _right_margin; S.height = S.raw_height - S.top_margin - _bottom_margin; imgdata.idata.filters = 0x1010101 * bayer_pattern; imgdata.idata.colors = 4 - !((imgdata.idata.filters & imgdata.idata.filters >> 1) & 0x5555); libraw_internal_data.unpacker_data.load_flags = otherflags; switch (libraw_internal_data.unpacker_data.tiff_bps = (datalen)*8 / (S.raw_width * S.raw_height)) { case 8: load_raw = &LibRaw::eight_bit_load_raw; break; case 10: if ((datalen) / S.raw_height * 3u >= S.raw_width * 4u) { load_raw = &LibRaw::android_loose_load_raw; break; } else if (libraw_internal_data.unpacker_data.load_flags & 1) { load_raw = &LibRaw::android_tight_load_raw; break; } case 12: libraw_internal_data.unpacker_data.load_flags |= 128; load_raw = &LibRaw::packed_load_raw; break; case 16: libraw_internal_data.unpacker_data.order = 0x4949 | 0x404 * (libraw_internal_data.unpacker_data.load_flags & 1); libraw_internal_data.unpacker_data.tiff_bps -= libraw_internal_data.unpacker_data.load_flags >> 4; libraw_internal_data.unpacker_data.tiff_bps -= libraw_internal_data.unpacker_data.load_flags = libraw_internal_data.unpacker_data.load_flags >> 1 & 7; load_raw = &LibRaw::unpacked_load_raw; } C.maximum = (1 << libraw_internal_data.unpacker_data.tiff_bps) - (1 << unused_bits); C.black = black_level; S.iwidth = S.width; S.iheight = S.height; imgdata.idata.colors = 3; imgdata.idata.filters |= ((imgdata.idata.filters >> 2 & 0x22222222) | (imgdata.idata.filters << 2 & 0x88888888)) & imgdata.idata.filters << 1; imgdata.idata.raw_count = 1; for (int i = 0; i < 4; i++) imgdata.color.pre_mul[i] = 1.0; strcpy(imgdata.idata.cdesc, "RGBG"); ID.input_internal = 1; SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY); return LIBRAW_SUCCESS; } struct foveon_data_t { const char *make; const char *model; const int raw_width, raw_height; const int white; const int left_margin, top_margin; const int width, height; } foveon_data[] = { {"Sigma", "SD9", 2304, 1531, 12000, 20, 8, 2266, 1510}, {"Sigma", "SD9", 1152, 763, 12000, 10, 2, 1132, 755}, {"Sigma", "SD10", 2304, 1531, 12000, 20, 8, 2266, 1510}, {"Sigma", "SD10", 1152, 763, 12000, 10, 2, 1132, 755}, {"Sigma", "SD14", 2688, 1792, 14000, 18, 12, 2651, 1767}, {"Sigma", "SD14", 2688, 896, 14000, 18, 6, 2651, 883}, // 2/3 {"Sigma", "SD14", 1344, 896, 14000, 9, 6, 1326, 883}, // 1/2 {"Sigma", "SD15", 2688, 1792, 2900, 18, 12, 2651, 1767}, {"Sigma", "SD15", 2688, 896, 2900, 18, 6, 2651, 883}, // 2/3 ? {"Sigma", "SD15", 1344, 896, 2900, 9, 6, 1326, 883}, // 1/2 ? {"Sigma", "DP1", 2688, 1792, 2100, 18, 12, 2651, 1767}, {"Sigma", "DP1", 2688, 896, 2100, 18, 6, 2651, 883}, // 2/3 ? {"Sigma", "DP1", 1344, 896, 2100, 9, 6, 1326, 883}, // 1/2 ? {"Sigma", "DP1S", 2688, 1792, 2200, 18, 12, 2651, 1767}, {"Sigma", "DP1S", 2688, 896, 2200, 18, 6, 2651, 883}, // 2/3 {"Sigma", "DP1S", 1344, 896, 2200, 9, 6, 1326, 883}, // 1/2 {"Sigma", "DP1X", 2688, 1792, 3560, 18, 12, 2651, 1767}, {"Sigma", "DP1X", 2688, 896, 3560, 18, 6, 2651, 883}, // 2/3 {"Sigma", "DP1X", 1344, 896, 3560, 9, 6, 1326, 883}, // 1/2 {"Sigma", "DP2", 2688, 1792, 2326, 13, 16, 2651, 1767}, {"Sigma", "DP2", 2688, 896, 2326, 13, 8, 2651, 883}, // 2/3 ?? {"Sigma", "DP2", 1344, 896, 2326, 7, 8, 1325, 883}, // 1/2 ?? {"Sigma", "DP2S", 2688, 1792, 2300, 18, 12, 2651, 1767}, {"Sigma", "DP2S", 2688, 896, 2300, 18, 6, 2651, 883}, // 2/3 {"Sigma", "DP2S", 1344, 896, 2300, 9, 6, 1326, 883}, // 1/2 {"Sigma", "DP2X", 2688, 1792, 2300, 18, 12, 2651, 1767}, {"Sigma", "DP2X", 2688, 896, 2300, 18, 6, 2651, 883}, // 2/3 {"Sigma", "DP2X", 1344, 896, 2300, 9, 6, 1325, 883}, // 1/2 {"Sigma", "SD1", 4928, 3264, 3900, 12, 52, 4807, 3205}, // Full size {"Sigma", "SD1", 4928, 1632, 3900, 12, 26, 4807, 1603}, // 2/3 size {"Sigma", "SD1", 2464, 1632, 3900, 6, 26, 2403, 1603}, // 1/2 size {"Sigma", "SD1 Merrill", 4928, 3264, 3900, 12, 52, 4807, 3205}, // Full size {"Sigma", "SD1 Merrill", 4928, 1632, 3900, 12, 26, 4807, 1603}, // 2/3 size {"Sigma", "SD1 Merrill", 2464, 1632, 3900, 6, 26, 2403, 1603}, // 1/2 size {"Sigma", "DP1 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205}, {"Sigma", "DP1 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size {"Sigma", "DP1 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size {"Sigma", "DP2 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205}, {"Sigma", "DP2 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size {"Sigma", "DP2 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size {"Sigma", "DP3 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205}, {"Sigma", "DP3 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size {"Sigma", "DP3 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size {"Polaroid", "x530", 1440, 1088, 2700, 10, 13, 1419, 1059}, // dp2 Q {"Sigma", "dp3 Quattro", 5888, 3776, 16383, 204, 76, 5446, 3624}, // full size, new fw ?? {"Sigma", "dp3 Quattro", 5888, 3672, 16383, 204, 24, 5446, 3624}, // full size {"Sigma", "dp3 Quattro", 2944, 1836, 16383, 102, 12, 2723, 1812}, // half size {"Sigma", "dp3 Quattro", 2944, 1888, 16383, 102, 38, 2723, 1812}, // half size, new fw?? {"Sigma", "dp2 Quattro", 5888, 3776, 16383, 204, 76, 5446, 3624}, // full size, new fw {"Sigma", "dp2 Quattro", 5888, 3672, 16383, 204, 24, 5446, 3624}, // full size {"Sigma", "dp2 Quattro", 2944, 1836, 16383, 102, 12, 2723, 1812}, // half size {"Sigma", "dp2 Quattro", 2944, 1888, 16383, 102, 38, 2723, 1812}, // half size, new fw {"Sigma", "dp1 Quattro", 5888, 3776, 16383, 204, 76, 5446, 3624}, // full size, new fw?? {"Sigma", "dp1 Quattro", 5888, 3672, 16383, 204, 24, 5446, 3624}, // full size {"Sigma", "dp1 Quattro", 2944, 1836, 16383, 102, 12, 2723, 1812}, // half size {"Sigma", "dp1 Quattro", 2944, 1888, 16383, 102, 38, 2723, 1812}, // half size, new fw {"Sigma", "dp0 Quattro", 5888, 3776, 16383, 204, 76, 5446, 3624}, // full size, new fw?? {"Sigma", "dp0 Quattro", 5888, 3672, 16383, 204, 24, 5446, 3624}, // full size {"Sigma", "dp0 Quattro", 2944, 1836, 16383, 102, 12, 2723, 1812}, // half size {"Sigma", "dp0 Quattro", 2944, 1888, 16383, 102, 38, 2723, 1812}, // half size, new fw // Sigma sd Quattro {"Sigma", "sd Quattro", 5888, 3776, 16383, 204, 76, 5446, 3624}, // full size {"Sigma", "sd Quattro", 2944, 1888, 16383, 102, 38, 2723, 1812}, // half size // Sd Quattro H {"Sigma", "sd Quattro H", 6656, 4480, 4000, 224, 160, 6208, 4160}, // full size {"Sigma", "sd Quattro H", 3328, 2240, 4000, 112, 80, 3104, 2080}, // half size {"Sigma", "sd Quattro H", 5504, 3680, 4000, 0, 4, 5496, 3668}, // full size {"Sigma", "sd Quattro H", 2752, 1840, 4000, 0, 2, 2748, 1834}, // half size }; const int foveon_count = sizeof(foveon_data) / sizeof(foveon_data[0]); int LibRaw::open_datastream(LibRaw_abstract_datastream *stream) { if (!stream) return ENOENT; if (!stream->valid()) return LIBRAW_IO_ERROR; if ((stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) && (stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE)) return LIBRAW_TOO_BIG; recycle(); if (callbacks.pre_identify_cb) { int r = (callbacks.pre_identify_cb)(this); if (r == 1) goto final; } try { ID.input = stream; SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN); identify(); // Fuji layout files: either DNG or unpacked_load_raw should be used if (libraw_internal_data.internal_output_params.fuji_width || libraw_internal_data.unpacker_data.fuji_layout) { if (!imgdata.idata.dng_version && load_raw != &LibRaw::unpacked_load_raw && load_raw != &LibRaw::unpacked_load_raw_FujiDBP && load_raw != &LibRaw::unpacked_load_raw_fuji_f700s20 ) return LIBRAW_FILE_UNSUPPORTED; } // promote the old single thumbnail to the thumbs_list if not present already if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT) { bool already = false; if(imgdata.thumbnail.tlength || libraw_internal_data.internal_data.toffset) for(int i = 0; i < imgdata.thumbs_list.thumbcount; i++) if (imgdata.thumbs_list.thumblist[i].toffset == libraw_internal_data.internal_data.toffset && imgdata.thumbs_list.thumblist[i].tlength == imgdata.thumbnail.tlength) { already = true; break; } if (!already) { int idx = imgdata.thumbs_list.thumbcount; imgdata.thumbs_list.thumblist[idx].toffset = libraw_internal_data.internal_data.toffset; imgdata.thumbs_list.thumblist[idx].tlength = imgdata.thumbnail.tlength; imgdata.thumbs_list.thumblist[idx].tflip = 0xffff; imgdata.thumbs_list.thumblist[idx].tformat = libraw_internal_data.unpacker_data.thumb_format; imgdata.thumbs_list.thumblist[idx].tmisc = libraw_internal_data.unpacker_data.thumb_misc; // promote if set imgdata.thumbs_list.thumblist[idx].twidth = imgdata.thumbnail.twidth; imgdata.thumbs_list.thumblist[idx].theight = imgdata.thumbnail.theight; imgdata.thumbs_list.thumbcount++; } } imgdata.lens.Lens[sizeof(imgdata.lens.Lens) - 1] = 0; // make sure lens is 0-terminated if (callbacks.post_identify_cb) (callbacks.post_identify_cb)(this); #define isRIC imgdata.sizes.raw_inset_crops[0] if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && (!strcmp(imgdata.idata.normalized_model, "S3Pro") || !strcmp(imgdata.idata.normalized_model, "S5Pro") || !strcmp(imgdata.idata.normalized_model, "S2Pro"))) { isRIC.cleft = isRIC.ctop = 0xffff; isRIC.cwidth = isRIC.cheight = 0; } // Wipe out canon incorrect in-camera crop if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Canon) && isRIC.cleft == 0 && isRIC.ctop == 0 // non symmetric! && isRIC.cwidth < (imgdata.sizes.raw_width * 4 / 5)) // less than 80% of sensor width { isRIC.cleft = isRIC.ctop = 0xffff; isRIC.cwidth = isRIC.cheight = 0; } // Wipe out non-standard WB if (!imgdata.idata.dng_version && (makeIs(LIBRAW_CAMERAMAKER_Sony) && !strcmp(imgdata.idata.normalized_model, "DSC-F828")) && !(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_PROVIDE_NONSTANDARD_WB)) { for (int i = 0; i < 4; i++) imgdata.color.cam_mul[i] = (i == 1); memset(imgdata.color.WB_Coeffs, 0, sizeof(imgdata.color.WB_Coeffs)); memset(imgdata.color.WBCT_Coeffs, 0, sizeof(imgdata.color.WBCT_Coeffs)); } if (load_raw == &LibRaw::nikon_load_raw) nikon_read_curve(); if (load_raw == &LibRaw::lossless_jpeg_load_raw && MN.canon.RecordMode && makeIs(LIBRAW_CAMERAMAKER_Kodak) && /* Not normalized models here, it is intentional */ (!strncasecmp(imgdata.idata.model, "EOS D2000", 9) || // if we want something different for B&W cameras, !strncasecmp(imgdata.idata.model, "EOS D6000", 9))) // it's better to compare with CamIDs { imgdata.color.black = 0; imgdata.color.maximum = 4501; memset(imgdata.color.cblack, 0, sizeof(imgdata.color.cblack)); memset(imgdata.sizes.mask, 0, sizeof(imgdata.sizes.mask)); imgdata.sizes.mask[0][3] = 1; // to skip mask re-calc libraw_internal_data.unpacker_data.load_flags |= 512; } if (load_raw == &LibRaw::panasonic_load_raw) { if (libraw_internal_data.unpacker_data.pana_encoding == 6 || libraw_internal_data.unpacker_data.pana_encoding == 7) { for (int i = 0; i < 3; i++) imgdata.color.cblack[i] = libraw_internal_data.internal_data.pana_black[i]; imgdata.color.cblack[3] = imgdata.color.cblack[1]; imgdata.color.cblack[4] = imgdata.color.cblack[5] = 0; imgdata.color.black = 0; imgdata.color.maximum = MAX(imgdata.color.linear_max[0], MAX(imgdata.color.linear_max[1], imgdata.color.linear_max[2])); } if (libraw_internal_data.unpacker_data.pana_encoding == 6) { int rowbytes11 = imgdata.sizes.raw_width / 11 * 16; int rowbytes14 = imgdata.sizes.raw_width / 14 * 16; INT64 ds = INT64(libraw_internal_data.unpacker_data.data_size); if (!ds) ds = libraw_internal_data.internal_data.input->size() - libraw_internal_data.unpacker_data.data_offset; if ((imgdata.sizes.raw_width % 11) == 0 && (INT64(imgdata.sizes.raw_height) * rowbytes11 == ds)) load_raw = &LibRaw::panasonicC6_load_raw; else if ((imgdata.sizes.raw_width % 14) == 0 && (INT64(imgdata.sizes.raw_height) * rowbytes14 == ds)) load_raw = &LibRaw::panasonicC6_load_raw; else imgdata.idata.raw_count = 0; // incorrect size } else if (libraw_internal_data.unpacker_data.pana_encoding == 7) { int pixperblock = libraw_internal_data.unpacker_data.pana_bpp == 14 ? 9 : 10; int rowbytes = imgdata.sizes.raw_width / pixperblock * 16; if ((imgdata.sizes.raw_width % pixperblock) == 0 && (INT64(imgdata.sizes.raw_height) * rowbytes == INT64(libraw_internal_data.unpacker_data.data_size))) load_raw = &LibRaw::panasonicC7_load_raw; else imgdata.idata.raw_count = 0; // incorrect size } } #define NIKON_14BIT_SIZE(rw, rh) \ (((unsigned)(ceilf((float)(rw * 7 / 4) / 16.0)) * 16) * rh) // Ugly hack, replace with proper data/line size for different // cameras/format when available if (makeIs(LIBRAW_CAMERAMAKER_Nikon) && (!strncasecmp(imgdata.idata.model, "Z", 1) || !strcasecmp(imgdata.idata.model,"D6")) && NIKON_14BIT_SIZE(imgdata.sizes.raw_width, imgdata.sizes.raw_height) == libraw_internal_data.unpacker_data.data_size) { load_raw = &LibRaw::nikon_14bit_load_raw; } #undef NIKON_14BIT_SIZE // Linear max from 14-bit camera, but on 12-bit data? if (makeIs(LIBRAW_CAMERAMAKER_Sony) && imgdata.color.maximum > 0 && imgdata.color.linear_max[0] > (long)imgdata.color.maximum && imgdata.color.linear_max[0] <= (long)imgdata.color.maximum * 4) for (int c = 0; c < 4; c++) imgdata.color.linear_max[c] /= 4; if (makeIs(LIBRAW_CAMERAMAKER_Canon)) { if (!imgdata.idata.dng_version && (MN.canon.DefaultCropAbsolute.l != -1)) // tag 0x00e0 SensorInfo was parsed { if (imgdata.sizes.raw_aspect != LIBRAW_IMAGE_ASPECT_UNKNOWN) { // tag 0x009a AspectInfo was parsed isRIC.cleft += MN.canon.DefaultCropAbsolute.l; isRIC.ctop += MN.canon.DefaultCropAbsolute.t; } else { isRIC.cleft = MN.canon.DefaultCropAbsolute.l; isRIC.ctop = MN.canon.DefaultCropAbsolute.t; isRIC.cwidth = MN.canon.DefaultCropAbsolute.r - MN.canon.DefaultCropAbsolute.l + 1; isRIC.cheight = MN.canon.DefaultCropAbsolute.b - MN.canon.DefaultCropAbsolute.t + 1; } } else { if (imgdata.sizes.raw_aspect != LIBRAW_IMAGE_ASPECT_UNKNOWN) { } else { // Canon PowerShot S2 IS } } #undef isRIC if (imgdata.color.raw_bps < 14 && !imgdata.idata.dng_version && load_raw != &LibRaw::canon_sraw_load_raw) { int xmax = (1 << imgdata.color.raw_bps) - 1; if (MN.canon.SpecularWhiteLevel > xmax) // Adjust 14-bit metadata to real bps { int div = 1 << (14 - imgdata.color.raw_bps); for (int c = 0; c < 4; c++) imgdata.color.linear_max[c] /= div; for (int c = 0; c < 4; c++) MN.canon.ChannelBlackLevel[c] /= div; MN.canon.AverageBlackLevel /= div; MN.canon.SpecularWhiteLevel /= div; MN.canon.NormalWhiteLevel /= div; } } } if (makeIs(LIBRAW_CAMERAMAKER_Canon) && (load_raw == &LibRaw::canon_sraw_load_raw) && imgdata.sizes.raw_width > 0) { float ratio = float(imgdata.sizes.raw_height) / float(imgdata.sizes.raw_width); if ((ratio < 0.57 || ratio > 0.75) && MN.canon.SensorHeight > 1 && MN.canon.SensorWidth > 1) { imgdata.sizes.raw_width = MN.canon.SensorWidth; imgdata.sizes.left_margin = MN.canon.DefaultCropAbsolute.l; imgdata.sizes.iwidth = imgdata.sizes.width = MN.canon.DefaultCropAbsolute.r - MN.canon.DefaultCropAbsolute.l + 1; imgdata.sizes.raw_height = MN.canon.SensorHeight; imgdata.sizes.top_margin = MN.canon.DefaultCropAbsolute.t; imgdata.sizes.iheight = imgdata.sizes.height = MN.canon.DefaultCropAbsolute.b - MN.canon.DefaultCropAbsolute.t + 1; libraw_internal_data.unpacker_data.load_flags |= 256; // reset width/height in canon_sraw_load_raw() imgdata.sizes.raw_pitch = 8 * imgdata.sizes.raw_width; } else if (imgdata.sizes.raw_width == 4032 && imgdata.sizes.raw_height == 3402 && !strcasecmp(imgdata.idata.model, "EOS 80D")) // 80D hardcoded { imgdata.sizes.raw_width = 4536; imgdata.sizes.left_margin = 28; imgdata.sizes.iwidth = imgdata.sizes.width = imgdata.sizes.raw_width - imgdata.sizes.left_margin; imgdata.sizes.raw_height = 3024; imgdata.sizes.top_margin = 8; imgdata.sizes.iheight = imgdata.sizes.height = imgdata.sizes.raw_height - imgdata.sizes.top_margin; libraw_internal_data.unpacker_data.load_flags |= 256; imgdata.sizes.raw_pitch = 8 * imgdata.sizes.raw_width; } } #ifdef USE_DNGSDK if (imgdata.idata.dng_version &&libraw_internal_data.unpacker_data.tiff_compress == 34892 && libraw_internal_data.unpacker_data.tiff_bps == 8 && libraw_internal_data.unpacker_data.tiff_samples == 3 && load_raw == &LibRaw::lossy_dng_load_raw) { // Data should be linearized by DNG SDK C.black = 0; memset(C.cblack, 0, sizeof(C.cblack)); } #endif // XTrans Compressed? if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && (load_raw == &LibRaw::unpacked_load_raw)) { if (imgdata.sizes.raw_width * (imgdata.sizes.raw_height * 2ul) != libraw_internal_data.unpacker_data.data_size) { if ((imgdata.sizes.raw_width * (imgdata.sizes.raw_height * 7ul)) / 4 == libraw_internal_data.unpacker_data.data_size) load_raw = &LibRaw::fuji_14bit_load_raw; else parse_fuji_compressed_header(); } else if (!strcmp(imgdata.idata.normalized_model, "X-H2S") && libraw_internal_data.internal_data.input->size() < (libraw_internal_data.unpacker_data.data_size + libraw_internal_data.unpacker_data.data_offset)) { parse_fuji_compressed_header(); // try to use compressed header: X-H2S may record wrong data size } } // set raw_inset_crops[1] via raw_aspect if (imgdata.sizes.raw_aspect >= LIBRAW_IMAGE_ASPECT_MINIMAL_REAL_ASPECT_VALUE && imgdata.sizes.raw_aspect <= LIBRAW_IMAGE_ASPECT_MAXIMAL_REAL_ASPECT_VALUE /* crops[0] is valid*/ && (imgdata.sizes.raw_inset_crops[0].cleft < 0xffff) && (imgdata.sizes.raw_inset_crops[0].cleft + imgdata.sizes.raw_inset_crops[0].cwidth <= imgdata.sizes.raw_width) && (imgdata.sizes.raw_inset_crops[0].ctop < 0xffff) && (imgdata.sizes.raw_inset_crops[0].ctop + imgdata.sizes.raw_inset_crops[0].cheight <= imgdata.sizes.raw_height) && imgdata.sizes.raw_inset_crops[0].cwidth > 0 && imgdata.sizes.raw_inset_crops[0].cheight >0 /* crops[1] is not set*/ && (imgdata.sizes.raw_inset_crops[1].cleft == 0xffff) && (imgdata.sizes.raw_inset_crops[1].ctop == 0xffff) ) { float c0_ratio = float(imgdata.sizes.raw_inset_crops[0].cwidth) / float(imgdata.sizes.raw_inset_crops[0].cheight); float c1_ratio = float(imgdata.sizes.raw_aspect) / 1000.f; if (c0_ratio / c1_ratio < 0.98 || c0_ratio / c1_ratio > 1.02) // set crops[1] { if (c1_ratio > c0_ratio) // requested image is wider, cut from top/bottom { int newheight = int(imgdata.sizes.raw_inset_crops[0].cwidth / c1_ratio); int dtop = (imgdata.sizes.raw_inset_crops[0].cheight - newheight) / 2; imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop + dtop; imgdata.sizes.raw_inset_crops[1].cheight = newheight; imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft; imgdata.sizes.raw_inset_crops[1].cwidth = imgdata.sizes.raw_inset_crops[0].cwidth; } else { int newwidth = int(imgdata.sizes.raw_inset_crops[0].cheight * c1_ratio); int dleft = (imgdata.sizes.raw_inset_crops[0].cwidth - newwidth) / 2; imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft + dleft; imgdata.sizes.raw_inset_crops[1].cwidth = newwidth; imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop; imgdata.sizes.raw_inset_crops[1].cheight = imgdata.sizes.raw_inset_crops[0].cheight; } } } int adjust_margins = 0; if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && (imgdata.idata.filters == 9)) { // Adjust top/left margins for X-Trans int newtm = imgdata.sizes.top_margin % 6 ? (imgdata.sizes.top_margin / 6 + 1) * 6 : imgdata.sizes.top_margin; int newlm = imgdata.sizes.left_margin % 6 ? (imgdata.sizes.left_margin / 6 + 1) * 6 : imgdata.sizes.left_margin; if (newtm != imgdata.sizes.top_margin || newlm != imgdata.sizes.left_margin) { imgdata.sizes.height -= (newtm - imgdata.sizes.top_margin); imgdata.sizes.top_margin = newtm; imgdata.sizes.width -= (newlm - imgdata.sizes.left_margin); imgdata.sizes.left_margin = newlm; for (int c1 = 0; c1 < 6; c1++) for (int c2 = 0; c2 < 6; c2++) imgdata.idata.xtrans[c1][c2] = imgdata.idata.xtrans_abs[c1][c2]; } adjust_margins = 6; } else if (!libraw_internal_data.internal_output_params.fuji_width && imgdata.idata.filters >= 1000) { if ((imgdata.sizes.top_margin % 2) || (imgdata.sizes.left_margin % 2)) { int crop[2] = { 0,0 }; unsigned filt; int c; if (imgdata.sizes.top_margin % 2) { imgdata.sizes.top_margin += 1; imgdata.sizes.height -= 1; crop[1] = 1; } if (imgdata.sizes.left_margin % 2) { imgdata.sizes.left_margin += 1; imgdata.sizes.width -= 1; crop[0] = 1; } for (filt = c = 0; c < 16; c++) filt |= FC((c >> 1) + (crop[1]), (c & 1) + (crop[0])) << c * 2; imgdata.idata.filters = filt; } adjust_margins = 2; } if(adjust_margins) // adjust crop_inset margins for (int i = 0; i < 2; i++) { if (imgdata.sizes.raw_inset_crops[i].cleft && imgdata.sizes.raw_inset_crops[i].cleft < 0xffff && imgdata.sizes.raw_inset_crops[i].cwidth && imgdata.sizes.raw_inset_crops[i].cwidth < 0xffff && (imgdata.sizes.raw_inset_crops[i].cleft%adjust_margins) && (imgdata.sizes.raw_inset_crops[i].cwidth > adjust_margins)) { int newleft = ((imgdata.sizes.raw_inset_crops[i].cleft / adjust_margins) + 1) * adjust_margins; int diff = newleft - imgdata.sizes.raw_inset_crops[i].cleft; if (diff > 0) { imgdata.sizes.raw_inset_crops[i].cleft += diff; imgdata.sizes.raw_inset_crops[i].cwidth -= diff; } } if (imgdata.sizes.raw_inset_crops[i].ctop && imgdata.sizes.raw_inset_crops[i].ctop < 0xffff && imgdata.sizes.raw_inset_crops[i].cheight && imgdata.sizes.raw_inset_crops[i].cheight < 0xffff && (imgdata.sizes.raw_inset_crops[i].ctop%adjust_margins) && (imgdata.sizes.raw_inset_crops[i].cheight > adjust_margins)) { int newtop = ((imgdata.sizes.raw_inset_crops[i].ctop / adjust_margins) + 1) * adjust_margins; int diff = newtop - imgdata.sizes.raw_inset_crops[i].ctop; if (diff > 0) { imgdata.sizes.raw_inset_crops[i].ctop += diff; imgdata.sizes.raw_inset_crops[i].cheight -= diff; } } } #ifdef USE_DNGSDK if ( imgdata.rawparams.use_dngsdk && !(imgdata.rawparams.options & (LIBRAW_RAWOPTIONS_DNG_STAGE2 | LIBRAW_RAWOPTIONS_DNG_STAGE3 | LIBRAW_RAWOPTIONS_DNG_DISABLEWBADJUST))) #endif { // Fix DNG white balance if needed: observed only for Kalpanika X3F tools produced DNGs if (imgdata.idata.dng_version && (imgdata.idata.filters == 0) && imgdata.idata.colors > 1 && imgdata.idata.colors < 5) { float delta[4] = { 0.f, 0.f, 0.f, 0.f }; int black[4]; for (int c = 0; c < 4; c++) black[c] = imgdata.color.dng_levels.dng_black + imgdata.color.dng_levels.dng_cblack[c]; for (int c = 0; c < imgdata.idata.colors; c++) delta[c] = imgdata.color.dng_levels.dng_whitelevel[c] - black[c]; float mindelta = delta[0], maxdelta = delta[0]; for (int c = 1; c < imgdata.idata.colors; c++) { if (mindelta > delta[c]) mindelta = delta[c]; if (maxdelta < delta[c]) maxdelta = delta[c]; } if (mindelta > 1 && maxdelta < (mindelta * 20)) // safety { for (int c = 0; c < imgdata.idata.colors; c++) { imgdata.color.cam_mul[c] /= (delta[c] / maxdelta); imgdata.color.pre_mul[c] /= (delta[c] / maxdelta); } imgdata.color.maximum = imgdata.color.cblack[0] + maxdelta; } } } if (imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Panasonic) && !strcasecmp(imgdata.idata.normalized_model, "DMC-LX100")) imgdata.sizes.width = 4288; if (imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Leica) && !strcasecmp(imgdata.idata.normalized_model, "SL2")) imgdata.sizes.height -= 16; if (makeIs(LIBRAW_CAMERAMAKER_Sony) && imgdata.idata.dng_version) { if (S.raw_width == 3984) S.width = 3925; else if (S.raw_width == 4288) S.width = S.raw_width - 32; else if (S.raw_width == 4928 && S.height < 3280) S.width = S.raw_width - 8; else if (S.raw_width == 5504) S.width = S.raw_width - (S.height > 3664 ? 8 : 32); } if (makeIs(LIBRAW_CAMERAMAKER_Sony) && !imgdata.idata.dng_version) { if(load_raw ==&LibRaw::sony_arq_load_raw) { if(S.raw_width > 12000) // A7RM4 16x, both APS-C and APS S.width = S.raw_width - 64; else // A7RM3/M4 4x merge S.width = S.raw_width - 32; } if (((!strncasecmp(imgdata.idata.model, "ILCE-7RM", 8) || !strcasecmp(imgdata.idata.model, "ILCA-99M2")) && (S.raw_width == 5216 || S.raw_width == 6304)) // A7RM2/M3/A99M2 in APS mode; A7RM4 in APS-C || (!strcasecmp(imgdata.idata.model, "ILCE-7R") && S.raw_width >= 4580 && S.raw_width < 5020) // A7R in crop mode, no samples, so size est. || (!strcasecmp(imgdata.idata.model, "ILCE-7") && S.raw_width == 3968) // A7 in crop mode || ((!strncasecmp(imgdata.idata.model, "ILCE-7M", 7) || !strcasecmp(imgdata.idata.model, "ILCE-9") || #if 0 !strcasecmp(imgdata.idata.model, "SLT-A99V")) // Does SLT-A99 also have APS-C mode?? #endif (mnCamID == SonyID_SLT_A99)) // 2 reasons: some cameras are SLT-A99, no 'V'; some are Hasselblad HV && S.raw_width > 3750 && S.raw_width < 4120) // A7M2, A7M3, AA9, most likely APS-C raw_width // is 3968 (same w/ A7), but no samples, so guess || (!strncasecmp(imgdata.idata.model, "ILCE-7S", 7) && S.raw_width == 2816) // A7S2=> exact, hope it works for A7S-I too ) S.width = S.raw_width - 32; } // FIXME: it is possible that DNG contains 4x main frames + some previews; in this case imgdata.idata.raw_count will be greater than 4 if (makeIs(LIBRAW_CAMERAMAKER_Pentax) && /*!strcasecmp(imgdata.idata.model,"K-3 II") &&*/ imgdata.idata.raw_count == 4 && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_PENTAX_PS_ALLFRAMES)) { imgdata.idata.raw_count = 1; imgdata.idata.filters = 0; imgdata.idata.colors = 4; imgdata.sizes.top_margin+=2; imgdata.sizes.left_margin+=2; imgdata.sizes.width-=4; imgdata.sizes.height-=4; IO.mix_green = 1; pentax_component_load_raw = load_raw; load_raw = &LibRaw::pentax_4shot_load_raw; } if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Leaf) && !strcmp(imgdata.idata.model, "Credo 50")) { imgdata.color.pre_mul[0] = 1.f / 0.3984f; imgdata.color.pre_mul[2] = 1.f / 0.7666f; imgdata.color.pre_mul[1] = imgdata.color.pre_mul[3] = 1.0; } if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && (!strncmp(imgdata.idata.model, "S20Pro", 6) || !strncmp(imgdata.idata.model, "F700", 4))) { imgdata.sizes.raw_width /= 2; load_raw = &LibRaw::unpacked_load_raw_fuji_f700s20; } if (load_raw == &LibRaw::packed_load_raw && makeIs(LIBRAW_CAMERAMAKER_Nikon) && !libraw_internal_data.unpacker_data.load_flags && (!strncasecmp(imgdata.idata.model, "D810", 4) || !strcasecmp(imgdata.idata.model, "D4S")) && libraw_internal_data.unpacker_data.data_size * 2u == imgdata.sizes.raw_height * imgdata.sizes.raw_width * 3u) { libraw_internal_data.unpacker_data.load_flags = 80; } // Adjust BL for Sony A900/A850 if (load_raw == &LibRaw::packed_load_raw && makeIs(LIBRAW_CAMERAMAKER_Sony)) // 12 bit sony, but metadata may be for 14-bit range { if (C.maximum > 4095) C.maximum = 4095; if (C.black > 256 || C.cblack[0] > 256) { C.black /= 4; for (int c = 0; c < 4; c++) C.cblack[c] /= 4; for (unsigned c = 0; c < C.cblack[4] * C.cblack[5]; c++) C.cblack[6 + c] /= 4; } } if (load_raw == &LibRaw::nikon_yuv_load_raw) // Is it Nikon sRAW? { load_raw = &LibRaw::nikon_load_sraw; C.black = 0; memset(C.cblack, 0, sizeof(C.cblack)); imgdata.idata.filters = 0; libraw_internal_data.unpacker_data.tiff_samples = 3; imgdata.idata.colors = 3; double beta_1 = -5.79342238397656E-02; double beta_2 = 3.28163551282665; double beta_3 = -8.43136004842678; double beta_4 = 1.03533181861023E+01; for (int i = 0; i <= 3072; i++) { double x = (double)i / 3072.; double y = (1. - exp(-beta_1 * x - beta_2 * x * x - beta_3 * x * x * x - beta_4 * x * x * x * x)); if (y < 0.) y = 0.; imgdata.color.curve[i] = (y * 16383.); } for (int i = 0; i < 3; i++) for (int j = 0; j < 4; j++) imgdata.color.rgb_cam[i][j] = float(i == j); } // Adjust BL for Nikon 12bit if ((load_raw == &LibRaw::nikon_load_raw || load_raw == &LibRaw::packed_load_raw || load_raw == &LibRaw::nikon_load_padded_packed_raw) && makeIs(LIBRAW_CAMERAMAKER_Nikon) && strncmp(imgdata.idata.model, "COOLPIX", 7) && libraw_internal_data.unpacker_data.tiff_bps == 12) { C.maximum = 4095; C.black /= 4; for (int c = 0; c < 4; c++) C.cblack[c] /= 4; for (unsigned c = 0; c < C.cblack[4] * C.cblack[5]; c++) C.cblack[6 + c] /= 4; } // Adjust wb_already_applied if (load_raw == &LibRaw::nikon_load_sraw) imgdata.color.as_shot_wb_applied = LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_NIKON_SRAW; else if (makeIs(LIBRAW_CAMERAMAKER_Canon) && MN.canon.multishot[0] >= 8 && MN.canon.multishot[1] > 0) imgdata.color.as_shot_wb_applied = LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_CANON; else if (makeIs(LIBRAW_CAMERAMAKER_Nikon) && MN.nikon.ExposureMode == 1) imgdata.color.as_shot_wb_applied = LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_NIKON; else if (makeIs(LIBRAW_CAMERAMAKER_Pentax) && ((MN.pentax.MultiExposure & 0x01) == 1)) imgdata.color.as_shot_wb_applied = LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_PENTAX; else imgdata.color.as_shot_wb_applied = 0; // Adjust Highlight Linearity limit if (C.linear_max[0] < 0) { if (imgdata.idata.dng_version) { for (int c = 0; c < 4; c++) C.linear_max[c] = -1 * C.linear_max[c] + imgdata.color.cblack[c + 6]; } else { for (int c = 0; c < 4; c++) C.linear_max[c] = -1 * C.linear_max[c] + imgdata.color.cblack[c]; } } if (makeIs(LIBRAW_CAMERAMAKER_Nikon) && (!C.linear_max[0]) && (C.maximum > 1024) && (load_raw != &LibRaw::nikon_load_sraw)) { C.linear_max[0] = C.linear_max[1] = C.linear_max[2] = C.linear_max[3] = (long)((float)(C.maximum) / 1.07f); } // Correct WB for Samsung GX20 if ( #if 0 /* GX20 should be corrected, but K20 is not */ makeIs(LIBRAW_CAMERAMAKER_Pentax) && !strcasecmp(imgdata.idata.normalized_model, "K20D") #endif #if 0 !strcasecmp(imgdata.idata.make, "Samsung") && !strcasecmp(imgdata.idata.model, "GX20") #endif makeIs(LIBRAW_CAMERAMAKER_Pentax) && (mnCamID == PentaxID_GX20) // Samsung rebranding ) { for (int cnt = LIBRAW_WBI_Unknown; cnt <= LIBRAW_WBI_StudioTungsten; cnt++) { if (C.WB_Coeffs[cnt][1]) { C.WB_Coeffs[cnt][0] = (int)((float)(C.WB_Coeffs[cnt][0]) * 1.0503f); C.WB_Coeffs[cnt][2] = (int)((float)(C.WB_Coeffs[cnt][2]) * 2.2867f); } } for (int cnt = 0; cnt < 64; cnt++) { if (C.WBCT_Coeffs[cnt][0] > 0.0f) { C.WBCT_Coeffs[cnt][1] *= 1.0503f; C.WBCT_Coeffs[cnt][3] *= 2.2867f; } } for(int cnt = 0; cnt < 4; cnt++) imgdata.color.pre_mul[cnt] = C.WB_Coeffs[LIBRAW_WBI_Daylight][cnt]; } // Adjust BL for Panasonic if (load_raw == &LibRaw::panasonic_load_raw && makeIs(LIBRAW_CAMERAMAKER_Panasonic) && ID.pana_black[0] && ID.pana_black[1] && ID.pana_black[2]) { if (libraw_internal_data.unpacker_data.pana_encoding == 5) libraw_internal_data.internal_output_params.zero_is_bad = 0; C.black = 0; int add = libraw_internal_data.unpacker_data.pana_encoding == 4 ? 15 : 0; C.cblack[0] = ID.pana_black[0] + add; C.cblack[1] = C.cblack[3] = ID.pana_black[1] + add; C.cblack[2] = ID.pana_black[2] + add; unsigned i = C.cblack[3]; for (int c = 0; c < 3; c++) if (i > C.cblack[c]) i = C.cblack[c]; for (int c = 0; c < 4; c++) C.cblack[c] -= i; C.black = i; } // Adjust sizes for X3F processing #ifdef USE_X3FTOOLS if (load_raw == &LibRaw::x3f_load_raw) { for (int i = 0; i < foveon_count; i++) if (!strcasecmp(imgdata.idata.make, foveon_data[i].make) && !strcasecmp(imgdata.idata.model, foveon_data[i].model) && imgdata.sizes.raw_width == foveon_data[i].raw_width && imgdata.sizes.raw_height == foveon_data[i].raw_height) { imgdata.sizes.top_margin = foveon_data[i].top_margin; imgdata.sizes.left_margin = foveon_data[i].left_margin; imgdata.sizes.width = imgdata.sizes.iwidth = foveon_data[i].width; imgdata.sizes.height = imgdata.sizes.iheight = foveon_data[i].height; C.maximum = foveon_data[i].white; break; } } #endif #if 0 size_t bytes = ID.input->size()-libraw_internal_data.unpacker_data.data_offset; float bpp = float(bytes)/float(S.raw_width)/float(S.raw_height); float bpp2 = float(bytes)/float(S.width)/float(S.height); if(!strcasecmp(imgdata.idata.make,"Hasselblad") && bpp == 6.0f) { load_raw = &LibRaw::hasselblad_full_load_raw; S.width = S.raw_width; S.height = S.raw_height; P1.filters = 0; P1.colors=3; P1.raw_count=1; C.maximum=0xffff; } #endif if (C.profile_length) { if (C.profile) free(C.profile); INT64 profile_sz = MIN(INT64(C.profile_length), ID.input->size() - ID.profile_offset); if (profile_sz > 0LL && profile_sz < LIBRAW_MAX_PROFILE_SIZE_MB * 1024LL * 1024LL) { C.profile = calloc(size_t(profile_sz),1); C.profile_length = unsigned(profile_sz); ID.input->seek(ID.profile_offset, SEEK_SET); ID.input->read(C.profile, size_t(profile_sz), 1); } else C.profile = NULL; } SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY); } catch (const std::bad_alloc&) { EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); } catch (const LibRaw_exceptions& err) { EXCEPTION_HANDLER(err); } catch (const std::exception& ) { EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT); } final:; if (P1.raw_count < 1) return LIBRAW_FILE_UNSUPPORTED; write_fun = &LibRaw::write_ppm_tiff; if (load_raw == &LibRaw::kodak_ycbcr_load_raw) { S.height += S.height & 1; S.width += S.width & 1; } IO.shrink = P1.filters && (O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1))); if (IO.shrink && P1.filters >= 1000) { S.width &= 65534; S.height &= 65534; } S.iheight = (S.height + IO.shrink) >> IO.shrink; S.iwidth = (S.width + IO.shrink) >> IO.shrink; // Save color,sizes and internal data into raw_image fields memmove(&imgdata.rawdata.color, &imgdata.color, sizeof(imgdata.color)); memmove(&imgdata.rawdata.sizes, &imgdata.sizes, sizeof(imgdata.sizes)); memmove(&imgdata.rawdata.iparams, &imgdata.idata, sizeof(imgdata.idata)); memmove(&imgdata.rawdata.ioparams, &libraw_internal_data.internal_output_params, sizeof(libraw_internal_data.internal_output_params)); SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST); return LIBRAW_SUCCESS; } LibRaw-0.21.4/src/utils/phaseone_processing.cpp000066400000000000000000000060631477673233700214770ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/libraw_cxx_defs.h" void LibRaw::phase_one_allocate_tempbuffer() { // Allocate temp raw_image buffer imgdata.rawdata.raw_image = (ushort *)malloc(S.raw_pitch * S.raw_height); } void LibRaw::phase_one_free_tempbuffer() { free(imgdata.rawdata.raw_image); imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; } int LibRaw::phase_one_subtract_black(ushort *src, ushort *dest) { try { if (O.user_black < 0 && O.user_cblack[0] <= -1000000 && O.user_cblack[1] <= -1000000 && O.user_cblack[2] <= -1000000 && O.user_cblack[3] <= -1000000) { if (!imgdata.rawdata.ph1_cblack || !imgdata.rawdata.ph1_rblack) { int bl = imgdata.color.phase_one_data.t_black; for (int row = 0; row < S.raw_height; row++) { checkCancel(); for (int col = 0; col < S.raw_width; col++) { int idx = row * S.raw_width + col; int val = int(src[idx]) - bl; dest[idx] = val > 0 ? val : 0; } } } else { int bl = imgdata.color.phase_one_data.t_black; for (int row = 0; row < S.raw_height; row++) { checkCancel(); for (int col = 0; col < S.raw_width; col++) { int idx = row * S.raw_width + col; int val = int(src[idx]) - bl + imgdata.rawdata .ph1_cblack[row][col >= imgdata.rawdata.color.phase_one_data .split_col] + imgdata.rawdata .ph1_rblack[col][row >= imgdata.rawdata.color.phase_one_data .split_row]; dest[idx] = val > 0 ? val : 0; } } } } else // black set by user interaction { // Black level in cblack! for (int row = 0; row < S.raw_height; row++) { checkCancel(); unsigned short cblk[16]; for (int cc = 0; cc < 16; cc++) cblk[cc] = C.cblack[fcol(row, cc)]; for (int col = 0; col < S.raw_width; col++) { int idx = row * S.raw_width + col; ushort val = src[idx]; ushort bl = cblk[col & 0xf]; dest[idx] = val > bl ? val - bl : 0; } } } return 0; } catch (const LibRaw_exceptions& ) { return LIBRAW_CANCELLED_BY_CALLBACK; } } LibRaw-0.21.4/src/utils/read_utils.cpp000066400000000000000000000110731477673233700175710ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" ushort LibRaw::sget2Rev(uchar *s) // specific to some Canon Makernotes fields, // where they have endian in reverse { if (order == 0x4d4d) /* "II" means little-endian, and we reverse to "MM" - big endian */ return s[0] | s[1] << 8; else /* "MM" means big-endian... */ return s[0] << 8 | s[1]; } ushort libraw_sget2_static(short _order, uchar *s) { if (_order == 0x4949) /* "II" means little-endian */ return s[0] | s[1] << 8; else /* "MM" means big-endian */ return s[0] << 8 | s[1]; } ushort LibRaw::sget2(uchar *s) { return libraw_sget2_static(order, s); } ushort LibRaw::get2() { uchar str[2] = {0xff, 0xff}; fread(str, 1, 2, ifp); return sget2(str); } unsigned LibRaw::sget4(uchar *s) { return libraw_sget4_static(order, s); } unsigned libraw_sget4_static(short _order, uchar *s) { if (_order == 0x4949) return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; else return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; } unsigned LibRaw::get4() { uchar str[4] = {0xff, 0xff, 0xff, 0xff}; fread(str, 1, 4, ifp); return sget4(str); } unsigned LibRaw::getint(int type) { return tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) ? get2() : get4(); } float libraw_int_to_float(int i) { union { int i; float f; } u; u.i = i; return u.f; } float LibRaw::int_to_float(int i) { return libraw_int_to_float(i); } double LibRaw::getreal(int type) { union { char c[8]; double d; } u, v; int i, rev; switch (type) { case LIBRAW_EXIFTAG_TYPE_SHORT: return (unsigned short)get2(); case LIBRAW_EXIFTAG_TYPE_LONG: return (unsigned int)get4(); case LIBRAW_EXIFTAG_TYPE_RATIONAL: // (unsigned, unsigned) u.d = (unsigned int)get4(); v.d = (unsigned int)get4(); return u.d / (v.d ? v.d : 1); case LIBRAW_EXIFTAG_TYPE_SSHORT: return (signed short)get2(); case LIBRAW_EXIFTAG_TYPE_SLONG: return (signed int)get4(); case LIBRAW_EXIFTAG_TYPE_SRATIONAL: // (int, int) u.d = (signed int)get4(); v.d = (signed int)get4(); return u.d / (v.d ? v.d : 1); case LIBRAW_EXIFTAG_TYPE_FLOAT: return int_to_float(get4()); case LIBRAW_EXIFTAG_TYPE_DOUBLE: rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234)); for (i = 0; i < 8; i++) u.c[i ^ rev] = fgetc(ifp); return u.d; default: return fgetc(ifp); } } double LibRaw::sgetreal(int type, uchar *s) { return libraw_sgetreal_static(order, type, s); } double libraw_sgetreal_static(short _order, int type, uchar *s) { union { char c[8]; double d; } u, v; int i, rev; switch (type) { case LIBRAW_EXIFTAG_TYPE_SHORT: return (unsigned short) libraw_sget2_static(_order,s); case LIBRAW_EXIFTAG_TYPE_LONG: return (unsigned int)libraw_sget4_static(_order, s); case LIBRAW_EXIFTAG_TYPE_RATIONAL: // (unsigned, unsigned) u.d = (unsigned int)libraw_sget4_static(_order,s); v.d = (unsigned int)libraw_sget4_static(_order,s+4); return u.d / (v.d ? v.d : 1); case LIBRAW_EXIFTAG_TYPE_SSHORT: return (signed short)libraw_sget2_static(_order,s); case LIBRAW_EXIFTAG_TYPE_SLONG: return (signed int) libraw_sget4_static(_order,s); case LIBRAW_EXIFTAG_TYPE_SRATIONAL: // (int, int) u.d = (signed int)libraw_sget4_static(_order,s); v.d = (signed int)libraw_sget4_static(_order,s+4); return u.d / (v.d ? v.d : 1); case LIBRAW_EXIFTAG_TYPE_FLOAT: return libraw_int_to_float(libraw_sget4_static(_order,s)); case LIBRAW_EXIFTAG_TYPE_DOUBLE: rev = 7 * ((_order == 0x4949) == (ntohs(0x1234) == 0x1234)); for (i = 0; i < 8; i++) u.c[i ^ rev] = *(s+1); return u.d; default: return *(s+1); } } void LibRaw::read_shorts(ushort *pixel, unsigned count) { if ((unsigned)fread(pixel, 2, count, ifp) < count) derror(); if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) libraw_swab(pixel, count * 2); } LibRaw-0.21.4/src/utils/thumb_utils.cpp000066400000000000000000000222041477673233700177730ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" void LibRaw::kodak_thumb_loader() { INT64 est_datasize = T.theight * T.twidth / 3; // is 0.3 bytes per pixel good estimate? if (ID.toffset < 0) throw LIBRAW_EXCEPTION_IO_CORRUPT; if (ID.toffset + est_datasize > ID.input->size() + THUMB_READ_BEYOND) throw LIBRAW_EXCEPTION_IO_EOF; if(INT64(T.theight) * INT64(T.twidth) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) throw LIBRAW_EXCEPTION_IO_CORRUPT; if (INT64(T.theight) * INT64(T.twidth) < 64ULL) throw LIBRAW_EXCEPTION_IO_CORRUPT; if(T.twidth < 16 || T.twidth > 8192 || T.theight < 16 || T.theight > 8192) throw LIBRAW_EXCEPTION_IO_CORRUPT; // some kodak cameras ushort s_height = S.height, s_width = S.width, s_iwidth = S.iwidth, s_iheight = S.iheight; ushort s_flags = libraw_internal_data.unpacker_data.load_flags; libraw_internal_data.unpacker_data.load_flags = 12; int s_colors = P1.colors; unsigned s_filters = P1.filters; ushort(*s_image)[4] = imgdata.image; S.height = T.theight; S.width = T.twidth; P1.filters = 0; #define Tformat libraw_internal_data.unpacker_data.thumb_format if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_KODAK_YCBCR) { S.height += S.height & 1; S.width += S.width & 1; } S.iheight = S.height; S.iwidth = S.width; imgdata.image = (ushort(*)[4])calloc(S.iheight * S.iwidth, sizeof(*imgdata.image)); ID.input->seek(ID.toffset, SEEK_SET); // read kodak thumbnail into T.image[] try { if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_KODAK_YCBCR) kodak_ycbcr_load_raw(); else if(Tformat == LIBRAW_INTERNAL_THUMBNAIL_KODAK_RGB) kodak_rgb_load_raw(); else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_KODAK_THUMB) kodak_thumb_load_raw(); } catch (...) { free(imgdata.image); imgdata.image = s_image; T.twidth = 0; S.width = s_width; S.iwidth = s_iwidth; S.iheight = s_iheight; T.theight = 0; S.height = s_height; T.tcolors = 0; P1.colors = s_colors; P1.filters = s_filters; T.tlength = 0; libraw_internal_data.unpacker_data.load_flags = s_flags; return; } // from scale_colors { double dmax; float scale_mul[4]; int c, val; for (dmax = DBL_MAX, c = 0; c < 3; c++) if (dmax > C.pre_mul[c]) dmax = C.pre_mul[c]; for (c = 0; c < 3; c++) scale_mul[c] = (C.pre_mul[c] / dmax) * 65535.0 / C.maximum; scale_mul[3] = scale_mul[1]; size_t size = S.height * S.width; for (unsigned i = 0; i < size * 4; i++) { val = imgdata.image[0][i]; if (!val) continue; val *= scale_mul[i & 3]; imgdata.image[0][i] = CLIP(val); } } // from convert_to_rgb ushort *img; int row, col; int(*t_hist)[LIBRAW_HISTOGRAM_SIZE] = (int(*)[LIBRAW_HISTOGRAM_SIZE])calloc(sizeof(*t_hist), 4); if (imgdata.idata.maker_index == LIBRAW_CAMERAMAKER_Canon) // Skip color conversion for canon PPM tiffs { for (img = imgdata.image[0], row = 0; row < S.height; row++) for (col = 0; col < S.width; col++, img += 4) for (int c = 0; c < P1.colors; c++) t_hist[c][img[c] >> 3]++; } else { float out[3], out_cam[3][4] = {{2.81761312f, -1.98369181f, 0.166078627f, 0}, {-0.111855984f, 1.73688626f, -0.625030339f, 0}, {-0.0379119813f, -0.891268849f, 1.92918086f, 0}}; for (img = imgdata.image[0], row = 0; row < S.height; row++) for (col = 0; col < S.width; col++, img += 4) { out[0] = out[1] = out[2] = 0; int c; for (c = 0; c < 3; c++) { out[0] += out_cam[0][c] * img[c]; out[1] += out_cam[1][c] * img[c]; out[2] += out_cam[2][c] * img[c]; } for (c = 0; c < 3; c++) img[c] = CLIP((int)out[c]); for (c = 0; c < P1.colors; c++) t_hist[c][img[c] >> 3]++; } } // from gamma_lut int(*save_hist)[LIBRAW_HISTOGRAM_SIZE] = libraw_internal_data.output_data.histogram; libraw_internal_data.output_data.histogram = t_hist; // make curve output curve! ushort *t_curve = (ushort *)calloc(sizeof(C.curve), 1); memmove(t_curve, C.curve, sizeof(C.curve)); memset(C.curve, 0, sizeof(C.curve)); { int perc, val, total, t_white = 0x2000, c; perc = S.width * S.height * 0.01; /* 99th percentile white level */ if (IO.fuji_width) perc /= 2; if (!((O.highlight & ~2) || O.no_auto_bright)) for (t_white = c = 0; c < P1.colors; c++) { for (val = 0x2000, total = 0; --val > 32;) if ((total += libraw_internal_data.output_data.histogram[c][val]) > perc) break; if (t_white < val) t_white = val; } gamma_curve(O.gamm[0], O.gamm[1], 2, (t_white << 3) / O.bright); } libraw_internal_data.output_data.histogram = save_hist; free(t_hist); // from write_ppm_tiff - copy pixels into bitmap int s_flip = imgdata.sizes.flip; if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_NO_ROTATE_FOR_KODAK_THUMBNAILS) imgdata.sizes.flip = 0; S.iheight = S.height; S.iwidth = S.width; if (S.flip & 4) SWAP(S.height, S.width); if (T.thumb) free(T.thumb); T.thumb = (char *)calloc(S.width * S.height, P1.colors); T.tlength = S.width * S.height * P1.colors; // from write_tiff_ppm { int soff = flip_index(0, 0); int cstep = flip_index(0, 1) - soff; int rstep = flip_index(1, 0) - flip_index(0, S.width); for (int rr = 0; rr < S.height; rr++, soff += rstep) { char *ppm = T.thumb + rr * S.width * P1.colors; for (int cc = 0; cc < S.width; cc++, soff += cstep) for (int c = 0; c < P1.colors; c++) ppm[cc * P1.colors + c] = imgdata.color.curve[imgdata.image[soff][c]] >> 8; } } memmove(C.curve, t_curve, sizeof(C.curve)); free(t_curve); // restore variables free(imgdata.image); imgdata.image = s_image; if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_NO_ROTATE_FOR_KODAK_THUMBNAILS) imgdata.sizes.flip = s_flip; T.twidth = S.width; S.width = s_width; S.iwidth = s_iwidth; S.iheight = s_iheight; T.theight = S.height; S.height = s_height; T.tcolors = P1.colors; P1.colors = s_colors; P1.filters = s_filters; libraw_internal_data.unpacker_data.load_flags = s_flags; } // ������� thumbnail �� �����, ������ thumb_format � ������������ � �������� int LibRaw::thumbOK(INT64 maxsz) { if (!ID.input) return 0; if (!ID.toffset && !(imgdata.thumbnail.tlength > 0 && load_raw == &LibRaw::broadcom_load_raw) // RPi #ifdef USE_6BY9RPI && !(imgdata.thumbnail.tlength > 0 && libraw_internal_data.unpacker_data.load_flags & 0x4000 && (load_raw == &LibRaw::rpi_load_raw8 || load_raw == &LibRaw::nokia_load_raw || load_raw == &LibRaw::rpi_load_raw12 || load_raw == &LibRaw::rpi_load_raw14)) #endif ) return 0; INT64 fsize = ID.input->size(); if (fsize > 0xffffffffU) return 0; // No thumb for raw > 4Gb-1 int tsize = 0; int tcol = (T.tcolors > 0 && T.tcolors < 4) ? T.tcolors : 3; if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_JPEG) tsize = T.tlength; else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_PPM) tsize = tcol * T.twidth * T.theight; else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_PPM16) tsize = tcol * T.twidth * T.theight * ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_USE_PPM16_THUMBS) ? 2 : 1); #ifdef USE_X3FTOOLS else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_X3F) { tsize = x3f_thumb_size(); } #endif else // Kodak => no check tsize = 1; if (tsize < 0) return 0; if (maxsz > 0 && tsize > maxsz) return 0; return (tsize + ID.toffset <= fsize) ? 1 : 0; } int LibRaw::dcraw_thumb_writer(const char *fname) { // CHECK_ORDER_LOW(LIBRAW_PROGRESS_THUMB_LOAD); if (!fname) return ENOENT; FILE *tfp = fopen(fname, "wb"); if (!tfp) return errno; if (!T.thumb) { fclose(tfp); return LIBRAW_OUT_OF_ORDER_CALL; } try { switch (T.tformat) { case LIBRAW_THUMBNAIL_JPEG: jpeg_thumb_writer(tfp, T.thumb, T.tlength); break; case LIBRAW_THUMBNAIL_BITMAP: fprintf(tfp, "P%d\n%d %d\n255\n", T.tcolors == 1 ? 5 : 6, T.twidth, T.theight); fwrite(T.thumb, 1, T.tlength, tfp); break; default: fclose(tfp); return LIBRAW_UNSUPPORTED_THUMBNAIL; } fclose(tfp); return 0; } catch (const std::bad_alloc&) { fclose(tfp); EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); } catch (const LibRaw_exceptions& err) { fclose(tfp); EXCEPTION_HANDLER(err); } } LibRaw-0.21.4/src/utils/utils_dcraw.cpp000066400000000000000000000237461477673233700177700ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" int LibRaw::fcol(int row, int col) { static const char filter[16][16] = { {2, 1, 1, 3, 2, 3, 2, 0, 3, 2, 3, 0, 1, 2, 1, 0}, {0, 3, 0, 2, 0, 1, 3, 1, 0, 1, 1, 2, 0, 3, 3, 2}, {2, 3, 3, 2, 3, 1, 1, 3, 3, 1, 2, 1, 2, 0, 0, 3}, {0, 1, 0, 1, 0, 2, 0, 2, 2, 0, 3, 0, 1, 3, 2, 1}, {3, 1, 1, 2, 0, 1, 0, 2, 1, 3, 1, 3, 0, 1, 3, 0}, {2, 0, 0, 3, 3, 2, 3, 1, 2, 0, 2, 0, 3, 2, 2, 1}, {2, 3, 3, 1, 2, 1, 2, 1, 2, 1, 1, 2, 3, 0, 0, 1}, {1, 0, 0, 2, 3, 0, 0, 3, 0, 3, 0, 3, 2, 1, 2, 3}, {2, 3, 3, 1, 1, 2, 1, 0, 3, 2, 3, 0, 2, 3, 1, 3}, {1, 0, 2, 0, 3, 0, 3, 2, 0, 1, 1, 2, 0, 1, 0, 2}, {0, 1, 1, 3, 3, 2, 2, 1, 1, 3, 3, 0, 2, 1, 3, 2}, {2, 3, 2, 0, 0, 1, 3, 0, 2, 0, 1, 2, 3, 0, 1, 0}, {1, 3, 1, 2, 3, 2, 3, 2, 0, 2, 0, 1, 1, 0, 3, 0}, {0, 2, 0, 3, 1, 0, 0, 1, 1, 3, 3, 2, 3, 2, 2, 1}, {2, 1, 3, 2, 3, 1, 2, 1, 0, 3, 0, 2, 0, 2, 0, 2}, {0, 3, 1, 0, 0, 2, 0, 3, 2, 1, 3, 1, 1, 3, 1, 3}}; if (filters == 1) return filter[(row + top_margin) & 15][(col + left_margin) & 15]; if (filters == 9) return xtrans[(row + 6) % 6][(col + 6) % 6]; return FC(row, col); } size_t LibRaw::strnlen(const char *s, size_t n) { #if !defined(__FreeBSD__) && !defined(__OpenBSD__) const char *p = (const char *)memchr(s, 0, n); return (p ? p - s : n); #else return ::strnlen(s, n); #endif } void *LibRaw::memmem(char *haystack, size_t haystacklen, char *needle, size_t needlelen) { #if !defined(__GLIBC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) char *c; for (c = haystack; c <= haystack + haystacklen - needlelen; c++) if (!memcmp(c, needle, needlelen)) return c; return 0; #else return ::memmem(haystack, haystacklen, needle, needlelen); #endif } char *LibRaw::strcasestr(char *haystack, const char *needle) { char *c; for (c = haystack; *c; c++) if (!strncasecmp(c, needle, strlen(needle))) return c; return 0; } void LibRaw::initdata() { tiff_flip = flip = filters = UINT_MAX; /* unknown */ raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; maximum = height = width = top_margin = left_margin = 0; cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0; iso_speed = shutter = aperture = focal_len = 0; unique_id = 0ULL; tiff_nifds = 0; memset(tiff_ifd, 0, sizeof tiff_ifd); for (int i = 0; i < LIBRAW_IFD_MAXCOUNT; i++) { tiff_ifd[i].dng_color[0].illuminant = tiff_ifd[i].dng_color[1].illuminant = 0xffff; for (int c = 0; c < 4; c++) tiff_ifd[i].dng_levels.analogbalance[c] = 1.0f; } for (int i = 0; i < 0x10000; i++) curve[i] = i; memset(gpsdata, 0, sizeof gpsdata); memset(cblack, 0, sizeof cblack); memset(white, 0, sizeof white); memset(mask, 0, sizeof mask); thumb_offset = thumb_length = thumb_width = thumb_height = 0; load_raw = 0; thumb_format = LIBRAW_INTERNAL_THUMBNAIL_JPEG; // default to JPEG data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0; kodak_cbpp = zero_after_ff = dng_version = load_flags = 0; timestamp = shot_order = tiff_samples = black = is_foveon = 0; mix_green = profile_length = data_error = zero_is_bad = 0; pixel_aspect = is_raw = raw_color = 1; tile_width = tile_length = 0; metadata_blocks = 0; is_NikonTransfer = 0; is_Olympus = 0; OlympusDNG_SubDirOffsetValid = 0; is_Sony = 0; is_pana_raw = 0; maker_index = LIBRAW_CAMERAMAKER_Unknown; FujiCropMode = 0; is_PentaxRicohMakernotes = 0; normalized_model[0] = 0; normalized_make[0] = 0; CM_found = 0; } void LibRaw::aRGB_coeff(double aRGB_cam[3][3]) { static const double rgb_aRGB[3][3] = { {1.39828313770000, -0.3982830047, 9.64980900741708E-8}, {6.09219200572997E-8, 0.9999999809, 1.33230799934103E-8}, {2.17237099975343E-8, -0.0429383201, 1.04293828050000}}; double cmatrix_tmp[3][3] = { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; int i, j, k; for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) { for (k = 0; k < 3; k++) cmatrix_tmp[i][j] += rgb_aRGB[i][k] * aRGB_cam[k][j]; cmatrix[i][j] = (float)cmatrix_tmp[i][j]; } } void LibRaw::romm_coeff(float romm_cam[3][3]) { static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */ {{2.034193f, -0.727420f, -0.306766f}, {-0.228811f, 1.231729f, -0.002922f}, {-0.008565f, -0.153273f, 1.161839f}}; int i, j, k; for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) for (cmatrix[i][j] = k = 0; k < 3; k++) cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j]; } void LibRaw::remove_zeroes() { unsigned row, col, tot, n; int r, c; RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES, 0, 2); for (row = 0; row < height; row++) for (col = 0; col < width; col++) if (BAYER(row, col) == 0) { tot = n = 0; for (r = (int)row - 2; r <= (int)row + 2; r++) for (c = (int)col - 2; c <= (int)col + 2; c++) if (r >= 0 && r < height && c >= 0 && c < width && FC(r, c) == FC(row, col) && BAYER(r, c)) tot += (n++, BAYER(r, c)); if (n) BAYER(row, col) = tot / n; } RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES, 1, 2); } void LibRaw::crop_masked_pixels() { int row, col; unsigned c, m, zero, val; #define mblack imgdata.color.black_stat if (mask[0][3] > 0) goto mask_set; if (load_raw == &LibRaw::canon_load_raw || load_raw == &LibRaw::lossless_jpeg_load_raw || load_raw == &LibRaw::crxLoadRaw) { mask[0][1] = mask[1][1] += 2; mask[0][3] -= 2; goto sides; } if (load_raw == &LibRaw::canon_600_load_raw || load_raw == &LibRaw::sony_load_raw || (load_raw == &LibRaw::eight_bit_load_raw && strncmp(model, "DC2", 3)) || load_raw == &LibRaw::kodak_262_load_raw || (load_raw == &LibRaw::packed_load_raw && (load_flags & 32))) { sides: mask[0][0] = mask[1][0] = top_margin; mask[0][2] = mask[1][2] = top_margin + height; mask[0][3] += left_margin; mask[1][1] += left_margin + width; mask[1][3] += raw_width; } if (load_raw == &LibRaw::nokia_load_raw) { mask[0][2] = top_margin; mask[0][3] = width; } if (load_raw == &LibRaw::broadcom_load_raw) { mask[0][2] = top_margin; mask[0][3] = width; } mask_set: memset(mblack, 0, sizeof mblack); for (zero = m = 0; m < 8; m++) for (row = MAX(mask[m][0], 0); row < MIN(mask[m][2], raw_height); row++) for (col = MAX(mask[m][1], 0); col < MIN(mask[m][3], raw_width); col++) { /* No need to subtract margins because full area and active area filters are the same */ c = FC(row, col); mblack[c] += val = raw_image[(row)*raw_pitch / 2 + (col)]; mblack[4 + c]++; zero += !val; } if (load_raw == &LibRaw::canon_600_load_raw && width < raw_width) { black = (mblack[0] + mblack[1] + mblack[2] + mblack[3]) / MAX(1, (mblack[4] + mblack[5] + mblack[6] + mblack[7])) - 4; } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) { FORC4 cblack[c] = mblack[c] / MAX(1, mblack[4 + c]); black = cblack[4] = cblack[5] = cblack[6] = 0; } } #undef mblack void LibRaw::pseudoinverse(double (*in)[3], double (*out)[3], int size) { double work[3][6], num; int i, j, k; for (i = 0; i < 3; i++) { for (j = 0; j < 6; j++) work[i][j] = j == i + 3; for (j = 0; j < 3; j++) for (k = 0; k < size && k < 4; k++) work[i][j] += in[k][i] * in[k][j]; } for (i = 0; i < 3; i++) { num = work[i][i]; for (j = 0; j < 6; j++) if (fabs(num) > 0.00001f) work[i][j] /= num; for (k = 0; k < 3; k++) { if (k == i) continue; num = work[k][i]; for (j = 0; j < 6; j++) work[k][j] -= work[i][j] * num; } } for (i = 0; i < size && i < 4; i++) for (j = 0; j < 3; j++) for (out[i][j] = k = 0; k < 3; k++) out[i][j] += work[j][k + 3] * in[i][k]; } void LibRaw::cam_xyz_coeff(float _rgb_cam[3][4], double cam_xyz[4][3]) { double cam_rgb[4][3], inverse[4][3], num; int i, j, k; for (i = 0; i < colors && i < 4; i++) /* Multiply out XYZ colorspace */ for (j = 0; j < 3; j++) for (cam_rgb[i][j] = k = 0; k < 3; k++) cam_rgb[i][j] += cam_xyz[i][k] * LibRaw_constants::xyz_rgb[k][j]; for (i = 0; i < colors && i < 4; i++) { /* Normalize cam_rgb so that */ for (num = j = 0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */ num += cam_rgb[i][j]; if (num > 0.00001) { for (j = 0; j < 3; j++) cam_rgb[i][j] /= num; pre_mul[i] = 1 / num; } else { for (j = 0; j < 3; j++) cam_rgb[i][j] = 0.0; pre_mul[i] = 1.0; } } pseudoinverse(cam_rgb, inverse, colors); for (i = 0; i < 3; i++) for (j = 0; j < colors && j < 4; j++) _rgb_cam[i][j] = inverse[j][i]; } void LibRaw::tiff_get(unsigned base, unsigned *tag, unsigned *type, unsigned *len, unsigned *save) { #ifdef LIBRAW_IOSPACE_CHECK INT64 pos = ftell(ifp); INT64 fsize = ifp->size(); if (fsize < 12 || (fsize - pos) < 12) throw LIBRAW_EXCEPTION_IO_EOF; #endif *tag = get2(); *type = get2(); *len = get4(); *save = ftell(ifp) + 4; if (*len * tagtype_dataunit_bytes[(*type <= LIBRAW_EXIFTAG_TYPE_IFD8) ? *type : 0] > 4) fseek(ifp, get4() + base, SEEK_SET); } LibRaw-0.21.4/src/utils/utils_libraw.cpp000066400000000000000000000417311477673233700201420ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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 "../../internal/libraw_cxx_defs.h" #ifdef __cplusplus extern "C" { #endif void default_data_callback(void *, const char *file, const int offset) { if (offset < 0) fprintf(stderr, "%s: Unexpected end of file\n", file ? file : "unknown file"); else fprintf(stderr, "%s: data corrupted at %d\n", file ? file : "unknown file", offset); } const char *libraw_strerror(int e) { enum LibRaw_errors errorcode = (LibRaw_errors)e; switch (errorcode) { case LIBRAW_SUCCESS: return "No error"; case LIBRAW_UNSPECIFIED_ERROR: return "Unspecified error"; case LIBRAW_FILE_UNSUPPORTED: return "Unsupported file format or not RAW file"; case LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE: return "Request for nonexisting image number"; case LIBRAW_OUT_OF_ORDER_CALL: return "Out of order call of libraw function"; case LIBRAW_NO_THUMBNAIL: return "No thumbnail in file"; case LIBRAW_UNSUPPORTED_THUMBNAIL: return "Unsupported thumbnail format"; case LIBRAW_INPUT_CLOSED: return "No input stream, or input stream closed"; case LIBRAW_NOT_IMPLEMENTED: return "Decoder not implemented for this data format"; case LIBRAW_REQUEST_FOR_NONEXISTENT_THUMBNAIL: return "Request for nonexisting thumbnail number"; case LIBRAW_MEMPOOL_OVERFLOW: return "Libraw internal mempool overflowed"; case LIBRAW_UNSUFFICIENT_MEMORY: return "Unsufficient memory"; case LIBRAW_DATA_ERROR: return "Corrupted data or unexpected EOF"; case LIBRAW_IO_ERROR: return "Input/output error"; case LIBRAW_CANCELLED_BY_CALLBACK: return "Cancelled by user callback"; case LIBRAW_BAD_CROP: return "Bad crop box"; case LIBRAW_TOO_BIG: return "Image too big for processing"; default: return "Unknown error code"; } } #ifdef __cplusplus } #endif unsigned LibRaw::parse_custom_cameras(unsigned limit, libraw_custom_camera_t table[], char **list) { if (!list) return 0; unsigned index = 0; for (unsigned i = 0; i < limit; i++) { if (!list[i]) break; if (strlen(list[i]) < 10) continue; char *string = (char *)malloc(strlen(list[i]) + 1); strcpy(string, list[i]); char *start = string; memset(&table[index], 0, sizeof(table[0])); for (int j = 0; start && j < 14; j++) { char *end = strchr(start, ','); if (end) { *end = 0; end++; } // move to next char while (isspace(*start) && *start) start++; // skip leading spaces? unsigned val = strtol(start, 0, 10); switch (j) { case 0: table[index].fsize = val; break; case 1: table[index].rw = val; break; case 2: table[index].rh = val; break; case 3: table[index].lm = val; break; case 4: table[index].tm = val; break; case 5: table[index].rm = val; break; case 6: table[index].bm = val; break; case 7: table[index].lf = val; break; case 8: table[index].cf = val; break; case 9: table[index].max = val; break; case 10: table[index].flags = val; break; case 11: strncpy(table[index].t_make, start, sizeof(table[index].t_make) - 1); break; case 12: strncpy(table[index].t_model, start, sizeof(table[index].t_model) - 1); break; case 13: table[index].offset = val; break; default: break; } start = end; } free(string); if (table[index].t_make[0]) index++; } return index; } void LibRaw::derror() { if (!libraw_internal_data.unpacker_data.data_error && libraw_internal_data.internal_data.input) { if (libraw_internal_data.internal_data.input->eof()) { if (callbacks.data_cb) (*callbacks.data_cb)(callbacks.datacb_data, libraw_internal_data.internal_data.input->fname(), -1); throw LIBRAW_EXCEPTION_IO_EOF; } else { if (callbacks.data_cb) (*callbacks.data_cb)(callbacks.datacb_data, libraw_internal_data.internal_data.input->fname(), libraw_internal_data.internal_data.input->tell()); // throw LIBRAW_EXCEPTION_IO_CORRUPT; } } libraw_internal_data.unpacker_data.data_error++; } const char *LibRaw::version() { return LIBRAW_VERSION_STR; } int LibRaw::versionNumber() { return LIBRAW_VERSION; } const char *LibRaw::strerror(int p) { return libraw_strerror(p); } unsigned LibRaw::capabilities() { unsigned ret = 0; #ifdef USE_RAWSPEED ret |= LIBRAW_CAPS_RAWSPEED; #endif #ifdef USE_RAWSPEED3 ret |= LIBRAW_CAPS_RAWSPEED3; #endif #ifdef USE_RAWSPEED_BITS ret |= LIBRAW_CAPS_RAWSPEED_BITS; #endif #ifdef USE_DNGSDK ret |= LIBRAW_CAPS_DNGSDK; #ifdef USE_GPRSDK ret |= LIBRAW_CAPS_GPRSDK; #endif #ifdef LIBRAW_WIN32_UNICODEPATHS ret |= LIBRAW_CAPS_UNICODEPATHS; #endif #endif #ifdef USE_X3FTOOLS ret |= LIBRAW_CAPS_X3FTOOLS; #endif #ifdef USE_6BY9RPI ret |= LIBRAW_CAPS_RPI6BY9; #endif #ifdef USE_ZLIB ret |= LIBRAW_CAPS_ZLIB; #endif #ifdef USE_JPEG ret |= LIBRAW_CAPS_JPEG; #endif return ret; } int LibRaw::is_sraw() { return load_raw == &LibRaw::canon_sraw_load_raw || load_raw == &LibRaw::nikon_load_sraw; } int LibRaw::is_coolscan_nef() { return load_raw == &LibRaw::nikon_coolscan_load_raw; } int LibRaw::is_jpeg_thumb() { return libraw_internal_data.unpacker_data.thumb_format == LIBRAW_INTERNAL_THUMBNAIL_JPEG; } int LibRaw::is_nikon_sraw() { return load_raw == &LibRaw::nikon_load_sraw; } int LibRaw::sraw_midpoint() { if (load_raw == &LibRaw::canon_sraw_load_raw) return 8192; else if (load_raw == &LibRaw::nikon_load_sraw) return 2048; else return 0; } void *LibRaw::malloc(size_t t) { void *p = memmgr.malloc(t); if (!p) throw LIBRAW_EXCEPTION_ALLOC; return p; } void *LibRaw::realloc(void *q, size_t t) { void *p = memmgr.realloc(q, t); if (!p) throw LIBRAW_EXCEPTION_ALLOC; return p; } void *LibRaw::calloc(size_t n, size_t t) { void *p = memmgr.calloc(n, t); if (!p) throw LIBRAW_EXCEPTION_ALLOC; return p; } void LibRaw::free(void *p) { memmgr.free(p); } void LibRaw::recycle_datastream() { if (libraw_internal_data.internal_data.input && libraw_internal_data.internal_data.input_internal) { delete libraw_internal_data.internal_data.input; libraw_internal_data.internal_data.input = NULL; } libraw_internal_data.internal_data.input_internal = 0; } void LibRaw::clearCancelFlag() { #ifdef _MSC_VER InterlockedExchange(&_exitflag, 0); #else __sync_fetch_and_and(&_exitflag, 0); #endif #ifdef RAWSPEED_FASTEXIT if (_rawspeed_decoder) { RawSpeed::RawDecoder *d = static_cast(_rawspeed_decoder); d->resumeProcessing(); } #endif } void LibRaw::setCancelFlag() { #ifdef _MSC_VER InterlockedExchange(&_exitflag, 1); #else __sync_fetch_and_add(&_exitflag, 1); #endif #ifdef RAWSPEED_FASTEXIT if (_rawspeed_decoder) { RawSpeed::RawDecoder *d = static_cast(_rawspeed_decoder); d->cancelProcessing(); } #endif } void LibRaw::checkCancel() { #ifdef _MSC_VER if (InterlockedExchange(&_exitflag, 0)) throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; #else if (__sync_fetch_and_and(&_exitflag, 0)) throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; #endif } int LibRaw::is_curve_linear() { for (int i = 0; i < 0x10000; i++) if (imgdata.color.curve[i] != i) return 0; return 1; } void LibRaw::free_image(void) { if (imgdata.image) { free(imgdata.image); imgdata.image = 0; imgdata.progress_flags = LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN | LIBRAW_PROGRESS_IDENTIFY | LIBRAW_PROGRESS_SIZE_ADJUST | LIBRAW_PROGRESS_LOAD_RAW; } } int LibRaw::is_phaseone_compressed() { return (load_raw == &LibRaw::phase_one_load_raw_c || load_raw == &LibRaw::phase_one_load_raw_s || load_raw == &LibRaw::phase_one_load_raw); } int LibRaw::is_canon_600() { return load_raw == &LibRaw::canon_600_load_raw; } const char *LibRaw::strprogress(enum LibRaw_progress p) { switch (p) { case LIBRAW_PROGRESS_START: return "Starting"; case LIBRAW_PROGRESS_OPEN: return "Opening file"; case LIBRAW_PROGRESS_IDENTIFY: return "Reading metadata"; case LIBRAW_PROGRESS_SIZE_ADJUST: return "Adjusting size"; case LIBRAW_PROGRESS_LOAD_RAW: return "Reading RAW data"; case LIBRAW_PROGRESS_REMOVE_ZEROES: return "Clearing zero values"; case LIBRAW_PROGRESS_BAD_PIXELS: return "Removing dead pixels"; case LIBRAW_PROGRESS_DARK_FRAME: return "Subtracting dark frame data"; case LIBRAW_PROGRESS_FOVEON_INTERPOLATE: return "Interpolating Foveon sensor data"; case LIBRAW_PROGRESS_SCALE_COLORS: return "Scaling colors"; case LIBRAW_PROGRESS_PRE_INTERPOLATE: return "Pre-interpolating"; case LIBRAW_PROGRESS_INTERPOLATE: return "Interpolating"; case LIBRAW_PROGRESS_MIX_GREEN: return "Mixing green channels"; case LIBRAW_PROGRESS_MEDIAN_FILTER: return "Median filter"; case LIBRAW_PROGRESS_HIGHLIGHTS: return "Highlight recovery"; case LIBRAW_PROGRESS_FUJI_ROTATE: return "Rotating Fuji diagonal data"; case LIBRAW_PROGRESS_FLIP: return "Flipping image"; case LIBRAW_PROGRESS_APPLY_PROFILE: return "ICC conversion"; case LIBRAW_PROGRESS_CONVERT_RGB: return "Converting to RGB"; case LIBRAW_PROGRESS_STRETCH: return "Stretching image"; case LIBRAW_PROGRESS_THUMB_LOAD: return "Loading thumbnail"; default: return "Some strange things"; } } int LibRaw::adjust_sizes_info_only(void) { CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY); raw2image_start(); if (O.use_fuji_rotate) { if (IO.fuji_width) { IO.fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink; S.iwidth = (ushort)(IO.fuji_width / sqrt(0.5)); S.iheight = (ushort)((S.iheight - IO.fuji_width) / sqrt(0.5)); } else { if (S.pixel_aspect < 0.995) S.iheight = (ushort)(S.iheight / S.pixel_aspect + 0.5); if (S.pixel_aspect > 1.005) S.iwidth = (ushort)(S.iwidth * S.pixel_aspect + 0.5); } } SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE); if (S.flip & 4) { unsigned short t = S.iheight; S.iheight = S.iwidth; S.iwidth = t; SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP); } return 0; } int LibRaw::adjust_maximum() { ushort real_max; float auto_threshold; if (O.adjust_maximum_thr < 0.00001) return LIBRAW_SUCCESS; else if (O.adjust_maximum_thr > 0.99999) auto_threshold = LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD; else auto_threshold = O.adjust_maximum_thr; real_max = C.data_maximum; if (real_max > 0 && real_max < C.maximum && real_max > C.maximum * auto_threshold) { C.maximum = real_max; } return LIBRAW_SUCCESS; } void LibRaw::adjust_bl() { int clear_repeat = 0; if (O.user_black >= 0) { C.black = O.user_black; clear_repeat = 1; } for (int i = 0; i < 4; i++) if (O.user_cblack[i] > -1000000) { C.cblack[i] = O.user_cblack[i]; clear_repeat = 1; } if (clear_repeat) C.cblack[4] = C.cblack[5] = 0; // Add common part to cblack[] early if (imgdata.idata.filters > 1000 && (C.cblack[4] + 1) / 2 == 1 && (C.cblack[5] + 1) / 2 == 1) { int clrs[4]; int lastg = -1, gcnt = 0; for (int c = 0; c < 4; c++) { clrs[c] = FC(c / 2, c % 2); if (clrs[c] == 1) { gcnt++; lastg = c; } } if (gcnt > 1 && lastg >= 0) clrs[lastg] = 3; for (int c = 0; c < 4; c++) C.cblack[clrs[c]] += C.cblack[6 + c / 2 % C.cblack[4] * C.cblack[5] + c % 2 % C.cblack[5]]; C.cblack[4] = C.cblack[5] = 0; // imgdata.idata.filters = sfilters; } else if (imgdata.idata.filters <= 1000 && C.cblack[4] == 1 && C.cblack[5] == 1) // Fuji RAF dng { for (int c = 0; c < 4; c++) C.cblack[c] += C.cblack[6]; C.cblack[4] = C.cblack[5] = 0; } // remove common part from C.cblack[] int i = C.cblack[3]; int c; for (c = 0; c < 3; c++) if (i > (int)C.cblack[c]) i = C.cblack[c]; for (c = 0; c < 4; c++) C.cblack[c] -= i; // remove common part C.black += i; // Now calculate common part for cblack[6+] part and move it to C.black if (C.cblack[4] && C.cblack[5]) { i = C.cblack[6]; for (c = 1; c < int(C.cblack[4] * C.cblack[5]); c++) if (i > int(C.cblack[6 + c])) i = C.cblack[6 + c]; // Remove i from cblack[6+] int nonz = 0; for (c = 0; c < int(C.cblack[4] * C.cblack[5]); c++) { C.cblack[6 + c] -= i; if (C.cblack[6 + c]) nonz++; } C.black += i; if (!nonz) C.cblack[4] = C.cblack[5] = 0; } for (c = 0; c < 4; c++) C.cblack[c] += C.black; } int LibRaw::getwords(char *line, char *words[], int maxwords, int maxlen) { line[maxlen - 1] = 0; unsigned char *p = (unsigned char*)line; int nwords = 0; while (1) { while (isspace(*p)) p++; if (*p == '\0') return nwords; words[nwords++] = (char*)p; while (!isspace(*p) && *p != '\0') p++; if (*p == '\0') return nwords; *p++ = '\0'; if (nwords >= maxwords) return nwords; } } int LibRaw::stread(char *buf, size_t len, LibRaw_abstract_datastream *fp) { if (len > 0) { int r = fp->read(buf, len, 1); buf[len - 1] = 0; return r; } else return 0; } int LibRaw::find_ifd_by_offset(int o) { for(unsigned i = 0; i < libraw_internal_data.identify_data.tiff_nifds && i < LIBRAW_IFD_MAXCOUNT; i++) if(tiff_ifd[i].offset == o) return i; return -1; } short LibRaw::tiff_sget (unsigned save, uchar *buf, unsigned buf_len, INT64 *tag_offset, unsigned *tag_id, unsigned *tag_type, INT64 *tag_dataoffset, unsigned *tag_datalen, int *tag_dataunitlen) { uchar *pos = buf + *tag_offset; if ((((*tag_offset) + 12) > buf_len) || (*tag_offset < 0)) { // abnormal, tag buffer overrun return -1; } *tag_id = sget2(pos); pos += 2; *tag_type = sget2(pos); pos += 2; *tag_datalen = sget4(pos); pos += 4; *tag_dataunitlen = tagtype_dataunit_bytes[(*tag_type <= LIBRAW_EXIFTAG_TYPE_IFD8) ? *tag_type : 0]; if ((*tag_datalen * (*tag_dataunitlen)) > 4) { *tag_dataoffset = sget4(pos) - save; if ((*tag_dataoffset + *tag_datalen) > buf_len) { // abnormal, tag data buffer overrun return -2; } } else *tag_dataoffset = *tag_offset + 8; *tag_offset += 12; return 0; } #define rICC imgdata.sizes.raw_inset_crops #define S imgdata.sizes #define RS imgdata.rawdata.sizes int LibRaw::adjust_to_raw_inset_crop(unsigned mask, float maxcrop) { int adjindex = -1; int limwidth = S.width * maxcrop; int limheight = S.height * maxcrop; for(int i = 1; i >= 0; i--) if (mask & (1<= limwidth && rICC[i].cheight >= limheight) { adjindex = i; break; } if (adjindex >= 0) { RS.left_margin = S.left_margin = rICC[adjindex].cleft; RS.top_margin = S.top_margin = rICC[adjindex].ctop; RS.width = S.width = MIN(rICC[adjindex].cwidth, int(S.raw_width) - int(S.left_margin)); RS.height = S.height = MIN(rICC[adjindex].cheight, int(S.raw_height) - int(S.top_margin)); } return adjindex + 1; } char** LibRaw::malloc_omp_buffers(int buffer_count, size_t buffer_size) { char** buffers = (char**)calloc(sizeof(char*), buffer_count); for (int i = 0; i < buffer_count; i++) { buffers[i] = (char*)calloc(buffer_size,1); } return buffers; } void LibRaw::free_omp_buffers(char** buffers, int buffer_count) { for (int i = 0; i < buffer_count; i++) if(buffers[i]) free(buffers[i]); free(buffers); } void LibRaw::libraw_swab(void *arr, size_t len) { #ifdef LIBRAW_OWN_SWAB uint16_t *array = (uint16_t*)arr; size_t bytes = len/2; for(; bytes; --bytes) { *array = ((*array << 8) & 0xff00) | ((*array >> 8) & 0xff); array++; } #else swab((char*)arr,(char*)arr,len); #endif } LibRaw-0.21.4/src/write/000077500000000000000000000000001477673233700147225ustar00rootroot00000000000000LibRaw-0.21.4/src/write/apply_profile.cpp000066400000000000000000000043151477673233700202760ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_fileio_defs.h" #ifndef NO_LCMS void LibRaw::apply_profile(const char *input, const char *output) { char *prof; cmsHPROFILE hInProfile = 0, hOutProfile = 0; cmsHTRANSFORM hTransform; FILE *fp; unsigned size; if (strcmp(input, "embed")) hInProfile = cmsOpenProfileFromFile(input, "r"); else if (profile_length) { hInProfile = cmsOpenProfileFromMem(imgdata.color.profile, profile_length); } else { imgdata.process_warnings |= LIBRAW_WARN_NO_EMBEDDED_PROFILE; } if (!hInProfile) { imgdata.process_warnings |= LIBRAW_WARN_NO_INPUT_PROFILE; return; } if (!output) hOutProfile = cmsCreate_sRGBProfile(); else if ((fp = fopen(output, "rb"))) { fread(&size, 4, 1, fp); fseek(fp, 0, SEEK_SET); oprof = (unsigned *)calloc(size = ntohl(size),1); fread(oprof, 1, size, fp); fclose(fp); if (!(hOutProfile = cmsOpenProfileFromMem(oprof, size))) { free(oprof); oprof = 0; } } if (!hOutProfile) { imgdata.process_warnings |= LIBRAW_WARN_BAD_OUTPUT_PROFILE; goto quit; } RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE, 0, 2); hTransform = cmsCreateTransform(hInProfile, TYPE_RGBA_16, hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0); cmsDoTransform(hTransform, image, image, width * height); raw_color = 1; /* Don't use rgb_cam with a profile */ cmsDeleteTransform(hTransform); cmsCloseProfile(hOutProfile); quit: cmsCloseProfile(hInProfile); RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE, 1, 2); } #endif LibRaw-0.21.4/src/write/file_write.cpp000066400000000000000000000251561477673233700175700ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/dcraw_defs.h" #include int LibRaw::flip_index(int row, int col) { if (flip & 4) SWAP(row, col); if (flip & 2) row = iheight - 1 - row; if (flip & 1) col = iwidth - 1 - col; return row * iwidth + col; } void LibRaw::tiff_set(struct tiff_hdr *th, ushort *ntag, ushort tag, ushort type, int count, int val) { struct libraw_tiff_tag *tt; int c; tt = (struct libraw_tiff_tag *)(ntag + 1) + (*ntag)++; tt->val.i = val; if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_BYTE) && count <= 4) FORC(4) tt->val.c[c] = val >> (c << 3); else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII)) { count = int(strnlen((char *)th + val, count - 1)) + 1; if (count <= 4) FORC(4) tt->val.c[c] = ((char *)th)[val + c]; } else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) && count <= 2) FORC(2) tt->val.s[c] = val >> (c << 4); tt->count = count; tt->type = type; tt->tag = tag; } #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th) void LibRaw::tiff_head(struct tiff_hdr *th, int full) { int c, psize = 0; struct tm *t; memset(th, 0, sizeof *th); th->t_order = htonl(0x4d4d4949) >> 16; th->magic = 42; th->ifd = 10; th->rat[0] = th->rat[2] = 300; th->rat[1] = th->rat[3] = 1; FORC(6) th->rat[4 + c] = 1000000; th->rat[4] *= shutter; th->rat[6] *= aperture; th->rat[8] *= focal_len; strncpy(th->t_desc, desc, 512); strncpy(th->t_make, make, 64); strncpy(th->t_model, model, 64); strcpy(th->soft, "dcraw v" DCRAW_VERSION); t = localtime(×tamp); sprintf(th->date, "%04d:%02d:%02d %02d:%02d:%02d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); strncpy(th->t_artist, artist, 64); if (full) { tiff_set(th, &th->ntag, 254, 4, 1, 0); tiff_set(th, &th->ntag, 256, 4, 1, width); tiff_set(th, &th->ntag, 257, 4, 1, height); tiff_set(th, &th->ntag, 258, 3, colors, output_bps); if (colors > 2) th->tag[th->ntag - 1].val.i = TOFF(th->bps); FORC4 th->bps[c] = output_bps; tiff_set(th, &th->ntag, 259, 3, 1, 1); tiff_set(th, &th->ntag, 262, 3, 1, 1 + (colors > 1)); } tiff_set(th, &th->ntag, 270, 2, 512, TOFF(th->t_desc)); tiff_set(th, &th->ntag, 271, 2, 64, TOFF(th->t_make)); tiff_set(th, &th->ntag, 272, 2, 64, TOFF(th->t_model)); if (full) { if (oprof) psize = ntohl(oprof[0]); tiff_set(th, &th->ntag, 273, 4, 1, sizeof *th + psize); tiff_set(th, &th->ntag, 277, 3, 1, colors); tiff_set(th, &th->ntag, 278, 4, 1, height); tiff_set(th, &th->ntag, 279, 4, 1, height * width * colors * output_bps / 8); } else tiff_set(th, &th->ntag, 274, 3, 1, "12435867"[flip] - '0'); tiff_set(th, &th->ntag, 282, 5, 1, TOFF(th->rat[0])); tiff_set(th, &th->ntag, 283, 5, 1, TOFF(th->rat[2])); tiff_set(th, &th->ntag, 284, 3, 1, 1); tiff_set(th, &th->ntag, 296, 3, 1, 2); tiff_set(th, &th->ntag, 305, 2, 32, TOFF(th->soft)); tiff_set(th, &th->ntag, 306, 2, 20, TOFF(th->date)); tiff_set(th, &th->ntag, 315, 2, 64, TOFF(th->t_artist)); tiff_set(th, &th->ntag, 34665, 4, 1, TOFF(th->nexif)); if (psize) tiff_set(th, &th->ntag, 34675, 7, psize, sizeof *th); tiff_set(th, &th->nexif, 33434, 5, 1, TOFF(th->rat[4])); tiff_set(th, &th->nexif, 33437, 5, 1, TOFF(th->rat[6])); tiff_set(th, &th->nexif, 34855, 3, 1, iso_speed); tiff_set(th, &th->nexif, 37386, 5, 1, TOFF(th->rat[8])); if (gpsdata[1]) { uchar latref[4] = { (uchar)(gpsdata[29]),0,0,0 }, lonref[4] = { (uchar)(gpsdata[30]),0,0,0 }; tiff_set(th, &th->ntag, 34853, 4, 1, TOFF(th->ngps)); tiff_set(th, &th->ngps, 0, 1, 4, 0x202); tiff_set(th, &th->ngps, 1, 2, 2, TOFF(latref)); tiff_set(th, &th->ngps, 2, 5, 3, TOFF(th->gps[0])); tiff_set(th, &th->ngps, 3, 2, 2, TOFF(lonref)); tiff_set(th, &th->ngps, 4, 5, 3, TOFF(th->gps[6])); tiff_set(th, &th->ngps, 5, 1, 1, gpsdata[31]); tiff_set(th, &th->ngps, 6, 5, 1, TOFF(th->gps[18])); tiff_set(th, &th->ngps, 7, 5, 3, TOFF(th->gps[12])); tiff_set(th, &th->ngps, 18, 2, 12, TOFF(th->gps[20])); tiff_set(th, &th->ngps, 29, 2, 12, TOFF(th->gps[23])); memcpy(th->gps, gpsdata, sizeof th->gps); } } void LibRaw::jpeg_thumb_writer(FILE *tfp, char *t_humb, int t_humb_length) { ushort exif[5]; struct tiff_hdr th; fputc(0xff, tfp); fputc(0xd8, tfp); if (strcmp(t_humb + 6, "Exif")) { memcpy(exif, "\xff\xe1 Exif\0\0", 10); exif[1] = htons(8 + sizeof th); fwrite(exif, 1, sizeof exif, tfp); tiff_head(&th, 0); fwrite(&th, 1, sizeof th, tfp); } fwrite(t_humb + 2, 1, t_humb_length - 2, tfp); } void LibRaw::write_ppm_tiff() { try { struct tiff_hdr th; ushort *ppm2; int c, row, col, soff, rstep, cstep; int perc, val, total, t_white = 0x2000; perc = width * height * auto_bright_thr; if (fuji_width) perc /= 2; if (!((highlight & ~2) || no_auto_bright)) for (t_white = c = 0; c < colors; c++) { for (val = 0x2000, total = 0; --val > 32;) if ((total += histogram[c][val]) > perc) break; if (t_white < val) t_white = val; } gamma_curve(gamm[0], gamm[1], 2, (t_white << 3) / bright); iheight = height; iwidth = width; if (flip & 4) SWAP(height, width); std::vector ppm(width * colors * output_bps / 8); ppm2 = (ushort *)ppm.data(); if (output_tiff) { tiff_head(&th, 1); fwrite(&th, sizeof th, 1, ofp); if (oprof) fwrite(oprof, ntohl(oprof[0]), 1, ofp); } else if (colors > 3) { if(imgdata.params.output_flags & LIBRAW_OUTPUT_FLAGS_PPMMETA) fprintf(ofp, "P7\n# EXPTIME=%0.5f\n# TIMESTAMP=%d\n# ISOSPEED=%d\n" "# APERTURE=%0.1f\n# FOCALLEN=%0.1f\n# MAKE=%s\n# MODEL=%s\n" "WIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", shutter, (int)timestamp, (int)iso_speed,aperture, focal_len, make, model, width, height, colors, (1 << output_bps) - 1, cdesc); else fprintf( ofp, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", width, height, colors, (1 << output_bps) - 1, cdesc); } else { if(imgdata.params.output_flags & LIBRAW_OUTPUT_FLAGS_PPMMETA) fprintf(ofp, "P%d\n# EXPTIME=%0.5f\n# TIMESTAMP=%d\n" "# ISOSPEED=%d\n# APERTURE=%0.1f\n# FOCALLEN=%0.1f\n" "# MAKE=%s\n# MODEL=%s\n%d %d\n%d\n", colors/2+5, shutter, (int)timestamp, (int)iso_speed,aperture,focal_len, make,model, width, height, (1 << output_bps)-1); else fprintf(ofp, "P%d\n%d %d\n%d\n", colors / 2 + 5, width, height, (1 << output_bps) - 1); } soff = flip_index(0, 0); cstep = flip_index(0, 1) - soff; rstep = flip_index(1, 0) - flip_index(0, width); for (row = 0; row < height; row++, soff += rstep) { for (col = 0; col < width; col++, soff += cstep) if (output_bps == 8) FORCC ppm[col * colors + c] = curve[image[soff][c]] >> 8; else FORCC ppm2[col * colors + c] = curve[image[soff][c]]; if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa) libraw_swab(ppm2, width * colors * 2); fwrite(ppm.data(), colors * output_bps / 8, width, ofp); } } catch (...) { throw LIBRAW_EXCEPTION_ALLOC; // rethrow } } #if 0 void LibRaw::ppm_thumb() { try { thumb_length = thumb_width * thumb_height * 3; std::vector thumb(thumb_length); fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); fread(thumb.data(), 1, thumb_length, ifp); fwrite(thumb.data(), 1, thumb_length, ofp); } catch (...) { throw LIBRAW_EXCEPTION_ALLOC; // rethrow } } void LibRaw::ppm16_thumb() { try { unsigned i; thumb_length = thumb_width * thumb_height * 3; std::vector thumb(thumb_length * 2, 0); read_shorts((ushort *)thumb.data(), thumb_length); for (i = 0; i < thumb_length; i++) thumb[i] = ((ushort *)thumb.data())[i] >> 8; fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); fwrite(thumb.data(), 1, thumb_length, ofp); } catch (...) { throw LIBRAW_EXCEPTION_ALLOC; // rethrow } } void LibRaw::layer_thumb() { try { unsigned int i; int c; char map[][4] = { "012", "102" }; colors = thumb_misc >> 5 & 7; thumb_length = thumb_width * thumb_height; std::vector thumb(colors * thumb_length, 0); fprintf(ofp, "P%d\n%d %d\n255\n", 5 + (colors >> 1), thumb_width, thumb_height); fread(thumb.data(), thumb_length, colors, ifp); for (i = 0; i < thumb_length; i++) FORCC putc(thumb[i + thumb_length * (map[thumb_misc >> 8][c] - '0')], ofp); } catch (...) { throw LIBRAW_EXCEPTION_ALLOC; // rethrow } } void LibRaw::rollei_thumb() { try { unsigned i; thumb_length = thumb_width * thumb_height; std::vector thumb(thumb_length, 0); fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); read_shorts(thumb.data(), thumb_length); for (i = 0; i < thumb_length; i++) { putc(thumb[i] << 3, ofp); putc(thumb[i] >> 5 << 2, ofp); putc(thumb[i] >> 11 << 3, ofp); } } catch (...) { throw LIBRAW_EXCEPTION_ALLOC; // rethrow } } void LibRaw::jpeg_thumb() { try { std::vector thumb(thumb_length); fread(thumb.data(), 1, thumb_length, ifp); jpeg_thumb_writer(ofp, thumb.data(), thumb_length); } catch (...) { throw LIBRAW_EXCEPTION_ALLOC; // rethrow } } #endif LibRaw-0.21.4/src/write/tiff_writer.cpp000066400000000000000000000035271477673233700177610ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. LibRaw do not use RESTRICTED code from dcraw.c 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 "../../internal/libraw_cxx_defs.h" int LibRaw::dcraw_ppm_tiff_writer(const char *filename) { CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW); if (!imgdata.image) return LIBRAW_OUT_OF_ORDER_CALL; if (!filename) return ENOENT; FILE *f = NULL; if (!strcmp(filename, "-")) { #ifdef LIBRAW_WIN32_CALLS _setmode(_fileno(stdout), _O_BINARY); #endif f = stdout; } else f = fopen(filename, "wb"); if (!f) return errno; try { if (!libraw_internal_data.output_data.histogram) { libraw_internal_data.output_data.histogram = (int(*)[LIBRAW_HISTOGRAM_SIZE])malloc( sizeof(*libraw_internal_data.output_data.histogram) * 4); } libraw_internal_data.internal_data.output = f; write_ppm_tiff(); SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP); libraw_internal_data.internal_data.output = NULL; if (strcmp(filename, "-")) fclose(f); return 0; } catch (const LibRaw_exceptions& err) { if (strcmp(filename, "-")) fclose(f); EXCEPTION_HANDLER(err); } catch (const std::bad_alloc&) { if (strcmp(filename, "-")) fclose(f); EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); } } LibRaw-0.21.4/src/write/write_ph.cpp000066400000000000000000000020551477673233700172510ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 LibRaw LLC (info@libraw.org) * Placeholder functions to build LibRaw w/o postprocessing and preprocessing calls 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 "../../internal/dcraw_defs.h" int LibRaw::flip_index(int row, int col) { if (flip & 4) SWAP(row, col); if (flip & 2) row = iheight - 1 - row; if (flip & 1) col = iwidth - 1 - col; return row * iwidth + col; } void LibRaw::write_ppm_tiff(){} void LibRaw::jpeg_thumb_writer(FILE *tfp, char *t_humb, int t_humb_length){} #if 0 void LibRaw::ppm_thumb(){} void LibRaw::jpeg_thumb(){} void LibRaw::rollei_thumb(){} void LibRaw::ppm16_thumb(){} void LibRaw::layer_thumb(){} #endifLibRaw-0.21.4/src/x3f/000077500000000000000000000000001477673233700142705ustar00rootroot00000000000000LibRaw-0.21.4/src/x3f/x3f_parse_process.cpp000066400000000000000000000573631477673233700204420ustar00rootroot00000000000000/* -*- C++ -*- * Copyright 2019-2021 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). */ /* Library for accessing X3F Files ---------------------------------------------------------------- BSD-style License ---------------------------------------------------------------- * Copyright (c) 2010, Roland Karlsson (roland@proxel.se) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the organization nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY ROLAND KARLSSON ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL ROLAND KARLSSON BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef USE_X3FTOOLS #include "../../internal/libraw_cxx_defs.h" #if defined __sun && defined DS #undef DS #endif #ifdef ID #undef ID /* used in x3f utils */ #endif #include "../../internal/x3f_tools.h" #define Sigma_X3F 22 void x3f_clear(void *p) { x3f_delete((x3f_t *)p); } static void utf2char(utf16_t *str, char *buffer, unsigned bufsz) { if (bufsz < 1) return; buffer[bufsz - 1] = 0; char *b = buffer; while (*str != 0x00 && --bufsz > 0) { char *chr = (char *)str; *b++ = *chr; str++; } *b = 0; } static void *lr_memmem(const void *l, size_t l_len, const void *s, size_t s_len) { char *cur, *last; const char *cl = (const char *)l; const char *cs = (const char *)s; /* we need something to compare */ if (l_len == 0 || s_len == 0) return NULL; /* "s" must be smaller or equal to "l" */ if (l_len < s_len) return NULL; /* special case where s_len == 1 */ if (s_len == 1) return (void *)memchr(l, (int)*cs, l_len); /* the last position where its possible to find "s" in "l" */ last = (char *)cl + l_len - s_len; for (cur = (char *)cl; cur <= last; cur++) if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) return cur; return NULL; } void LibRaw::parse_x3f() { x3f_t *x3f = x3f_new_from_file(libraw_internal_data.internal_data.input); if (!x3f) return; _x3f_data = x3f; x3f_header_t *H = NULL; H = &x3f->header; // Parse RAW size from RAW section x3f_directory_entry_t *DE = x3f_get_raw(x3f); if (!DE) return; imgdata.sizes.flip = H->rotation; x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; imgdata.sizes.raw_width = ID->columns; imgdata.sizes.raw_height = ID->rows; // Parse other params from property section DE = x3f_get_prop(x3f); if ((x3f_load_data(x3f, DE) == X3F_OK)) { // Parse property list DEH = &DE->header; x3f_property_list_t *PL = &DEH->data_subsection.property_list; utf16_t *datap = (utf16_t *)PL->data; uint32_t maxitems = PL->data_size / sizeof(utf16_t); if (PL->property_table.size != 0) { int i; x3f_property_t *P = PL->property_table.element; for (i = 0; i < (int)PL->num_properties; i++) { char name[100], value[100]; int noffset = (P[i].name - datap); int voffset = (P[i].value - datap); if (noffset < 0 || noffset > (int)maxitems || voffset < 0 || voffset > (int)maxitems) throw LIBRAW_EXCEPTION_IO_CORRUPT; int maxnsize = maxitems - (P[i].name - datap); int maxvsize = maxitems - (P[i].value - datap); utf2char(P[i].name, name, MIN(maxnsize, ((int)sizeof(name)))); utf2char(P[i].value, value, MIN(maxvsize, ((int)sizeof(value)))); if (!strcmp(name, "ISO")) imgdata.other.iso_speed = atoi(value); if (!strcmp(name, "CAMMANUF")) strcpy(imgdata.idata.make, value); if (!strcmp(name, "CAMMODEL")) strcpy(imgdata.idata.model, value); if (!strcmp(name, "CAMSERIAL")) strcpy(imgdata.shootinginfo.BodySerial, value); if (!strcmp(name, "WB_DESC")) strcpy(imgdata.color.model2, value); if (!strcmp(name, "TIME")) imgdata.other.timestamp = atoi(value); if (!strcmp(name, "SHUTTER")) imgdata.other.shutter = atof(value); if (!strcmp(name, "APERTURE")) imgdata.other.aperture = atof(value); if (!strcmp(name, "FLENGTH")) imgdata.other.focal_len = atof(value); if (!strcmp(name, "FLEQ35MM")) imgdata.lens.makernotes.FocalLengthIn35mmFormat = atof(value); if (!strcmp(name, "IMAGERTEMP")) MN.common.SensorTemperature = atof(value); if (!strcmp(name, "LENSARANGE")) { char *sp; imgdata.lens.makernotes.MaxAp4CurFocal = imgdata.lens.makernotes.MinAp4CurFocal = atof(value); sp = strrchr(value, ' '); if (sp) { imgdata.lens.makernotes.MinAp4CurFocal = atof(sp); if (imgdata.lens.makernotes.MaxAp4CurFocal > imgdata.lens.makernotes.MinAp4CurFocal) my_swap(float, imgdata.lens.makernotes.MaxAp4CurFocal, imgdata.lens.makernotes.MinAp4CurFocal); } } if (!strcmp(name, "LENSFRANGE")) { char *sp; imgdata.lens.makernotes.MinFocal = imgdata.lens.makernotes.MaxFocal = atof(value); sp = strrchr(value, ' '); if (sp) { imgdata.lens.makernotes.MaxFocal = atof(sp); if ((imgdata.lens.makernotes.MaxFocal + 0.17f) < imgdata.lens.makernotes.MinFocal) my_swap(float, imgdata.lens.makernotes.MaxFocal, imgdata.lens.makernotes.MinFocal); } } if (!strcmp(name, "LENSMODEL")) { char *sp; imgdata.lens.makernotes.LensID = strtol(value, &sp, 16); // atoi(value); if (imgdata.lens.makernotes.LensID) imgdata.lens.makernotes.LensMount = Sigma_X3F; } } imgdata.idata.raw_count = 1; load_raw = &LibRaw::x3f_load_raw; imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 6; imgdata.idata.is_foveon = 1; libraw_internal_data.internal_output_params.raw_color = 1; // Force adobe coeff imgdata.color.maximum = 0x3fff; // To be reset by color table libraw_internal_data.unpacker_data.order = 0x4949; } } else { // No property list if (imgdata.sizes.raw_width == 5888 || imgdata.sizes.raw_width == 2944 || imgdata.sizes.raw_width == 6656 || imgdata.sizes.raw_width == 3328 || imgdata.sizes.raw_width == 5504 || imgdata.sizes.raw_width == 2752) // Quattro { imgdata.idata.raw_count = 1; load_raw = &LibRaw::x3f_load_raw; imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 6; imgdata.idata.is_foveon = 1; libraw_internal_data.internal_output_params.raw_color = 1; // Force adobe coeff libraw_internal_data.unpacker_data.order = 0x4949; strcpy(imgdata.idata.make, "SIGMA"); #if 1 // Try to find model number in first 2048 bytes; int pos = libraw_internal_data.internal_data.input->tell(); libraw_internal_data.internal_data.input->seek(0, SEEK_SET); unsigned char buf[2048]; libraw_internal_data.internal_data.input->read(buf, 2048, 1); libraw_internal_data.internal_data.input->seek(pos, SEEK_SET); unsigned char *fnd = (unsigned char *)lr_memmem(buf, 2048, "SIGMA dp", 8); unsigned char *fndsd = (unsigned char *)lr_memmem(buf, 2048, "sd Quatt", 8); if (fnd) { unsigned char *nm = fnd + 8; snprintf(imgdata.idata.model, 64, "dp%c Quattro", *nm <= '9' && *nm >= '0' ? *nm : '2'); } else if (fndsd) { snprintf(imgdata.idata.model, 64, "%s", fndsd); } else #endif if (imgdata.sizes.raw_width == 6656 || imgdata.sizes.raw_width == 3328) strcpy(imgdata.idata.model, "sd Quattro H"); else strcpy(imgdata.idata.model, "dp2 Quattro"); } // else } // Try to get thumbnail data LibRaw_thumbnail_formats format = LIBRAW_THUMBNAIL_UNKNOWN; if ((DE = x3f_get_thumb_jpeg(x3f))) { format = LIBRAW_THUMBNAIL_JPEG; } else if ((DE = x3f_get_thumb_plain(x3f))) { format = LIBRAW_THUMBNAIL_BITMAP; } if (DE) { x3f_directory_entry_header_t *_DEH = &DE->header; x3f_image_data_t *_ID = &_DEH->data_subsection.image_data; imgdata.thumbnail.twidth = _ID->columns; imgdata.thumbnail.theight = _ID->rows; imgdata.thumbnail.tcolors = 3; imgdata.thumbnail.tformat = format; libraw_internal_data.internal_data.toffset = DE->input.offset; libraw_internal_data.unpacker_data.thumb_format = LIBRAW_INTERNAL_THUMBNAIL_X3F; } DE = x3f_get_camf(x3f); if (DE && DE->input.size > 28) { libraw_internal_data.unpacker_data.meta_offset = DE->input.offset + 8; libraw_internal_data.unpacker_data.meta_length = DE->input.size - 28; } } INT64 LibRaw::x3f_thumb_size() { try { x3f_t *x3f = (x3f_t *)_x3f_data; if (!x3f) return -1; // No data pointer set x3f_directory_entry_t *DE = x3f_get_thumb_jpeg(x3f); if (!DE) DE = x3f_get_thumb_plain(x3f); if (!DE) return -1; int64_t p = x3f_load_data_size(x3f, DE); if (p < 0 || p > 0xffffffff) return -1; return p; } catch (...) { return -1; } } void LibRaw::x3f_thumb_loader() { try { x3f_t *x3f = (x3f_t *)_x3f_data; if (!x3f) return; // No data pointer set x3f_directory_entry_t *DE = x3f_get_thumb_jpeg(x3f); if (!DE) DE = x3f_get_thumb_plain(x3f); if (!DE) return; if (X3F_OK != x3f_load_data(x3f, DE)) throw LIBRAW_EXCEPTION_IO_CORRUPT; x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; imgdata.thumbnail.twidth = ID->columns; imgdata.thumbnail.theight = ID->rows; imgdata.thumbnail.tcolors = 3; if (imgdata.thumbnail.tformat == LIBRAW_THUMBNAIL_JPEG) { imgdata.thumbnail.thumb = (char *)malloc(ID->data_size); memmove(imgdata.thumbnail.thumb, ID->data, ID->data_size); imgdata.thumbnail.tlength = ID->data_size; } else if (imgdata.thumbnail.tformat == LIBRAW_THUMBNAIL_BITMAP) { imgdata.thumbnail.tlength = ID->columns * ID->rows * 3; imgdata.thumbnail.thumb = (char *)malloc(ID->columns * ID->rows * 3); char *src0 = (char *)ID->data; for (int row = 0; row < (int)ID->rows; row++) { int offset = row * ID->row_stride; if (offset + ID->columns * 3 > ID->data_size) break; char *dest = &imgdata.thumbnail.thumb[row * ID->columns * 3]; char *src = &src0[offset]; memmove(dest, src, ID->columns * 3); } } } catch (...) { // do nothing } } void LibRaw::x3f_dpq_interpolate_rg() { int w = imgdata.sizes.raw_width / 2; int h = imgdata.sizes.raw_height / 2; unsigned short *image = (ushort *)imgdata.rawdata.color3_image; for (int color = 0; color < 2; color++) { for (int y = 2; y < (h - 2); y++) { uint16_t *row0 = &image[imgdata.sizes.raw_width * 3 * (y * 2) + color]; // dst[1] uint16_t *row1 = &image[imgdata.sizes.raw_width * 3 * (y * 2 + 1) + color]; // dst1[1] for (int x = 2; x < (w - 2); x++) { row1[0] = row1[3] = row0[3] = row0[0]; row0 += 6; row1 += 6; } } } } #ifdef _ABS #undef _ABS #endif #define _ABS(a) ((a) < 0 ? -(a) : (a)) #undef CLIP #define CLIP(value, high) ((value) > (high) ? (high) : (value)) void LibRaw::x3f_dpq_interpolate_af(int xstep, int ystep, int scale) { unsigned short *image = (ushort *)imgdata.rawdata.color3_image; for (int y = 0; y < imgdata.rawdata.sizes.height + imgdata.rawdata.sizes.top_margin; y += ystep) { if (y < imgdata.rawdata.sizes.top_margin) continue; if (y < scale) continue; if (y > imgdata.rawdata.sizes.raw_height - scale) break; uint16_t *row0 = &image[imgdata.sizes.raw_width * 3 * y]; // Ðаша Ñтрока uint16_t *row_minus = &image[imgdata.sizes.raw_width * 3 * (y - scale)]; // Строка выше uint16_t *row_plus = &image[imgdata.sizes.raw_width * 3 * (y + scale)]; // Строка ниже for (int x = 0; x < imgdata.rawdata.sizes.width + imgdata.rawdata.sizes.left_margin; x += xstep) { if (x < imgdata.rawdata.sizes.left_margin) continue; if (x < scale) continue; if (x > imgdata.rawdata.sizes.raw_width - scale) break; uint16_t *pixel0 = &row0[x * 3]; uint16_t *pixel_top = &row_minus[x * 3]; uint16_t *pixel_bottom = &row_plus[x * 3]; uint16_t *pixel_left = &row0[(x - scale) * 3]; uint16_t *pixel_right = &row0[(x + scale) * 3]; uint16_t *pixf = pixel_top; if (_ABS(pixf[2] - pixel0[2]) > _ABS(pixel_bottom[2] - pixel0[2])) pixf = pixel_bottom; if (_ABS(pixf[2] - pixel0[2]) > _ABS(pixel_left[2] - pixel0[2])) pixf = pixel_left; if (_ABS(pixf[2] - pixel0[2]) > _ABS(pixel_right[2] - pixel0[2])) pixf = pixel_right; int blocal = pixel0[2], bnear = pixf[2]; if (blocal < (int)imgdata.color.black + 16 || bnear < (int)imgdata.color.black + 16) { if (pixel0[0] < imgdata.color.black) pixel0[0] = imgdata.color.black; if (pixel0[1] < imgdata.color.black) pixel0[1] = imgdata.color.black; pixel0[0] = CLIP( (pixel0[0] - imgdata.color.black) * 4 + imgdata.color.black, 16383); pixel0[1] = CLIP( (pixel0[1] - imgdata.color.black) * 4 + imgdata.color.black, 16383); } else { float multip = float(bnear - imgdata.color.black) / float(blocal - imgdata.color.black); if (pixel0[0] < imgdata.color.black) pixel0[0] = imgdata.color.black; if (pixel0[1] < imgdata.color.black) pixel0[1] = imgdata.color.black; float pixf0 = pixf[0]; if (pixf0 < imgdata.color.black) pixf0 = imgdata.color.black; float pixf1 = pixf[1]; if (pixf1 < imgdata.color.black) pixf1 = imgdata.color.black; pixel0[0] = CLIP( ((float(pixf0 - imgdata.color.black) * multip + imgdata.color.black) + ((pixel0[0] - imgdata.color.black) * 3.75 + imgdata.color.black)) / 2, 16383); pixel0[1] = CLIP( ((float(pixf1 - imgdata.color.black) * multip + imgdata.color.black) + ((pixel0[1] - imgdata.color.black) * 3.75 + imgdata.color.black)) / 2, 16383); // pixel0[1] = float(pixf[1]-imgdata.color.black)*multip + // imgdata.color.black; } } } } void LibRaw::x3f_dpq_interpolate_af_sd(int xstart, int ystart, int xend, int yend, int xstep, int ystep, int scale) { unsigned short *image = (ushort *)imgdata.rawdata.color3_image; for (int y = ystart; y <= yend && y < imgdata.rawdata.sizes.height + imgdata.rawdata.sizes.top_margin; y += ystep) { uint16_t *row0 = &image[imgdata.sizes.raw_width * 3 * y]; // Ðаша Ñтрока uint16_t *row1 = &image[imgdata.sizes.raw_width * 3 * (y + 1)]; // Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ñтрока uint16_t *row_minus = &image[imgdata.sizes.raw_width * 3 * (y - scale)]; // Строка выше uint16_t *row_plus = &image[imgdata.sizes.raw_width * 3 * (y + scale)]; // Строка ниже AF-point (scale=2 -> ниже row1 uint16_t *row_minus1 = &image[imgdata.sizes.raw_width * 3 * (y - 1)]; for (int x = xstart; x < xend && x < imgdata.rawdata.sizes.width + imgdata.rawdata.sizes.left_margin; x += xstep) { uint16_t *pixel00 = &row0[x * 3]; // Current pixel float sumR = 0.f, sumG = 0.f; float cnt = 0.f; for (int xx = -scale; xx <= scale; xx += scale) { sumR += row_minus[(x + xx) * 3]; sumR += row_plus[(x + xx) * 3]; sumG += row_minus[(x + xx) * 3 + 1]; sumG += row_plus[(x + xx) * 3 + 1]; cnt += 1.f; if (xx) { cnt += 1.f; sumR += row0[(x + xx) * 3]; sumG += row0[(x + xx) * 3 + 1]; } } pixel00[0] = sumR / 8.f; pixel00[1] = sumG / 8.f; if (scale == 2) { uint16_t *pixel0B = &row0[x * 3 + 3]; // right pixel uint16_t *pixel1B = &row1[x * 3 + 3]; // right pixel float sumG0 = 0, sumG1 = 0.f; float _cnt = 0.f; for (int xx = -scale; xx <= scale; xx += scale) { sumG0 += row_minus1[(x + xx) * 3 + 2]; sumG1 += row_plus[(x + xx) * 3 + 2]; _cnt += 1.f; if (xx) { sumG0 += row0[(x + xx) * 3 + 2]; sumG1 += row1[(x + xx) * 3 + 2]; _cnt += 1.f; } } if (_cnt > 1.0) { pixel0B[2] = sumG0 / _cnt; pixel1B[2] = sumG1 / _cnt; } } // uint16_t* pixel10 = &row1[x*3]; // Pixel below current // uint16_t* pixel_bottom = &row_plus[x*3]; } } } void LibRaw::x3f_load_raw() { // already in try/catch int raise_error = 0; x3f_t *x3f = (x3f_t *)_x3f_data; if (!x3f) return; // No data pointer set if (X3F_OK == x3f_load_data(x3f, x3f_get_raw(x3f))) { x3f_directory_entry_t *DE = x3f_get_raw(x3f); x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; if (!ID) throw LIBRAW_EXCEPTION_IO_CORRUPT; x3f_quattro_t *Q = ID->quattro; x3f_huffman_t *HUF = ID->huffman; x3f_true_t *TRU = ID->tru; uint16_t *data = NULL; if (ID->rows != S.raw_height || ID->columns != S.raw_width) { raise_error = 1; goto end; } if (HUF != NULL) data = HUF->x3rgb16.data; if (TRU != NULL) data = TRU->x3rgb16.data; if (data == NULL) { raise_error = 1; goto end; } size_t datasize = S.raw_height * S.raw_width * 3 * sizeof(unsigned short); S.raw_pitch = S.raw_width * 3 * sizeof(unsigned short); if (!(imgdata.rawdata.raw_alloc = malloc(datasize))) throw LIBRAW_EXCEPTION_ALLOC; imgdata.rawdata.color3_image = (ushort(*)[3])imgdata.rawdata.raw_alloc; // swap R/B channels for known old cameras if (!strcasecmp(P1.make, "Polaroid") && !strcasecmp(P1.model, "x530")) { ushort(*src)[3] = (ushort(*)[3])data; for (int p = 0; p < S.raw_height * S.raw_width; p++) { imgdata.rawdata.color3_image[p][0] = src[p][2]; imgdata.rawdata.color3_image[p][1] = src[p][1]; imgdata.rawdata.color3_image[p][2] = src[p][0]; } } else if (HUF) memmove(imgdata.rawdata.raw_alloc, data, datasize); else if (TRU && (!Q || !Q->quattro_layout)) memmove(imgdata.rawdata.raw_alloc, data, datasize); else if (TRU && Q) { // Move quattro data in place // R/B plane for (int prow = 0; prow < (int)TRU->x3rgb16.rows && prow < S.raw_height / 2; prow++) { ushort(*destrow)[3] = (unsigned short(*)[3]) & imgdata.rawdata .color3_image[prow * 2 * S.raw_pitch / 3 / sizeof(ushort)][0]; ushort(*srcrow)[3] = (unsigned short(*)[3]) & data[prow * TRU->x3rgb16.row_stride]; for (int pcol = 0; pcol < (int)TRU->x3rgb16.columns && pcol < S.raw_width / 2; pcol++) { destrow[pcol * 2][0] = srcrow[pcol][0]; destrow[pcol * 2][1] = srcrow[pcol][1]; } } for (int row = 0; row < (int)Q->top16.rows && row < S.raw_height; row++) { ushort(*destrow)[3] = (unsigned short(*)[3]) & imgdata.rawdata .color3_image[row * S.raw_pitch / 3 / sizeof(ushort)][0]; ushort *srcrow = (unsigned short *)&Q->top16.data[row * Q->top16.columns]; for (int col = 0; col < (int)Q->top16.columns && col < S.raw_width; col++) destrow[col][2] = srcrow[col]; } } #if 1 if (TRU && Q && !(imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATEAF)) { if (imgdata.sizes.raw_width == 5888 && imgdata.sizes.raw_height == 3672) // dpN Quattro normal { x3f_dpq_interpolate_af(32, 8, 2); } else if (imgdata.sizes.raw_width == 5888 && imgdata.sizes.raw_height == 3776) // sd Quattro normal raw { x3f_dpq_interpolate_af_sd(216, 464, imgdata.sizes.raw_width - 1, 3312, 16, 32, 2); } else if (imgdata.sizes.raw_width == 6656 && imgdata.sizes.raw_height == 4480) // sd Quattro H normal raw { x3f_dpq_interpolate_af_sd(232, 592, imgdata.sizes.raw_width - 1, 3920, 16, 32, 2); } else if (imgdata.sizes.raw_width == 3328 && imgdata.sizes.raw_height == 2240) // sd Quattro H half size { x3f_dpq_interpolate_af_sd(116, 296, imgdata.sizes.raw_width - 1, 2200, 8, 16, 1); } else if (imgdata.sizes.raw_width == 5504 && imgdata.sizes.raw_height == 3680) // sd Quattro H APS-C raw { x3f_dpq_interpolate_af_sd(8, 192, imgdata.sizes.raw_width - 1, 3185, 16, 32, 2); } else if (imgdata.sizes.raw_width == 2752 && imgdata.sizes.raw_height == 1840) // sd Quattro H APS-C half size { x3f_dpq_interpolate_af_sd(4, 96, imgdata.sizes.raw_width - 1, 1800, 8, 16, 1); } else if (imgdata.sizes.raw_width == 2944 && imgdata.sizes.raw_height == 1836) // dpN Quattro small raw { x3f_dpq_interpolate_af(16, 4, 1); } else if (imgdata.sizes.raw_width == 2944 && imgdata.sizes.raw_height == 1888) // sd Quattro small { x3f_dpq_interpolate_af_sd(108, 232, imgdata.sizes.raw_width - 1, 1656, 8, 16, 1); } } #endif if (TRU && Q && Q->quattro_layout && !(imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATERG)) x3f_dpq_interpolate_rg(); } else raise_error = 1; end: if (raise_error) throw LIBRAW_EXCEPTION_IO_CORRUPT; } #endif LibRaw-0.21.4/src/x3f/x3f_utils_patched.cpp000066400000000000000000001637751477673233700204270ustar00rootroot00000000000000#ifdef USE_X3FTOOLS /* Library for accessing X3F Files ---------------------------------------------------------------- BSD-style License ---------------------------------------------------------------- * Copyright (c) 2010, Roland Karlsson (roland@proxel.se) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the organization nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY ROLAND KARLSSON ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL ROLAND KARLSSON BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "../../internal/libraw_cxx_defs.h" #if defined __sun && defined DS #undef DS #endif #ifdef ID #undef ID /* used in x3f utils */ #endif #include "../../internal/x3f_tools.h" /* extern */ int legacy_offset = 0; /* extern */ bool_t auto_legacy_offset = 1; /* --------------------------------------------------------------------- */ /* Reading and writing - assuming little endian in the file */ /* --------------------------------------------------------------------- */ static int x3f_get1(LibRaw_abstract_datastream *f) { /* Little endian file */ return f->get_char(); } static int x3f_sget2(uchar *s) { return s[0] | s[1] << 8; } static int x3f_get2(LibRaw_abstract_datastream *f) { uchar str[2] = {0xff, 0xff}; f->read(str, 1, 2); return x3f_sget2(str); } unsigned x3f_sget4(uchar *s) { return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; } unsigned x3f_get4(LibRaw_abstract_datastream *f) { uchar str[4] = {0xff, 0xff, 0xff, 0xff}; f->read(str, 1, 4); return x3f_sget4(str); } #define FREE(P) \ do \ { \ free(P); \ (P) = NULL; \ } while (0) #define PUT_GET_N(_buffer, _size, _file, _func) \ do \ { \ int _left = _size; \ while (_left != 0) \ { \ int _cur = _file->_func(_buffer, 1, _left); \ if (_cur == 0) \ { \ throw LIBRAW_EXCEPTION_IO_CORRUPT; \ } \ _left -= _cur; \ } \ } while (0) #define GET1(_v) \ do \ { \ (_v) = x3f_get1(I->input.file); \ } while (0) #define GET2(_v) \ do \ { \ (_v) = x3f_get2(I->input.file); \ } while (0) #define GET4(_v) \ do \ { \ (_v) = x3f_get4(I->input.file); \ } while (0) #define GET4F(_v) \ do \ { \ union { \ int32_t i; \ float f; \ } _tmp; \ _tmp.i = x3f_get4(I->input.file); \ (_v) = _tmp.f; \ } while (0) #define GETN(_v, _s) PUT_GET_N(_v, _s, I->input.file, read) #define GET_TABLE(_T, _GETX, _NUM, _TYPE) \ do \ { \ int _i; \ (_T).size = (_NUM); \ (_T).element = \ (_TYPE *)realloc((_T).element, (_NUM) * sizeof((_T).element[0])); \ for (_i = 0; _i < (int)(_T).size; _i++) \ _GETX((_T).element[_i]); \ } while (0) #define GET_PROPERTY_TABLE(_T, _NUM) \ do \ { \ int _i; \ (_T).size = (_NUM); \ (_T).element = (x3f_property_t *)realloc( \ (_T).element, (_NUM) * sizeof((_T).element[0])); \ for (_i = 0; _i < (int)(_T).size; _i++) \ { \ GET4((_T).element[_i].name_offset); \ GET4((_T).element[_i].value_offset); \ } \ } while (0) #define GET_TRUE_HUFF_TABLE(_T) \ do \ { \ int _i; \ (_T).element = NULL; \ for (_i = 0;; _i++) \ { \ (_T).size = _i + 1; \ (_T).element = (x3f_true_huffman_element_t *)realloc( \ (_T).element, (_i + 1) * sizeof((_T).element[0])); \ GET1((_T).element[_i].code_size); \ GET1((_T).element[_i].code); \ if ((_T).element[_i].code_size == 0) \ break; \ } \ } while (0) /* --------------------------------------------------------------------- */ /* Allocating Huffman tree help data */ /* --------------------------------------------------------------------- */ static void cleanup_huffman_tree(x3f_hufftree_t *HTP) { free(HTP->nodes); } static void new_huffman_tree(x3f_hufftree_t *HTP, int bits) { int leaves = 1 << bits; HTP->free_node_index = 0; HTP->total_node_index = HUF_TREE_MAX_NODES(leaves); HTP->nodes = (x3f_huffnode_t *)calloc(1, HUF_TREE_MAX_NODES(leaves) * sizeof(x3f_huffnode_t)); } /* --------------------------------------------------------------------- */ /* Allocating TRUE engine RAW help data */ /* --------------------------------------------------------------------- */ static void cleanup_true(x3f_true_t **TRUP) { x3f_true_t *TRU = *TRUP; if (TRU == NULL) return; FREE(TRU->table.element); FREE(TRU->plane_size.element); cleanup_huffman_tree(&TRU->tree); FREE(TRU->x3rgb16.buf); FREE(TRU); *TRUP = NULL; } static x3f_true_t *new_true(x3f_true_t **TRUP) { x3f_true_t *TRU = (x3f_true_t *)calloc(1, sizeof(x3f_true_t)); cleanup_true(TRUP); TRU->table.size = 0; TRU->table.element = NULL; TRU->plane_size.size = 0; TRU->plane_size.element = NULL; TRU->tree.nodes = NULL; TRU->x3rgb16.data = NULL; TRU->x3rgb16.buf = NULL; *TRUP = TRU; return TRU; } static void cleanup_quattro(x3f_quattro_t **QP) { x3f_quattro_t *Q = *QP; if (Q == NULL) return; FREE(Q->top16.buf); FREE(Q); *QP = NULL; } static x3f_quattro_t *new_quattro(x3f_quattro_t **QP) { x3f_quattro_t *Q = (x3f_quattro_t *)calloc(1, sizeof(x3f_quattro_t)); int i; cleanup_quattro(QP); for (i = 0; i < TRUE_PLANES; i++) { Q->plane[i].columns = 0; Q->plane[i].rows = 0; } Q->unknown = 0; Q->top16.data = NULL; Q->top16.buf = NULL; *QP = Q; return Q; } /* --------------------------------------------------------------------- */ /* Allocating Huffman engine help data */ /* --------------------------------------------------------------------- */ static void cleanup_huffman(x3f_huffman_t **HUFP) { x3f_huffman_t *HUF = *HUFP; if (HUF == NULL) return; FREE(HUF->mapping.element); FREE(HUF->table.element); cleanup_huffman_tree(&HUF->tree); FREE(HUF->row_offsets.element); FREE(HUF->rgb8.buf); FREE(HUF->x3rgb16.buf); FREE(HUF); *HUFP = NULL; } static x3f_huffman_t *new_huffman(x3f_huffman_t **HUFP) { x3f_huffman_t *HUF = (x3f_huffman_t *)calloc(1, sizeof(x3f_huffman_t)); cleanup_huffman(HUFP); /* Set all not read data block pointers to NULL */ HUF->mapping.size = 0; HUF->mapping.element = NULL; HUF->table.size = 0; HUF->table.element = NULL; HUF->tree.nodes = NULL; HUF->row_offsets.size = 0; HUF->row_offsets.element = NULL; HUF->rgb8.data = NULL; HUF->rgb8.buf = NULL; HUF->x3rgb16.data = NULL; HUF->x3rgb16.buf = NULL; *HUFP = HUF; return HUF; } /* --------------------------------------------------------------------- */ /* Creating a new x3f structure from file */ /* --------------------------------------------------------------------- */ /* extern */ x3f_t *x3f_new_from_file(LibRaw_abstract_datastream *infile) { if (!infile) return NULL; INT64 fsize = infile->size(); x3f_t *x3f = (x3f_t *)calloc(1, sizeof(x3f_t)); if (!x3f) throw LIBRAW_EXCEPTION_ALLOC; try { x3f_info_t *I = NULL; x3f_header_t *H = NULL; x3f_directory_section_t *DS = NULL; int i, d; I = &x3f->info; I->error = NULL; I->input.file = infile; I->output.file = NULL; /* Read file header */ H = &x3f->header; infile->seek(0, SEEK_SET); GET4(H->identifier); if (H->identifier != X3F_FOVb) { free(x3f); return NULL; } GET4(H->version); GETN(H->unique_identifier, SIZE_UNIQUE_IDENTIFIER); /* TODO: the meaning of the rest of the header for version >= 4.0 (Quattro) * is unknown */ if (H->version < X3F_VERSION_4_0) { GET4(H->mark_bits); GET4(H->columns); GET4(H->rows); GET4(H->rotation); if (H->version >= X3F_VERSION_2_1) { int num_ext_data = H->version >= X3F_VERSION_3_0 ? NUM_EXT_DATA_3_0 : NUM_EXT_DATA_2_1; GETN(H->white_balance, SIZE_WHITE_BALANCE); if (H->version >= X3F_VERSION_2_3) GETN(H->color_mode, SIZE_COLOR_MODE); GETN(H->extended_types, num_ext_data); for (i = 0; i < num_ext_data; i++) GET4F(H->extended_data[i]); } } /* Go to the beginning of the directory */ infile->seek(-4, SEEK_END); infile->seek(x3f_get4(infile), SEEK_SET); /* Read the directory header */ DS = &x3f->directory_section; GET4(DS->identifier); GET4(DS->version); GET4(DS->num_directory_entries); if (DS->num_directory_entries > 50) goto _err; // too much direntries, most likely broken file if (DS->num_directory_entries > 0) { size_t size = DS->num_directory_entries * sizeof(x3f_directory_entry_t); DS->directory_entry = (x3f_directory_entry_t *)calloc(1, size); } /* Traverse the directory */ for (d = 0; d < (int)DS->num_directory_entries; d++) { x3f_directory_entry_t *DE = &DS->directory_entry[d]; x3f_directory_entry_header_t *DEH = &DE->header; uint32_t save_dir_pos; /* Read the directory entry info */ GET4(DE->input.offset); GET4(DE->input.size); if (DE->input.offset + DE->input.size > fsize * 2) goto _err; DE->output.offset = 0; DE->output.size = 0; GET4(DE->type); /* Save current pos and go to the entry */ save_dir_pos = infile->tell(); infile->seek(DE->input.offset, SEEK_SET); /* Read the type independent part of the entry header */ DEH = &DE->header; GET4(DEH->identifier); GET4(DEH->version); /* NOTE - the tests below could be made on DE->type instead */ if (DEH->identifier == X3F_SECp) { x3f_property_list_t *PL = &DEH->data_subsection.property_list; if (!PL) goto _err; /* Read the property part of the header */ GET4(PL->num_properties); GET4(PL->character_format); GET4(PL->reserved); GET4(PL->total_length); /* Set all not read data block pointers to NULL */ PL->data = NULL; PL->data_size = 0; } if (DEH->identifier == X3F_SECi) { x3f_image_data_t *ID = &DEH->data_subsection.image_data; if (!ID) goto _err; /* Read the image part of the header */ GET4(ID->type); GET4(ID->format); ID->type_format = (ID->type << 16) + (ID->format); GET4(ID->columns); GET4(ID->rows); GET4(ID->row_stride); /* Set all not read data block pointers to NULL */ ID->huffman = NULL; ID->data = NULL; ID->data_size = 0; } if (DEH->identifier == X3F_SECc) { x3f_camf_t *CAMF = &DEH->data_subsection.camf; if (!CAMF) goto _err; /* Read the CAMF part of the header */ GET4(CAMF->type); GET4(CAMF->tN.val0); GET4(CAMF->tN.val1); GET4(CAMF->tN.val2); GET4(CAMF->tN.val3); /* Set all not read data block pointers to NULL */ CAMF->data = NULL; CAMF->data_size = 0; /* Set all not allocated help pointers to NULL */ CAMF->table.element = NULL; CAMF->table.size = 0; CAMF->tree.nodes = NULL; CAMF->decoded_data = NULL; CAMF->decoded_data_size = 0; CAMF->entry_table.element = NULL; CAMF->entry_table.size = 0; } /* Reset the file pointer back to the directory */ infile->seek(save_dir_pos, SEEK_SET); } return x3f; _err: if (x3f) { DS = &x3f->directory_section; if (DS && DS->directory_entry) free(DS->directory_entry); free(x3f); } return NULL; } catch (...) { x3f_directory_section_t *DS = &x3f->directory_section; if (DS && DS->directory_entry) free(DS->directory_entry); free(x3f); return NULL; } } /* --------------------------------------------------------------------- */ /* Clean up an x3f structure */ /* --------------------------------------------------------------------- */ static void free_camf_entry(camf_entry_t *entry) { FREE(entry->property_name); FREE(entry->property_value); FREE(entry->matrix_decoded); FREE(entry->matrix_dim_entry); } /* extern */ x3f_return_t x3f_delete(x3f_t *x3f) { x3f_directory_section_t *DS; int d; if (x3f == NULL) return X3F_ARGUMENT_ERROR; DS = &x3f->directory_section; if (DS->num_directory_entries > 50) return X3F_ARGUMENT_ERROR; for (d = 0; d < (int)DS->num_directory_entries; d++) { x3f_directory_entry_t *DE = &DS->directory_entry[d]; x3f_directory_entry_header_t *DEH = &DE->header; if (DEH->identifier == X3F_SECp) { x3f_property_list_t *PL = &DEH->data_subsection.property_list; FREE(PL->property_table.element); FREE(PL->data); } if (DEH->identifier == X3F_SECi) { x3f_image_data_t *ID = &DEH->data_subsection.image_data; if (ID) { cleanup_huffman(&ID->huffman); cleanup_true(&ID->tru); cleanup_quattro(&ID->quattro); FREE(ID->data); } } if (DEH->identifier == X3F_SECc) { x3f_camf_t *CAMF = &DEH->data_subsection.camf; int i; if (CAMF) { FREE(CAMF->data); FREE(CAMF->table.element); cleanup_huffman_tree(&CAMF->tree); FREE(CAMF->decoded_data); for (i = 0; i < (int)CAMF->entry_table.size; i++) { free_camf_entry(&CAMF->entry_table.element[i]); } } FREE(CAMF->entry_table.element); } } FREE(DS->directory_entry); FREE(x3f); return X3F_OK; } /* --------------------------------------------------------------------- */ /* Getting a reference to a directory entry */ /* --------------------------------------------------------------------- */ /* TODO: all those only get the first instance */ static x3f_directory_entry_t *x3f_get(x3f_t *x3f, uint32_t type, uint32_t image_type) { x3f_directory_section_t *DS; int d; if (x3f == NULL) return NULL; DS = &x3f->directory_section; for (d = 0; d < (int)DS->num_directory_entries; d++) { x3f_directory_entry_t *DE = &DS->directory_entry[d]; x3f_directory_entry_header_t *DEH = &DE->header; if (DEH->identifier == type) { switch (DEH->identifier) { case X3F_SECi: { x3f_image_data_t *ID = &DEH->data_subsection.image_data; if (ID->type_format == image_type) return DE; } break; default: return DE; } } } return NULL; } /* extern */ x3f_directory_entry_t *x3f_get_raw(x3f_t *x3f) { x3f_directory_entry_t *DE; if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_HUFFMAN_X530)) != NULL) return DE; if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_HUFFMAN_10BIT)) != NULL) return DE; if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_TRUE)) != NULL) return DE; if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_MERRILL)) != NULL) return DE; if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_QUATTRO)) != NULL) return DE; if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_SDQ)) != NULL) return DE; if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_SDQH)) != NULL) return DE; if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_SDQH2)) != NULL) return DE; return NULL; } /* extern */ x3f_directory_entry_t *x3f_get_thumb_plain(x3f_t *x3f) { return x3f_get(x3f, X3F_SECi, X3F_IMAGE_THUMB_PLAIN); } /* extern */ x3f_directory_entry_t *x3f_get_thumb_huffman(x3f_t *x3f) { return x3f_get(x3f, X3F_SECi, X3F_IMAGE_THUMB_HUFFMAN); } /* extern */ x3f_directory_entry_t *x3f_get_thumb_jpeg(x3f_t *x3f) { return x3f_get(x3f, X3F_SECi, X3F_IMAGE_THUMB_JPEG); } /* extern */ x3f_directory_entry_t *x3f_get_camf(x3f_t *x3f) { return x3f_get(x3f, X3F_SECc, 0); } /* extern */ x3f_directory_entry_t *x3f_get_prop(x3f_t *x3f) { return x3f_get(x3f, X3F_SECp, 0); } /* For some obscure reason, the bit numbering is weird. It is generally some kind of "big endian" style - e.g. the bit 7 is the first in a byte and bit 31 first in a 4 byte int. For patterns in the huffman pattern table, bit 27 is the first bit and bit 26 the next one. */ #define PATTERN_BIT_POS(_len, _bit) ((_len) - (_bit)-1) #define MEMORY_BIT_POS(_bit) PATTERN_BIT_POS(8, _bit) /* --------------------------------------------------------------------- */ /* Huffman Decode */ /* --------------------------------------------------------------------- */ /* Make the huffman tree */ #ifdef DBG_PRNT static char *display_code(int length, uint32_t code, char *buffer) { int i; for (i = 0; i < length; i++) { int pos = PATTERN_BIT_POS(length, i); buffer[i] = ((code >> pos) & 1) == 0 ? '0' : '1'; } buffer[i] = 0; return buffer; } #endif static x3f_huffnode_t *new_node(x3f_hufftree_t *tree) { if (tree->free_node_index >= tree->total_node_index) throw LIBRAW_EXCEPTION_IO_CORRUPT; x3f_huffnode_t *t = &tree->nodes[tree->free_node_index]; t->branch[0] = NULL; t->branch[1] = NULL; t->leaf = UNDEFINED_LEAF; tree->free_node_index++; return t; } static void add_code_to_tree(x3f_hufftree_t *tree, int length, uint32_t code, uint32_t value) { int i; x3f_huffnode_t *t = tree->nodes; for (i = 0; i < length; i++) { int pos = PATTERN_BIT_POS(length, i); int bit = (code >> pos) & 1; x3f_huffnode_t *t_next = t->branch[bit]; if (t_next == NULL) t_next = t->branch[bit] = new_node(tree); t = t_next; } t->leaf = value; } static void populate_true_huffman_tree(x3f_hufftree_t *tree, x3f_true_huffman_t *table) { int i; new_node(tree); for (i = 0; i < (int)table->size; i++) { x3f_true_huffman_element_t *element = &table->element[i]; uint32_t length = element->code_size; if (length != 0) { /* add_code_to_tree wants the code right adjusted */ uint32_t code = ((element->code) >> (8 - length)) & 0xff; uint32_t value = i; add_code_to_tree(tree, length, code, value); #ifdef DBG_PRNT { char buffer[100]; x3f_printf(DEBUG, "H %5d : %5x : %5d : %02x %08x (%08x) (%s)\n", i, i, value, length, code, value, display_code(length, code, buffer)); } #endif } } } static void populate_huffman_tree(x3f_hufftree_t *tree, x3f_table32_t *table, x3f_table16_t *mapping) { int i; new_node(tree); for (i = 0; i < (int)table->size; i++) { uint32_t element = table->element[i]; if (element != 0) { uint32_t length = HUF_TREE_GET_LENGTH(element); uint32_t code = HUF_TREE_GET_CODE(element); uint32_t value; /* If we have a valid mapping table - then the value from the mapping table shall be used. Otherwise we use the current index in the table as value. */ if (table->size == mapping->size) value = mapping->element[i]; else value = i; add_code_to_tree(tree, length, code, value); #ifdef DBG_PRNT { char buffer[100]; x3f_printf(DEBUG, "H %5d : %5x : %5d : %02x %08x (%08x) (%s)\n", i, i, value, length, code, element, display_code(length, code, buffer)); } #endif } } } #ifdef DBG_PRNT static void print_huffman_tree(x3f_huffnode_t *t, int length, uint32_t code) { char buf1[100]; char buf2[100]; x3f_printf(DEBUG, "%*s (%s,%s) %s (%s)\n", length, length < 1 ? "-" : (code & 1) ? "1" : "0", t->branch[0] == NULL ? "-" : "0", t->branch[1] == NULL ? "-" : "1", t->leaf == UNDEFINED_LEAF ? "-" : (sprintf(buf1, "%x", t->leaf), buf1), display_code(length, code, buf2)); code = code << 1; if (t->branch[0]) print_huffman_tree(t->branch[0], length + 1, code + 0); if (t->branch[1]) print_huffman_tree(t->branch[1], length + 1, code + 1); } #endif /* Help machinery for reading bits in a memory */ typedef struct bit_state_s { uint8_t *next_address; uint8_t bit_offset; uint8_t bits[8]; } bit_state_t; static void set_bit_state(bit_state_t *BS, uint8_t *address) { BS->next_address = address; BS->bit_offset = 8; } static uint8_t get_bit(bit_state_t *BS) { if (BS->bit_offset == 8) { uint8_t byte = *BS->next_address; int i; for (i = 7; i >= 0; i--) { BS->bits[i] = byte & 1; byte = byte >> 1; } BS->next_address++; BS->bit_offset = 0; } return BS->bits[BS->bit_offset++]; } /* Decode use the TRUE algorithm */ static int32_t get_true_diff(bit_state_t *BS, x3f_hufftree_t *HTP) { int32_t diff; x3f_huffnode_t *node = &HTP->nodes[0]; uint8_t bits; while (node->branch[0] != NULL || node->branch[1] != NULL) { uint8_t bit = get_bit(BS); x3f_huffnode_t *new_node = node->branch[bit]; node = new_node; if (node == NULL) { /* TODO: Shouldn't this be treated as a fatal error? */ return 0; } } bits = node->leaf; if (bits == 0) diff = 0; else { uint8_t first_bit = get_bit(BS); int i; diff = first_bit; for (i = 1; i < bits; i++) diff = (diff << 1) + get_bit(BS); if (first_bit == 0) diff -= (1 << bits) - 1; } return diff; } /* This code (that decodes one of the X3F color planes, really is a decoding of a compression algorithm suited for Bayer CFA data. In Bayer CFA the data is divided into 2x2 squares that represents (R,G1,G2,B) data. Those four positions are (in this compression) treated as one data stream each, where you store the differences to previous data in the stream. The reason for this is, of course, that the date is more often than not near to the next data in a stream that represents the same color. */ /* TODO: write more about the compression */ static void true_decode_one_color(x3f_image_data_t *ID, int color) { x3f_true_t *TRU = ID->tru; x3f_quattro_t *Q = ID->quattro; uint32_t seed = TRU->seed[color]; /* TODO : Is this correct ? */ int row; x3f_hufftree_t *tree = &TRU->tree; bit_state_t BS; int32_t row_start_acc[2][2]; uint32_t rows = ID->rows; uint32_t cols = ID->columns; x3f_area16_t *area = &TRU->x3rgb16; uint16_t *dst = area->data + color; set_bit_state(&BS, TRU->plane_address[color]); row_start_acc[0][0] = seed; row_start_acc[0][1] = seed; row_start_acc[1][0] = seed; row_start_acc[1][1] = seed; if (ID->type_format == X3F_IMAGE_RAW_QUATTRO || ID->type_format == X3F_IMAGE_RAW_SDQ || ID->type_format == X3F_IMAGE_RAW_SDQH || ID->type_format == X3F_IMAGE_RAW_SDQH2) { rows = Q->plane[color].rows; cols = Q->plane[color].columns; if (Q->quattro_layout && color == 2) { area = &Q->top16; dst = area->data; } } else { } if (rows != area->rows || cols < area->columns) throw LIBRAW_EXCEPTION_IO_CORRUPT; for (row = 0; row < (int)rows; row++) { int col; bool_t odd_row = row & 1; int32_t acc[2]; for (col = 0; col < (int)cols; col++) { bool_t odd_col = col & 1; int32_t diff = get_true_diff(&BS, tree); int32_t prev = col < 2 ? row_start_acc[odd_row][odd_col] : acc[odd_col]; int32_t value = prev + diff; acc[odd_col] = value; if (col < 2) row_start_acc[odd_row][odd_col] = value; /* Discard additional data at the right for binned Quattro plane 2 */ if (col >= (int)area->columns) continue; *dst = value; dst += area->channels; } } } static void true_decode(x3f_info_t * /*I*/, x3f_directory_entry_t *DE) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; int color; for (color = 0; color < 3; color++) { true_decode_one_color(ID, color); } } /* Decode use the huffman tree */ static int32_t get_huffman_diff(bit_state_t *BS, x3f_hufftree_t *HTP) { int32_t diff; x3f_huffnode_t *node = &HTP->nodes[0]; while (node->branch[0] != NULL || node->branch[1] != NULL) { uint8_t bit = get_bit(BS); x3f_huffnode_t *new_node = node->branch[bit]; node = new_node; if (node == NULL) { /* TODO: Shouldn't this be treated as a fatal error? */ throw LIBRAW_EXCEPTION_IO_CORRUPT; return 0; /* unreachable code */ } } diff = node->leaf; return diff; } static void huffman_decode_row(x3f_info_t * /*I*/, x3f_directory_entry_t *DE, int /*bits*/, int row, int offset, int *minimum) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; x3f_huffman_t *HUF = ID->huffman; int16_t c[3] = {(int16_t)offset, (int16_t)offset, (int16_t)offset}; int col; bit_state_t BS; if (HUF->row_offsets.element[row] > ID->data_size - 1) throw LIBRAW_EXCEPTION_IO_CORRUPT; set_bit_state(&BS, (uint8_t *)ID->data + HUF->row_offsets.element[row]); for (col = 0; col < (int)ID->columns; col++) { int color; for (color = 0; color < 3; color++) { uint16_t c_fix; c[color] += get_huffman_diff(&BS, &HUF->tree); if (c[color] < 0) { c_fix = 0; if (c[color] < *minimum) *minimum = c[color]; } else { c_fix = c[color]; } switch (ID->type_format) { case X3F_IMAGE_RAW_HUFFMAN_X530: case X3F_IMAGE_RAW_HUFFMAN_10BIT: HUF->x3rgb16.data[3 * (row * ID->columns + col) + color] = (uint16_t)c_fix; break; case X3F_IMAGE_THUMB_HUFFMAN: HUF->rgb8.data[3 * (row * ID->columns + col) + color] = (uint8_t)c_fix; break; default: /* TODO: Shouldn't this be treated as a fatal error? */ throw LIBRAW_EXCEPTION_IO_CORRUPT; } } } } static void huffman_decode(x3f_info_t *I, x3f_directory_entry_t *DE, int bits) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; int row; int minimum = 0; int offset = legacy_offset; for (row = 0; row < (int)ID->rows; row++) huffman_decode_row(I, DE, bits, row, offset, &minimum); if (auto_legacy_offset && minimum < 0) { offset = -minimum; for (row = 0; row < (int)ID->rows; row++) huffman_decode_row(I, DE, bits, row, offset, &minimum); } } static int32_t get_simple_diff(x3f_huffman_t *HUF, uint16_t index) { if (HUF->mapping.size == 0) return index; else return HUF->mapping.element[index]; } static void simple_decode_row(x3f_info_t * /*I*/, x3f_directory_entry_t *DE, int bits, int row, int row_stride) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; x3f_huffman_t *HUF = ID->huffman; if (row*row_stride > (int)(ID->data_size - (ID->columns*sizeof(uint32_t)))) throw LIBRAW_EXCEPTION_IO_CORRUPT; uint32_t *data = (uint32_t *)((unsigned char *)ID->data + row * row_stride); uint16_t c[3] = {0, 0, 0}; int col; uint32_t mask = 0; switch (bits) { case 8: mask = 0x0ff; break; case 9: mask = 0x1ff; break; case 10: mask = 0x3ff; break; case 11: mask = 0x7ff; break; case 12: mask = 0xfff; break; default: mask = 0; /* TODO: Shouldn't this be treated as a fatal error? */ throw LIBRAW_EXCEPTION_IO_CORRUPT; break; } for (col = 0; col < (int)ID->columns; col++) { int color; uint32_t val = data[col]; for (color = 0; color < 3; color++) { uint16_t c_fix; c[color] += get_simple_diff(HUF, (val >> (color * bits)) & mask); switch (ID->type_format) { case X3F_IMAGE_RAW_HUFFMAN_X530: case X3F_IMAGE_RAW_HUFFMAN_10BIT: c_fix = (int16_t)c[color] > 0 ? c[color] : 0; HUF->x3rgb16.data[3 * (row * ID->columns + col) + color] = c_fix; break; case X3F_IMAGE_THUMB_HUFFMAN: c_fix = (int8_t)c[color] > 0 ? c[color] : 0; HUF->rgb8.data[3 * (row * ID->columns + col) + color] = c_fix; break; default: /* TODO: Shouldn't this be treated as a fatal error? */ throw LIBRAW_EXCEPTION_IO_CORRUPT; } } } } static void simple_decode(x3f_info_t *I, x3f_directory_entry_t *DE, int bits, int row_stride) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; int row; for (row = 0; row < (int)ID->rows; row++) simple_decode_row(I, DE, bits, row, row_stride); } /* --------------------------------------------------------------------- */ /* Loading the data in a directory entry */ /* --------------------------------------------------------------------- */ /* First you set the offset to where to start reading the data ... */ static void read_data_set_offset(x3f_info_t *I, x3f_directory_entry_t *DE, uint32_t header_size) { uint32_t i_off = DE->input.offset + header_size; I->input.file->seek(i_off, SEEK_SET); } /* ... then you read the data, block for block */ static uint32_t read_data_block(void **data, x3f_info_t *I, x3f_directory_entry_t *DE, uint32_t footer) { INT64 fpos = I->input.file->tell(); uint32_t size = DE->input.size + DE->input.offset - fpos - footer; if (fpos + size > I->input.file->size()) throw LIBRAW_EXCEPTION_IO_CORRUPT; *data = (void *)malloc(size); GETN(*data, size); return size; } static uint32_t data_block_size(void ** /*data*/, x3f_info_t *I, x3f_directory_entry_t *DE, uint32_t footer) { uint32_t size = DE->input.size + DE->input.offset - I->input.file->tell() - footer; return size; } static void x3f_load_image_verbatim(x3f_info_t *I, x3f_directory_entry_t *DE) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; if (!ID->data_size) ID->data_size = read_data_block(&ID->data, I, DE, 0); } static int32_t x3f_load_image_verbatim_size(x3f_info_t *I, x3f_directory_entry_t *DE) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; return data_block_size(&ID->data, I, DE, 0); } static void x3f_load_property_list(x3f_info_t *I, x3f_directory_entry_t *DE) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_property_list_t *PL = &DEH->data_subsection.property_list; int i; read_data_set_offset(I, DE, X3F_PROPERTY_LIST_HEADER_SIZE); GET_PROPERTY_TABLE(PL->property_table, PL->num_properties); if (!PL->data_size) PL->data_size = read_data_block(&PL->data, I, DE, 0); uint32_t maxoffset = PL->data_size / sizeof(utf16_t) - 2; // at least 2 chars, value + terminating 0x0000 for (i = 0; i < (int)PL->num_properties; i++) { x3f_property_t *P = &PL->property_table.element[i]; if (P->name_offset > maxoffset || P->value_offset > maxoffset) throw LIBRAW_EXCEPTION_IO_CORRUPT; P->name = ((utf16_t *)PL->data + P->name_offset); P->value = ((utf16_t *)PL->data + P->value_offset); } } static void x3f_load_true(x3f_info_t *I, x3f_directory_entry_t *DE) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; x3f_true_t *TRU = new_true(&ID->tru); x3f_quattro_t *Q = NULL; int i; if (ID->type_format == X3F_IMAGE_RAW_QUATTRO || ID->type_format == X3F_IMAGE_RAW_SDQ || ID->type_format == X3F_IMAGE_RAW_SDQH || ID->type_format == X3F_IMAGE_RAW_SDQH2) { Q = new_quattro(&ID->quattro); for (i = 0; i < TRUE_PLANES; i++) { GET2(Q->plane[i].columns); GET2(Q->plane[i].rows); } if (Q->plane[0].rows == ID->rows / 2) { Q->quattro_layout = 1; } else if (Q->plane[0].rows == ID->rows) { Q->quattro_layout = 0; } else { throw LIBRAW_EXCEPTION_IO_CORRUPT; } } /* Read TRUE header data */ GET2(TRU->seed[0]); GET2(TRU->seed[1]); GET2(TRU->seed[2]); GET2(TRU->unknown); GET_TRUE_HUFF_TABLE(TRU->table); if (ID->type_format == X3F_IMAGE_RAW_QUATTRO || ID->type_format == X3F_IMAGE_RAW_SDQ || ID->type_format == X3F_IMAGE_RAW_SDQH || ID->type_format == X3F_IMAGE_RAW_SDQH2) { GET4(Q->unknown); } GET_TABLE(TRU->plane_size, GET4, TRUE_PLANES, uint32_t); /* Read image data */ if (!ID->data_size) ID->data_size = read_data_block(&ID->data, I, DE, 0); /* TODO: can it be fewer than 8 bits? Maybe taken from TRU->table? */ new_huffman_tree(&TRU->tree, 8); populate_true_huffman_tree(&TRU->tree, &TRU->table); #ifdef DBG_PRNT print_huffman_tree(TRU->tree.nodes, 0, 0); #endif TRU->plane_address[0] = (uint8_t *)ID->data; for (i = 1; i < TRUE_PLANES; i++) TRU->plane_address[i] = TRU->plane_address[i - 1] + (((TRU->plane_size.element[i - 1] + 15) / 16) * 16); if ((ID->type_format == X3F_IMAGE_RAW_QUATTRO || ID->type_format == X3F_IMAGE_RAW_SDQ || ID->type_format == X3F_IMAGE_RAW_SDQH || ID->type_format == X3F_IMAGE_RAW_SDQH2) && Q->quattro_layout) { uint32_t columns = Q->plane[0].columns; uint32_t rows = Q->plane[0].rows; uint32_t channels = 3; uint32_t size = columns * rows * channels; TRU->x3rgb16.columns = columns; TRU->x3rgb16.rows = rows; TRU->x3rgb16.channels = channels; TRU->x3rgb16.row_stride = columns * channels; TRU->x3rgb16.buf = malloc(sizeof(uint16_t) * size); TRU->x3rgb16.data = (uint16_t *)TRU->x3rgb16.buf; columns = Q->plane[2].columns; rows = Q->plane[2].rows; channels = 1; size = columns * rows * channels; Q->top16.columns = columns; Q->top16.rows = rows; Q->top16.channels = channels; Q->top16.row_stride = columns * channels; Q->top16.buf = malloc(sizeof(uint16_t) * size); Q->top16.data = (uint16_t *)Q->top16.buf; } else { uint32_t size = ID->columns * ID->rows * 3; TRU->x3rgb16.columns = ID->columns; TRU->x3rgb16.rows = ID->rows; TRU->x3rgb16.channels = 3; TRU->x3rgb16.row_stride = ID->columns * 3; TRU->x3rgb16.buf = malloc(sizeof(uint16_t) * size); TRU->x3rgb16.data = (uint16_t *)TRU->x3rgb16.buf; } true_decode(I, DE); } static void x3f_load_huffman_compressed(x3f_info_t *I, x3f_directory_entry_t *DE, int bits, int /*use_map_table*/) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; x3f_huffman_t *HUF = ID->huffman; int table_size = 1 << bits; int row_offsets_size = ID->rows * sizeof(HUF->row_offsets.element[0]); GET_TABLE(HUF->table, GET4, table_size, uint32_t); if (!ID->data_size) ID->data_size = read_data_block(&ID->data, I, DE, row_offsets_size); GET_TABLE(HUF->row_offsets, GET4, ID->rows, uint32_t); new_huffman_tree(&HUF->tree, bits); populate_huffman_tree(&HUF->tree, &HUF->table, &HUF->mapping); huffman_decode(I, DE, bits); } static void x3f_load_huffman_not_compressed(x3f_info_t *I, x3f_directory_entry_t *DE, int bits, int /*use_map_table*/, int row_stride) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; if (!ID->data_size) ID->data_size = read_data_block(&ID->data, I, DE, 0); simple_decode(I, DE, bits, row_stride); } static void x3f_load_huffman(x3f_info_t *I, x3f_directory_entry_t *DE, int bits, int use_map_table, int row_stride) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; x3f_huffman_t *HUF = new_huffman(&ID->huffman); uint32_t size; if (use_map_table) { int table_size = 1 << bits; GET_TABLE(HUF->mapping, GET2, table_size, uint16_t); } switch (ID->type_format) { case X3F_IMAGE_RAW_HUFFMAN_X530: case X3F_IMAGE_RAW_HUFFMAN_10BIT: size = ID->columns * ID->rows * 3; HUF->x3rgb16.columns = ID->columns; HUF->x3rgb16.rows = ID->rows; HUF->x3rgb16.channels = 3; HUF->x3rgb16.row_stride = ID->columns * 3; HUF->x3rgb16.buf = malloc(sizeof(uint16_t) * size); HUF->x3rgb16.data = (uint16_t *)HUF->x3rgb16.buf; break; case X3F_IMAGE_THUMB_HUFFMAN: size = ID->columns * ID->rows * 3; HUF->rgb8.columns = ID->columns; HUF->rgb8.rows = ID->rows; HUF->rgb8.channels = 3; HUF->rgb8.row_stride = ID->columns * 3; HUF->rgb8.buf = malloc(sizeof(uint8_t) * size); HUF->rgb8.data = (uint8_t *)HUF->rgb8.buf; break; default: /* TODO: Shouldn't this be treated as a fatal error? */ throw LIBRAW_EXCEPTION_IO_CORRUPT; } if (row_stride == 0) return x3f_load_huffman_compressed(I, DE, bits, use_map_table); else return x3f_load_huffman_not_compressed(I, DE, bits, use_map_table, row_stride); } static void x3f_load_pixmap(x3f_info_t *I, x3f_directory_entry_t *DE) { x3f_load_image_verbatim(I, DE); } static uint32_t x3f_load_pixmap_size(x3f_info_t *I, x3f_directory_entry_t *DE) { return x3f_load_image_verbatim_size(I, DE); } static void x3f_load_jpeg(x3f_info_t *I, x3f_directory_entry_t *DE) { x3f_load_image_verbatim(I, DE); } static uint32_t x3f_load_jpeg_size(x3f_info_t *I, x3f_directory_entry_t *DE) { return x3f_load_image_verbatim_size(I, DE); } static void x3f_load_image(x3f_info_t *I, x3f_directory_entry_t *DE) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; if (ID->rows > 65535 || ID->columns > 65535) throw LIBRAW_EXCEPTION_IO_CORRUPT; read_data_set_offset(I, DE, X3F_IMAGE_HEADER_SIZE); switch (ID->type_format) { case X3F_IMAGE_RAW_TRUE: case X3F_IMAGE_RAW_MERRILL: case X3F_IMAGE_RAW_QUATTRO: case X3F_IMAGE_RAW_SDQ: case X3F_IMAGE_RAW_SDQH: case X3F_IMAGE_RAW_SDQH2: x3f_load_true(I, DE); break; case X3F_IMAGE_RAW_HUFFMAN_X530: case X3F_IMAGE_RAW_HUFFMAN_10BIT: x3f_load_huffman(I, DE, 10, 1, ID->row_stride); break; case X3F_IMAGE_THUMB_PLAIN: x3f_load_pixmap(I, DE); break; case X3F_IMAGE_THUMB_HUFFMAN: x3f_load_huffman(I, DE, 8, 0, ID->row_stride); break; case X3F_IMAGE_THUMB_JPEG: x3f_load_jpeg(I, DE); break; default: /* TODO: Shouldn't this be treated as a fatal error? */ throw LIBRAW_EXCEPTION_IO_CORRUPT; } } // Used only for thumbnail size estimation static uint32_t x3f_load_image_size(x3f_info_t *I, x3f_directory_entry_t *DE) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_image_data_t *ID = &DEH->data_subsection.image_data; read_data_set_offset(I, DE, X3F_IMAGE_HEADER_SIZE); switch (ID->type_format) { case X3F_IMAGE_THUMB_PLAIN: return x3f_load_pixmap_size(I, DE); case X3F_IMAGE_THUMB_JPEG: return x3f_load_jpeg_size(I, DE); break; default: return 0; } } static void x3f_load_camf_decode_type2(x3f_camf_t *CAMF) { uint32_t key = CAMF->t2.crypt_key; int i; CAMF->decoded_data_size = CAMF->data_size; CAMF->decoded_data = malloc(CAMF->decoded_data_size); for (i = 0; i < (int)CAMF->data_size; i++) { uint8_t old, _new; uint32_t tmp; old = ((uint8_t *)CAMF->data)[i]; key = (key * 1597 + 51749) % 244944; tmp = (uint32_t)(key * ((int64_t)301593171) >> 24); _new = (uint8_t)(old ^ (uint8_t)(((((key << 8) - tmp) >> 1) + tmp) >> 17)); ((uint8_t *)CAMF->decoded_data)[i] = _new; } } /* NOTE: the unpacking in this code is in big respects identical to true_decode_one_color(). The difference is in the output you build. It might be possible to make some parts shared. NOTE ALSO: This means that the meta data is obfuscated using an image compression algorithm. */ static void camf_decode_type4(x3f_camf_t *CAMF) { uint32_t seed = CAMF->t4.decode_bias; int row; uint8_t *dst; uint32_t dst_size = CAMF->t4.decoded_data_size; uint8_t *dst_end; bool_t odd_dst = 0; x3f_hufftree_t *tree = &CAMF->tree; bit_state_t BS; int32_t row_start_acc[2][2]; uint32_t rows = CAMF->t4.block_count; uint32_t cols = CAMF->t4.block_size; CAMF->decoded_data_size = dst_size; CAMF->decoded_data = malloc(CAMF->decoded_data_size); memset(CAMF->decoded_data, 0, CAMF->decoded_data_size); dst = (uint8_t *)CAMF->decoded_data; dst_end = dst + dst_size; set_bit_state(&BS, CAMF->decoding_start); row_start_acc[0][0] = seed; row_start_acc[0][1] = seed; row_start_acc[1][0] = seed; row_start_acc[1][1] = seed; for (row = 0; row < (int)rows; row++) { int col; bool_t odd_row = row & 1; int32_t acc[2]; /* We loop through all the columns and the rows. But the actual data is smaller than that, so we break the loop when reaching the end. */ for (col = 0; col < (int)cols; col++) { bool_t odd_col = col & 1; int32_t diff = get_true_diff(&BS, tree); int32_t prev = col < 2 ? row_start_acc[odd_row][odd_col] : acc[odd_col]; int32_t value = prev + diff; acc[odd_col] = value; if (col < 2) row_start_acc[odd_row][odd_col] = value; switch (odd_dst) { case 0: *dst++ = (uint8_t)((value >> 4) & 0xff); if (dst >= dst_end) { goto ready; } *dst = (uint8_t)((value << 4) & 0xf0); break; case 1: *dst++ |= (uint8_t)((value >> 8) & 0x0f); if (dst >= dst_end) { goto ready; } *dst++ = (uint8_t)((value << 0) & 0xff); if (dst >= dst_end) { goto ready; } break; } odd_dst = !odd_dst; } /* end col */ } /* end row */ ready:; } static void x3f_load_camf_decode_type4(x3f_camf_t *CAMF) { int i; uint8_t *p; x3f_true_huffman_element_t *element = NULL; for (i = 0, p = (uint8_t *)CAMF->data; *p != 0; i++) { /* TODO: Is this too expensive ??*/ element = (x3f_true_huffman_element_t *)realloc(element, (i + 1) * sizeof(*element)); element[i].code_size = *p++; element[i].code = *p++; } CAMF->table.size = i; CAMF->table.element = element; /* TODO: where does the values 28 and 32 come from? */ #define CAMF_T4_DATA_SIZE_OFFSET 28 #define CAMF_T4_DATA_OFFSET 32 CAMF->decoding_size = *(uint32_t *)((unsigned char *)CAMF->data + CAMF_T4_DATA_SIZE_OFFSET); CAMF->decoding_start = (uint8_t *)CAMF->data + CAMF_T4_DATA_OFFSET; /* TODO: can it be fewer than 8 bits? Maybe taken from TRU->table? */ new_huffman_tree(&CAMF->tree, 8); populate_true_huffman_tree(&CAMF->tree, &CAMF->table); #ifdef DBG_PRNT print_huffman_tree(CAMF->tree.nodes, 0, 0); #endif camf_decode_type4(CAMF); } static void camf_decode_type5(x3f_camf_t *CAMF) { int32_t acc = CAMF->t5.decode_bias; uint8_t *dst; x3f_hufftree_t *tree = &CAMF->tree; bit_state_t BS; int32_t i; CAMF->decoded_data_size = CAMF->t5.decoded_data_size; CAMF->decoded_data = malloc(CAMF->decoded_data_size); dst = (uint8_t *)CAMF->decoded_data; set_bit_state(&BS, CAMF->decoding_start); for (i = 0; i < (int)CAMF->decoded_data_size; i++) { int32_t diff = get_true_diff(&BS, tree); acc = acc + diff; *dst++ = (uint8_t)(acc & 0xff); } } static void x3f_load_camf_decode_type5(x3f_camf_t *CAMF) { int i; uint8_t *p; x3f_true_huffman_element_t *element = NULL; for (i = 0, p = (uint8_t *)CAMF->data; *p != 0; i++) { /* TODO: Is this too expensive ??*/ element = (x3f_true_huffman_element_t *)realloc(element, (i + 1) * sizeof(*element)); element[i].code_size = *p++; element[i].code = *p++; } CAMF->table.size = i; CAMF->table.element = element; /* TODO: where does the values 28 and 32 come from? */ #define CAMF_T5_DATA_SIZE_OFFSET 28 #define CAMF_T5_DATA_OFFSET 32 CAMF->decoding_size = *(uint32_t *)((uint8_t *)CAMF->data + CAMF_T5_DATA_SIZE_OFFSET); CAMF->decoding_start = (uint8_t *)CAMF->data + CAMF_T5_DATA_OFFSET; /* TODO: can it be fewer than 8 bits? Maybe taken from TRU->table? */ new_huffman_tree(&CAMF->tree, 8); populate_true_huffman_tree(&CAMF->tree, &CAMF->table); #ifdef DBG_PRNT print_huffman_tree(CAMF->tree.nodes, 0, 0); #endif camf_decode_type5(CAMF); } static void x3f_setup_camf_text_entry(camf_entry_t *entry) { entry->text_size = *(uint32_t *)entry->value_address; entry->text = (char *)entry->value_address + 4; } static void x3f_setup_camf_property_entry(camf_entry_t *entry) { int i; uint8_t *e = (uint8_t *)entry->entry; uint8_t *v = (uint8_t *)entry->value_address; uint32_t num = entry->property_num = *(uint32_t *)v; uint32_t off = *(uint32_t *)(v + 4); entry->property_name = (char **)malloc(num * sizeof(uint8_t *)); entry->property_value = (uint8_t **)malloc(num * sizeof(uint8_t *)); for (i = 0; i < (int)num; i++) { uint32_t name_off = off + *(uint32_t *)(v + 8 + 8 * i); uint32_t value_off = off + *(uint32_t *)(v + 8 + 8 * i + 4); entry->property_name[i] = (char *)(e + name_off); entry->property_value[i] = e + value_off; } } static void set_matrix_element_info(uint32_t type, uint32_t *size, matrix_type_t *decoded_type) { switch (type) { case 0: *size = 2; *decoded_type = M_INT; /* known to be true */ break; case 1: *size = 4; *decoded_type = M_UINT; /* TODO: unknown ???? */ break; case 2: *size = 4; *decoded_type = M_UINT; /* TODO: unknown ???? */ break; case 3: *size = 4; *decoded_type = M_FLOAT; /* known to be true */ break; case 5: *size = 1; *decoded_type = M_UINT; /* TODO: unknown ???? */ break; case 6: *size = 2; *decoded_type = M_UINT; /* TODO: unknown ???? */ break; default: throw LIBRAW_EXCEPTION_IO_CORRUPT; } } static void get_matrix_copy(camf_entry_t *entry) { uint32_t element_size = entry->matrix_element_size; uint32_t elements = entry->matrix_elements; int i, size = (entry->matrix_decoded_type == M_FLOAT ? sizeof(double) : sizeof(uint32_t)) * elements; entry->matrix_decoded = malloc(size); switch (element_size) { case 4: switch (entry->matrix_decoded_type) { case M_INT: case M_UINT: memcpy(entry->matrix_decoded, entry->matrix_data, size); break; case M_FLOAT: for (i = 0; i < (int)elements; i++) ((double *)entry->matrix_decoded)[i] = (double)((float *)entry->matrix_data)[i]; break; default: throw LIBRAW_EXCEPTION_IO_CORRUPT; } break; case 2: switch (entry->matrix_decoded_type) { case M_INT: for (i = 0; i < (int)elements; i++) ((int32_t *)entry->matrix_decoded)[i] = (int32_t)((int16_t *)entry->matrix_data)[i]; break; case M_UINT: for (i = 0; i < (int)elements; i++) ((uint32_t *)entry->matrix_decoded)[i] = (uint32_t)((uint16_t *)entry->matrix_data)[i]; break; default: throw LIBRAW_EXCEPTION_IO_CORRUPT; } break; case 1: switch (entry->matrix_decoded_type) { case M_INT: for (i = 0; i < (int)elements; i++) ((int32_t *)entry->matrix_decoded)[i] = (int32_t)((int8_t *)entry->matrix_data)[i]; break; case M_UINT: for (i = 0; i < (int)elements; i++) ((uint32_t *)entry->matrix_decoded)[i] = (uint32_t)((uint8_t *)entry->matrix_data)[i]; break; default: throw LIBRAW_EXCEPTION_IO_CORRUPT; } break; default: throw LIBRAW_EXCEPTION_IO_CORRUPT; } } static void x3f_setup_camf_matrix_entry(camf_entry_t *entry) { int i; int totalsize = 1; uint8_t *e = (uint8_t *)entry->entry; uint8_t *v = (uint8_t *)entry->value_address; uint32_t type = entry->matrix_type = *(uint32_t *)(v + 0); uint32_t dim = entry->matrix_dim = *(uint32_t *)(v + 4); uint32_t off = entry->matrix_data_off = *(uint32_t *)(v + 8); camf_dim_entry_t *dentry = entry->matrix_dim_entry = (camf_dim_entry_t *)malloc(dim * sizeof(camf_dim_entry_t)); for (i = 0; i < (int)dim; i++) { uint32_t size = dentry[i].size = *(uint32_t *)(v + 12 + 12 * i + 0); dentry[i].name_offset = *(uint32_t *)(v + 12 + 12 * i + 4); dentry[i].n = *(uint32_t *)(v + 12 + 12 * i + 8); dentry[i].name = (char *)(e + dentry[i].name_offset); if ((int)dentry[i].n != i) { } totalsize *= size; } set_matrix_element_info(type, &entry->matrix_element_size, &entry->matrix_decoded_type); entry->matrix_data = (void *)(e + off); entry->matrix_elements = totalsize; entry->matrix_used_space = entry->entry_size - off; /* This estimate only works for matrices above a certain size */ entry->matrix_estimated_element_size = entry->matrix_used_space / totalsize; get_matrix_copy(entry); } static void x3f_setup_camf_entries(x3f_camf_t *CAMF) { uint8_t *p = (uint8_t *)CAMF->decoded_data; uint8_t *end = p + CAMF->decoded_data_size; camf_entry_t *entry = NULL; int i; for (i = 0; p < end; i++) { uint32_t *p4 = (uint32_t *)p; switch (*p4) { case X3F_CMbP: case X3F_CMbT: case X3F_CMbM: break; default: goto stop; } /* TODO: lots of realloc - may be inefficient */ entry = (camf_entry_t *)realloc(entry, (i + 1) * sizeof(camf_entry_t)); /* Pointer */ entry[i].entry = p; /* Header */ entry[i].id = *p4++; entry[i].version = *p4++; entry[i].entry_size = *p4++; entry[i].name_offset = *p4++; entry[i].value_offset = *p4++; /* Compute addresses and sizes */ entry[i].name_address = (char *)(p + entry[i].name_offset); entry[i].value_address = p + entry[i].value_offset; entry[i].name_size = entry[i].value_offset - entry[i].name_offset; entry[i].value_size = entry[i].entry_size - entry[i].value_offset; entry[i].text_size = 0; entry[i].text = NULL; entry[i].property_num = 0; entry[i].property_name = NULL; entry[i].property_value = NULL; entry[i].matrix_type = 0; entry[i].matrix_dim = 0; entry[i].matrix_data_off = 0; entry[i].matrix_data = NULL; entry[i].matrix_dim_entry = NULL; entry[i].matrix_decoded = NULL; switch (entry[i].id) { case X3F_CMbP: x3f_setup_camf_property_entry(&entry[i]); break; case X3F_CMbT: x3f_setup_camf_text_entry(&entry[i]); break; case X3F_CMbM: x3f_setup_camf_matrix_entry(&entry[i]); break; } p += entry[i].entry_size; } stop: CAMF->entry_table.size = i; CAMF->entry_table.element = entry; } static void x3f_load_camf(x3f_info_t *I, x3f_directory_entry_t *DE) { x3f_directory_entry_header_t *DEH = &DE->header; x3f_camf_t *CAMF = &DEH->data_subsection.camf; read_data_set_offset(I, DE, X3F_CAMF_HEADER_SIZE); if (!CAMF->data_size) CAMF->data_size = read_data_block(&CAMF->data, I, DE, 0); switch (CAMF->type) { case 2: /* Older SD9-SD14 */ x3f_load_camf_decode_type2(CAMF); break; case 4: /* TRUE ... Merrill */ x3f_load_camf_decode_type4(CAMF); break; case 5: /* Quattro ... */ x3f_load_camf_decode_type5(CAMF); break; default: /* TODO: Shouldn't this be treated as a fatal error? */ throw LIBRAW_EXCEPTION_IO_CORRUPT; } if (CAMF->decoded_data != NULL) x3f_setup_camf_entries(CAMF); else throw LIBRAW_EXCEPTION_IO_CORRUPT; } /* extern */ x3f_return_t x3f_load_data(x3f_t *x3f, x3f_directory_entry_t *DE) { x3f_info_t *I = &x3f->info; if (DE == NULL) return X3F_ARGUMENT_ERROR; switch (DE->header.identifier) { case X3F_SECp: x3f_load_property_list(I, DE); break; case X3F_SECi: x3f_load_image(I, DE); break; case X3F_SECc: x3f_load_camf(I, DE); break; default: return X3F_INTERNAL_ERROR; } return X3F_OK; } /* extern */ int64_t x3f_load_data_size(x3f_t *x3f, x3f_directory_entry_t *DE) { x3f_info_t *I = &x3f->info; if (DE == NULL) return -1; switch (DE->header.identifier) { case X3F_SECi: return x3f_load_image_size(I, DE); default: return 0; } } /* extern */ x3f_return_t x3f_load_image_block(x3f_t *x3f, x3f_directory_entry_t *DE) { x3f_info_t *I = &x3f->info; if (DE == NULL) return X3F_ARGUMENT_ERROR; switch (DE->header.identifier) { case X3F_SECi: read_data_set_offset(I, DE, X3F_IMAGE_HEADER_SIZE); x3f_load_image_verbatim(I, DE); break; default: throw LIBRAW_EXCEPTION_IO_CORRUPT; return X3F_INTERNAL_ERROR; /* unreachable code*/ } return X3F_OK; } /* --------------------------------------------------------------------- */ /* The End */ /* --------------------------------------------------------------------- */ #endif LibRaw-0.21.4/version.sh000077500000000000000000000007241477673233700150300ustar00rootroot00000000000000#!/bin/sh vfile=./libraw/libraw_version.h major=`grep LIBRAW_MAJOR_VERSION $vfile |head -1 | awk '{print $3}'` minor=`grep LIBRAW_MINOR_VERSION $vfile | head -1 | awk '{print $3}'` patch=`grep LIBRAW_PATCH_VERSION $vfile | head -1 | awk '{print $3}'` tail=`grep LIBRAW_VERSION_TAIL $vfile | head -1 | awk '{print $3}'` if [ x$tail = xRelease ] ; then echo "$major.$minor.$patch" | awk '{printf $1}' else echo "$major.$minor.$patch-$tail" | awk '{printf $1}' fi