diff --git a/include/exiv2/bmffimage.hpp b/include/exiv2/bmffimage.hpp index 7784e7cb..5e2a8601 100644 --- a/include/exiv2/bmffimage.hpp +++ b/include/exiv2/bmffimage.hpp @@ -70,6 +70,7 @@ namespace Exiv2 BmffImage(BasicIo::AutoPtr io, size_t start, size_t count); //@} + void parseTiff(uint32_t root_tag,uint32_t length); //! @name Manipulators //@{ void readMetadata() /* override */ ; @@ -136,7 +137,7 @@ namespace Exiv2 std::string boxName (uint32_t box); bool superBox(uint32_t box); bool fullBox (uint32_t box); - + std::string uuidName(Exiv2::DataBuf& uuid); }; // class BmffImage diff --git a/src/bmffimage.cpp b/src/bmffimage.cpp index f190054e..eeb32d54 100755 --- a/src/bmffimage.cpp +++ b/src/bmffimage.cpp @@ -28,6 +28,7 @@ #include "image.hpp" #include "image_int.hpp" #include "tiffimage.hpp" +#include "tiffimage_int.hpp" #include "bmffimage.hpp" #include "basicio.hpp" #include "error.hpp" @@ -66,6 +67,11 @@ struct BmffBoxHeader #define TAG_ispe 0x69737065 /**< "ispe" Image spatial extents */ #define TAG_infe 0x696e6665 /**< "infe" Item Info Extention */ #define TAG_ipma 0x69706d61 /**< "ipma" Item Property Association */ +#define TAG_cmt1 0x434d5431 /**< ifd0Id */ +#define TAG_cmt2 0x434D5432 /**< exifID */ +#define TAG_cmt3 0x434D5433 /**< canonID */ +#define TAG_cmt4 0x434D5434 /**< gpsID */ + // ***************************************************************************** // class member definitions @@ -97,8 +103,8 @@ namespace Exiv2 uint32_t start_ ; uint32_t length_ ; - std::string toString() { - return Internal::stringFormat("ID = %d from,length = %d,%d", ID_,start_,length_); + std::string toString(long address=0) const { + return Internal::stringFormat("ID = %d from,length = %d,%d", ID_,start_+address,length_); } }; // class Iloc @@ -160,6 +166,18 @@ namespace Exiv2 } } + std::string BmffImage::uuidName(Exiv2::DataBuf& uuid) + { + const char* uuidCano = "\x85\xC0\xB6\x87\x82\xF\x11\xE0\x81\x11\xF4\xCE\x46\x2B\x6A\x48"; + const char* uuidXmp = "\xBE\x7A\xCF\xCB\x97\xA9\x42\xE8\x9C\x71\x99\x94\x91\xE3\xAF\xAC"; + const char* uuidCanp = "\xEA\xF4\x2B\x5E\x1C\x98\x4B\x88\xB9\xFB\xB7\xDC\x40\x6E\x4D\x16"; + const char* result = std::memcmp(uuid.pData_, uuidCano, 16) == 0 ? "cano" + : std::memcmp(uuid.pData_, uuidXmp, 16) == 0 ? "xmp" + : std::memcmp(uuid.pData_, uuidCanp, 16) == 0 ? "canp" + : "" ; + return result; + } + long BmffImage::boxHandler(int depth /* =0 */) { long result = (long) io_->size(); @@ -219,7 +237,6 @@ namespace Exiv2 #endif } break; - // 8.11.6.1 case TAG_iinf: { @@ -242,7 +259,7 @@ namespace Exiv2 uint16_t ID = getShort(data.pData_+skip,bigEndian) ; skip+=2; /* getShort(data.pData_+skip,bigEndian) ; */ skip+=2; // protection std::string name((const char*)data.pData_+skip); - if ( name.find("Exif")== 0 || name.find("Exif")== 0 ) { // "Exif" or "ExifExif" + if ( name.find("Exif")== 0 ) { // "Exif" or "ExifExif" exifID_ = ID ; } #ifdef EXIV2_DEBUG_MESSAGES @@ -251,6 +268,7 @@ namespace Exiv2 } break; + case TAG_moov: case TAG_iprp: case TAG_ipco: case TAG_meta: { @@ -262,6 +280,14 @@ namespace Exiv2 while ( (long) io_->tell() < (long)(address + box.length) ) { io_->seek(boxHandler(depth+1),BasicIo::beg); } + if ( box.type == TAG_meta && ilocs_.find(exifID_) != ilocs_.end() ) { + const Iloc& iloc = ilocs_.find(exifID_)->second; +#ifdef EXIV2_DEBUG_MESSAGES + std::cerr << indent(depth) << "Exiv2::BMFF Exif: " << iloc.toString(address+20) << std::endl; +#endif + // parseTiff(Internal::Tag::root,iloc.length_,iloc.start_+address); + exifID_ = unknownID_; + } } break; // 8.11.3.1 @@ -320,22 +346,54 @@ namespace Exiv2 #endif } break; + case TAG_uuid: + { + DataBuf uuid(16); + io_->read(uuid.pData_, uuid.size_); + std::string name = uuidName(uuid); +#ifdef EXIV2_DEBUG_MESSAGES + std::cout << " uuidName " << name; +#endif + // if we are in uuid cano we want to jump past box(8) + uuid(16) + // and enter the uuid + if (name == "cano") { + box.length = 24; + } + } break; + + case TAG_cmt1: parseTiff(Internal::Tag::root ,box.length); break; + case TAG_cmt2: parseTiff(Internal::Tag::cr3_exif,box.length); break; + case TAG_cmt3: parseTiff(Internal::Tag::cr3_mn ,box.length); break; + case TAG_cmt4: parseTiff(Internal::Tag::cr3_gps ,box.length); break; + default: {} ; /* do nothing */ } #ifdef EXIV2_DEBUG_MESSAGES if ( bLF ) std::cerr << std::endl; - if ( ilocs_.find(exifID_) != ilocs_.end() ) { - std::cerr << indent(depth) << "Exiv2::BMFF Exif: " << ilocs_.find(exifID_)->second.toString() << std::endl; - exifID_ = unknownID_; - } #endif - // return address of next box if ( box.length != 1 ) result = static_cast(address + box.length); return result ; } + void BmffImage::parseTiff(uint32_t root_tag,uint32_t length) + { + if ( length > 8 ) { + DataBuf data(length - 8); + // rawData.alloc(length - 8); + long bufRead = io_->read(data.pData_, data.size_); + + if (io_->error()) + throw Error(kerFailedToReadImageData); + if (bufRead != data.size_) + throw Error(kerInputDataReadFailed); + + Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), data.pData_, data.size_, root_tag, + Internal::TiffMapping::findDecoder); + } + } + void BmffImage::setComment(const std::string& /*comment*/) { // Todo: implement me! diff --git a/src/tiffcomposite_int.hpp b/src/tiffcomposite_int.hpp index 7153243b..b23f4dd9 100644 --- a/src/tiffcomposite_int.hpp +++ b/src/tiffcomposite_int.hpp @@ -76,12 +76,15 @@ namespace Exiv2 { Special TIFF tags for the use in TIFF structures only */ namespace Tag { - const uint32_t none = 0x10000; //!< Dummy tag - const uint32_t root = 0x20000; //!< Special tag: root IFD - const uint32_t next = 0x30000; //!< Special tag: next IFD - const uint32_t all = 0x40000; //!< Special tag: all tags in a group - const uint32_t pana = 0x80000; //!< Special tag: root IFD of Panasonic RAW images - const uint32_t fuji = 0x100000; //!< Special tag: root IFD of Fujifilm RAF images + const uint32_t none = 0x10000; //!< Dummy tag + const uint32_t root = 0x20000; //!< Special tag: root IFD + const uint32_t next = 0x30000; //!< Special tag: next IFD + const uint32_t all = 0x40000; //!< Special tag: all tags in a group + const uint32_t pana = 0x80000; //!< Special tag: root IFD of Panasonic RAW images + const uint32_t fuji = 0x100000; //!< Special tag: root IFD of Fujifilm RAF images + const uint32_t cr3_exif = 0x110000; //!< Special tag: root IFD of CR3 images + const uint32_t cr3_mn = 0x120000; //!< Special tag: root IFD of CR3 images + const uint32_t cr3_gps = 0x130000; //!< Special tag: root IFD of CR3 images } /*! diff --git a/src/tiffimage_int.cpp b/src/tiffimage_int.cpp index 8007a3b3..05d32621 100644 --- a/src/tiffimage_int.cpp +++ b/src/tiffimage_int.cpp @@ -3,6 +3,7 @@ #include "error.hpp" #include "makernote_int.hpp" #include "sonymn_int.hpp" +#include "tags_int.hpp" #include "tiffvisitor_int.hpp" #include "i18n.h" // NLS support. @@ -1125,6 +1126,11 @@ namespace Exiv2 { { Tag::fuji, ifdIdNotSet, newTiffDirectory }, { 0xf000, fujiId, newTiffSubIfd }, + + // CR3 images + { Tag::cr3_exif, ifdIdNotSet, newTiffDirectory }, + { Tag::cr3_mn, ifdIdNotSet, newTiffDirectory }, + { Tag::cr3_gps, ifdIdNotSet, newTiffDirectory }, // IFD0 { 0x8769, ifd0Id, newTiffSubIfd }, { 0x8825, ifd0Id, newTiffSubIfd },