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
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.
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, size_t start, size_t count);
//@}
//@{
/*!
@brief parse embedded tiff file (Exif metadata)
@ -119,6 +115,8 @@ namespace Exiv2
int pixelWidth() const;
int pixelHeight() const;
//@}
Exiv2::ByteOrder endian_ ;
private:
void openOrThrow();

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

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

@ -18,8 +18,9 @@ class pr_1475_2021_heic(metaclass=system_tests.CaseMeta):
print("*** test skipped. requires enable_bmff=1***")
else:
commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pC --binary $filename"
]
retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands)
@ -158,9 +159,21 @@ Exiv2::BmffImage::boxHandler: meta 36->3380
3376 | 16 | ID | 50 | 3432, 17469
3392 | 16 | ID | 51 | 20901, 2364
Exiv2::BMFF Exif: ID = 51 from,length = 20901,2364
Exiv2::BmffImage::boxHandler: mdat 3416->1 (1474454)
Exiv2::BmffImage::boxHandler: __% 1474446->2641356760
""",""]
Exiv2::BmffImage::boxHandler: mdat 3416->1
""","","""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):
url = "https://github.com/Exiv2/exiv2/pull/1475"
@ -174,8 +187,9 @@ class pr_1475_IMG_3578_heic(metaclass=system_tests.CaseMeta):
print("*** test skipped. requires enable_bmff=1***")
else:
commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pC --binary $filename"
]
retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands)
@ -313,9 +327,21 @@ Exiv2::BmffImage::boxHandler: meta 32->3380
3372 | 16 | ID | 50 | 3428, 5479
3388 | 16 | ID | 51 | 8907, 2024
Exiv2::BMFF Exif: ID = 51 from,length = 8907,2024
Exiv2::BmffImage::boxHandler: mdat 3412->1 (1122310)
Exiv2::BmffImage::boxHandler: .... 1122302->4115011359
""",""]
Exiv2::BmffImage::boxHandler: mdat 3412->1
""","","""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):
url = "https://github.com/Exiv2/exiv2/pull/1475"
@ -329,8 +355,9 @@ class pr_1475_Stonehenge_heic(metaclass=system_tests.CaseMeta):
print("*** test skipped. requires enable_bmff=1***")
else:
commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pC --binary $filename"
]
retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands)
@ -384,8 +411,7 @@ Exiv2::BmffImage::boxHandler: meta 24->508
510 | 14 | ID | 3 | 1630, 3150
Exiv2::BMFF Exif: ID = 2 from,length = 548,1082
Exiv2::BMFF XMP: ID = 3 from,length = 1630,3150
Exiv2::BmffImage::boxHandler: mdat 532->1 (18241)
Exiv2::BmffImage::boxHandler: Q.&. 18233->2350779715
Exiv2::BmffImage::boxHandler: mdat 532->1
""","""<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<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#">
@ -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):
url = "https://github.com/Exiv2/exiv2/pull/1475"
@ -458,8 +484,9 @@ class pr_1475_heic_heic(metaclass=system_tests.CaseMeta):
print("*** test skipped. requires enable_bmff=1***")
else:
commands = ["$exiv2 -pa $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pC --binary $filename"
]
retval = [ 0 ] * 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 689332->28766
Exiv2::BmffImage::boxHandler: mdat 718098->16
""",""]
""","",""]

Loading…
Cancel
Save