#include "../../internal/dcraw_defs.h"
#ifdef _MSC_VER
#if _MSC_VER < 1800
float roundf(float f)
{
return floorf(f + 0.5);
}
#endif
#endif
void LibRaw::ciff_block_1030()
{
static const ushort key[] = {0x410, 0x45f3};
int i, bpp, row, col, vbits = 0;
unsigned long bitbuf = 0;
if ((get2(), get4()) != 0x80008 || !get4())
return;
bpp = get2();
if (bpp != 10 && bpp != 12)
return;
for (i = row = 0; row < 8; row++)
for (col = 0; col < 8; col++)
{
if (vbits < bpp)
{
bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
vbits += 16;
}
white[row][col] = bitbuf >> (vbits -= bpp) & ~(-1 << bpp);
}
}
void LibRaw::parse_ciff(int offset, int length, int depth)
{
int tboff, nrecs, c, type, len, save, wbi = -1;
ushort key[] = {0x410, 0x45f3};
ushort CanonColorInfo1_key;
ushort Appendix_A = 0;
INT64 WB_table_offset = 0;
int UseWBfromTable_as_AsShot = 1;
int Got_AsShotWB = 0;
INT64 fsize = ifp->size();
if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS)
throw LIBRAW_EXCEPTION_IO_CORRUPT;
fseek(ifp, offset + length - 4, SEEK_SET);
tboff = get4() + offset;
fseek(ifp, tboff, SEEK_SET);
nrecs = get2();
if (nrecs < 1)
return;
if ((nrecs | depth) > 127)
return;
if (nrecs * 10 + offset > fsize)
return;
while (nrecs--)
{
type = get2();
len = get4();
INT64 see = offset + get4();
save = ftell(ifp);
if ((type != 0x2007) && (type != 0x580b) && (type != 0x501c) &&
(type != 0x5029) && (type != 0x5813) && (type != 0x5814) &&
(type != 0x5817) && (type != 0x5834) && (type != 0x580e))
{
if (see >= fsize)
{ fseek(ifp, save, SEEK_SET);
continue;
}
fseek(ifp, see, SEEK_SET);
if ((((type >> 8) + 8) | 8) == 0x38)
{
parse_ciff(ftell(ifp), len, depth + 1);
}
}
if (type == 0x3004)
{
parse_ciff(ftell(ifp), len, depth + 1);
}
else if (type == 0x0810)
{
fread(artist, 64, 1, ifp);
}
else if (type == 0x080a)
{
fread(make, 64, 1, ifp);
fseek(ifp, strbuflen(make) - 63, SEEK_CUR);
fread(model, 64, 1, ifp);
} else if (type == 0x080b) {
char *p;
stmread(imCommon.firmware, (unsigned)len, ifp);
if (p = strrchr(imCommon.firmware, ' ')) {
imCanon.firmware = atof(p+1);
}
} else if (type == 0x1810)
{
width = get4();
height = get4();
pixel_aspect = int_to_float(get4());
flip = get4();
}
else if (type == 0x1835)
{
tiff_compress = get4();
}
else if (type == 0x2007)
{
thumb_offset = see;
thumb_length = len;
}
else if (type == 0x1818)
{
shutter = libraw_powf64l(2.0f, -int_to_float((get4(), get4())));
ilm.CurAp = aperture = libraw_powf64l(2.0f, int_to_float(get4()) / 2);
}
else if (type == 0x102a) {
get2(); iso_speed =
libraw_powf64l(2.0f, (get2() + get2()) / 32.0f - 5.0f) * 100.0f;
ilm.CurAp = aperture = _CanonConvertAperture((get2(), get2()));
shutter = libraw_powf64l(2.0, -((short)get2()) / 32.0);
imCanon.wbi = wbi = (get2(), get2());
if (wbi >= Canon_wbi2std.size())
wbi = 0;
fseek(ifp, 32, SEEK_CUR);
if (shutter > 1e6)
shutter = get2() / 10.0;
}
else if (type == 0x102c) {
int CanonColorInfo2_type = get2(); if (CanonColorInfo2_type > 512) {
fseek(ifp, 118, SEEK_CUR);
FORC4 cam_mul[BG2RG1_2_RGBG(c)] = get2();
}
else if (CanonColorInfo2_type != 276) {
Appendix_A = 1;
WB_table_offset = -14;
fseek(ifp, 98, SEEK_CUR);
FORC4 cam_mul[GRBG_2_RGBG(c)] = get2();
if (cam_mul[0] > 0.001f) Got_AsShotWB = 1;
}
}
else if (type == 0x10a9) {
int bls = 0;
int nWB =
((get2() - 2) / 8) -
1; if (nWB)
FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();
if (nWB >= 7)
Canon_WBpresets(0, 0);
else
FORC4 cam_mul[c] = icWBC[LIBRAW_WBI_Auto][c];
if (nWB == 7) {
if ((wbi >= 0) && (wbi < 9) && (wbi != 6))
{
FORC4 cam_mul[c] = icWBC[Canon_wbi2std[wbi]][c];
}
else
{
FORC4 cam_mul[c] = icWBC[LIBRAW_WBI_Auto][c];
}
}
else if (nWB == 9) {
FORC4 icWBC[LIBRAW_WBI_Custom][RGGB_2_RGBG(c)] = get2();
FORC4 icWBC[LIBRAW_WBI_Kelvin][RGGB_2_RGBG(c)] = get2();
if ((wbi >= 0) && (wbi < 10))
{
FORC4 cam_mul[c] = icWBC[Canon_wbi2std[wbi]][c];
}
else
{
FORC4 cam_mul[c] = icWBC[LIBRAW_WBI_Auto][c];
}
}
FORC4
bls += (imCanon.ChannelBlackLevel[RGGB_2_RGBG(c)] = get2());
imCanon.AverageBlackLevel = bls / 4;
}
else if (type == 0x102d)
{
Canon_CameraSettings(len >> 1);
}
else if (type == 0x10b4) {
switch (get2()) {
case 1:
imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB;
break;
case 2:
imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB;
break;
default:
imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown;
break;
}
} else if (type == 0x580b)
{
if (strcmp(model, "Canon EOS D30"))
sprintf(imgdata.shootinginfo.BodySerial, "%d", len);
else
sprintf(imgdata.shootinginfo.BodySerial, "%0x-%05d", len >> 16,
len & 0xffff);
}
else if (type == 0x0032) {
if (len == 768) {
ushort q;
fseek(ifp, 4, SEEK_CUR);
for (int linenum = 0; linenum < Canon_D30_linenums_2_StdWBi.size(); linenum++) {
if (Canon_D30_linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown) {
FORC4 {
q = get2();
icWBC[Canon_D30_linenums_2_StdWBi[linenum]][RGGB_2_RGBG(c)] =
(int)(roundf(1024000.0f / (float)MAX(1, q)));
}
}
}
fseek (ifp, 68-Canon_D30_linenums_2_StdWBi.size()*8, SEEK_CUR);
FORC4 {
q = get2();
cam_mul[RGGB_2_RGBG(c)] = 1024.0 / MAX(1, q);
}
if (!wbi)
cam_mul[0] = -1;
}
else if ((cam_mul[0] <= 0.001f) || Appendix_A) {
libraw_static_table_t linenums_2_StdWBi;
int AsShotWB_linenum = Canon_wbi2std.size();
CanonColorInfo1_key = get2();
if ((CanonColorInfo1_key == key[0]) && (len == 2048)) { linenums_2_StdWBi = Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi;
WB_table_offset = 8;
} else if ((CanonColorInfo1_key == key[0]) && (len == 3072)) { linenums_2_StdWBi = Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi;
WB_table_offset = 16;
} else if (!CanonColorInfo1_key && (len == 2048)) { key[0] = key[1] = 0;
linenums_2_StdWBi = Canon_KeyIsZero_Len2048_linenums_2_StdWBi;
if (imCanon.firmware < 1.02f)
UseWBfromTable_as_AsShot = 0;
} else goto next_tag;
if ((Canon_wbi2std[wbi] == LIBRAW_WBI_Auto) ||
(Canon_wbi2std[wbi] == LIBRAW_WBI_Unknown) ||
Got_AsShotWB)
UseWBfromTable_as_AsShot = 0;
if (UseWBfromTable_as_AsShot) {
int temp_wbi;
if (Canon_wbi2std[wbi] == LIBRAW_WBI_Custom) temp_wbi = LIBRAW_WBI_Daylight;
else temp_wbi = wbi;
for (AsShotWB_linenum = 0; AsShotWB_linenum < linenums_2_StdWBi.size(); AsShotWB_linenum++) {
if (Canon_wbi2std[temp_wbi] == linenums_2_StdWBi[AsShotWB_linenum]) {
break;
}
}
}
fseek (ifp, 78+WB_table_offset, SEEK_CUR);
for (int linenum = 0; linenum < linenums_2_StdWBi.size(); linenum++) {
if (linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown) {
FORC4 icWBC[linenums_2_StdWBi[linenum]][GRBG_2_RGBG(c)] = get2() ^ key[c & 1];
if (UseWBfromTable_as_AsShot && (AsShotWB_linenum == linenum)) {
FORC4 cam_mul[c] = icWBC[linenums_2_StdWBi[linenum]][c];
Got_AsShotWB = 1;
}
} else {
fseek(ifp, 8, SEEK_CUR);
}
}
if (!Got_AsShotWB)
cam_mul[0] = -1;
}
}
else if (type == 0x1030 && wbi >= 0 && (0x18040 >> wbi & 1))
{
ciff_block_1030(); }
else if (type == 0x1031)
{
raw_width = imCanon.SensorWidth = (get2(), get2());
raw_height = imCanon.SensorHeight = get2();
imCanon.SensorLeftBorder = (get2(), get2(), get2());
imCanon.SensorTopBorder = get2();
imCanon.SensorRightBorder = get2();
imCanon.SensorBottomBorder = get2();
imCanon.BlackMaskLeftBorder = get2();
imCanon.BlackMaskTopBorder = get2();
imCanon.BlackMaskRightBorder = get2();
imCanon.BlackMaskBottomBorder = get2();
}
else if (type == 0x501c)
{
iso_speed = len & 0xffff;
}
else if (type == 0x5029)
{
ilm.CurFocal = len >> 16;
ilm.FocalType = len & 0xffff;
if (ilm.FocalType == LIBRAW_FT_ZOOM_LENS)
{
ilm.FocalUnits = 32;
if (ilm.FocalUnits > 1)
ilm.CurFocal /= (float)ilm.FocalUnits;
}
focal_len = ilm.CurFocal;
}
else if (type == 0x5813)
{
flash_used = int_to_float(len);
}
else if (type == 0x5814)
{
canon_ev = int_to_float(len);
}
else if (type == 0x5817)
{
shot_order = len;
}
else if (type == 0x5834)
{
unique_id = ((unsigned long long)len << 32) >> 32;
setCanonBodyFeatures(unique_id);
}
else if (type == 0x580e)
{
timestamp = len;
}
else if (type == 0x180e)
{
timestamp = get4();
}
next_tag:;
#ifdef LOCALTIME
if ((type | 0x4000) == 0x580e)
timestamp = mktime(gmtime(×tamp));
#endif
fseek(ifp, save, SEEK_SET);
}
}