#include "../../internal/dcraw_defs.h"
#include "../../internal/libraw_cameraids.h"
int LibRaw::parse_tiff_ifd(int base)
{
unsigned entries, tag, type, len, plen = 16, save, utmp;
int ifd, use_cm = 0, cfa, i, j, c, ima_len = 0;
char *cbuf, *cp;
uchar cfa_pat[16], cfa_pc[] = {0, 1, 2, 3}, tab[256];
double fm[3][4], cc[4][4], cm[4][3], cam_xyz[4][3], num;
double ab[] = {1, 1, 1, 1}, asn[] = {0, 0, 0, 0}, xyz[] = {1, 1, 1};
unsigned sony_curve[] = {0, 0, 0, 0, 0, 4095};
unsigned *buf, sony_offset = 0, sony_length = 0, sony_key = 0;
struct jhead jh;
ushort *rafdata;
if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
return 1;
ifd = tiff_nifds++;
for (j = 0; j < 4; j++)
for (i = 0; i < 4; i++)
cc[j][i] = i == j;
entries = get2();
if (entries > 512)
return 1;
INT64 fsize = ifp->size();
while (entries--)
{
tiff_get(base, &tag, &type, &len, &save);
INT64 savepos = ftell(ifp);
if (len > 8 && savepos + len > 2 * fsize)
{
fseek(ifp, save, SEEK_SET); continue;
}
if (callbacks.exif_cb)
{
callbacks.exif_cb(callbacks.exifparser_data,
tag | (is_pana_raw ? 0x30000 : ((ifd + 1) << 20)), type,
len, order, ifp, base);
fseek(ifp, savepos, SEEK_SET);
}
if (!is_pana_raw)
{
switch (tag)
{
case 0x0001:
if (len == 4)
is_pana_raw = get4();
break;
case 0x000b:
fgets(software, 64, ifp);
if (!strncmp(software, "Adobe", 5) || !strncmp(software, "dcraw", 5) ||
!strncmp(software, "UFRaw", 5) || !strncmp(software, "Bibble", 6) ||
!strcmp(software, "Digital Photo Professional"))
is_raw = 0;
break;
case 0x001c:
case 0x001d:
case 0x001e:
cblack[tag - 0x001c] = get2();
cblack[3] = cblack[1];
break;
case 0x0111:
if (len > 1 && len < 16384)
{
off_t sav = ftell(ifp);
tiff_ifd[ifd].strip_offsets = (int *)calloc(len, sizeof(int));
tiff_ifd[ifd].strip_offsets_count = len;
for (int i = 0; i < (int)len; i++)
tiff_ifd[ifd].strip_offsets[i] = get4() + base;
fseek(ifp, sav, SEEK_SET); }
case 0x0201:
case 0xf007: tiff_ifd[ifd].offset = get4() + base;
if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0)
{
fseek(ifp, tiff_ifd[ifd].offset, SEEK_SET);
if (ljpeg_start(&jh, 1))
{
tiff_ifd[ifd].comp = 6;
tiff_ifd[ifd].t_width = jh.wide;
tiff_ifd[ifd].t_height = jh.high;
tiff_ifd[ifd].bps = jh.bits;
tiff_ifd[ifd].samples = jh.clrs;
if (!(jh.sraw || (jh.clrs & 1)))
tiff_ifd[ifd].t_width *= jh.clrs;
if ((tiff_ifd[ifd].t_width > 4 * tiff_ifd[ifd].t_height) & ~jh.clrs)
{
tiff_ifd[ifd].t_width /= 2;
tiff_ifd[ifd].t_height *= 2;
}
i = order;
parse_tiff(tiff_ifd[ifd].offset + 12);
order = i;
}
}
break;
}
}
else
{
switch (tag)
{
case 0x0004:
imgdata.sizes.raw_inset_crop.ctop = get2();
break;
case 0x000a:
pana_bpp = get2();
break;
case 0x000b:
imPana.Compression = get2();
break;
case 0x000e:
case 0x000f:
case 0x0010:
imgdata.color.linear_max[tag - 14] = get2();
if (tag == 0x000f) imgdata.color.linear_max[3] = imgdata.color.linear_max[1];
break;
case 0x0013:
if ((i = get2()) > 0x100)
break;
for (c = 0; c < i; c++)
{
if ((j = get2()) < 0x100)
{
icWBC[j][0] = get2();
icWBC[j][2] = get2();
icWBC[j][1] = icWBC[j][3] =
0x100;
}
else get4();
}
break;
case 0x0018:
case 0x0019:
case 0x001a:
imPana.HighISOMultiplier[tag - 0x0018] = get2();
break;
case 0x001c:
case 0x001d:
case 0x001e:
pana_black[tag - 0x001c] = get2();
break;
case 0x002d:
pana_encoding = get2();
break;
case 0x002f:
imgdata.sizes.raw_inset_crop.ctop = get2();
break;
case 0x0030:
imgdata.sizes.raw_inset_crop.cleft = get2();
break;
case 0x0031:
imgdata.sizes.raw_inset_crop.cheight =
get2() - imgdata.sizes.raw_inset_crop.ctop;
break;
case 0x0032:
imgdata.sizes.raw_inset_crop.cwidth =
get2() - imgdata.sizes.raw_inset_crop.cleft;
break;
case 0x0037:
if (iso_speed == 65535)
iso_speed = get4();
break;
case 0x011c:
{
int n = get2();
if (n >= 1024)
imPana.gamma = (float)n / 1024.0f;
else if (n >= 256)
imPana.gamma = (float)n / 256.0f;
else
imPana.gamma = (float)n / 100.0f;
}
break;
case 0x0120:
{
unsigned sorder = order;
unsigned long sbase = base;
base = ftell(ifp);
order = get2();
fseek(ifp, 2, SEEK_CUR);
fseek(ifp, get4() - 8, SEEK_CUR);
parse_tiff_ifd(base);
base = sbase;
order = sorder;
}
break;
case 0x0121:
imPana.Multishot = get4();
break;
case 0x1201:
if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) {
ilm.LensID = fgetc(ifp);
if (ilm.LensID && (ilm.LensID != 0xff)) ilm.LensID <<= 16;
} else if (type == 258) {
unsigned n = get4();
if (n == 257) {
ilm.LensMount = LIBRAW_MOUNT_LPS_L;
ilm.LensFormat = LIBRAW_FORMAT_FF;
}
}
break;
case 0x1202:
if (ilm.LensID != 0xffffffffffffffff) {
utmp = (fgetc(ifp) << 8) | fgetc(ifp);
if (utmp) ilm.LensID += utmp;
else ilm.LensID = 0xffffffffffffffff;
}
break;
case 0x1203:
if (imgdata.lens.FocalLengthIn35mmFormat < 0.65f)
imgdata.lens.FocalLengthIn35mmFormat = get2();
break;
case 0x2009:
if ((pana_encoding == 4) || (pana_encoding == 5))
{
i = MIN(8, len);
int permut[8] = {3, 2, 1, 0, 3 + 4, 2 + 4, 1 + 4, 0 + 4};
imPana.BlackLevelDim = len;
for (j = 0; j < i; j++)
{
imPana.BlackLevel[permut[j]] =
(float)(get2()) / (float)(powf(2.f, 14.f - pana_bpp));
}
}
break;
case 0x3420:
icWBC[LIBRAW_WBI_Auto][0] = get2();
icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] = 1024.0f;
break;
case 0x3421:
icWBC[LIBRAW_WBI_Auto][2] = get2();
break;
case 0x0002:
tiff_ifd[ifd].t_width = getint(type);
break;
case 0x0003:
tiff_ifd[ifd].t_height = getint(type);
break;
case 0x0005:
width = get2();
imgdata.sizes.raw_inset_crop.cleft = width;
break;
case 0x0006:
height = get2();
imgdata.sizes.raw_inset_crop.cheight =
height - imgdata.sizes.raw_inset_crop.ctop;
break;
case 0x0007:
i = get2();
width += i;
imgdata.sizes.raw_inset_crop.cwidth =
i - imgdata.sizes.raw_inset_crop.cleft;
break;
case 0x0009:
if ((i = get2()))
filters = i;
break;
case 0x0011:
case 0x0012:
if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) && len == 1)
cam_mul[(tag - 0x0011) * 2] = get2() / 256.0;
break;
case 0x0017:
if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT))
iso_speed = get2();
break;
case 0x0024:
case 0x0025:
case 0x0026:
cam_mul[tag - 0x0024] = get2();
break;
case 0x0027:
if ((i = get2()) > 0x100)
break;
for (c = 0; c < i; c++)
{
if ((j = get2()) < 0x100)
{
icWBC[j][0] = get2();
icWBC[j][1] = icWBC[j][3] = get2();
icWBC[j][2] = get2();
}
else
fseek(ifp, 6, SEEK_CUR);
}
break;
if (len < 50 || cam_mul[0] > 0.001f)
break;
fseek(ifp, 12, SEEK_CUR);
FORC3 cam_mul[c] = get2();
break;
case 0x002e:
if ((type != LIBRAW_EXIFTAG_TYPE_UNDEFINED) || (fgetc(ifp) != 0xff) || (fgetc(ifp) != 0xd8))
break;
thumb_offset = ftell(ifp) - 2;
thumb_length = len;
break;
case 0x0118:
if (type != LIBRAW_EXIFTAG_TYPE_LONG)
break;
load_raw = &LibRaw::panasonic_load_raw;
load_flags = 0x2008;
case 0x0111:
if (len > 1 && len < 16384)
{
off_t sav = ftell(ifp);
tiff_ifd[ifd].strip_offsets = (int *)calloc(len, sizeof(int));
tiff_ifd[ifd].strip_offsets_count = len;
for (int i = 0; i < (int)len; i++)
tiff_ifd[ifd].strip_offsets[i] = get4() + base;
fseek(ifp, sav, SEEK_SET); }
tiff_ifd[ifd].offset = get4() + base;
if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0)
{
fseek(ifp, tiff_ifd[ifd].offset, SEEK_SET);
if (ljpeg_start(&jh, 1))
{
tiff_ifd[ifd].comp = 6;
tiff_ifd[ifd].t_width = jh.wide;
tiff_ifd[ifd].t_height = jh.high;
tiff_ifd[ifd].bps = jh.bits;
tiff_ifd[ifd].samples = jh.clrs;
if (!(jh.sraw || (jh.clrs & 1)))
tiff_ifd[ifd].t_width *= jh.clrs;
if ((tiff_ifd[ifd].t_width > 4 * tiff_ifd[ifd].t_height) & ~jh.clrs)
{
tiff_ifd[ifd].t_width /= 2;
tiff_ifd[ifd].t_height *= 2;
}
i = order;
parse_tiff(tiff_ifd[ifd].offset + 12);
order = i;
}
}
break;
}
}
switch (tag)
{
case 0xf000:
fseek(ifp, get4() + base, SEEK_SET);
parse_tiff_ifd(base);
break;
case 0x00fe:
tiff_ifd[ifd].newsubfiletype = getreal(type);
break;
case 0x0100:
case 0xf001:
tiff_ifd[ifd].t_width = getint(type);
break;
case 0x0101:
case 0xf002:
tiff_ifd[ifd].t_height = getint(type);
break;
case 0x0102:
case 0xf003:
tiff_ifd[ifd].samples = len & 7;
tiff_ifd[ifd].bps = getint(type);
if (tiff_bps < (unsigned)tiff_ifd[ifd].bps)
tiff_bps = tiff_ifd[ifd].bps;
break;
case 0xf006:
raw_height = 0;
if (tiff_ifd[ifd].bps > 12)
break;
load_raw = &LibRaw::packed_load_raw;
load_flags = get4() ? 24 : 80;
break;
case 0x0103:
tiff_ifd[ifd].comp = getint(type);
break;
case 0x0106:
tiff_ifd[ifd].phint = get2();
break;
case 0x010e:
fread(desc, 512, 1, ifp);
break;
case 0x010f:
fgets(make, 64, ifp);
break;
case 0x0110:
if (!strncmp(make, "Hasselblad", 10) && model[0] &&
(imHassy.format != LIBRAW_HF_Imacon))
break;
fgets(model, 64, ifp);
break;
case 0x0116: tiff_ifd[ifd].rows_per_strip = getint(type);
break;
case 0x0112:
tiff_ifd[ifd].t_flip = "50132467"[get2() & 7] - '0';
break;
case 0x0115:
tiff_ifd[ifd].samples = getint(type) & 7;
break;
case 0x0152:
tiff_ifd[ifd].extrasamples = (getint(type) & 0xff) + 1024;
break;
case 0x0117:
if (len > 1 && len < 16384)
{
off_t sav = ftell(ifp);
tiff_ifd[ifd].strip_byte_counts = (int *)calloc(len, sizeof(int));
tiff_ifd[ifd].strip_byte_counts_count = len;
for (int i = 0; i < (int)len; i++)
tiff_ifd[ifd].strip_byte_counts[i] = get4();
fseek(ifp, sav, SEEK_SET); }
case 0x0202: case 0xf008: tiff_ifd[ifd].bytes = get4();
break;
case 0xf00e: FORC3 cam_mul[(4 - c) % 3] = getint(type);
break;
case 0x0131:
fgets(software, 64, ifp);
if (!strncmp(software, "Adobe", 5) || !strncmp(software, "dcraw", 5) ||
!strncmp(software, "UFRaw", 5) || !strncmp(software, "Bibble", 6) ||
!strcmp(software, "Digital Photo Professional"))
is_raw = 0;
break;
case 0x0132:
get_timestamp(0);
break;
case 0x013b:
fread(artist, 64, 1, ifp);
break;
case 0x013d: tiff_ifd[ifd].predictor = getint(type);
break;
case 0x0142:
tiff_ifd[ifd].t_tile_width = getint(type);
break;
case 0x0143:
tiff_ifd[ifd].t_tile_length = getint(type);
break;
case 0x0144:
tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
if (len == 1)
tiff_ifd[ifd].t_tile_width = tiff_ifd[ifd].t_tile_length = 0;
if (len == 4)
{
load_raw = &LibRaw::sinar_4shot_load_raw;
is_raw = 5;
}
break;
case 0x0145: tiff_ifd[ifd].bytes = len > 1 ? ftell(ifp) : get4();
break;
case 0x014a:
if (!strcmp(model, "DSLR-A100") && tiff_ifd[ifd].t_width == 3872)
{
load_raw = &LibRaw::sony_arw_load_raw;
data_offset = get4() + base;
ifd++;
if (ifd >= int(sizeof tiff_ifd / sizeof tiff_ifd[0]))
throw LIBRAW_EXCEPTION_IO_CORRUPT;
break;
}
if (!strncmp(make, "Hasselblad", 10) &&
libraw_internal_data.unpacker_data.hasselblad_parser_flag)
{
fseek(ifp, ftell(ifp) + 4, SEEK_SET);
fseek(ifp, get4() + base, SEEK_SET);
parse_tiff_ifd(base);
break;
}
if (len > 1000)
len = 1000;
while (len--)
{
i = ftell(ifp);
fseek(ifp, get4() + base, SEEK_SET);
if (parse_tiff_ifd(base))
break;
fseek(ifp, i + 4, SEEK_SET);
}
break;
case 0x0153: tiff_ifd[ifd].sample_format = getint(type);
break;
case 0x0190: strcpy(make, "Sarnoff");
maximum = 0xfff;
break;
case 0x02bc: if ((tagtypeIs(LIBRAW_EXIFTAG_TYPE_BYTE) ||
tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII) ||
tagtypeIs(LIBRAW_EXIFTAG_TYPE_SBYTE) ||
tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary)) &&
(len > 1) && (len < 5100000))
{
xmpdata = (char *)malloc(xmplen = len + 1);
fread(xmpdata, len, 1, ifp);
xmpdata[len] = 0;
}
break;
case 0x7000:
imSony.SonyRawFileType = get2();
break;
case 0x7010: FORC4 sony_curve[c + 1] = get2() >> 2 & 0xfff;
for (i = 0; i < 5; i++)
for (j = sony_curve[i] + 1; j <= (int)sony_curve[i + 1]; j++)
curve[j] = curve[j - 1] + (1 << i);
break;
case 0x7200: sony_offset = get4();
break;
case 0x7201: sony_length = get4();
break;
case 0x7221: sony_key = get4();
break;
case 0x7250: parse_minolta(ftell(ifp));
raw_width = 0;
break;
case 0x7303: FORC4 cam_mul[GRBG_2_RGBG(c)] = get2();
break;
case 0x7313: FORC4 cam_mul[RGGB_2_RGBG(c)] = get2();
break;
case 0x7310: FORC4 cblack[RGGB_2_RGBG(c)] = get2();
i = cblack[3];
FORC3 if (i > (int)cblack[c]) i = cblack[c];
FORC4 cblack[c] -= i;
black = i;
break;
case 0x827d:
fgets(model2, 64, ifp);
break;
case 0x828d:
if (get2() == 6 && get2() == 6)
tiff_ifd[ifd].t_filters = filters = 9;
break;
case 0x828e:
if (filters == 9)
{
FORC(36)((char *)xtrans)[c] = fgetc(ifp) & 3;
break;
}
case 0xfd09:
if (len == 36)
{
tiff_ifd[ifd].t_filters = filters = 9;
colors = 3;
FORC(36) xtrans[0][c] = fgetc(ifp) & 3;
}
else if (len > 0)
{
if ((plen = len) > 16)
plen = 16;
fread(cfa_pat, 1, plen, ifp);
for (colors = cfa = i = 0; i < (int)plen && colors < 4; i++)
{
if (cfa_pat[i] > 31)
continue; colors += !(cfa & (1 << cfa_pat[i]));
cfa |= 1 << cfa_pat[i];
}
if (cfa == 070)
memcpy(cfa_pc, "\003\004\005", 3);
if (cfa == 072)
memcpy(cfa_pc, "\005\003\004\001", 4);
goto guess_cfa_pc;
}
break;
case 0x8290: case 0xfe00: fseek(ifp, get4() + base, SEEK_SET);
parse_kodak_ifd(base);
break;
case 0x829a:
tiff_ifd[ifd].t_shutter = shutter = getreal(type);
break;
case 0x829d:
aperture = getreal(type);
break;
case 0x9400:
imCommon.exifAmbientTemperature = getreal(type);
if ((imCommon.CameraTemperature > -273.15f) &&
((OlyID == OlyID_TG_5) || (OlyID == OlyID_TG_6)))
imCommon.CameraTemperature +=
imCommon.exifAmbientTemperature;
break;
case 0x9401:
imCommon.exifHumidity = getreal(type);
break;
case 0x9402:
imCommon.exifPressure = getreal(type);
break;
case 0x9403:
imCommon.exifWaterDepth = getreal(type);
break;
case 0x9404:
imCommon.exifAcceleration = getreal(type);
break;
case 0x9405:
imCommon.exifCameraElevationAngle = getreal(type);
break;
case 0xa405: imgdata.lens.FocalLengthIn35mmFormat = get2();
break;
case 0xa431: case 0xc62f:
stmread(imgdata.shootinginfo.BodySerial, len, ifp);
break;
case 0xa432: imgdata.lens.MinFocal = getreal(type);
imgdata.lens.MaxFocal = getreal(type);
imgdata.lens.MaxAp4MinFocal = getreal(type);
imgdata.lens.MaxAp4MaxFocal = getreal(type);
break;
case 0xa435: stmread(imgdata.lens.LensSerial, len, ifp);
break;
case 0xc630: imgdata.lens.MinFocal = getreal(type);
imgdata.lens.MaxFocal = getreal(type);
imgdata.lens.MaxAp4MinFocal = getreal(type);
imgdata.lens.MaxAp4MaxFocal = getreal(type);
break;
case 0xa420:
stmread(imgdata.color.ImageUniqueID, len, ifp);
break;
case 0xc65d:
imgdata.color.RawDataUniqueID[16] = 0;
fread(imgdata.color.RawDataUniqueID, 1, 16, ifp);
break;
case 0xa433: stmread(imgdata.lens.LensMake, len, ifp);
break;
case 0xa434: stmread(imgdata.lens.Lens, len, ifp);
if (!strncmp(imgdata.lens.Lens, "----", 4))
imgdata.lens.Lens[0] = 0;
break;
case 0x9205:
imgdata.lens.EXIF_MaxAp = libraw_powf64l(2.0f, (getreal(type) / 2.0f));
break;
case 0x8602:
FORC4
{
int q = get2();
if (q)
cam_mul[GRGB_2_RGBG(c)] = 4096.0 / q;
}
break;
case 0x8603:
fread(software, 1, 7, ifp);
if (strncmp(software, "MATRIX", 6))
break;
colors = 4;
for (raw_color = i = 0; i < 3; i++)
{
FORC4 fscanf(ifp, "%f", &rgb_cam[i][GRGB_2_RGBG(c)]);
if (!use_camera_wb)
continue;
num = 0;
FORC4 num += rgb_cam[i][c];
FORC4 rgb_cam[i][c] /= MAX(1, num);
}
break;
case 0x8606:
parse_mos(ftell(ifp));
case 0x85ff: strcpy(make, "Leaf");
break;
case 0x8769:
fseek(ifp, get4() + base, SEEK_SET);
parse_exif(base);
break;
case 0x8825:
{
unsigned pos;
fseek(ifp, pos = (get4() + base), SEEK_SET);
parse_gps(base);
fseek(ifp, pos, SEEK_SET);
parse_gps_libraw(base);
}
break;
case 0x8773:
case 0xc68f:
profile_offset = ftell(ifp);
profile_length = len;
break;
case 0x9102:
kodak_cbpp = get4();
break;
case 0x920a:
focal_len = getreal(type);
break;
case 0x9211:
shot_order = getint(type);
break;
case 0x9215:
imCommon.exifExposureIndex = getreal(type);
break;
case 0x9218:
for (raw_color = i = 0; i < 3; i++)
{
getreal(type);
FORC3 rgb_cam[i][c] = getreal(type);
}
break;
case 0xa010: strip_offset = get4();
switch (tiff_ifd[ifd].comp)
{
case 0x8002: load_raw = &LibRaw::samsung_load_raw;
break;
case 0x8004: load_raw = &LibRaw::samsung2_load_raw;
break;
case 0x8005: load_raw = &LibRaw::samsung3_load_raw;
break;
}
break;
case 0xb4c3:
imHassy.format = LIBRAW_HF_Imacon;
strcpy(make, "Imacon");
data_offset = ftell(ifp);
ima_len = len;
break;
case 0xb4c7: if (!ima_len)
break;
fseek(ifp, 38, SEEK_CUR);
case 0xb4c2: fseek(ifp, 40, SEEK_CUR);
raw_width = get4();
raw_height = get4();
left_margin = get4() & 7;
width = raw_width - left_margin - (get4() & 7);
top_margin = get4() & 7;
height = raw_height - top_margin - (get4() & 7);
if (raw_width == 7262 && ima_len == 234317952)
{
height = 5412;
width = 7216;
left_margin = 7;
filters = 0;
}
else if (raw_width == 7262)
{
height = 5444;
width = 7244;
left_margin = 7;
}
fseek(ifp, 52, SEEK_CUR);
FORC3 cam_mul[c] = getreal(11);
fseek(ifp, 114, SEEK_CUR);
flip = (get2() >> 7) * 90;
if (width * (height * 6l) == ima_len)
{
if (flip % 180 == 90)
SWAP(width, height);
raw_width = width;
raw_height = height;
left_margin = top_margin = filters = flip = 0;
}
c = unsigned(height) * unsigned(width) / 1000000;
if (c == 32)
c--;
sprintf(model, "Ixpress %d-Mp", c);
load_raw = &LibRaw::imacon_full_load_raw;
if (filters)
{
if (left_margin & 1)
filters = 0x61616161;
load_raw = &LibRaw::unpacked_load_raw;
}
maximum = 0xffff;
break;
case 0xc516:
case 0xc517: if (len < 1 || len > 2560000 || !(cbuf = (char *)malloc(len)))
break;
if (fread(cbuf, 1, len, ifp) != (int)len)
throw LIBRAW_EXCEPTION_IO_CORRUPT; cbuf[len - 1] = 0;
for (cp = cbuf - 1; cp && cp < cbuf + len; cp = strchr(cp, '\n'))
if (!strncmp(++cp, "Neutral ", 8))
sscanf(cp + 8, "%f %f %f", cam_mul, cam_mul + 1, cam_mul + 2);
free(cbuf);
break;
case 0xc51a: if (!make[0])
strcpy(make, "Hasselblad");
break;
case 0xc51b:
if (!libraw_internal_data.unpacker_data.hasselblad_parser_flag)
{
libraw_internal_data.unpacker_data.hasselblad_parser_flag = 1;
i = order;
j = ftell(ifp);
c = tiff_nifds;
order = get2();
fseek(ifp, j + (get2(), get4()), SEEK_SET);
parse_tiff_ifd(j);
maximum = 0xffff;
tiff_nifds = c;
order = i;
break;
}
case 0xc612:
FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
if (!make[0])
strcpy(make, "DNG");
is_raw = 1;
break;
case 0xc614:
stmread(imgdata.color.UniqueCameraModel, len, ifp);
if (model[0])
break;
strncpy(make, imgdata.color.UniqueCameraModel,
MIN(len, sizeof(imgdata.color.UniqueCameraModel)));
if ((cp = strchr(make, ' ')))
{
strcpy(model, cp + 1);
*cp = 0;
}
break;
case 0xc616:
if (filters == 9)
break;
if (len > 4)
len = 4;
colors = len;
fread(cfa_pc, 1, colors, ifp);
guess_cfa_pc:
FORCC tab[cfa_pc[c]] = c;
cdesc[c] = 0;
for (i = 16; i--;)
filters = filters << 2 | tab[cfa_pat[i % plen]];
filters -= !filters;
tiff_ifd[ifd].t_filters = filters;
break;
case 0xc617:
if (get2() == 2)
tiff_ifd[ifd].t_fuji_width = fuji_width = 1;
break;
case 0x0123: case 0xc618:
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_LINTABLE;
tiff_ifd[ifd].lineartable_offset = ftell(ifp);
tiff_ifd[ifd].lineartable_len = len;
linear_table(len);
break;
case 0xc619:
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
tiff_ifd[ifd].dng_levels.dng_fcblack[4] =
tiff_ifd[ifd].dng_levels.dng_cblack[4] = cblack[4] = get2();
tiff_ifd[ifd].dng_levels.dng_fcblack[5] =
tiff_ifd[ifd].dng_levels.dng_cblack[5] = cblack[5] = get2();
if (cblack[4] * cblack[5] >
(LIBRAW_CBLACK_SIZE -
7)) tiff_ifd[ifd].dng_levels.dng_fcblack[4] =
tiff_ifd[ifd].dng_levels.dng_fcblack[5] =
tiff_ifd[ifd].dng_levels.dng_cblack[4] =
tiff_ifd[ifd].dng_levels.dng_cblack[5] = cblack[4] =
cblack[5] = 1;
break;
case 0xf00c:
if (!is_4K_RAFdata)
{
unsigned fwb[4];
FORC4 fwb[c] = get4();
if (fwb[3] < 0x100)
{
icWBC[fwb[3]][0] = fwb[1];
icWBC[fwb[3]][1] = icWBC[fwb[3]][3] = fwb[0];
icWBC[fwb[3]][2] = fwb[2];
if ((fwb[3] == 17) &&
(libraw_internal_data.unpacker_data.lenRAFData > 3) &&
(libraw_internal_data.unpacker_data.lenRAFData < 10240000))
{
INT64 f_save = ftell(ifp);
rafdata = (ushort *)malloc(
sizeof(ushort) * libraw_internal_data.unpacker_data.lenRAFData);
fseek(ifp, libraw_internal_data.unpacker_data.posRAFData, SEEK_SET);
fread(rafdata, sizeof(ushort),
libraw_internal_data.unpacker_data.lenRAFData, ifp);
fseek(ifp, f_save, SEEK_SET);
uchar *PrivateMknBuf = (uchar *)rafdata;
int PrivateMknLength = libraw_internal_data.unpacker_data.lenRAFData
<< 1;
for (int pos = 0; pos < PrivateMknLength - 16; pos++)
{
if (!memcmp(PrivateMknBuf + pos, "TSNERDTS", 8))
{
imFuji.isTSNERDTS = 1;
break;
}
}
if (!rafdata[0])
imFuji.RAFDataVersion = rafdata[1];
int fj;
for (int fi = 0;
fi < int(libraw_internal_data.unpacker_data.lenRAFData - 3); fi++)
{ if ((fwb[0] == rafdata[fi]) && (fwb[1] == rafdata[fi + 1]) &&
(fwb[2] == rafdata[fi + 2]))
{
if (rafdata[fi - 15] !=
fwb[0]) continue;
for (int wb_ind = 0, ofst = fi - 15; wb_ind < Fuji_wb_list1.size();
wb_ind++, ofst += 3)
{
icWBC[Fuji_wb_list1[wb_ind]][1] =
icWBC[Fuji_wb_list1[wb_ind]][3] = rafdata[ofst];
icWBC[Fuji_wb_list1[wb_ind]][0] = rafdata[ofst + 1];
icWBC[Fuji_wb_list1[wb_ind]][2] = rafdata[ofst + 2];
}
if ((imFuji.RAFDataVersion == 0x0260) || (imFuji.RAFDataVersion == 0x0261) || (imFuji.RAFDataVersion == 0x0262)) fi += 24;
fi += 96;
for (fj = fi; fj < (fi + 15); fj += 3)
{
if (rafdata[fj] != rafdata[fi])
{
fj -= 93;
if ((imFuji.RAFDataVersion == 0x0260) || (imFuji.RAFDataVersion == 0x0261) || (imFuji.RAFDataVersion == 0x0262)) fj -= 9;
for (int iCCT = 0, ofst = fj; iCCT < 31;
iCCT++, ofst += 3)
{
icWBCCTC[iCCT][0] = FujiCCT_K[iCCT];
icWBCCTC[iCCT][1] = rafdata[ofst + 1];
icWBCCTC[iCCT][2] = icWBCCTC[iCCT][4] = rafdata[ofst];
icWBCCTC[iCCT][3] = rafdata[ofst + 2];
}
break;
}
}
free(rafdata);
break;
}
}
}
}
FORC4 fwb[c] = get4();
if (fwb[3] < 0x100)
{
icWBC[fwb[3]][0] = fwb[1];
icWBC[fwb[3]][1] =
icWBC[fwb[3]][3] = fwb[0];
icWBC[fwb[3]][2] = fwb[2];
}
}
break;
case 0xf00d:
if (!is_4K_RAFdata)
{
FORC3 icWBC[LIBRAW_WBI_Auto][(4 - c) % 3] = getint(type);
icWBC[LIBRAW_WBI_Auto][3] = icWBC[LIBRAW_WBI_Auto][1];
}
break;
case 0xc615:
stmread(imgdata.color.LocalizedCameraModel, len, ifp);
break;
case 0xf00a: cblack[4] = cblack[5] = MIN(sqrt((double)len), 64);
case 0xc61a:
if (tiff_ifd[ifd].samples > 1 &&
tiff_ifd[ifd].samples == (int)len) {
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
for (i = 0; i < 4 && i < (int)len; i++)
{
tiff_ifd[ifd].dng_levels.dng_fcblack[i] = getreal(type);
tiff_ifd[ifd].dng_levels.dng_cblack[i] = cblack[i] =
tiff_ifd[ifd].dng_levels.dng_fcblack[i] + 0.5;
}
tiff_ifd[ifd].dng_levels.dng_fblack =
tiff_ifd[ifd].dng_levels.dng_black = black = 0;
}
else if (tiff_ifd[ifd].samples > 1 && (tiff_ifd[ifd].samples * cblack[4] * cblack[5] == len))
{
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
tiff_ifd[ifd].dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1] =
cblack[LIBRAW_CBLACK_SIZE - 1] = len;
for (i = 0; i < (int)len && i < LIBRAW_CBLACK_SIZE - 7; i++)
{
tiff_ifd[ifd].dng_levels.dng_fcblack[i + 6] = getreal(type);
tiff_ifd[ifd].dng_levels.dng_cblack[i + 6] = cblack[i + 6] =
tiff_ifd[ifd].dng_levels.dng_fcblack[i + 6] + 0.5;
}
}
else if ((cblack[4] * cblack[5] < 2) && len == 1)
{
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
tiff_ifd[ifd].dng_levels.dng_fblack = getreal(type);
black = tiff_ifd[ifd].dng_levels.dng_black =
tiff_ifd[ifd].dng_levels.dng_fblack;
}
else if (cblack[4] * cblack[5] <= len)
{
FORC(int(cblack[4] * cblack[5]))
{
tiff_ifd[ifd].dng_levels.dng_fcblack[6 + c] = getreal(type);
cblack[6 + c] = tiff_ifd[ifd].dng_levels.dng_fcblack[6 + c];
}
black = 0;
FORC4
cblack[c] = 0;
if (tag == 0xc61a)
{
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
FORC(int(cblack[4] * cblack[5]))
tiff_ifd[ifd].dng_levels.dng_cblack[6 + c] = cblack[6 + c];
tiff_ifd[ifd].dng_levels.dng_fblack = 0;
tiff_ifd[ifd].dng_levels.dng_black = 0;
FORC4
tiff_ifd[ifd].dng_levels.dng_fcblack[c] =
tiff_ifd[ifd].dng_levels.dng_cblack[c] = 0;
}
}
break;
case 0xc61b:
case 0xc61c:
for (num = i = 0; i < (int)len && i < 65536; i++)
num += getreal(type);
if (len > 0)
{
black += num / len + 0.5;
tiff_ifd[ifd].dng_levels.dng_fblack += num / float(len);
tiff_ifd[ifd].dng_levels.dng_black += num / len + 0.5;
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
}
break;
case 0xc61d:
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_WHITE;
tiff_ifd[ifd].dng_levels.dng_whitelevel[0] = maximum = getint(type);
if (tiff_ifd[ifd].samples > 1) for (i = 1; i < 4 && i < (int)len; i++)
tiff_ifd[ifd].dng_levels.dng_whitelevel[i] = getint(type);
break;
case 0xc61e:
{
float q1 = getreal(type);
float q2 = getreal(type);
if (q1 > 0.00001f && q2 > 0.00001f)
{
pixel_aspect = q1 / q2;
if (pixel_aspect > 0.995 && pixel_aspect < 1.005)
pixel_aspect = 1.0;
}
}
break;
case 0xc61f:
if (len == 2)
{
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_CROPORIGIN;
tiff_ifd[ifd].dng_levels.default_crop[0] = getreal(type);
tiff_ifd[ifd].dng_levels.default_crop[1] = getreal(type);
if (!strncasecmp(make, "SONY", 4))
{
imgdata.sizes.raw_inset_crop.cleft =
tiff_ifd[ifd].dng_levels.default_crop[0];
imgdata.sizes.raw_inset_crop.ctop =
tiff_ifd[ifd].dng_levels.default_crop[1];
}
}
break;
case 0xc620:
if (len == 2)
{
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_CROPSIZE;
tiff_ifd[ifd].dng_levels.default_crop[2] = getreal(type);
tiff_ifd[ifd].dng_levels.default_crop[3] = getreal(type);
if (!strncasecmp(make, "SONY", 4))
{
imgdata.sizes.raw_inset_crop.cwidth =
tiff_ifd[ifd].dng_levels.default_crop[2];
imgdata.sizes.raw_inset_crop.cheight =
tiff_ifd[ifd].dng_levels.default_crop[3];
}
}
break;
case 0x74c7:
if ((len == 2) && !strncasecmp(make, "SONY", 4))
{
imgdata.sizes.raw_inset_crop.cleft = get4();
imgdata.sizes.raw_inset_crop.ctop = get4();
}
break;
case 0x74c8:
if ((len == 2) && !strncasecmp(make, "SONY", 4))
{
imgdata.sizes.raw_inset_crop.cwidth = get4();
imgdata.sizes.raw_inset_crop.cheight = get4();
}
break;
case 0xc65a: tiff_ifd[ifd].dng_color[0].illuminant = get2();
tiff_ifd[ifd].dng_color[0].parsedfields |= LIBRAW_DNGFM_ILLUMINANT;
break;
case 0xc65b: tiff_ifd[ifd].dng_color[1].illuminant = get2();
tiff_ifd[ifd].dng_color[1].parsedfields |= LIBRAW_DNGFM_ILLUMINANT;
break;
case 0xc621:
case 0xc622:
{
int chan = (len == 9) ? 3 : (len == 12 ? 4 : 0);
i = tag == 0xc621 ? 0 : 1;
if (chan)
{
tiff_ifd[ifd].dng_color[i].parsedfields |= LIBRAW_DNGFM_COLORMATRIX;
imHassy.nIFD_CM[i] = ifd;
}
FORC(chan) for (j = 0; j < 3; j++)
{
tiff_ifd[ifd].dng_color[i].colormatrix[c][j] = cm[c][j] = getreal(type);
}
use_cm = 1;
}
break;
case 0xc714:
case 0xc715:
{
int chan = (len == 9) ? 3 : (len == 12 ? 4 : 0);
i = tag == 0xc714 ? 0 : 1;
if (chan)
tiff_ifd[ifd].dng_color[i].parsedfields |= LIBRAW_DNGFM_FORWARDMATRIX;
for (j = 0; j < 3; j++)
FORC(chan)
{
tiff_ifd[ifd].dng_color[i].forwardmatrix[j][c] = fm[j][c] =
getreal(type);
}
}
break;
case 0xc623:
case 0xc624:
{
int chan = (len == 9) ? 3 : (len == 16 ? 4 : 0);
j = tag == 0xc623 ? 0 : 1;
if (chan)
tiff_ifd[ifd].dng_color[j].parsedfields |= LIBRAW_DNGFM_CALIBRATION;
for (i = 0; i < chan; i++)
FORC(chan)
{
tiff_ifd[ifd].dng_color[j].calibration[i][c] = cc[i][c] =
getreal(type);
}
}
break;
case 0xc627:
if (len >= 3)
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_ANALOGBALANCE;
for (c = 0; c < (int)len && c < 4; c++)
{
tiff_ifd[ifd].dng_levels.analogbalance[c] = ab[c] = getreal(type);
}
break;
case 0xc628:
if (len >= 3)
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_ASSHOTNEUTRAL;
for (c = 0; c < (int)len && c < 4; c++)
tiff_ifd[ifd].dng_levels.asshotneutral[c] = asn[c] = getreal(type);
break;
case 0xc629:
xyz[0] = getreal(type);
xyz[1] = getreal(type);
xyz[2] = 1 - xyz[0] - xyz[1];
FORC3 xyz[c] /= LibRaw_constants::d65_white[c];
break;
case 0xc62a:
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BASELINEEXPOSURE;
tiff_ifd[ifd].dng_levels.baseline_exposure = getreal(type);
break;
case 0xc62e:
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_LINEARRESPONSELIMIT;
tiff_ifd[ifd].dng_levels.LinearResponseLimit = getreal(type);
break;
case 0xc634:
if (!(imgdata.params.raw_processing_options &
LIBRAW_PROCESSING_SKIP_MAKERNOTES))
{
char mbuf[64];
INT64 curr_pos, start_pos = ftell(ifp);
unsigned MakN_order, m_sorder = order;
unsigned MakN_length;
unsigned pos_in_original_raw;
fread(mbuf, 1, 6, ifp);
if (!strcmp(mbuf, "Adobe"))
{
order = 0x4d4d; curr_pos = start_pos + 6;
while (curr_pos + 8 - start_pos <= len)
{
fread(mbuf, 1, 4, ifp);
curr_pos += 8;
if (!strncmp(mbuf, "Pano", 4))
{ parseAdobePanoMakernote();
}
if (!strncmp(mbuf, "MakN", 4))
{
MakN_length = get4();
MakN_order = get2();
pos_in_original_raw = get4();
order = MakN_order;
INT64 save_pos = ifp->tell();
parse_makernote_0xc634(curr_pos + 6 - pos_in_original_raw, 0,
AdobeDNG);
curr_pos = save_pos + MakN_length - 6;
fseek(ifp, curr_pos, SEEK_SET);
fread(mbuf, 1, 4, ifp);
curr_pos += 8;
if (!strncmp(mbuf, "Pano ", 4))
{
parseAdobePanoMakernote();
}
if (!strncmp(mbuf, "RAF ", 4))
{ parseAdobeRAFMakernote();
}
if (!strncmp(mbuf, "SR2 ", 4))
{
order = 0x4d4d;
MakN_length = get4();
MakN_order = get2();
pos_in_original_raw = get4();
order = MakN_order;
unsigned *buf_SR2;
unsigned entries, tag, type, len, save;
unsigned SR2SubIFDOffset = 0;
unsigned SR2SubIFDLength = 0;
unsigned SR2SubIFDKey = 0;
int base = curr_pos + 6 - pos_in_original_raw;
entries = get2();
while (entries--)
{
tiff_get(base, &tag, &type, &len, &save);
if (tag == 0x7200)
{
SR2SubIFDOffset = get4();
}
else if (tag == 0x7201)
{
SR2SubIFDLength = get4();
}
else if (tag == 0x7221)
{
SR2SubIFDKey = get4();
}
fseek(ifp, save, SEEK_SET);
}
if (SR2SubIFDLength && (SR2SubIFDLength < 10240000) &&
(buf_SR2 = (unsigned *)malloc(SR2SubIFDLength + 1024)))
{ fseek(ifp, SR2SubIFDOffset + base, SEEK_SET);
fread(buf_SR2, SR2SubIFDLength, 1, ifp);
sony_decrypt(buf_SR2, SR2SubIFDLength / 4, 1, SR2SubIFDKey);
parseSonySR2((uchar *)buf_SR2, SR2SubIFDOffset,
SR2SubIFDLength, AdobeDNG);
free(buf_SR2);
}
}
break;
}
}
}
else
{
fread(mbuf + 6, 1, 2, ifp);
if (!strcmp(mbuf, "RICOH") && ((sget2((uchar *)mbuf + 6) == 0x4949) ||
(sget2((uchar *)mbuf + 6) == 0x4d4d)))
{
is_PentaxRicohMakernotes = 1;
}
if (!strcmp(mbuf, "PENTAX ") || !strcmp(mbuf, "SAMSUNG") ||
is_PentaxRicohMakernotes)
{
fseek(ifp, start_pos, SEEK_SET);
parse_makernote_0xc634(base, 0, CameraDNG);
}
}
fseek(ifp, start_pos, SEEK_SET);
order = m_sorder;
}
if (dng_version)
{
break;
}
parse_minolta(j = get4() + base);
fseek(ifp, j, SEEK_SET);
parse_tiff_ifd(base);
break;
case 0xc640: read_shorts(cr2_slice, 3);
break;
case 0xc68b:
stmread(imgdata.color.OriginalRawFileName, len, ifp);
break;
case 0xc68d:
tiff_ifd[ifd].t_tm = top_margin = getint(type);
tiff_ifd[ifd].t_lm = left_margin = getint(type);
tiff_ifd[ifd].t_vheight = height = getint(type) - top_margin;
tiff_ifd[ifd].t_vwidth = width = getint(type) - left_margin;
break;
case 0xc68e:
for (i = 0; i < (int)len && i < 32; i++)
((int *)mask)[i] = getint(type);
black = 0;
break;
case 0xc71a:
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_PREVIEWCS;
tiff_ifd[ifd].dng_levels.preview_colorspace = getint(type);
break;
case 0xc741:
tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_OPCODE2;
tiff_ifd[ifd].opcode2_offset = meta_offset = ftell(ifp);
break;
case 0xfd04:
if (len < 13)
break;
fseek(ifp, 16, SEEK_CUR);
data_offset = get4();
fseek(ifp, 28, SEEK_CUR);
data_offset += get4();
load_raw = &LibRaw::packed_load_raw;
break;
case 0xfe02: if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII))
fgets(model2, 64, ifp);
}
fseek(ifp, save, SEEK_SET);
}
if (sony_length && sony_length < 10240000 &&
(buf = (unsigned *)malloc(sony_length)))
{
fseek(ifp, sony_offset, SEEK_SET);
fread(buf, sony_length, 1, ifp);
sony_decrypt(buf, sony_length / 4, 1, sony_key);
parseSonySR2((uchar *)buf, sony_offset, sony_length, nonDNG);
free(buf);
}
for (i = 0; i < colors && i < 4; i++)
FORCC cc[i][c] *= ab[i];
if (use_cm)
{
FORCC for (i = 0; i < 3; i++) for (cam_xyz[c][i] = j = 0; j < colors; j++)
cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
cam_xyz_coeff(cmatrix, cam_xyz);
}
if (asn[0])
{
cam_mul[3] = 0;
FORCC
if (fabs(asn[c]) > 0.0001)
cam_mul[c] = 1 / asn[c];
}
if (!use_cm)
FORCC if (fabs(cc[c][c]) > 0.0001) pre_mul[c] /= cc[c][c];
return 0;
}
int LibRaw::parse_tiff(int base)
{
int doff;
fseek(ifp, base, SEEK_SET);
order = get2();
if (order != 0x4949 && order != 0x4d4d)
return 0;
get2();
while ((doff = get4()))
{
fseek(ifp, doff + base, SEEK_SET);
if (parse_tiff_ifd(base))
break;
}
return 1;
}
struct ifd_size_t
{
int ifdi;
INT64 databits;
};
int ifd_size_t_cmp(const void *a, const void *b)
{
if (!a || !b)
return 0;
const ifd_size_t *ai = (ifd_size_t *)a;
const ifd_size_t *bi = (ifd_size_t *)b;
return bi->databits > ai->databits ? 1
: (bi->databits < ai->databits ? -1 : 0);
}
void LibRaw::apply_tiff()
{
int max_samp = 0, ties = 0, raw = -1, thm = -1, i;
unsigned long long ns, os;
struct jhead jh;
thumb_misc = 16;
if (thumb_offset)
{
fseek(ifp, thumb_offset, SEEK_SET);
if (ljpeg_start(&jh, 1))
{
if ((unsigned)jh.bits < 17 && (unsigned)jh.wide < 0x10000 &&
(unsigned)jh.high < 0x10000)
{
thumb_misc = jh.bits;
thumb_width = jh.wide;
thumb_height = jh.high;
}
}
}
for (i = tiff_nifds; i--;)
{
if (tiff_ifd[i].t_shutter)
shutter = tiff_ifd[i].t_shutter;
tiff_ifd[i].t_shutter = shutter;
}
if (dng_version)
{
int ifdc = 0;
for (i = 0; i < (int)tiff_nifds; i++)
{
if (tiff_ifd[i].t_width < 1 || tiff_ifd[i].t_width > 65535 ||
tiff_ifd[i].t_height < 1 || tiff_ifd[i].t_height > 65535)
continue;
int samp = tiff_ifd[i].samples;
if (samp == 2)
samp = 1; max_samp = LIM(MAX(max_samp, samp), 1,
3);
if (tiff_ifd[i].phint != 32803 && tiff_ifd[i].phint != 34892)
continue;
if ((tiff_ifd[i].newsubfiletype == 0) || (tiff_ifd[i].newsubfiletype == 16 &&
(imgdata.params.raw_processing_options &
LIBRAW_PROCESSING_DNG_ADD_ENHANCED))
|| ((tiff_ifd[i].newsubfiletype & 0xffff) == 1 &&
(imgdata.params.raw_processing_options &
LIBRAW_PROCESSING_DNG_ADD_PREVIEWS)))
{
libraw_internal_data.unpacker_data.dng_frames[ifdc] =
((tiff_ifd[i].newsubfiletype & 0xffff) << 16) | ((i << 8) & 0xff00);
ifdc++;
if ((tiff_ifd[i].newsubfiletype == 0) && tiff_ifd[i].samples == 2)
{
libraw_internal_data.unpacker_data.dng_frames[ifdc] =
((tiff_ifd[i].newsubfiletype & 0xffff) << 16) |
((i << 8) & 0xff00) | 1;
ifdc++;
}
}
}
if (ifdc)
{
if (ifdc > 1 && (imgdata.params.raw_processing_options &
LIBRAW_PROCESSING_DNG_PREFER_LARGEST_IMAGE))
{
ifd_size_t arr[LIBRAW_IFD_MAXCOUNT * 2];
memset(arr, 0, sizeof(arr));
for (int i = 0; i < ifdc && i < LIBRAW_IFD_MAXCOUNT * 2; i++)
{
int ifdidx =
(libraw_internal_data.unpacker_data.dng_frames[i] >> 8) & 0xff;
arr[i].ifdi = libraw_internal_data.unpacker_data.dng_frames[i];
arr[i].databits =
tiff_ifd[ifdidx].t_width * tiff_ifd[ifdidx].t_height *
tiff_ifd[ifdidx].samples * tiff_ifd[ifdidx].bps +
(0x100 -
(arr[i].ifdi & 0xff)); }
qsort(arr, MIN(ifdc, LIBRAW_IFD_MAXCOUNT * 2), sizeof(arr[0]),
ifd_size_t_cmp);
for (int i = 0; i < ifdc && i < LIBRAW_IFD_MAXCOUNT * 2; i++)
libraw_internal_data.unpacker_data.dng_frames[i] = arr[i].ifdi;
}
int idx = LIM((int)shot_select, 0, ifdc - 1);
i = (libraw_internal_data.unpacker_data.dng_frames[idx] >> 8) &
0xff;
raw_width = tiff_ifd[i].t_width;
raw_height = tiff_ifd[i].t_height;
tiff_bps = tiff_ifd[i].bps;
tiff_compress = tiff_ifd[i].comp;
tiff_sampleformat = tiff_ifd[i].sample_format;
data_offset = tiff_ifd[i].offset;
data_size = tiff_ifd[i].bytes;
tiff_flip = tiff_ifd[i].t_flip;
tiff_samples = tiff_ifd[i].samples;
tile_width = tiff_ifd[i].t_tile_width;
tile_length = tiff_ifd[i].t_tile_length;
fuji_width = tiff_ifd[i].t_fuji_width;
if (tiff_samples != 2)
{
if (tiff_ifd[i].phint == 34892)
filters = 0;
else if (i > 0 && tiff_ifd[i].phint == 32803 &&
tiff_ifd[0].phint == 32803 && !tiff_ifd[i].t_filters &&
tiff_ifd[0].t_filters)
filters = tiff_ifd[0].t_filters;
else
filters = tiff_ifd[i].t_filters;
width = tiff_ifd[i].t_vwidth;
height = tiff_ifd[i].t_vheight;
top_margin = tiff_ifd[i].t_tm;
left_margin = tiff_ifd[i].t_lm;
shutter = tiff_ifd[i].t_shutter;
if (tiff_ifd[i].dng_levels.dng_whitelevel[0])
maximum = tiff_ifd[i].dng_levels.dng_whitelevel[0];
else if (tiff_ifd[i].sample_format <= 2 && tiff_bps > 0 &&
tiff_bps < 32) maximum = (1 << tiff_bps) - 1;
else if (tiff_ifd[i].sample_format == 3)
maximum = 1; }
raw = i;
is_raw = ifdc;
}
else
is_raw = 0;
}
else
{
for (i = 0; i < (int)tiff_nifds; i++)
{
if (tiff_ifd[i].t_width < 1 || tiff_ifd[i].t_width > 65535 ||
tiff_ifd[i].t_height < 1 || tiff_ifd[i].t_height > 65535)
continue;
if (max_samp < tiff_ifd[i].samples)
max_samp = tiff_ifd[i].samples;
if (max_samp > 3)
max_samp = 3;
os = unsigned(raw_width) * unsigned(raw_height);
ns = unsigned(tiff_ifd[i].t_width) * unsigned(tiff_ifd[i].t_height);
if (tiff_bps)
{
os *= tiff_bps;
ns *= tiff_ifd[i].bps;
}
if (tiff_ifd[i].phint == 2 && tiff_ifd[i].extrasamples > 0 && tiff_ifd[i].samples > 3)
continue;
if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 &&
(unsigned)tiff_ifd[i].bps < 33 &&
(unsigned)tiff_ifd[i].samples < 13 && ns &&
((ns > os && (ties = 1)) || (ns == os && (int)shot_select == ties++)))
{
raw_width = tiff_ifd[i].t_width;
raw_height = tiff_ifd[i].t_height;
tiff_bps = tiff_ifd[i].bps;
tiff_compress = tiff_ifd[i].comp;
tiff_sampleformat = tiff_ifd[i].sample_format;
data_offset = tiff_ifd[i].offset;
data_size = tiff_ifd[i].bytes;
tiff_flip = tiff_ifd[i].t_flip;
tiff_samples = tiff_ifd[i].samples;
tile_width = tiff_ifd[i].t_tile_width;
tile_length = tiff_ifd[i].t_tile_length;
shutter = tiff_ifd[i].t_shutter;
raw = i;
}
}
if (is_raw == 1 && ties)
is_raw = ties;
}
if (is_NikonTransfer && raw >= 0)
{
if (tiff_ifd[raw].bps == 16)
{
if (tiff_compress == 1)
{
if ((raw_width * raw_height * 3) == (tiff_ifd[raw].bytes << 1))
{
tiff_bps = tiff_ifd[raw].bps = 12;
}
else
{
tiff_bps = tiff_ifd[raw].bps = 14;
}
}
}
else if (tiff_ifd[raw].bps == 8)
{
if (tiff_compress == 1)
{
is_NikonTransfer = 2; imgdata.params.coolscan_nef_gamma = 2.2f;
}
}
}
if (!tile_width)
tile_width = INT_MAX;
if (!tile_length)
tile_length = INT_MAX;
for (i = tiff_nifds; i--;)
if (tiff_ifd[i].t_flip)
tiff_flip = tiff_ifd[i].t_flip;
#if 0#endif
if (raw >= 0 && !load_raw)
switch (tiff_compress)
{
case 32767:
if (!dng_version &&
INT64(tiff_ifd[raw].bytes) == INT64(raw_width) * INT64(raw_height))
{
tiff_bps = 14;
load_raw = &LibRaw::sony_arw2_load_raw;
break;
}
if (!dng_version && !strncasecmp(make, "Sony", 4) &&
INT64(tiff_ifd[raw].bytes) ==
INT64(raw_width) * INT64(raw_height) * 2LL)
{
tiff_bps = 14;
load_raw = &LibRaw::unpacked_load_raw;
break;
}
if (INT64(tiff_ifd[raw].bytes) * 8ULL !=
INT64(raw_width) * INT64(raw_height) * INT64(tiff_bps))
{
raw_height += 8;
load_raw = &LibRaw::sony_arw_load_raw;
break;
}
load_flags = 79;
case 32769:
load_flags++;
case 32770:
case 32773:
goto slr;
case 0:
case 1:
#ifdef USE_DNGSDK
if (dng_version && tiff_sampleformat == 3 &&
(tiff_bps > 8 && (tiff_bps % 8 == 0))) {
load_raw = &LibRaw::float_dng_load_raw_placeholder;
break;
}
#endif
if (!dng_version && !strncasecmp(make, "Sony", 4) &&
INT64(tiff_ifd[raw].bytes) ==
INT64(raw_width) * INT64(raw_height) * 2LL)
{
tiff_bps = 14;
load_raw = &LibRaw::unpacked_load_raw;
break;
}
if (!dng_version && !strncasecmp(make, "Sony", 4) &&
tiff_ifd[raw].samples == 4 &&
INT64(tiff_ifd[raw].bytes) ==
INT64(raw_width) * INT64(raw_height) * 8LL) {
tiff_bps = 14;
tiff_samples = 4;
load_raw = &LibRaw::sony_arq_load_raw;
filters = 0;
strcpy(cdesc, "RGBG");
break;
}
if (!strncasecmp(make, "Nikon", 5) &&
(!strncmp(software, "Nikon Scan", 10) || (is_NikonTransfer == 2) ||
strcasestr(model, "COOLSCAN")))
{
load_raw = &LibRaw::nikon_coolscan_load_raw;
raw_color = 1;
filters = 0;
break;
}
if ((!strncmp(make, "OLYMPUS", 7) ||
(!strncasecmp(make, "CLAUSS", 6) &&
!strncasecmp(model, "piX 5oo", 7))) && (INT64(tiff_ifd[raw].bytes) * 2ULL ==
INT64(raw_width) * INT64(raw_height) * 3ULL))
load_flags = 24;
if (!dng_version && INT64(tiff_ifd[raw].bytes) * 5ULL ==
INT64(raw_width) * INT64(raw_height) * 8ULL)
{
load_flags = 81;
tiff_bps = 12;
}
slr:
switch (tiff_bps)
{
case 8:
load_raw = &LibRaw::eight_bit_load_raw;
break;
case 12:
if (tiff_ifd[raw].phint == 2)
load_flags = 6;
if (!strncasecmp(make, "NIKON", 5) &&
!strncasecmp(model, "COOLPIX A1000", 13) &&
data_size == raw_width * raw_height * 2)
load_raw = &LibRaw::unpacked_load_raw;
else
load_raw = &LibRaw::packed_load_raw;
break;
case 14:
load_flags = 0;
case 16:
load_raw = &LibRaw::unpacked_load_raw;
if ((!strncmp(make, "OLYMPUS", 7) ||
(!strncasecmp(make, "CLAUSS", 6) &&
!strncasecmp(model, "piX 5oo", 7))) && (INT64(tiff_ifd[raw].bytes) * 7ULL >
INT64(raw_width) * INT64(raw_height)))
load_raw = &LibRaw::olympus_load_raw;
}
break;
case 6:
case 7:
case 99:
load_raw = &LibRaw::lossless_jpeg_load_raw;
break;
case 262:
load_raw = &LibRaw::kodak_262_load_raw;
break;
case 34713:
if ((INT64(raw_width) + 9LL) / 10LL * 16LL * INT64(raw_height) ==
INT64(tiff_ifd[raw].bytes))
{
load_raw = &LibRaw::packed_load_raw;
load_flags = 1;
}
else if (INT64(raw_width) * INT64(raw_height) * 3LL ==
INT64(tiff_ifd[raw].bytes) * 2LL)
{
load_raw = &LibRaw::packed_load_raw;
if (model[0] == 'N')
load_flags = 80;
}
else if (INT64(raw_width) * INT64(raw_height) * 3LL ==
INT64(tiff_ifd[raw].bytes))
{
load_raw = &LibRaw::nikon_yuv_load_raw;
gamma_curve(1 / 2.4, 12.92, 1, 4095);
memset(cblack, 0, sizeof cblack);
filters = 0;
}
else if (INT64(raw_width) * INT64(raw_height) * 2LL ==
INT64(tiff_ifd[raw].bytes))
{
load_raw = &LibRaw::unpacked_load_raw;
load_flags = 4;
order = 0x4d4d;
}
else if (INT64(raw_width) * INT64(raw_height) * 3LL ==
INT64(tiff_ifd[raw].bytes) * 2LL)
{
load_raw = &LibRaw::packed_load_raw;
load_flags = 80;
}
else if (tiff_ifd[raw].rows_per_strip &&
tiff_ifd[raw].strip_offsets_count &&
tiff_ifd[raw].strip_offsets_count ==
tiff_ifd[raw].strip_byte_counts_count)
{
int fit = 1;
for (int i = 0; i < tiff_ifd[raw].strip_byte_counts_count - 1;
i++) if (INT64(tiff_ifd[raw].strip_byte_counts[i]) * 2LL !=
INT64(tiff_ifd[raw].rows_per_strip) * INT64(raw_width) * 3LL)
{
fit = 0;
break;
}
if (fit)
load_raw = &LibRaw::nikon_load_striped_packed_raw;
else
load_raw = &LibRaw::nikon_load_raw; }
else if ((((INT64(raw_width) * 3LL / 2LL) + 15LL) / 16LL) * 16LL *
INT64(raw_height) ==
INT64(tiff_ifd[raw].bytes))
{
load_raw = &LibRaw::nikon_load_padded_packed_raw;
load_flags = (((INT64(raw_width) * 3ULL / 2ULL) + 15ULL) / 16ULL) *
16ULL; }
else
load_raw = &LibRaw::nikon_load_raw;
break;
case 65535:
load_raw = &LibRaw::pentax_load_raw;
break;
case 65000:
switch (tiff_ifd[raw].phint)
{
case 2:
load_raw = &LibRaw::kodak_rgb_load_raw;
filters = 0;
break;
case 6:
load_raw = &LibRaw::kodak_ycbcr_load_raw;
filters = 0;
break;
case 32803:
load_raw = &LibRaw::kodak_65000_load_raw;
}
case 32867:
case 34892:
break;
case 8:
break;
#ifdef USE_GPRSDK
case 9:
if (dng_version)
break;
#endif
default:
is_raw = 0;
}
if (!dng_version)
{
if (((tiff_samples == 3 && tiff_ifd[raw].bytes &&
!(tiff_bps == 16 &&
!strncmp(make, "Leaf", 4)) && tiff_bps != 14 &&
(tiff_compress & -16) != 32768) ||
(tiff_bps == 8 && strncmp(make, "Phase", 5) &&
strncmp(make, "Leaf", 4) && !strcasestr(make, "Kodak") &&
!strstr(model2, "DEBUG RAW"))) &&
!strcasestr(model, "COOLSCAN") && strncmp(software, "Nikon Scan", 10) &&
is_NikonTransfer != 2)
is_raw = 0;
if (is_raw && raw >= 0 && tiff_ifd[raw].phint == 2 && tiff_ifd[raw].extrasamples > 0 && tiff_ifd[raw].samples > 3)
is_raw = 0; }
for (i = 0; i < (int)tiff_nifds; i++)
if (i != raw &&
(tiff_ifd[i].samples == max_samp ||
(tiff_ifd[i].comp == 7 &&
tiff_ifd[i].samples == 1))
&& tiff_ifd[i].bps > 0 && tiff_ifd[i].bps < 33 &&
tiff_ifd[i].phint != 32803 && tiff_ifd[i].phint != 34892 &&
unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 &&
unsigned(tiff_ifd[i].t_width * tiff_ifd[i].t_height /
(SQR(tiff_ifd[i].bps) + 1)) >
unsigned(thumb_width * thumb_height / (SQR(thumb_misc) + 1)) &&
tiff_ifd[i].comp != 34892)
{
thumb_width = tiff_ifd[i].t_width;
thumb_height = tiff_ifd[i].t_height;
thumb_offset = tiff_ifd[i].offset;
thumb_length = tiff_ifd[i].bytes;
thumb_misc = tiff_ifd[i].bps;
thm = i;
}
if (thm >= 0)
{
thumb_misc |= tiff_ifd[thm].samples << 5;
switch (tiff_ifd[thm].comp)
{
case 0:
write_thumb = &LibRaw::layer_thumb;
break;
case 1:
if (tiff_ifd[thm].bps <= 8)
write_thumb = &LibRaw::ppm_thumb;
else if (!strncmp(make, "Imacon", 6))
write_thumb = &LibRaw::ppm16_thumb;
else
thumb_load_raw = &LibRaw::kodak_thumb_load_raw;
break;
case 65000:
thumb_load_raw = tiff_ifd[thm].phint == 6 ? &LibRaw::kodak_ycbcr_load_raw
: &LibRaw::kodak_rgb_load_raw;
}
}
}