blob: 324185a0d8241c6f32e5735a38faafe175f4747e [file]
/* -*- 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
}