DCraw::parseCR3() cleanup

This commit is contained in:
Flössie 2019-11-26 09:52:51 +01:00
parent 2ae5f198d7
commit e89b6be76e

View File

@ -280,12 +280,17 @@ int DCraw::parseCR3(
{"uuid", 3}, {"uuid", 3},
}; };
const char sHandlerType[5][5] = {"unk.", "soun", "vide", "hint", "meta"}; const char sHandlerType[5][5] = {
"unk.",
"soun",
"vide",
"hint",
"meta"
};
unsigned int c;
int err = 0; int err = 0;
ushort tL; // Atom length represented in 4 or 8 bytes unsigned short tL; // Atom length represented in 4 or 8 bytes
char nmAtom[5]; // Atom name char nmAtom[5]; // Atom name
unsigned long long oAtom; unsigned long long oAtom;
unsigned long long szAtom; // Atom offset and Atom size unsigned long long szAtom; // Atom offset and Atom size
@ -297,19 +302,19 @@ int DCraw::parseCR3(
uchar CMP1[36]; uchar CMP1[36];
char HandlerType[5]; char HandlerType[5];
char MediaFormatID[5]; char MediaFormatID[5];
// unsigned ImageWidth, ImageHeight; // unsigned int ImageWidth, ImageHeight;
long relpos_inDir; long relpos_inDir;
long relpos_inBox; long relpos_inBox;
unsigned szItem; unsigned int szItem;
unsigned Tag; unsigned int Tag;
unsigned lTag; unsigned int lTag;
ushort tItem; unsigned short tItem;
nmAtom[0] = MediaFormatID[0] = nmAtom[4] = MediaFormatID[4] = '\0'; nmAtom[0] = MediaFormatID[0] = nmAtom[4] = MediaFormatID[4] = '\0';
strcpy(HandlerType, sHandlerType[0]); strncpy(HandlerType, sHandlerType[0], sizeof(HandlerType));
// ImageWidth = ImageHeight = 0U; // ImageWidth = ImageHeight = 0U;
oAtom = oAtomList; oAtom = oAtomList;
nesting++; ++nesting;
if (nesting > 31) { if (nesting > 31) {
return -14; // too deep nesting return -14; // too deep nesting
@ -329,20 +334,20 @@ int DCraw::parseCR3(
|| get4() != 0x00000008; || get4() != 0x00000008;
}; };
while ((oAtom + 8ULL) <= (oAtomList + szAtomList)) { while ((oAtom + 8) <= (oAtomList + szAtomList)) {
lHdr = 0ULL; lHdr = 0U;
err = 0; err = 0;
order = 0x4d4d; order = 0x4D4D;
fseek(ifp, oAtom, SEEK_SET); fseek(ifp, oAtom, SEEK_SET);
szAtom = get4(); szAtom = get4();
for (c = 0; c < 4; c++) { for (unsigned int c = 0; c < 4; ++c) {
nmAtom[c] = AtomNameStack[nesting * 4 + c] = fgetc(ifp); nmAtom[c] = AtomNameStack[nesting * 4 + c] = fgetc(ifp);
} }
AtomNameStack[(nesting + 1) * 4] = '\0'; AtomNameStack[(nesting + 1) * 4] = '\0';
tL = 4; tL = 4;
AtomType = 0; AtomType = 0;
for (c = 0; c < sizeof AtomNamesList / sizeof * AtomNamesList; c++) { for (unsigned int c = 0; c < sizeof(AtomNamesList) / sizeof(*AtomNamesList); ++c) {
if (!strcmp(nmAtom, AtomNamesList[c].AtomName)) { if (!strcmp(nmAtom, AtomNamesList[c].AtomName)) {
AtomType = AtomNamesList[c].AtomType; AtomType = AtomNamesList[c].AtomType;
break; break;
@ -353,28 +358,28 @@ int DCraw::parseCR3(
err = 1; err = 1;
} }
if (szAtom == 0ULL) { if (szAtom == 0) {
if (nesting != 0) { if (nesting != 0) {
err = -2; err = -2;
goto fin; goto fin;
} }
szAtom = szAtomList - oAtom; szAtom = szAtomList - oAtom;
oAtomContent = oAtom + 8ULL; oAtomContent = oAtom + 8;
szAtomContent = szAtom - 8ULL; szAtomContent = szAtom - 8;
} else if (szAtom == 1ULL) { } else if (szAtom == 1) {
if ((oAtom + 16ULL) > (oAtomList + szAtomList)) { if ((oAtom + 16) > (oAtomList + szAtomList)) {
err = -3; err = -3;
goto fin; goto fin;
} }
tL = 8; tL = 8;
szAtom = (((unsigned long long)get4()) << 32) | get4(); szAtom = (static_cast<unsigned long long>(get4()) << 32) | get4();
oAtomContent = oAtom + 16ULL; oAtomContent = oAtom + 16;
szAtomContent = szAtom - 16ULL; szAtomContent = szAtom - 16;
} else { } else {
oAtomContent = oAtom + 8ULL; oAtomContent = oAtom + 8;
szAtomContent = szAtom - 8ULL; szAtomContent = szAtom - 8;
} }
if (!strcmp(nmAtom, "trak")) { if (!strcmp(nmAtom, "trak")) {
@ -387,7 +392,7 @@ int DCraw::parseCR3(
} }
if (!strcmp(AtomNameStack, "moovuuid")) { if (!strcmp(AtomNameStack, "moovuuid")) {
lHdr = 16ULL; lHdr = 16;
fread(UIID, 1, lHdr, ifp); fread(UIID, 1, lHdr, ifp);
if (!strncmp(UIID, UIID_Canon, lHdr)) { if (!strncmp(UIID, UIID_Canon, lHdr)) {
@ -396,12 +401,12 @@ int DCraw::parseCR3(
fseek(ifp, -lHdr, SEEK_CUR); fseek(ifp, -lHdr, SEEK_CUR);
} }
} else if (!strcmp(AtomNameStack, "moovuuidCCTP")) { } else if (!strcmp(AtomNameStack, "moovuuidCCTP")) {
lHdr = 12ULL; lHdr = 12;
} else if (!strcmp(AtomNameStack, "moovuuidCMT1")) { } else if (!strcmp(AtomNameStack, "moovuuidCMT1")) {
short q_order = order; const short q_order = order;
order = get2(); order = get2();
if ((tL != 4) || is_bad_header()) { if (tL != 4 || is_bad_header()) {
err = -4; err = -4;
goto fin; goto fin;
} }
@ -409,10 +414,10 @@ int DCraw::parseCR3(
parse_tiff_ifd(oAtomContent); parse_tiff_ifd(oAtomContent);
order = q_order; order = q_order;
} else if (!strcmp(AtomNameStack, "moovuuidCMT2")) { } else if (!strcmp(AtomNameStack, "moovuuidCMT2")) {
short q_order = order; const short q_order = order;
order = get2(); order = get2();
if ((tL != 4) || is_bad_header()) { if (tL != 4 || is_bad_header()) {
err = -5; err = -5;
goto fin; goto fin;
} }
@ -420,10 +425,10 @@ int DCraw::parseCR3(
parse_exif(oAtomContent); parse_exif(oAtomContent);
order = q_order; order = q_order;
} else if (!strcmp(AtomNameStack, "moovuuidCMT3")) { } else if (!strcmp(AtomNameStack, "moovuuidCMT3")) {
short q_order = order; const short q_order = order;
order = get2(); order = get2();
if ((tL != 4) || is_bad_header()) { if (tL != 4 || is_bad_header()) {
err = -6; err = -6;
goto fin; goto fin;
} }
@ -432,26 +437,26 @@ int DCraw::parseCR3(
parse_makernote(oAtomContent, 0); parse_makernote(oAtomContent, 0);
order = q_order; order = q_order;
} else if (!strcmp(AtomNameStack, "moovuuidCMT4")) { } else if (!strcmp(AtomNameStack, "moovuuidCMT4")) {
short q_order = order; const short q_order = order;
order = get2(); order = get2();
if ((tL != 4) || is_bad_header()) { if (tL != 4 || is_bad_header()) {
err = -6; err = -6;
goto fin; goto fin;
} }
std::int64_t off = ftell(ifp); const std::int64_t off = ftell(ifp); // FIXME: ftell() returns int
parse_gps(oAtomContent); parse_gps(oAtomContent);
fseek(ifp, off, SEEK_SET); fseek(ifp, off, SEEK_SET); // FIXME: fseek() takes int offset
// parse_gps_libraw(oAtomContent); // parse_gps_libraw(oAtomContent);
order = q_order; order = q_order;
} else if (!strcmp(AtomNameStack, "moovtrakmdiahdlr")) { } else if (!strcmp(AtomNameStack, "moovtrakmdiahdlr")) {
fseek(ifp, 8L, SEEK_CUR); fseek(ifp, 8, SEEK_CUR);
for (c = 0; c < 4; c++) { for (unsigned int c = 0; c < 4; ++c) {
HandlerType[c] = fgetc(ifp); HandlerType[c] = fgetc(ifp);
} }
for (c = 1; c < sizeof sHandlerType / sizeof * sHandlerType; c++) { for (unsigned int c = 1; c < sizeof(sHandlerType) / sizeof(*sHandlerType); ++c) {
if (!strcmp(HandlerType, sHandlerType[c])) { if (!strcmp(HandlerType, sHandlerType[c])) {
TrackType = c; TrackType = c;
break; break;
@ -466,13 +471,13 @@ int DCraw::parseCR3(
goto fin; goto fin;
} }
for (c = 0; c < 4; c++) { for (unsigned int c = 0; c < 4; ++c) {
MediaFormatID[c] = fgetc(ifp); MediaFormatID[c] = fgetc(ifp);
} }
if ((TrackType == 2) && (!strcmp(MediaFormatID, "CRAW"))) { if (TrackType == 2 && !strcmp(MediaFormatID, "CRAW")) {
if (szAtomContent >= 44) { if (szAtomContent >= 44) {
fseek(ifp, 24L, SEEK_CUR); fseek(ifp, 24, SEEK_CUR);
} else { } else {
err = -8; err = -8;
goto fin; goto fin;
@ -482,8 +487,6 @@ int DCraw::parseCR3(
lHdr = 0; lHdr = 0;
} }
#define current_track RT_canon_CR3_data.crx_header[nTrack]
/*ImageWidth = */ get2(); /*ImageWidth = */ get2();
/*ImageHeight = */ get2(); /*ImageHeight = */ get2();
} else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAW")) { } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAW")) {
@ -497,69 +500,81 @@ int DCraw::parseCR3(
} }
if (!crxParseImageHeader(CMP1, nTrack)) { if (!crxParseImageHeader(CMP1, nTrack)) {
current_track.MediaType = 1; RT_canon_CR3_data.crx_header[nTrack].MediaType = 1;
} }
} else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAWJPEG")) { } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAWJPEG")) {
current_track.MediaType = 2; RT_canon_CR3_data.crx_header[nTrack].MediaType = 2;
} else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsz")) { } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsz")) {
if (szAtomContent == 12) { if (szAtomContent == 12) {
fseek(ifp, 4L, SEEK_CUR); fseek(ifp, 4, SEEK_CUR);
} else if (szAtomContent == 16) { } else if (szAtomContent == 16) {
fseek(ifp, 12L, SEEK_CUR); fseek(ifp, 12, SEEK_CUR);
} else { } else {
err = -9; err = -9;
goto fin; goto fin;
} }
current_track.MediaSize = get4(); RT_canon_CR3_data.crx_header[nTrack].MediaSize = get4();
} else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblco64")) { } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblco64")) {
if (szAtomContent == 16) { if (szAtomContent == 16) {
fseek(ifp, 8L, SEEK_CUR); fseek(ifp, 8, SEEK_CUR);
} else { } else {
err = -10; err = -10;
goto fin; goto fin;
} }
current_track.MediaOffset = (((unsigned long long)get4()) << 32) | get4(); RT_canon_CR3_data.crx_header[nTrack].MediaOffset = (static_cast<unsigned long long>(get4()) << 32) | get4();
} }
if (current_track.MediaSize && current_track.MediaOffset && if (
((oAtom + szAtom) >= (oAtomList + szAtomList)) && RT_canon_CR3_data.crx_header[nTrack].MediaSize
!strncmp(AtomNameStack, "moovtrakmdiaminfstbl", 20)) { && RT_canon_CR3_data.crx_header[nTrack].MediaOffset
if ((TrackType == 4) && (!strcmp(MediaFormatID, "CTMD"))) { && oAtom + szAtom >= oAtomList + szAtomList
&& !strncmp(AtomNameStack, "moovtrakmdiaminfstbl", 20)
) {
if (TrackType == 4 && !strcmp(MediaFormatID, "CTMD")) {
order = 0x4949; order = 0x4949;
relpos_inDir = 0L; relpos_inDir = 0;
while (relpos_inDir + 6 < current_track.MediaSize) { while (relpos_inDir + 6 < RT_canon_CR3_data.crx_header[nTrack].MediaSize) {
fseek(ifp, current_track.MediaOffset + relpos_inDir, SEEK_SET); fseek(ifp, RT_canon_CR3_data.crx_header[nTrack].MediaOffset + relpos_inDir, SEEK_SET);
szItem = get4(); szItem = get4();
tItem = get2(); tItem = get2();
if ((relpos_inDir + szItem) > current_track.MediaSize) { if ((relpos_inDir + szItem) > RT_canon_CR3_data.crx_header[nTrack].MediaSize) {
err = -11; err = -11;
goto fin; goto fin;
} }
if ((tItem == 7) || (tItem == 8) || (tItem == 9)) { if (
relpos_inBox = relpos_inDir + 12L; tItem == 7
|| tItem == 8
|| tItem == 9
) {
relpos_inBox = relpos_inDir + 12;
while (relpos_inBox + 8 < relpos_inDir + szItem) { while (relpos_inBox + 8 < relpos_inDir + szItem) {
fseek(ifp, current_track.MediaOffset + relpos_inBox, SEEK_SET); fseek(ifp, RT_canon_CR3_data.crx_header[nTrack].MediaOffset + relpos_inBox, SEEK_SET);
lTag = get4(); lTag = get4();
Tag = get4(); Tag = get4();
if (lTag < 8) { if (lTag < 8) {
err = -12; err = -12;
goto fin; goto fin;
} else if ((relpos_inBox + lTag) > (relpos_inDir + szItem)) { } else if (relpos_inBox + lTag > relpos_inDir + szItem) {
err = -11; err = -11;
goto fin; goto fin;
} }
if ((Tag == 0x927c) && ((tItem == 7) || (tItem == 8))) { if (
fseek(ifp, current_track.MediaOffset + relpos_inBox + 8L, Tag == 0x927C
SEEK_SET); && (
short q_order = order; tItem == 7
|| tItem == 8
)
) {
fseek(ifp, RT_canon_CR3_data.crx_header[nTrack].MediaOffset + relpos_inBox + 8, SEEK_SET);
const short q_order = order;
order = get2(); order = get2();
if (is_bad_header()) { if (is_bad_header()) {
@ -567,10 +582,9 @@ int DCraw::parseCR3(
goto fin; goto fin;
} }
fseek(ifp, -8L, SEEK_CUR); fseek(ifp, -8, SEEK_CUR);
RT_canon_CR3_data.CR3_CTMDtag = 1; RT_canon_CR3_data.CR3_CTMDtag = 1;
parse_makernote(current_track.MediaOffset + relpos_inBox + 8, parse_makernote(RT_canon_CR3_data.crx_header[nTrack].MediaOffset + relpos_inBox + 8, 0);
0);
RT_canon_CR3_data.CR3_CTMDtag = 0; RT_canon_CR3_data.CR3_CTMDtag = 0;
order = q_order; order = q_order;
} }
@ -582,15 +596,12 @@ int DCraw::parseCR3(
relpos_inDir += szItem; relpos_inDir += szItem;
} }
order = 0x4d4d; order = 0x4D4D;
} }
} }
#undef current_track
if (AtomType == 1) { if (AtomType == 1) {
err = parseCR3(oAtomContent + lHdr, szAtomContent - lHdr, nesting, err = parseCR3(oAtomContent + lHdr, szAtomContent - lHdr, nesting, AtomNameStack, nTrack, TrackType);
AtomNameStack, nTrack, TrackType);
if (err) { if (err) {
goto fin; goto fin;
@ -601,7 +612,7 @@ int DCraw::parseCR3(
} }
fin: fin:
nesting--; --nesting;
if (nesting >= 0) { if (nesting >= 0) {
AtomNameStack[nesting * 4] = '\0'; AtomNameStack[nesting * 4] = '\0';
@ -610,7 +621,6 @@ fin:
order = s_order; order = s_order;
return err; return err;
} }
#undef bad_hdr
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -633,9 +643,9 @@ fin:
namespace namespace
{ {
static unsigned sgetn(int n, unsigned char* s) static unsigned int sgetn(int n, unsigned char* s)
{ {
unsigned result = 0; unsigned int result = 0;
while (n-- > 0) { while (n-- > 0) {
result = (result << 8) | (*s++); result = (result << 8) | (*s++);