blob: ff14cf22ad9c0c21c464a002731165e1cd67c3b5 [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 "third_party/libraw/internal/dcraw_defs.h"
#include "third_party/libraw/internal/libraw_cameraids.h"
#include "third_party/libraw/internal/libraw_checked_buffer.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) {
#define sbfDSLR_DX LIBRAW_FORMAT_APSC,LIBRAW_MOUNT_Minolta_A,LIBRAW_SONY_DSLR,LIBRAW_MOUNT_Unknown
#define sbfDSLR_FF LIBRAW_FORMAT_FF,LIBRAW_MOUNT_Minolta_A,LIBRAW_SONY_DSLR,LIBRAW_MOUNT_Unknown
#define sbfNEX_DX LIBRAW_FORMAT_APSC,LIBRAW_MOUNT_Sony_E,LIBRAW_SONY_NEX,LIBRAW_MOUNT_Unknown
#define sbfNEX_FF LIBRAW_FORMAT_FF,LIBRAW_MOUNT_Sony_E,LIBRAW_SONY_NEX,LIBRAW_MOUNT_Unknown
#define sbfSLT_DX LIBRAW_FORMAT_APSC,LIBRAW_MOUNT_Minolta_A,LIBRAW_SONY_SLT,LIBRAW_MOUNT_Unknown
#define sbfSLT_FF LIBRAW_FORMAT_FF,LIBRAW_MOUNT_Minolta_A,LIBRAW_SONY_SLT,LIBRAW_MOUNT_Unknown
#define sbfDSC_1div2p3in LIBRAW_FORMAT_1div2p3INCH,LIBRAW_MOUNT_FixedLens,LIBRAW_SONY_DSC,LIBRAW_MOUNT_FixedLens
#define sbfDSC_1in LIBRAW_FORMAT_1INCH,LIBRAW_MOUNT_FixedLens,LIBRAW_SONY_DSC,LIBRAW_MOUNT_FixedLens
#define sbfDSC_FF LIBRAW_FORMAT_FF,LIBRAW_MOUNT_FixedLens,LIBRAW_SONY_DSC,LIBRAW_MOUNT_FixedLens
#define sbfILCE_DX LIBRAW_FORMAT_APSC,LIBRAW_MOUNT_Sony_E,LIBRAW_SONY_ILCE,LIBRAW_MOUNT_Unknown
#define sbfILCE_FF LIBRAW_FORMAT_FF,LIBRAW_MOUNT_Sony_E,LIBRAW_SONY_ILCE,LIBRAW_MOUNT_Unknown
#define sbfILCA_DX LIBRAW_FORMAT_APSC,LIBRAW_MOUNT_Minolta_A,LIBRAW_SONY_ILCA,LIBRAW_MOUNT_Unknown
#define sbfILCA_FF LIBRAW_FORMAT_FF,LIBRAW_MOUNT_Minolta_A,LIBRAW_SONY_ILCA,LIBRAW_MOUNT_Unknown
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, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A900, sbfDSLR_FF,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A700, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A200, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A350, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A300, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A900_APSC, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A380, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A330, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A230, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A290, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A850, sbfDSLR_FF,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A850_APSC, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A550, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A500, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A450, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_NEX_5, sbfNEX_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_NEX_3, sbfNEX_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_SLT_A33, sbfSLT_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_SLT_A55, sbfSLT_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A560, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_DSLR_A580, sbfDSLR_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_NEX_C3, sbfNEX_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_SLT_A35, sbfSLT_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_SLT_A65, sbfSLT_DX,
LIBRAW_SONY_Tag2010b, 0x1218, 0x01bd, 0x1178, 0x1179, 0x112c},
{SonyID_SLT_A77, sbfSLT_DX,
LIBRAW_SONY_Tag2010b, 0x1218, 0x01bd, 0x1178, 0x1179, 0x112c},
{SonyID_NEX_5N, sbfNEX_DX,
LIBRAW_SONY_Tag2010a, 0x113e, 0x01bd, 0x1174, 0x1175, 0x112c},
{SonyID_NEX_7, sbfNEX_DX,
LIBRAW_SONY_Tag2010b, 0x1218, 0x01bd, 0x1178, 0x1179, 0x112c},
{SonyID_NEX_VG20, sbfNEX_DX,
LIBRAW_SONY_Tag2010b, 0x1218, 0x01bd, 0x1178, 0x1179, 0x112c},
{SonyID_SLT_A37, sbfSLT_DX,
LIBRAW_SONY_Tag2010c, 0x11f4, 0x01bd, 0x1154, 0x1155, 0x1108},
{SonyID_SLT_A57, sbfSLT_DX,
LIBRAW_SONY_Tag2010c, 0x11f4, 0x01bd, 0x1154, 0x1155, 0x1108},
{SonyID_NEX_F3, sbfNEX_DX,
LIBRAW_SONY_Tag2010c, 0x11f4, 0x01bd, 0x1154, 0x1155, 0x1108},
{SonyID_SLT_A99, sbfSLT_FF,
LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160},
{SonyID_NEX_6, sbfNEX_DX,
LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160},
{SonyID_NEX_5R, sbfNEX_DX,
LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160},
{SonyID_DSC_RX100, sbfDSC_1in,
LIBRAW_SONY_Tag2010e, 0x1254, 0xffff, 0x11ac, 0x11ad, 0x1160},
{SonyID_DSC_RX1, sbfDSC_FF,
LIBRAW_SONY_Tag2010e, 0x1258, 0xffff, 0x11ac, 0x11ad, 0x1160},
{SonyID_NEX_VG900, sbfNEX_FF,
LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160},
{SonyID_NEX_VG30, sbfNEX_DX,
LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160},
{SonyID_ILCE_3000, sbfILCE_DX,
LIBRAW_SONY_Tag2010e, 0x1280, 0x01aa, 0x11ac, 0x11ad, 0x1160},
{SonyID_SLT_A58, sbfSLT_DX,
LIBRAW_SONY_Tag2010e, 0x1280, 0x01aa, 0x11ac, 0x11ad, 0x1160},
{SonyID_NEX_3N, sbfNEX_DX,
LIBRAW_SONY_Tag2010e, 0x1280, 0x01aa, 0x11ac, 0x11ad, 0x1160},
{SonyID_ILCE_7, sbfILCE_FF,
LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210},
{SonyID_NEX_5T, sbfNEX_DX,
LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160},
{SonyID_DSC_RX100M2, sbfDSC_1in,
LIBRAW_SONY_Tag2010f, 0x113c, 0xffff, 0x1064, 0x1065, 0x1018},
{SonyID_DSC_RX10, sbfDSC_1in,
LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210},
{SonyID_DSC_RX1R, sbfDSC_FF,
LIBRAW_SONY_Tag2010e, 0x1258, 0xffff, 0x11ac, 0x11ad, 0x1160},
{SonyID_ILCE_7R, sbfILCE_FF,
LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210},
{SonyID_ILCE_6000, sbfILCE_DX,
LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210},
{SonyID_ILCE_5000, sbfILCE_DX,
LIBRAW_SONY_Tag2010g, 0x0344, 0x01aa, 0x025c, 0x025d, 0x0210},
{SonyID_DSC_RX100M3, sbfDSC_1in,
LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210},
{SonyID_ILCE_7S, sbfILCE_FF,
LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210},
{SonyID_ILCA_77M2, sbfILCA_DX,
LIBRAW_SONY_Tag2010g, 0x0344, 0x01a0, 0x025c, 0x025d, 0x0210},
{SonyID_ILCE_5100, sbfILCE_DX,
LIBRAW_SONY_Tag2010g, 0x0344, 0x01a0, 0x025c, 0x025d, 0x0210},
{SonyID_ILCE_7M2, sbfILCE_FF,
LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210},
{SonyID_DSC_RX100M4, sbfDSC_1in,
LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210},
{SonyID_DSC_RX10M2, sbfDSC_1in,
LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210},
{SonyID_DSC_RX1RM2, sbfDSC_FF,
LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210},
{SonyID_ILCE_QX1, sbfILCE_DX,
LIBRAW_SONY_Tag2010g, 0x0344, 0x01a0, 0x025c, 0x025d, 0x0210},
{SonyID_ILCE_7RM2, sbfILCE_FF,
LIBRAW_SONY_Tag2010h, 0x0346, 0x01cb, 0x025c, 0x025d, 0x0210},
{SonyID_ILCE_7SM2, sbfILCE_FF,
LIBRAW_SONY_Tag2010h, 0x0346, 0x01cb, 0x025c, 0x025d, 0x0210},
{SonyID_ILCA_68, sbfILCA_DX,
LIBRAW_SONY_Tag2010g, 0x0344, 0x01a0, 0x025c, 0x025d, 0x0210},
{SonyID_ILCA_99M2, sbfILCA_FF,
LIBRAW_SONY_Tag2010h, 0x0346, 0x01cd, 0x025c, 0x025d, 0x0210},
{SonyID_DSC_RX10M3, sbfDSC_1in,
LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210},
{SonyID_DSC_RX100M5, sbfDSC_1in,
LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210},
{SonyID_ILCE_6300, sbfILCE_DX,
LIBRAW_SONY_Tag2010h, 0x0346, 0x01cd, 0x025c, 0x025d, 0x0210},
{SonyID_ILCE_9, sbfILCE_FF,
LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208},
{SonyID_ILCE_6500, sbfILCE_DX,
LIBRAW_SONY_Tag2010h, 0x0346, 0x01cd, 0x025c, 0x025d, 0x0210},
{SonyID_ILCE_7RM3, sbfILCE_FF,
LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208},
{SonyID_ILCE_7M3, sbfILCE_FF,
LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208},
{SonyID_DSC_RX0, sbfDSC_1in,
LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210},
{SonyID_DSC_RX10M4, sbfDSC_1in,
LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208},
{SonyID_DSC_RX100M6, sbfDSC_1in,
LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208},
{SonyID_DSC_HX99, sbfDSC_1div2p3in,
LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208},
{SonyID_DSC_RX100M5A, sbfDSC_1in,
LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208},
{SonyID_ILCE_6400, sbfILCE_DX,
LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208},
{SonyID_DSC_RX0M2, sbfDSC_1in,
LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208},
{SonyID_DSC_HX95, sbfDSC_1div2p3in,
LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208},
{SonyID_DSC_RX100M7, sbfDSC_1in,
LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208},
{SonyID_ILCE_7RM4, sbfILCE_FF,
LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208},
{SonyID_ILCE_9M2, sbfILCE_FF,
LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208},
{SonyID_ILCE_6600, sbfILCE_DX,
LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208},
{SonyID_ILCE_6100, sbfILCE_DX,
LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208},
{SonyID_ZV_1, sbfDSC_1in,
LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208},
{SonyID_ILCE_7C, sbfILCE_FF,
LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208},
{SonyID_ZV_E10, sbfILCE_DX,
LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208},
{SonyID_ILCE_7SM3, sbfILCE_FF,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_ILCE_1, sbfILCE_FF,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_ILME_FX3, sbfILCE_FF,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_ILME_FX2, sbfILCE_FF,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_ILCE_7RM3A, sbfILCE_FF,
LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208},
{SonyID_ILCE_7RM4A, sbfILCE_FF,
LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208},
{SonyID_ILCE_7M4, sbfILCE_FF,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_ILCE_7RM5, sbfILCE_FF,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_ILME_FX30, sbfILCE_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_ILCE_9M3, sbfILCE_FF,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_ZV_E1, sbfILCE_FF,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_ILCE_6700, sbfILCE_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_ZV_1M2, sbfDSC_1in,
LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208},
{SonyID_ILCE_7CR, sbfILCE_FF,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_ILCE_7CM2, sbfILCE_FF,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_ILX_LR1, sbfILCE_FF,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
{SonyID_ZV_E10M2, sbfILCE_DX,
LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
};
ilm.CamID = id;
int isPreProductionFW = 0;
if (
(!strncmp(model, "MODEL-NAME", 10))
|| (!strncmp(model, "DSLR-A000", 9))
|| (!strncmp(model, "SLT-A00", 7))
|| (!strncmp(model, "NEX-00", 6))
) {
isPreProductionFW = 1;
}
if (id == SonyID_DSC_R1)
{
ilm.CameraFormat = LIBRAW_FORMAT_APSC;
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_7RM3:
case SonyID_ILCE_7RM3A:
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:
if (!isPreProductionFW)
{
imSony.group9050 = LIBRAW_SONY_Tag9050b; // length: 944 bytes
}
else
{
imSony.group9050 = LIBRAW_SONY_Tag9050a;
imSony.ImageCount3_offset = 0xffff; // not valid
}
break;
case SonyID_ILCE_1:
case SonyID_ILCE_7M4:
case SonyID_ILCE_7RM5:
case SonyID_ILCE_7SM3:
case SonyID_ILME_FX3:
case SonyID_ILX_LR1:
if (!isPreProductionFW)
{
imSony.group9050 = LIBRAW_SONY_Tag9050c; // length: 256 bytes
}
else
{
imSony.group9050 = LIBRAW_SONY_Tag9050a;
imSony.ImageCount3_offset = 0xffff; // not valid
}
break;
case SonyID_ILME_FX2:
case SonyID_ZV_E1:
case SonyID_ILCE_6700:
case SonyID_ILCE_7CR:
case SonyID_ILCE_7CM2:
case SonyID_ILCE_9M3:
case SonyID_ZV_E10M2:
imSony.group9050 = LIBRAW_SONY_Tag9050d;
break;
default: // see also process_Sony_0x9050
if (
(imSony.CameraType != LIBRAW_SONY_DSC) &&
(imSony.CameraType != LIBRAW_SONY_DSLR)
)
imSony.group9050 = LIBRAW_SONY_Tag9050a; // length: 3072 or 944 bytes
else
imSony.group9050 = LIBRAW_SONY_Tag9050None;
break;
}
if (isPreProductionFW) return;
char *sbstr = strstr(software, " v");
if (sbstr != NULL)
{
sbstr += 2;
strcpy(imCommon.firmware, sbstr);
imSony.firmware = float(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;
}
}
#undef sbfILCA_FF
#undef sbfILCA_DX
#undef sbfILCE_FF
#undef sbfILCE_DX
#undef sbfDSC_FF
#undef sbfDSC_1in
#undef sbfDSC_1div2p3in
#undef sbfSLT_FF
#undef sbfSLT_DX
#undef sbfNEX_FF
#undef sbfNEX_DX
#undef sbfDSLR_FF
#undef sbfDSLR_DX
} // closing setSonyBodyFeatures()
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;
ushort ar_offset = 0;
if (imSony.group2010 == LIBRAW_SONY_Tag2010e) {
if (ilm.CamID == SonyID_DSC_RX100) {
ar_offset = 0x1a88;
} else {
ar_offset = 0x192c;
}
} else if (imSony.group2010 == LIBRAW_SONY_Tag2010f) {
ar_offset = 0x192c;
} else if (imSony.group2010 == LIBRAW_SONY_Tag2010g) {
ar_offset = 0x1958;
} else if (imSony.group2010 == LIBRAW_SONY_Tag2010h) {
ar_offset = 0x192c;
} else if (imSony.group2010 == LIBRAW_SONY_Tag2010i) {
ar_offset = 0x188c;
}
if (ar_offset != 0 && ar_offset<len) {
int s = (int)SonySubstitution[buf[ar_offset]];
if (s == 0) {
imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_16to9;
} else if (s == 1) {
imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_4to3;
} else if (s == 2) {
imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_3to2;
} else if (s == 3) {
imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_1to1;
} else {
imSony.AspectRatio = (float)s;
}
}
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)) &&
(len > (imSony.ExposureProgram_offset))
)
{
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)))
{
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;
}
/*
printf ("==>> Tag9050, len: 0x%04x, type: %s, model: =%s=, CamID: %llu, ARW version: %d\n",
len,
imSony.group9050==LIBRAW_SONY_Tag9050None?"None":
imSony.group9050==LIBRAW_SONY_Tag9050a?"9050a":
imSony.group9050==LIBRAW_SONY_Tag9050b?"9050b":
imSony.group9050==LIBRAW_SONY_Tag9050c?"9050c":
imSony.group9050==LIBRAW_SONY_Tag9050d?"9050d":
"---",
model, id,
imSony.FileFormat);
*/
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.0f - 1.06f) / 2.0f) *
10.0f) / 10.0f;
if (buf[1])
ilm.MinAp4CurFocal =
my_roundf(
libraw_powf64l(2.0f, ((float)SonySubstitution[buf[1]] / 8.0f - 1.06f) / 2.0f) *
10.0f) / 10.0f;
}
if ((imSony.group9050 == LIBRAW_SONY_Tag9050b) ||
(imSony.group9050 == LIBRAW_SONY_Tag9050c)) {
unsigned start_InternalBodySerial = 0x88;
if (id == SonyID_ILCE_1) start_InternalBodySerial += 2;
if (len <= start_InternalBodySerial+5) return;
unsigned long long b88 = SonySubstitution[buf[start_InternalBodySerial]];
unsigned long long b89 = SonySubstitution[buf[start_InternalBodySerial+1]];
unsigned long long b8a = SonySubstitution[buf[start_InternalBodySerial+2]];
unsigned long long b8b = SonySubstitution[buf[start_InternalBodySerial+3]];
unsigned long long b8c = SonySubstitution[buf[start_InternalBodySerial+4]];
unsigned long long b8d = SonySubstitution[buf[start_InternalBodySerial+5]];
sprintf(imgdata.shootinginfo.InternalBodySerial, "%06llx",
(b88 << 40) + (b89 << 32) + (b8a << 24) + (b8b << 16) + (b8c << 8) + b8d);
} else if (imSony.group9050 == LIBRAW_SONY_Tag9050d) {
unsigned start_InternalBodySerial = 0x38;
if (len <= start_InternalBodySerial+5) return;
unsigned long long b38 = SonySubstitution[buf[start_InternalBodySerial]];
unsigned long long b39 = SonySubstitution[buf[start_InternalBodySerial+1]];
unsigned long long b4a = SonySubstitution[buf[start_InternalBodySerial+2]];
unsigned long long b4b = SonySubstitution[buf[start_InternalBodySerial+3]];
unsigned long long b4c = SonySubstitution[buf[start_InternalBodySerial+4]];
unsigned long long b4d = SonySubstitution[buf[start_InternalBodySerial+5]];
sprintf(imgdata.shootinginfo.InternalBodySerial, "%06llx",
(b38 << 40) + (b39 << 32) + (b4a << 24) + (b4b << 16) + (b4c << 8) + b4d);
} 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) ||
(bufx == 0x32) ||
(bufx == 0x33))
&&
(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(
INT64 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;
ushort u16temp;
// 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 == 0xb000)
{
FORC4 imSony.FileFormat = imSony.FileFormat * 10 + fgetc(ifp);
}
else 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)
{
imSony.len_group9050 = 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 == 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.f + bcd2dec(table_buf[3]);
if (table_buf[2] | table_buf[5])
ilm.MaxFocal = bcd2dec(table_buf[2]) * 100.f + 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.f + bcd2dec(table_buf[2]);
if (table_buf[3] | table_buf[4])
ilm.MaxFocal = bcd2dec(table_buf[3]) * 100.f + 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 = getrealf(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;
}
lid = 0x55 << 1;
u16temp = ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]);
switch (u16temp) {
case 1:
imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_3to2;
break;
case 2:
imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_16to9;
break;
default:
imSony.AspectRatio = (float)u16temp;
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 = 0x55 << 1;
u16temp = ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]);
switch (u16temp) {
case 1:
imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_3to2;
break;
case 2:
imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_16to9;
break;
default:
imSony.AspectRatio = (float)u16temp;
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[0x0a]) {
case 4:
imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_3to2;
break;
case 8:
imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_16to9;
break;
default:
imSony.AspectRatio = (float)table_buf[0x0a];
break;
}
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,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,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,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)
{
imSony.len_group9050 = table_buf_0x9050_len;
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.f + bcd2dec(table_buf[2]);
if (table_buf[3] | table_buf[4])
ilm.MaxFocal = bcd2dec(table_buf[3]) * 100.f + 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();
}
}
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.sget2LL(tag_dataoffset + tag_dataunitlen * c);
TagProcessed = 1;
break;
case 0x7303:
FORC4 cam_mul[GRBG_2_RGBG(c)] = cbuf_SR2.sget2LL(tag_dataoffset + tag_dataunitlen * c);
TagProcessed = 1;
break;
case 0x7310:
FORC4 cblack[RGGB_2_RGBG(c)] = cbuf_SR2.sget2LL(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.sget2LL(tag_dataoffset + tag_dataunitlen * c);
TagProcessed = 1;
break;
case 0x74a0:
ilm.MaxAp4MaxFocal = cbuf_SR2.sgetrealf(tag_type, int(tag_dataoffset));
TagProcessed = 1;
break;
case 0x74a1:
ilm.MaxAp4MinFocal = cbuf_SR2.sgetrealf(tag_type, int(tag_dataoffset));
TagProcessed = 1;
break;
case 0x74a2:
ilm.MaxFocal = cbuf_SR2.sgetrealf(tag_type, int(tag_dataoffset));
TagProcessed = 1;
break;
case 0x74a3:
ilm.MinFocal = cbuf_SR2.sgetrealf(tag_type, int(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.sget2LL(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.sget2LL(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.sget2LL(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] = float(Sony_SR2_wb_list[i]);
FORC3 icWBCCTC[WBCTC_count][c + 1] = cbuf_SR2.sget2LL(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.sget2LL(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] = float(Sony_SR2_wb_list1[i]);
FORC3 icWBCCTC[WBCTC_count][c + 1] = cbuf_SR2.sget2LL(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] = int(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.sget2LL(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.sget2LL(tag_dataoffset + tag_dataunitlen * c);
}
else if (tag_id == 0x7312) {
FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = cbuf_SR2.sget2LL(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[int(offset)] << 2;
int ioffset = int(offset);
/* master key is stored in big endian */
MasterKey = ((unsigned)srf_buf[ioffset] << 24) |
((unsigned)srf_buf[ioffset + 1] << 16) |
((unsigned)srf_buf[ioffset + 2] << 8) |
(unsigned)srf_buf[ioffset + 3];
/* skip SRF0 */
srf_offset = 0;
entries = srf_buf.sget2LL(srf_offset);
if (entries > 1000)
goto restore_after_parseSonySRF;
offset = srf_offset + 2;
srf_offset = srf_buf.sget4LL(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() + int(srf_offset)), int(decrypt_len - srf_offset / 4),
1, MasterKey);
entries = srf_buf.sget2LL(srf_offset);
if (entries > 1000)
goto restore_after_parseSonySRF;
offset = srf_offset + 2;
tag_offset = offset;
while (entries--) {
if (tiff_sget(unsigned(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.sget4LL(tag_dataoffset);
}
else if (tag_id == 0x0001) {
/*RawDataKey =*/ srf_buf.sget4LL(tag_dataoffset);
}
}
else goto restore_after_parseSonySRF;
}
offset = tag_offset;
/* get SRF2 */
srf_offset = srf_buf.sget4LL(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), int(decrypt_len - srf_offset / 4),
1, SRF2Key);
entries = srf_buf.sget2(int(srf_offset));
if (entries > 1000)
goto restore_after_parseSonySRF;
offset = srf_offset + 2;
tag_offset = offset;
while (entries--) {
if (srf_buf.tiff_sget(unsigned(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.sget4LL(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] = float(srf_buf.sget4LL(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.sgetrealf(tag_type, int(tag_dataoffset));
break;
case 0x0044:
ilm.MaxAp4MinFocal = srf_buf.sgetrealf(tag_type, int(tag_dataoffset));
break;
case 0x0045:
ilm.MinFocal = srf_buf.sgetrealf(tag_type, int(tag_dataoffset));
break;
case 0x0046:
ilm.MaxFocal = srf_buf.sgetrealf(tag_type, int(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);
}