With good fortune, bmffimage is ready for review.

main
clanmills 4 years ago
parent c3e7011835
commit 0ad46453ed

@ -810,7 +810,7 @@ All project resources are accessible from the project website.
### 3.1 License ### 3.1 License
Copyright (C) 2004-2011 Exiv2 authors. Copyright (C) 2004-2021 Exiv2 authors.
You should have received a copy of the file [COPYING](COPYING) which details the GPLv2 license. You should have received a copy of the file [COPYING](COPYING) which details the GPLv2 license.
Exiv2 is free software; you can redistribute it and/or modify Exiv2 is free software; you can redistribute it and/or modify

@ -79,10 +79,6 @@ namespace Exiv2
BmffImage(BasicIo::AutoPtr io, bool create); BmffImage(BasicIo::AutoPtr io, bool create);
//@} //@}
//@{
BmffImage(BasicIo::AutoPtr io, size_t start, size_t count);
//@}
//@{ //@{
/*! /*!
@brief parse embedded tiff file (Exif metadata) @brief parse embedded tiff file (Exif metadata)
@ -120,6 +116,8 @@ namespace Exiv2
int pixelHeight() const; int pixelHeight() const;
//@} //@}
Exiv2::ByteOrder endian_ ;
private: private:
void openOrThrow(); void openOrThrow();
/*! /*!

@ -237,17 +237,17 @@ namespace Action {
std::stringstream output(std::stringstream::out|std::stringstream::binary); std::stringstream output(std::stringstream::out|std::stringstream::binary);
result = printStructure(output, option, path); result = printStructure(output, option, path);
if ( result == 0 ) { if ( result == 0 ) {
uint32_t size = output.str().size(); size_t size = (long) output.str().size();
char* iccProfile[size]; Exiv2::DataBuf iccProfile((long)size);
::memcpy(iccProfile,output.str().c_str(),size); Exiv2::DataBuf ascii((long)(size * 3 + 1));
char ascii[size*3+1]; ascii.pData_[size * 3] = 0;
ascii [size*3]=0; ::memcpy(iccProfile.pData_,output.str().c_str(),size);
if ( Exiv2::base64encode(iccProfile,size,ascii,size*3) ) { if ( Exiv2::base64encode(iccProfile.pData_,size,(char*)ascii.pData_,size*3) ) {
uint32_t chunk = 60 ; long chunk = 60 ;
std::string code = std::string("data:") + std::string(ascii); std::string code = std::string("data:") + std::string((char*)ascii.pData_);
uint32_t length = code.size() ; long length = (long) code.size() ;
for ( uint32_t start = 0 ; start < length ; start += chunk ) { for ( long start = 0 ; start < length ; start += chunk ) {
uint32_t count = (start+chunk) < length ? chunk : length - start ; long count = (start+chunk) < length ? chunk : length - start ;
std::cout << code.substr(start,count) << std::endl; std::cout << code.substr(start,count) << std::endl;
} }
} }

@ -94,7 +94,9 @@ namespace Exiv2
return Internal::stringFormat("ID = %u from,length = %u,%u", ID_, start_, length_); return Internal::stringFormat("ID = %u from,length = %u,%u", ID_, start_, length_);
} }
BmffImage::BmffImage(BasicIo::AutoPtr io, bool /* create */) : Image(ImageType::bmff, mdExif | mdIptc | mdXmp, io) BmffImage::BmffImage(BasicIo::AutoPtr io, bool /* create */)
: Image(ImageType::bmff, mdExif | mdIptc | mdXmp, io)
, endian_(Exiv2::bigEndian)
{ {
pixelWidth_ = 0; pixelWidth_ = 0;
pixelHeight_ = 0; pixelHeight_ = 0;
@ -105,24 +107,15 @@ namespace Exiv2
{ {
const char* p = (const char*)&n; const char* p = (const char*)&n;
std::string result; std::string result;
bool bBigEndian = isBigEndianPlatform();
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
char c = p[bBigEndian ? i : (3 - i)]; char c = p[isBigEndianPlatform() ? i : (3 - i)];
result += (32<=c && c<=127) ? c // only allow 7-bit printable ascii result += (32<=c && c<127) ? c // only allow 7-bit printable ascii
: c==0 ? '_' // show 0 and _ : c==0 ? '_' // show 0 as _
: '.' ; // others . : '.' ; // others .
} }
return result; return result;
} }
std::string BmffImage::boxName(uint32_t box)
{
char name[5];
std::memcpy(name, &box, 4);
name[4] = 0;
return std::string(name);
}
bool BmffImage::superBox(uint32_t box) bool BmffImage::superBox(uint32_t box)
{ {
return box == TAG_moov || box == TAG_dinf || box == TAG_iprp || box == TAG_ipco || box == TAG_meta || return box == TAG_moov || box == TAG_dinf || box == TAG_iprp || box == TAG_ipco || box == TAG_meta ||
@ -183,6 +176,8 @@ namespace Exiv2
{ {
long result = (long)io_->size(); long result = (long)io_->size();
long address = (long)io_->tell(); long address = (long)io_->tell();
// never visit a box twice!
if ( depth == 0 ) visits_.clear();
if (visits_.find(address) != visits_.end() || visits_.size() > visits_max_) { if (visits_.find(address) != visits_.end() || visits_.size() > visits_max_) {
throw Error(kerCorruptedMetadata); throw Error(kerCorruptedMetadata);
} }
@ -197,8 +192,8 @@ namespace Exiv2
if (io_->read((byte*)&box, sizeof(box)) != sizeof(box)) if (io_->read((byte*)&box, sizeof(box)) != sizeof(box))
return result; return result;
box.length = getLong((byte*)&box.length, bigEndian); box.length = getLong((byte*)&box.length, endian_);
box.type = getLong((byte*)&box.type, bigEndian); box.type = getLong((byte*)&box.type, endian_);
bool bLF = true; bool bLF = true;
if ( bTrace ) { if ( bTrace ) {
@ -210,16 +205,13 @@ namespace Exiv2
if (box.length == 1) { if (box.length == 1) {
DataBuf data(8); DataBuf data(8);
io_->read(data.pData_, data.size_); io_->read(data.pData_, data.size_);
result = address + (long)getULongLong(data.pData_, bigEndian); result = (long) getULongLong(data.pData_, endian_);
// sanity check // sanity check
if (result < 8 || result > (long)io_->size()) { if (result < 8 || result+address > (long)io_->size()) {
result = (long)io_->size(); result = (long)io_->size();
box.length = result - address; box.length = result;
} else { } else {
box.length = io_->size() - address - 8; box.length = (long) (io_->size() - address);
}
if ( bTrace ) {
out << Internal::stringFormat(" (%lu)", result);
} }
} }
@ -234,7 +226,7 @@ namespace Exiv2
uint32_t flags = 0; uint32_t flags = 0;
if (fullBox(box.type)) { if (fullBox(box.type)) {
flags = getLong(data.pData_ + skip, bigEndian); // version/flags flags = getLong(data.pData_ + skip, endian_); // version/flags
version = (int8_t)flags >> 24; version = (int8_t)flags >> 24;
version &= 0x00ffffff; version &= 0x00ffffff;
skip += 4; skip += 4;
@ -242,7 +234,7 @@ namespace Exiv2
switch (box.type) { switch (box.type) {
case TAG_ftyp: { case TAG_ftyp: {
fileType_ = getLong(data.pData_, bigEndian); fileType_ = getLong(data.pData_, endian_);
if ( bTrace ) { if ( bTrace ) {
out << "brand: " << toAscii(fileType_); out << "brand: " << toAscii(fileType_);
} }
@ -255,7 +247,7 @@ namespace Exiv2
bLF = false; bLF = false;
} }
int n = getShort(data.pData_ + skip, bigEndian); int n = getShort(data.pData_ + skip, endian_);
skip += 2; skip += 2;
io_->seek(skip, BasicIo::cur); io_->seek(skip, BasicIo::cur);
@ -266,10 +258,10 @@ namespace Exiv2
// 8.11.6.2 // 8.11.6.2
case TAG_infe: { // .__._.__hvc1_ 2 0 0 1 0 1 0 0 104 118 99 49 0 case TAG_infe: { // .__._.__hvc1_ 2 0 0 1 0 1 0 0 104 118 99 49 0
/* getLong (data.pData_+skip,bigEndian) ; */ skip += 4; /* getLong (data.pData_+skip,endian_) ; */ skip += 4;
uint16_t ID = getShort(data.pData_ + skip, bigEndian); uint16_t ID = getShort(data.pData_ + skip, endian_);
skip += 2; skip += 2;
/* getShort(data.pData_+skip,bigEndian) ; */ skip += 2; // protection /* getShort(data.pData_+skip,endian_) ; */ skip += 2; // protection
std::string id; std::string id;
std::string name((const char*)data.pData_ + skip); std::string name((const char*)data.pData_ + skip);
if ( !name.find("Exif") ) { // "Exif" or "ExifExif" if ( !name.find("Exif") ) { // "Exif" or "ExifExif"
@ -330,8 +322,8 @@ namespace Exiv2
#else #else
skip++; skip++;
#endif #endif
uint32_t itemCount = version < 2 ? getShort(data.pData_ + skip, bigEndian) uint32_t itemCount = version < 2 ? getShort(data.pData_ + skip, endian_)
: getLong(data.pData_ + skip, bigEndian); : getLong(data.pData_ + skip, endian_);
skip += version < 2 ? 2 : 4; skip += version < 2 ? 2 : 4;
if (itemCount && itemCount < box.length / 14 && offsetSize == 4 && lengthSize == 4 && if (itemCount && itemCount < box.length / 14 && offsetSize == 4 && lengthSize == 4 &&
((box.length - 16) % itemCount) == 0) { ((box.length - 16) % itemCount) == 0) {
@ -343,13 +335,13 @@ namespace Exiv2
uint32_t base = skip; uint32_t base = skip;
for (uint32_t i = 0; i < itemCount; i++) { for (uint32_t i = 0; i < itemCount; i++) {
skip = base + i * step; // move in 14, 16 or 18 byte steps skip = base + i * step; // move in 14, 16 or 18 byte steps
uint32_t ID = version > 2 ? getLong(data.pData_ + skip, bigEndian) uint32_t ID = version > 2 ? getLong(data.pData_ + skip, endian_)
: getShort(data.pData_ + skip, bigEndian); : getShort(data.pData_ + skip, endian_);
uint32_t offset = step==14 || step==16 ? getLong(data.pData_ + skip + step - 8, bigEndian) uint32_t offset = step==14 || step==16 ? getLong(data.pData_ + skip + step - 8, endian_)
: step== 18 ? getLong(data.pData_ + skip + 4, bigEndian) : step== 18 ? getLong(data.pData_ + skip + 4, endian_)
: 0 ; : 0 ;
uint32_t ldata = getLong(data.pData_ + skip + step - 4, bigEndian); uint32_t ldata = getLong(data.pData_ + skip + step - 4, endian_);
if ( bTrace ) { if ( bTrace ) {
out << indent(depth) out << indent(depth)
<< Internal::stringFormat("%8ld | %8u | ID | %4u | %6u,%6u", address + skip, step, << Internal::stringFormat("%8ld | %8u | ID | %4u | %6u,%6u", address + skip, step,
@ -366,9 +358,9 @@ namespace Exiv2
case TAG_ispe: { case TAG_ispe: {
skip += 4; skip += 4;
int width = (int)getLong(data.pData_ + skip, bigEndian); int width = (int)getLong(data.pData_ + skip, endian_);
skip += 4; skip += 4;
int height = (int)getLong(data.pData_ + skip, bigEndian); int height = (int)getLong(data.pData_ + skip, endian_);
skip += 4; skip += 4;
if ( bTrace ) { if ( bTrace ) {
out << "pixelWidth_, pixelHeight_ = " << Internal::stringFormat("%d, %d", width, height); out << "pixelWidth_, pixelHeight_ = " << Internal::stringFormat("%d, %d", width, height);
@ -388,13 +380,13 @@ namespace Exiv2
uint8_t meth = data.pData_[skip+0]; uint8_t meth = data.pData_[skip+0];
uint8_t prec = data.pData_[skip+1]; uint8_t prec = data.pData_[skip+1];
uint8_t approx = data.pData_[skip+2]; uint8_t approx = data.pData_[skip+2];
uint32_t colour_type = getLong(data.pData_+skip,littleEndian) ; std::string colour_type = std::string((char*)data.pData_,4) ;
skip+=4; skip+=4;
if ( boxName(colour_type) == "rICC" || boxName(colour_type) == "prof" ) { if ( colour_type == "rICC" || colour_type == "prof" ) {
DataBuf profile(box.length-skip); DataBuf profile(box.length-skip);
::memcpy(profile.pData_,data.pData_+skip,profile.size_-skip); ::memcpy(profile.pData_,data.pData_+skip,profile.size_-skip);
// fix length header bug in iOS files. // fix length header bug in iOS files.
uint32_t iccLength = getLong((byte*)&profile.size_,bigEndian); uint32_t iccLength = getLong((byte*)&profile.size_,endian_);
::memcpy(profile.pData_,&iccLength,4); ::memcpy(profile.pData_,&iccLength,4);
setIccProfile(profile); setIccProfile(profile);
} else if ( meth == 2 && prec == 0 && approx == 0 ) { } else if ( meth == 2 && prec == 0 && approx == 0 ) {
@ -536,7 +528,6 @@ namespace Exiv2
clearMetadata(); clearMetadata();
ilocs_.clear(); ilocs_.clear();
visits_.clear();
visits_max_ = io_->size() / 16; visits_max_ = io_->size() / 16;
unknownID_ = 0xffff; unknownID_ = 0xffff;
exifID_ = unknownID_; exifID_ = unknownID_;
@ -573,7 +564,6 @@ namespace Exiv2
case kpsRecursive : { case kpsRecursive : {
openOrThrow(); openOrThrow();
IoCloser closer(*io_); IoCloser closer(*io_);
visits_.clear();
long address = 0; long address = 0;
while (address < (long)io_->size()) { while (address < (long)io_->size()) {

@ -20,6 +20,7 @@ class pr_1475_2021_heic(metaclass=system_tests.CaseMeta):
commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename" commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename"
,"$exiv2 -pS $filename" ,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename" ,"$exiv2 -pX $filename"
,"$exiv2 -pC --binary $filename"
] ]
retval = [ 0 ] * len(commands) retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands) stderr = [ "" ] * len(commands)
@ -158,9 +159,21 @@ Exiv2::BmffImage::boxHandler: meta 36->3380
3376 | 16 | ID | 50 | 3432, 17469 3376 | 16 | ID | 50 | 3432, 17469
3392 | 16 | ID | 51 | 20901, 2364 3392 | 16 | ID | 51 | 20901, 2364
Exiv2::BMFF Exif: ID = 51 from,length = 20901,2364 Exiv2::BMFF Exif: ID = 51 from,length = 20901,2364
Exiv2::BmffImage::boxHandler: mdat 3416->1 (1474454) Exiv2::BmffImage::boxHandler: mdat 3416->1
Exiv2::BmffImage::boxHandler: __% 1474446->2641356760 ""","","""data:AAACLGFwcGwEAAAAbW50clJHQiBYWVogB+EABwAHAA0AFgAgYWNzcEF
""",""] QUEwAAAAAQVBQTAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1hcHBsyhq
VgiV/EE04mRPV0eoVggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
KZGVzYwAAAPwAAABlY3BydAAAAWQAAAAjd3RwdAAAAYgAAAAUclhZWgAAAZw
AAAAUZ1hZWgAAAbAAAAAUYlhZWgAAAcQAAAAUclRSQwAAAdgAAAAgY2hhZAA
AAfgAAAAsYlRSQwAAAdgAAAAgZ1RSQwAAAdgAAAAgZGVzYwAAAAAAAAALRGl
zcGxheSBQMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBJbmMuLCAyMDE3AABYWVogAAAAAAA
A81EAAQAAAAEWzFhZWiAAAAAAAACD3wAAPb////+7WFlaIAAAAAAAAEq/AAC
xNwAACrlYWVogAAAAAAAAKDgAABELAADIuXBhcmEAAAAAAAMAAAACZmYAAPK
nAAANWQAAE9AAAApbc2YzMgAAAAAAAQxCAAAF3v//8yYAAAeTAAD9kP//+6L
///2jAAAD3AAAwG4AAAAAAAAAAA==
"""]
class pr_1475_IMG_3578_heic(metaclass=system_tests.CaseMeta): class pr_1475_IMG_3578_heic(metaclass=system_tests.CaseMeta):
url = "https://github.com/Exiv2/exiv2/pull/1475" url = "https://github.com/Exiv2/exiv2/pull/1475"
@ -176,6 +189,7 @@ class pr_1475_IMG_3578_heic(metaclass=system_tests.CaseMeta):
commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename" commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename"
,"$exiv2 -pS $filename" ,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename" ,"$exiv2 -pX $filename"
,"$exiv2 -pC --binary $filename"
] ]
retval = [ 0 ] * len(commands) retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands) stderr = [ "" ] * len(commands)
@ -313,9 +327,21 @@ Exiv2::BmffImage::boxHandler: meta 32->3380
3372 | 16 | ID | 50 | 3428, 5479 3372 | 16 | ID | 50 | 3428, 5479
3388 | 16 | ID | 51 | 8907, 2024 3388 | 16 | ID | 51 | 8907, 2024
Exiv2::BMFF Exif: ID = 51 from,length = 8907,2024 Exiv2::BMFF Exif: ID = 51 from,length = 8907,2024
Exiv2::BmffImage::boxHandler: mdat 3412->1 (1122310) Exiv2::BmffImage::boxHandler: mdat 3412->1
Exiv2::BmffImage::boxHandler: .... 1122302->4115011359 ""","","""data:AAACLGFwcGwEAAAAbW50clJHQiBYWVogB+EABwAHAA0AFgAgYWNzcEF
""",""] QUEwAAAAAQVBQTAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1hcHBsyhq
VgiV/EE04mRPV0eoVggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
KZGVzYwAAAPwAAABlY3BydAAAAWQAAAAjd3RwdAAAAYgAAAAUclhZWgAAAZw
AAAAUZ1hZWgAAAbAAAAAUYlhZWgAAAcQAAAAUclRSQwAAAdgAAAAgY2hhZAA
AAfgAAAAsYlRSQwAAAdgAAAAgZ1RSQwAAAdgAAAAgZGVzYwAAAAAAAAALRGl
zcGxheSBQMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBJbmMuLCAyMDE3AABYWVogAAAAAAA
A81EAAQAAAAEWzFhZWiAAAAAAAACD3wAAPb////+7WFlaIAAAAAAAAEq/AAC
xNwAACrlYWVogAAAAAAAAKDgAABELAADIuXBhcmEAAAAAAAMAAAACZmYAAPK
nAAANWQAAE9AAAApbc2YzMgAAAAAAAQxCAAAF3v//8yYAAAeTAAD9kP//+6L
///2jAAAD3AAAwG4AAAAAAAAAAA==
"""]
class pr_1475_Stonehenge_heic(metaclass=system_tests.CaseMeta): class pr_1475_Stonehenge_heic(metaclass=system_tests.CaseMeta):
url = "https://github.com/Exiv2/exiv2/pull/1475" url = "https://github.com/Exiv2/exiv2/pull/1475"
@ -331,6 +357,7 @@ class pr_1475_Stonehenge_heic(metaclass=system_tests.CaseMeta):
commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename" commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename"
,"$exiv2 -pS $filename" ,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename" ,"$exiv2 -pX $filename"
,"$exiv2 -pC --binary $filename"
] ]
retval = [ 0 ] * len(commands) retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands) stderr = [ "" ] * len(commands)
@ -384,8 +411,7 @@ Exiv2::BmffImage::boxHandler: meta 24->508
510 | 14 | ID | 3 | 1630, 3150 510 | 14 | ID | 3 | 1630, 3150
Exiv2::BMFF Exif: ID = 2 from,length = 548,1082 Exiv2::BMFF Exif: ID = 2 from,length = 548,1082
Exiv2::BMFF XMP: ID = 3 from,length = 1630,3150 Exiv2::BMFF XMP: ID = 3 from,length = 1630,3150
Exiv2::BmffImage::boxHandler: mdat 532->1 (18241) Exiv2::BmffImage::boxHandler: mdat 532->1
Exiv2::BmffImage::boxHandler: Q.&. 18233->2350779715
""","""<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> ""","""<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2"> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
@ -444,7 +470,7 @@ Exiv2::BmffImage::boxHandler: Q.&. 18233->2350779715
<?xpacket end="w"?>"""] <?xpacket end="w"?>""",""]
class pr_1475_heic_heic(metaclass=system_tests.CaseMeta): class pr_1475_heic_heic(metaclass=system_tests.CaseMeta):
url = "https://github.com/Exiv2/exiv2/pull/1475" url = "https://github.com/Exiv2/exiv2/pull/1475"
@ -460,6 +486,7 @@ class pr_1475_heic_heic(metaclass=system_tests.CaseMeta):
commands = ["$exiv2 -pa $filename" commands = ["$exiv2 -pa $filename"
,"$exiv2 -pS $filename" ,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename" ,"$exiv2 -pX $filename"
,"$exiv2 -pC --binary $filename"
] ]
retval = [ 0 ] * len(commands) retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands) stderr = [ "" ] * len(commands)
@ -489,5 +516,5 @@ Exiv2::BmffImage::boxHandler: mdat 334661->24531
Exiv2::BmffImage::boxHandler: mdat 359192->330140 Exiv2::BmffImage::boxHandler: mdat 359192->330140
Exiv2::BmffImage::boxHandler: mdat 689332->28766 Exiv2::BmffImage::boxHandler: mdat 689332->28766
Exiv2::BmffImage::boxHandler: mdat 718098->16 Exiv2::BmffImage::boxHandler: mdat 718098->16
""",""] ""","",""]

Loading…
Cancel
Save