| /* -*- C++ -*- |
| * Copyright 2019-2025 LibRaw LLC (info@libraw.org) |
| * |
| |
| LibRaw is free software; you can redistribute it and/or modify |
| it under the terms of the one of two licenses as you choose: |
| |
| 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 |
| (See file LICENSE.LGPL provided in LibRaw distribution archive for details). |
| |
| 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 |
| (See file LICENSE.CDDL provided in LibRaw distribution archive for details). |
| |
| */ |
| |
| #include <algorithm> |
| #include <limits> |
| |
| #include "third_party/libraw/internal/dcraw_defs.h" |
| #include "third_party/libraw/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_R1) |
| || (id == CanonID_EOS_R3) |
| || (id == CanonID_EOS_R5) |
| || (id == CanonID_EOS_R5_Mark_II) |
| || (id == CanonID_EOS_R5_C) |
| || (id == CanonID_EOS_R6) |
| || (id == CanonID_EOS_R6m2) |
| || (id == CanonID_EOS_R8) |
| ) |
| { |
| 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) |
| || (id == CanonID_EOS_R50) |
| || (id == CanonID_EOS_R100) |
| ) |
| { |
| 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; |
| } |
| } |
| |
| static int CanonCameraInfo_checkFirmwareRecordLocation (uchar *data, size_t _offset, size_t size) |
| { |
| if (size < _offset + 5) return 0; // overrun |
| uchar *offset = data + _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, |
| iAutoRotateMode = 0; |
| short SubVersion_offset = 0; |
| ushort SubVersion = 0, mgck = 0; |
| |
| // printf ("==>> CanonCameraInfo len: %d\n", maxlen); |
| 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 && iCanonCurFocal < maxlen - 1) |
| ilm.CurFocal = sget2(CameraInfo + iCanonCurFocal); |
| if (!ilm.MinFocal && iCanonMinFocal < maxlen - 1) |
| ilm.MinFocal = sget2(CameraInfo + iCanonMinFocal); |
| if (!ilm.MaxFocal && iCanonMaxFocal < maxlen - 1) |
| 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, maxlen)) |
| SubVersion = 1; |
| else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo, 0x1ed, maxlen)) |
| 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, maxlen)) |
| SubVersion = 1; |
| else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo, 0x279, maxlen)) |
| SubVersion = 2; |
| else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo, 0x280, maxlen)) |
| SubVersion = 3; |
| else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo, 0x285, maxlen)) |
| 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, maxlen)) |
| SubVersion = 1; |
| else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo, 0x22d, maxlen)) |
| SubVersion = 2; |
| else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo, 0x23c, maxlen)) |
| SubVersion = 3; |
| else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo, 0x242, maxlen)) |
| SubVersion = 4; |
| else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo, 0x247, maxlen)) |
| 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_5D_Mark_IV: |
| iMakernotesFlip = 0x96; |
| iAutoRotateMode = 0x5da; |
| //printf ("==>> 5DMkIV: MakernotesFlip: %d; AutoRotateMode: %d\n", CameraInfo[iMakernotesFlip], CameraInfo[iAutoRotateMode]); |
| break; |
| |
| case CanonID_EOS_5DS: |
| case CanonID_EOS_5DS_R: |
| iMakernotesFlip = 0x96; |
| iAutoRotateMode = 0x580; |
| //printf ("==>> 5DS/5DS R: MakernotesFlip: %d; AutoRotateMode: %d\n", CameraInfo[iMakernotesFlip], CameraInfo[iAutoRotateMode]); |
| break; |
| |
| case CanonID_EOS_6D: |
| iCanonCurFocal = 0x23; |
| iMakernotesFlip = 0x83; |
| iCanonLensID = 0x161; |
| iCanonMinFocal = 0x163; |
| iCanonMaxFocal = 0x165; |
| iAutoRotateMode = 0x3b2; |
| //printf ("==>> 6D: MakernotesFlip: %d; AutoRotateMode: %d\n", CameraInfo[iMakernotesFlip], CameraInfo[iAutoRotateMode]); |
| break; |
| |
| case CanonID_EOS_7D: |
| if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo, 0x1a8, maxlen)) |
| SubVersion = 1; |
| else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo, 0x1ac, maxlen)) |
| 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 && iMakernotesFlip < maxlen && (CameraInfo[iMakernotesFlip] < 3)) { |
| imCanon.MakernotesFlip = "065"[CameraInfo[iMakernotesFlip]] - '0'; |
| } 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'; |
| break; |
| } else i+=4; |
| } |
| |
| if (iAutoRotateMode && iAutoRotateMode < maxlen && CameraInfo[iAutoRotateMode] < 3) |
| imCanon.AutoRotateMode = CameraInfo[iAutoRotateMode]; |
| |
| if (iHTP && iHTP < maxlen) |
| { |
| imCanon.HighlightTonePriority = CameraInfo[iHTP]; |
| if ((imCanon.HighlightTonePriority > 5) || |
| (imCanon.HighlightTonePriority < 0)) |
| imCanon.HighlightTonePriority = 0; |
| if (imCanon.HighlightTonePriority) { |
| imCommon.ExposureCalibrationShift -= float(imCanon.HighlightTonePriority); |
| } |
| } |
| if (iALO && iALO < maxlen) |
| { |
| 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)std::clamp<float>( \ |
| (float)sraw_mul[c] * sraw_mul_max, std::numeric_limits<ushort>::min(), \ |
| std::numeric_limits<ushort>::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); |
| artist[63] = 0; |
| |
| } 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; |
| if (libraw_tagtype_dataunit_bytes(type)) // returns 0 on unknown type |
| imCommon.afdata[imCommon.afcount].AFInfoData_length *= libraw_tagtype_dataunit_bytes(type); |
| |
| unsigned datalen = 0; |
| if (tag == 0x0026 || tag == 0x003c) // AFInfo2 bytes 0-1 contains AFSize |
| { |
| INT64 here = ftell(ifp); |
| datalen = get2(); |
| fseek(ifp, here, SEEK_SET); |
| } |
| if (!datalen || datalen == imCommon.afdata[imCommon.afcount].AFInfoData_length) // data check not performed or passed |
| { |
| imCommon.afdata[imCommon.afcount].AFInfoData = |
| (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length+1, 1); |
| fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, |
| ifp); |
| imCommon.afcount = 1; |
| } |
| else |
| { |
| // check not passed: clean up afdata inited |
| imCommon.afdata[imCommon.afcount].AFInfoData_tag = 0; |
| imCommon.afdata[imCommon.afcount].AFInfoData_order = 0; |
| imCommon.afdata[imCommon.afcount].AFInfoData_length = 0; |
| } |
| } |
| |
| } 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); |
| ilm.Lens[63] = 0; |
| 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: |
| case 0x102: |
| 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, Ra; ColorDataSubVer: 17 |
| case 1816: // RP, 250D, SX70 HS; ColorDataSubVer: 18 |
| // R100, 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: // R6 Mark II, R7, R8, R10, R50; 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; |
| |
| case 4528: // R1, R5 Mark II; ColorDataSubVer: 64 |
| imCanon.ColorDataVer = 12; |
| AsShot_Auto_MeasuredWB(0x0069); |
| fseek(ifp, save1 + ((0x006d+0x0001) << 1), SEEK_SET); |
| Canon_WBpresets(2, 12); |
| fseek(ifp, save1 + ((0x0069+0x00d7) << 1), SEEK_SET); |
| Canon_WBCTpresets(0); |
| offsetChannelBlackLevel2 = save1 + ((0x0069+0x0116) << 1); |
| offsetChannelBlackLevel = save1 + ((0x0069+0x0227) << 1); |
| offsetWhiteLevels = save1 + ((0x0069+0x022b) << 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 |
| } |