Improved/fixed Exif (TIFF) type handling.
This commit is contained in:
parent
a9577e6c25
commit
8f167ee426
@ -665,8 +665,16 @@ namespace Action {
|
||||
if (Params::instance().printItems_ & Params::prType) {
|
||||
if (!first) std::cout << " ";
|
||||
first = false;
|
||||
std::cout << std::setw(9) << std::setfill(' ') << std::left
|
||||
<< md->typeName();
|
||||
std::cout << std::setw(9) << std::setfill(' ') << std::left;
|
||||
const char* tn = md->typeName();
|
||||
if (tn) {
|
||||
std::cout << tn;
|
||||
}
|
||||
else {
|
||||
std::ostringstream os;
|
||||
os << "0x" << std::setw(4) << std::setfill('0') << std::hex << md->typeId();
|
||||
std::cout << os.str();
|
||||
}
|
||||
}
|
||||
if (Params::instance().printItems_ & Params::prCount) {
|
||||
if (!first) std::cout << " ";
|
||||
|
||||
@ -145,31 +145,31 @@ namespace Exiv2 {
|
||||
{
|
||||
}
|
||||
|
||||
TiffEntryBase::TiffEntryBase(uint16_t tag, uint16_t group, TypeId typeId)
|
||||
TiffEntryBase::TiffEntryBase(uint16_t tag, uint16_t group, TiffType tiffType)
|
||||
: TiffComponent(tag, group),
|
||||
type_(typeId), count_(0), offset_(0),
|
||||
tiffType_(tiffType), count_(0), offset_(0),
|
||||
size_(0), pData_(0), isMalloced_(false),
|
||||
pValue_(0)
|
||||
{
|
||||
}
|
||||
|
||||
TiffSubIfd::TiffSubIfd(uint16_t tag, uint16_t group, uint16_t newGroup)
|
||||
: TiffEntryBase(tag, group, unsignedLong), newGroup_(newGroup)
|
||||
: TiffEntryBase(tag, group, ttUnsignedLong), newGroup_(newGroup)
|
||||
{
|
||||
}
|
||||
|
||||
TiffMnEntry::TiffMnEntry(uint16_t tag, uint16_t group, uint16_t mnGroup)
|
||||
: TiffEntryBase(tag, group, undefined), mnGroup_(mnGroup), mn_(0)
|
||||
: TiffEntryBase(tag, group, ttUndefined), mnGroup_(mnGroup), mn_(0)
|
||||
{
|
||||
}
|
||||
|
||||
TiffArrayEntry::TiffArrayEntry(uint16_t tag,
|
||||
uint16_t group,
|
||||
uint16_t elGroup,
|
||||
TypeId elTypeId,
|
||||
TiffType elTiffType,
|
||||
bool addSizeElement)
|
||||
: TiffEntryBase(tag, group, elTypeId),
|
||||
elSize_(static_cast<uint16_t>(TypeInfo::typeSize(elTypeId))),
|
||||
: TiffEntryBase(tag, group, elTiffType),
|
||||
elSize_(static_cast<uint16_t>(TypeInfo::typeSize(toTypeId(elTiffType, 0, elGroup)))),
|
||||
elGroup_(elGroup),
|
||||
addSizeElement_(addSizeElement)
|
||||
{
|
||||
@ -241,7 +241,7 @@ namespace Exiv2 {
|
||||
|
||||
void TiffEntryBase::setValue(Value::AutoPtr value)
|
||||
{
|
||||
type_ = static_cast<uint16_t>(value->typeId());
|
||||
tiffType_ = toTiffType(value->typeId());
|
||||
count_ = value->count();
|
||||
delete pValue_;
|
||||
pValue_ = value.release();
|
||||
@ -643,7 +643,7 @@ namespace Exiv2 {
|
||||
uint32_t TiffMnEntry::doCount() const
|
||||
{
|
||||
// Count of tag Exif.Photo.MakerNote is the size of the Makernote in bytes
|
||||
assert(typeId() == undefined);
|
||||
assert(tiffType() == ttUndefined);
|
||||
return size();
|
||||
}
|
||||
|
||||
@ -809,9 +809,9 @@ namespace Exiv2 {
|
||||
TiffEntryBase* pDirEntry = dynamic_cast<TiffEntryBase*>(pTiffComponent);
|
||||
assert(pDirEntry);
|
||||
byte buf[8];
|
||||
us2Data(buf, pDirEntry->tag(), byteOrder);
|
||||
us2Data(buf + 2, pDirEntry->typeId(), byteOrder);
|
||||
ul2Data(buf + 4, pDirEntry->count(), byteOrder);
|
||||
us2Data(buf, pDirEntry->tag(), byteOrder);
|
||||
us2Data(buf + 2, pDirEntry->tiffType(), byteOrder);
|
||||
ul2Data(buf + 4, pDirEntry->count(), byteOrder);
|
||||
append(blob, buf, 8);
|
||||
if (pDirEntry->size() > 4) {
|
||||
pDirEntry->setOffset(offset + static_cast<int32_t>(valueIdx));
|
||||
@ -851,18 +851,18 @@ namespace Exiv2 {
|
||||
|
||||
uint32_t TiffEntryBase::writeOffset(byte* buf,
|
||||
int32_t offset,
|
||||
TypeId type,
|
||||
TiffType tiffType,
|
||||
ByteOrder byteOrder)
|
||||
{
|
||||
uint32_t rc = 0;
|
||||
switch(type) {
|
||||
case unsignedShort:
|
||||
case signedShort:
|
||||
switch(tiffType) {
|
||||
case ttUnsignedShort:
|
||||
case ttSignedShort:
|
||||
if (static_cast<uint32_t>(offset) > 0xffff) throw Error(26);
|
||||
rc = s2Data(buf, static_cast<int16_t>(offset), byteOrder);
|
||||
break;
|
||||
case unsignedLong:
|
||||
case signedLong:
|
||||
case ttUnsignedLong:
|
||||
case ttSignedLong:
|
||||
rc = l2Data(buf, static_cast<int32_t>(offset), byteOrder);
|
||||
break;
|
||||
default:
|
||||
@ -889,7 +889,7 @@ namespace Exiv2 {
|
||||
+ static_cast<long>(dataIdx);
|
||||
idx += writeOffset(buf.pData_ + idx,
|
||||
offset + newDataIdx,
|
||||
typeId(),
|
||||
tiffType(),
|
||||
byteOrder);
|
||||
}
|
||||
append(blob, buf.pData_, buf.size_);
|
||||
@ -906,7 +906,7 @@ namespace Exiv2 {
|
||||
DataBuf buf(strips_.size() * 4);
|
||||
uint32_t idx = 0;
|
||||
for (Strips::const_iterator i = strips_.begin(); i != strips_.end(); ++i) {
|
||||
idx += writeOffset(buf.pData_ + idx, offset + imageIdx, typeId(), byteOrder);
|
||||
idx += writeOffset(buf.pData_ + idx, offset + imageIdx, tiffType(), byteOrder);
|
||||
imageIdx += i->second;
|
||||
}
|
||||
append(blob, buf.pData_, buf.size_);
|
||||
@ -923,7 +923,7 @@ namespace Exiv2 {
|
||||
DataBuf buf(ifds_.size() * 4);
|
||||
uint32_t idx = 0;
|
||||
for (Ifds::const_iterator i = ifds_.begin(); i != ifds_.end(); ++i) {
|
||||
idx += writeOffset(buf.pData_ + idx, offset + dataIdx, typeId(), byteOrder);
|
||||
idx += writeOffset(buf.pData_ + idx, offset + dataIdx, tiffType(), byteOrder);
|
||||
dataIdx += (*i)->size();
|
||||
}
|
||||
append(blob, buf.pData_, buf.size_);
|
||||
@ -1004,7 +1004,7 @@ namespace Exiv2 {
|
||||
{
|
||||
Value const* pv = pValue();
|
||||
if (!pv || pv->count() == 0) return 0;
|
||||
if (pv->typeId() != elTypeId_) {
|
||||
if (toTiffType(pv->typeId()) != elTiffType_) {
|
||||
throw Error(51, tag());
|
||||
}
|
||||
DataBuf buf(pv->size());
|
||||
@ -1236,6 +1236,29 @@ namespace Exiv2 {
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
|
||||
TypeId toTypeId(TiffType tiffType, uint16_t tag, uint16_t group)
|
||||
{
|
||||
TypeId ti = TypeId(tiffType);
|
||||
// On the fly type conversion for Exif.Photo.UserComment
|
||||
if (tag == 0x9286 && group == Group::exif && ti == undefined) {
|
||||
ti = comment;
|
||||
}
|
||||
return ti;
|
||||
}
|
||||
|
||||
TiffType toTiffType(TypeId typeId)
|
||||
{
|
||||
if (static_cast<uint32_t>(typeId) > 0xffff) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Error: '" << TypeInfo::typeName(typeId)
|
||||
<< "' is not a valid Exif (TIFF) type; using type '"
|
||||
<< TypeInfo::typeName(undefined) << "'.\n";
|
||||
#endif
|
||||
return undefined;
|
||||
}
|
||||
return static_cast<uint16_t>(typeId);
|
||||
}
|
||||
|
||||
bool cmpTagLt(TiffComponent const* lhs, TiffComponent const* rhs)
|
||||
{
|
||||
assert(lhs != 0);
|
||||
|
||||
@ -49,6 +49,27 @@ namespace Exiv2 {
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
//! TIFF value type.
|
||||
typedef uint16_t TiffType;
|
||||
|
||||
const TiffType ttUnsignedByte = 1; //!< Exif BYTE type
|
||||
const TiffType ttAsciiString = 2; //!< Exif ASCII type
|
||||
const TiffType ttUnsignedShort = 3; //!< Exif SHORT type
|
||||
const TiffType ttUnsignedLong = 4; //!< Exif LONG type
|
||||
const TiffType ttUnsignedRational = 5; //!< Exif RATIONAL type
|
||||
const TiffType ttSignedByte = 6; //!< Exif SBYTE type
|
||||
const TiffType ttUndefined = 7; //!< Exif UNDEFINED type
|
||||
const TiffType ttSignedShort = 8; //!< Exif SSHORT type
|
||||
const TiffType ttSignedLong = 9; //!< Exif SLONG type
|
||||
const TiffType ttSignedRational =10; //!< Exif SRATIONAL type
|
||||
const TiffType ttTiffFloat =11; //!< TIFF FLOAT type
|
||||
const TiffType ttTiffDouble =12; //!< TIFF DOUBLE type
|
||||
|
||||
//! Convert the \em tiffType of a \em tag and \em group to an Exiv2 \em typeId.
|
||||
TypeId toTypeId(TiffType tiffType, uint16_t tag, uint16_t group);
|
||||
//! Convert the %Exiv2 \em typeId to a TIFF value type.
|
||||
TiffType toTiffType(TypeId typeId);
|
||||
|
||||
/*!
|
||||
Known TIFF groups
|
||||
|
||||
@ -362,7 +383,7 @@ namespace Exiv2 {
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
TiffEntryBase(uint16_t tag, uint16_t group, TypeId typeId =invalidTypeId);
|
||||
TiffEntryBase(uint16_t tag, uint16_t group, TiffType tiffType =ttUndefined);
|
||||
//! Virtual destructor.
|
||||
virtual ~TiffEntryBase();
|
||||
//@}
|
||||
@ -396,8 +417,8 @@ namespace Exiv2 {
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
//! Return the Exiv2 type which corresponds to the field type
|
||||
TypeId typeId() const { return TypeId(type_); }
|
||||
//! Return the TIFF type
|
||||
TiffType tiffType() const { return tiffType_; }
|
||||
/*!
|
||||
@brief Return the offset to the data area relative to the base
|
||||
for the component (usually the start of the TIFF header)
|
||||
@ -470,7 +491,7 @@ namespace Exiv2 {
|
||||
//! Helper function to write an \em offset to a preallocated binary buffer
|
||||
static uint32_t writeOffset(byte* buf,
|
||||
int32_t offset,
|
||||
TypeId type,
|
||||
TiffType tiffType,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
private:
|
||||
@ -481,8 +502,8 @@ namespace Exiv2 {
|
||||
//@}
|
||||
|
||||
// DATA
|
||||
uint16_t type_; //!< Field Type
|
||||
uint32_t count_; //!< The number of values of the indicated Type
|
||||
TiffType tiffType_; //!< Field TIFF type
|
||||
uint32_t count_; //!< The number of values of the indicated type
|
||||
int32_t offset_; //!< Offset to the data area
|
||||
/*!
|
||||
Size of the data buffer holding the value in bytes, there is no
|
||||
@ -1033,7 +1054,7 @@ namespace Exiv2 {
|
||||
TiffArrayEntry(uint16_t tag,
|
||||
uint16_t group,
|
||||
uint16_t elGroup,
|
||||
TypeId elTypeId,
|
||||
TiffType elTiffType,
|
||||
bool addSizeElement);
|
||||
//! Virtual destructor
|
||||
virtual ~TiffArrayEntry();
|
||||
@ -1041,7 +1062,7 @@ namespace Exiv2 {
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
//! Return the type for the array elements
|
||||
//! Return the size of the array elements
|
||||
uint16_t elSize() const { return elSize_; }
|
||||
//! Return the group for the array elements
|
||||
uint16_t elGroup() const { return elGroup_; }
|
||||
@ -1107,10 +1128,10 @@ namespace Exiv2 {
|
||||
//! Constructor
|
||||
TiffArrayElement(uint16_t tag,
|
||||
uint16_t group,
|
||||
TypeId elTypeId,
|
||||
TiffType elTiffType,
|
||||
ByteOrder elByteOrder)
|
||||
: TiffEntryBase(tag, group),
|
||||
elTypeId_(elTypeId),
|
||||
elTiffType_(elTiffType),
|
||||
elByteOrder_(elByteOrder) {}
|
||||
//! Virtual destructor.
|
||||
virtual ~TiffArrayElement() {}
|
||||
@ -1118,7 +1139,7 @@ namespace Exiv2 {
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
TypeId elTypeId() const { return elTypeId_; }
|
||||
TiffType elTiffType() const { return elTiffType_; }
|
||||
ByteOrder elByteOrder() const { return elByteOrder_; }
|
||||
//@}
|
||||
|
||||
@ -1151,7 +1172,7 @@ namespace Exiv2 {
|
||||
|
||||
private:
|
||||
// DATA
|
||||
TypeId elTypeId_; //!< Type of the element
|
||||
TiffType elTiffType_; //!< TIFF type of the element
|
||||
ByteOrder elByteOrder_; //!< Byte order to read/write the element
|
||||
|
||||
}; // class TiffArrayElement
|
||||
@ -1188,30 +1209,30 @@ namespace Exiv2 {
|
||||
const TiffStructure* ts);
|
||||
|
||||
//! Function to create and initialize a new array entry
|
||||
template<TypeId typeId, bool addSizeElement>
|
||||
template<TiffType tiffType, bool addSizeElement>
|
||||
TiffComponent::AutoPtr newTiffArrayEntry(uint16_t tag,
|
||||
const TiffStructure* ts)
|
||||
{
|
||||
assert(ts);
|
||||
return TiffComponent::AutoPtr(
|
||||
new TiffArrayEntry(tag, ts->group_, ts->newGroup_, typeId, addSizeElement));
|
||||
new TiffArrayEntry(tag, ts->group_, ts->newGroup_, tiffType, addSizeElement));
|
||||
}
|
||||
|
||||
//! Function to create and initialize a new array element
|
||||
template<TypeId typeId, ByteOrder byteOrder>
|
||||
template<TiffType tiffType, ByteOrder byteOrder>
|
||||
TiffComponent::AutoPtr newTiffArrayElement(uint16_t tag,
|
||||
const TiffStructure* ts)
|
||||
{
|
||||
assert(ts);
|
||||
return TiffComponent::AutoPtr(
|
||||
new TiffArrayElement(tag, ts->group_, typeId, byteOrder));
|
||||
new TiffArrayElement(tag, ts->group_, tiffType, byteOrder));
|
||||
}
|
||||
|
||||
template<TypeId typeId>
|
||||
template<TiffType tiffType>
|
||||
TiffComponent::AutoPtr newTiffArrayElement(uint16_t tag,
|
||||
const TiffStructure* ts)
|
||||
{
|
||||
return newTiffArrayElement<typeId, invalidByteOrder>(tag, ts);
|
||||
return newTiffArrayElement<tiffType, invalidByteOrder>(tag, ts);
|
||||
}
|
||||
|
||||
//! Function to create and initialize a new TIFF entry for a thumbnail (data)
|
||||
|
||||
@ -333,8 +333,8 @@ namespace Exiv2 {
|
||||
|
||||
// Olympus makernote - some Olympus cameras use Minolta structures
|
||||
// Todo: Adding such tags will not work (maybe result in a Minolta makernote), need separate groups
|
||||
{ 0x0001, Group::olympmn, Group::minocso, 0x927c, Group::exif, newTiffArrayEntry<unsignedLong, false> },
|
||||
{ 0x0003, Group::olympmn, Group::minocsn, 0x927c, Group::exif, newTiffArrayEntry<unsignedLong, false> },
|
||||
{ 0x0001, Group::olympmn, Group::minocso, 0x927c, Group::exif, newTiffArrayEntry<ttUnsignedLong, false> },
|
||||
{ 0x0003, Group::olympmn, Group::minocsn, 0x927c, Group::exif, newTiffArrayEntry<ttUnsignedLong, false> },
|
||||
{ Tag::next, Group::olympmn, Group::ignr, 0x927c, Group::exif, newTiffDirectory },
|
||||
{ Tag::all, Group::olympmn, Group::olympmn, 0x927c, Group::exif, newTiffEntry },
|
||||
|
||||
@ -343,20 +343,20 @@ namespace Exiv2 {
|
||||
{ Tag::all, Group::fujimn, Group::fujimn, 0x927c, Group::exif, newTiffEntry },
|
||||
|
||||
// Canon makernote
|
||||
{ 0x0001, Group::canonmn, Group::canoncs, 0x927c, Group::exif, newTiffArrayEntry<unsignedShort, true> },
|
||||
{ 0x0004, Group::canonmn, Group::canonsi, 0x927c, Group::exif, newTiffArrayEntry<unsignedShort, true> },
|
||||
{ 0x0005, Group::canonmn, Group::canonpa, 0x927c, Group::exif, newTiffArrayEntry<unsignedShort, true> },
|
||||
{ 0x000f, Group::canonmn, Group::canoncf, 0x927c, Group::exif, newTiffArrayEntry<unsignedShort, true> },
|
||||
{ 0x0012, Group::canonmn, Group::canonpi, 0x927c, Group::exif, newTiffArrayEntry<unsignedShort, true> },
|
||||
{ 0x0001, Group::canonmn, Group::canoncs, 0x927c, Group::exif, newTiffArrayEntry<ttUnsignedShort, true> },
|
||||
{ 0x0004, Group::canonmn, Group::canonsi, 0x927c, Group::exif, newTiffArrayEntry<ttUnsignedShort, true> },
|
||||
{ 0x0005, Group::canonmn, Group::canonpa, 0x927c, Group::exif, newTiffArrayEntry<ttUnsignedShort, true> },
|
||||
{ 0x000f, Group::canonmn, Group::canoncf, 0x927c, Group::exif, newTiffArrayEntry<ttUnsignedShort, true> },
|
||||
{ 0x0012, Group::canonmn, Group::canonpi, 0x927c, Group::exif, newTiffArrayEntry<ttUnsignedShort, true> },
|
||||
{ Tag::next, Group::canonmn, Group::ignr, 0x927c, Group::exif, newTiffDirectory },
|
||||
{ Tag::all, Group::canonmn, Group::canonmn, 0x927c, Group::exif, newTiffEntry },
|
||||
|
||||
// Canon makernote composite tags
|
||||
{ Tag::all, Group::canoncs, Group::canoncs, 0x0001, Group::canonmn, newTiffArrayElement<unsignedShort> },
|
||||
{ Tag::all, Group::canonsi, Group::canonsi, 0x0004, Group::canonmn, newTiffArrayElement<unsignedShort> },
|
||||
{ Tag::all, Group::canonpa, Group::canonpa, 0x0005, Group::canonmn, newTiffArrayElement<unsignedShort> },
|
||||
{ Tag::all, Group::canoncf, Group::canoncf, 0x000f, Group::canonmn, newTiffArrayElement<unsignedShort> },
|
||||
{ Tag::all, Group::canonpi, Group::canonpi, 0x0012, Group::canonmn, newTiffArrayElement<unsignedShort> },
|
||||
{ Tag::all, Group::canoncs, Group::canoncs, 0x0001, Group::canonmn, newTiffArrayElement<ttUnsignedShort> },
|
||||
{ Tag::all, Group::canonsi, Group::canonsi, 0x0004, Group::canonmn, newTiffArrayElement<ttUnsignedShort> },
|
||||
{ Tag::all, Group::canonpa, Group::canonpa, 0x0005, Group::canonmn, newTiffArrayElement<ttUnsignedShort> },
|
||||
{ Tag::all, Group::canoncf, Group::canoncf, 0x000f, Group::canonmn, newTiffArrayElement<ttUnsignedShort> },
|
||||
{ Tag::all, Group::canonpi, Group::canonpi, 0x0012, Group::canonmn, newTiffArrayElement<ttUnsignedShort> },
|
||||
|
||||
// Nikon1 makernote
|
||||
{ Tag::next, Group::nikon1mn, Group::ignr, 0x927c, Group::exif, newTiffDirectory },
|
||||
@ -391,20 +391,20 @@ namespace Exiv2 {
|
||||
{ Tag::all, Group::sony2mn, Group::sony2mn, 0x927c, Group::exif, newTiffEntry },
|
||||
|
||||
// Minolta makernote
|
||||
{ 0x0001, Group::minoltamn, Group::minocso, 0x927c, Group::exif, newTiffArrayEntry<unsignedLong, false> },
|
||||
{ 0x0003, Group::minoltamn, Group::minocsn, 0x927c, Group::exif, newTiffArrayEntry<unsignedLong, false> },
|
||||
{ 0x0004, Group::minoltamn, Group::minocs7, 0x927c, Group::exif, newTiffArrayEntry<unsignedShort, false> },
|
||||
{ 0x0001, Group::minoltamn, Group::minocso, 0x927c, Group::exif, newTiffArrayEntry<ttUnsignedLong, false> },
|
||||
{ 0x0003, Group::minoltamn, Group::minocsn, 0x927c, Group::exif, newTiffArrayEntry<ttUnsignedLong, false> },
|
||||
{ 0x0004, Group::minoltamn, Group::minocs7, 0x927c, Group::exif, newTiffArrayEntry<ttUnsignedShort, false> },
|
||||
{ 0x0088, Group::minoltamn, Group::minoltamn, 0x927c, Group::exif, newTiffThumbData<0x0089, Group::minoltamn> },
|
||||
{ 0x0089, Group::minoltamn, Group::minoltamn, 0x927c, Group::exif, newTiffThumbSize<0x0088, Group::minoltamn> },
|
||||
{ 0x0114, Group::minoltamn, Group::minocs5, 0x927c, Group::exif, newTiffArrayEntry<unsignedShort, false> },
|
||||
{ 0x0114, Group::minoltamn, Group::minocs5, 0x927c, Group::exif, newTiffArrayEntry<ttUnsignedShort, false> },
|
||||
{ Tag::next, Group::minoltamn, Group::ignr, 0x927c, Group::exif, newTiffDirectory },
|
||||
{ Tag::all, Group::minoltamn, Group::minoltamn, 0x927c, Group::exif, newTiffEntry },
|
||||
|
||||
// Minolta makernote composite tags
|
||||
{ Tag::all, Group::minocso, Group::minocso, 0x0001, Group::minoltamn, newTiffArrayElement<unsignedLong, bigEndian> },
|
||||
{ Tag::all, Group::minocsn, Group::minocsn, 0x0003, Group::minoltamn, newTiffArrayElement<unsignedLong, bigEndian> },
|
||||
{ Tag::all, Group::minocs7, Group::minocs7, 0x0004, Group::minoltamn, newTiffArrayElement<unsignedShort, bigEndian> },
|
||||
{ Tag::all, Group::minocs5, Group::minocs5, 0x0114, Group::minoltamn, newTiffArrayElement<unsignedShort, bigEndian> },
|
||||
{ Tag::all, Group::minocso, Group::minocso, 0x0001, Group::minoltamn, newTiffArrayElement<ttUnsignedLong, bigEndian> },
|
||||
{ Tag::all, Group::minocsn, Group::minocsn, 0x0003, Group::minoltamn, newTiffArrayElement<ttUnsignedLong, bigEndian> },
|
||||
{ Tag::all, Group::minocs7, Group::minocs7, 0x0004, Group::minoltamn, newTiffArrayElement<ttUnsignedShort, bigEndian> },
|
||||
{ Tag::all, Group::minocs5, Group::minocs5, 0x0114, Group::minoltamn, newTiffArrayElement<ttUnsignedShort, bigEndian> },
|
||||
|
||||
// Tags which are not de/encoded
|
||||
{ Tag::next, Group::ignr, Group::ignr, Tag::none, Group::none, newTiffDirectory },
|
||||
|
||||
@ -348,8 +348,11 @@ namespace Exiv2 {
|
||||
{
|
||||
assert(object != 0);
|
||||
|
||||
// Don't decode the entry if value is not set
|
||||
if (!object->pValue()) return;
|
||||
|
||||
// Remember NewSubfileType
|
||||
if (object->tag() == 0x00fe && object->pValue()) {
|
||||
if (object->tag() == 0x00fe) {
|
||||
groupType_[object->group()] = object->pValue()->toLong();
|
||||
}
|
||||
|
||||
@ -567,8 +570,8 @@ namespace Exiv2 {
|
||||
assert(pTiffComponent);
|
||||
TiffEntryBase* pTiffEntry = dynamic_cast<TiffEntryBase*>(pTiffComponent);
|
||||
assert(pTiffEntry);
|
||||
us2Data(buf + 2, pTiffEntry->typeId(), byteOrder);
|
||||
ul2Data(buf + 4, pTiffEntry->count(), byteOrder);
|
||||
us2Data(buf + 2, pTiffEntry->tiffType(), byteOrder);
|
||||
ul2Data(buf + 4, pTiffEntry->count(), byteOrder);
|
||||
// Move data to offset field, if it fits and is not yet there.
|
||||
if (pTiffEntry->size() <= 4 && buf + 8 != pTiffEntry->pData()) {
|
||||
#ifdef DEBUG
|
||||
@ -997,7 +1000,7 @@ namespace Exiv2 {
|
||||
os_ << px << tiffGroupName(object->group())
|
||||
<< " " << _("tag") << " 0x" << std::setw(4) << std::setfill('0')
|
||||
<< std::hex << std::right << object->tag()
|
||||
<< ", " << _("type") << " " << TypeInfo::typeName(object->typeId())
|
||||
<< ", " << _("type") << " 0x" << std::hex << object->tiffType()
|
||||
<< ", " << std::dec << object->count() << " "<< _("component");
|
||||
if (object->count() > 1) os_ << "s";
|
||||
os_ << " in " << object->size() << " " << _("bytes");
|
||||
@ -1212,8 +1215,8 @@ namespace Exiv2 {
|
||||
assert(object != 0);
|
||||
|
||||
readTiffEntry(object);
|
||||
if ((object->typeId() == unsignedLong || object->typeId() == signedLong)
|
||||
&& object->count() >= 1) {
|
||||
if ( (object->tiffType() == ttUnsignedLong || object->tiffType() == ttSignedLong)
|
||||
&& object->count() >= 1) {
|
||||
for (uint32_t i = 0; i < object->count(); ++i) {
|
||||
int32_t offset = getLong(object->pData() + 4*i, byteOrder());
|
||||
if ( baseOffset() + offset > size_
|
||||
@ -1302,8 +1305,7 @@ namespace Exiv2 {
|
||||
|
||||
void TiffReader::visitIfdMakernoteEnd(TiffIfdMakernote* /*object*/)
|
||||
{
|
||||
// Reset state (byte order, create function, offset) back to that
|
||||
// for the image
|
||||
// Reset state (byte order, create function, offset) back to that for the image
|
||||
resetState();
|
||||
} // TiffReader::visitIfdMakernoteEnd
|
||||
|
||||
@ -1324,17 +1326,18 @@ namespace Exiv2 {
|
||||
}
|
||||
// Component already has tag
|
||||
p += 2;
|
||||
uint16_t type = getUShort(p, byteOrder());
|
||||
long typeSize = TypeInfo::typeSize(TypeId(type));
|
||||
TiffType tiffType = getUShort(p, byteOrder());
|
||||
TypeId typeId = toTypeId(tiffType, object->tag(), object->group());
|
||||
long typeSize = TypeInfo::typeSize(typeId);
|
||||
if (0 == typeSize) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Error: Directory " << tiffGroupName(object->group())
|
||||
std::cerr << "Warning: Directory " << tiffGroupName(object->group())
|
||||
<< ", entry 0x" << std::setw(4)
|
||||
<< std::setfill('0') << std::hex << object->tag()
|
||||
<< " has an invalid type " << std::dec << type
|
||||
<< "; skipping entry.\n";
|
||||
<< " has unknown Exif (TIFF) type " << std::dec << tiffType
|
||||
<< "; setting type size 1.\n";
|
||||
#endif
|
||||
return;
|
||||
typeSize = 1;
|
||||
}
|
||||
p += 2;
|
||||
uint32_t count = getULong(p, byteOrder());
|
||||
@ -1353,8 +1356,7 @@ namespace Exiv2 {
|
||||
uint32_t size = typeSize * count;
|
||||
uint32_t offset = getLong(p, byteOrder());
|
||||
byte* pData = p;
|
||||
if (size > 4) {
|
||||
if (baseOffset() + offset >= size_) {
|
||||
if (size > 4 && baseOffset() + offset >= size_) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Error: Offset of "
|
||||
<< "directory " << tiffGroupName(object->group())
|
||||
@ -1365,12 +1367,13 @@ namespace Exiv2 {
|
||||
<< std::setfill('0') << std::hex << offset
|
||||
<< "; truncating the entry\n";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
size = 0;
|
||||
}
|
||||
if (size > 4) {
|
||||
pData = const_cast<byte*>(pData_) + baseOffset() + offset;
|
||||
if (size > static_cast<uint32_t>(pLast_ - pData)) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Warning: Upper boundary of data for "
|
||||
std::cerr << "Error: Upper boundary of data for "
|
||||
<< "directory " << tiffGroupName(object->group())
|
||||
<< ", entry 0x" << std::setw(4)
|
||||
<< std::setfill('0') << std::hex << object->tag()
|
||||
@ -1387,16 +1390,7 @@ namespace Exiv2 {
|
||||
// Todo: adjust count, make size a multiple of typeSize
|
||||
}
|
||||
}
|
||||
// On the fly type conversion for Exif.Photo.UserComment
|
||||
// Todo: This should be somewhere else, maybe in a Value factory
|
||||
// which takes a Key and Type
|
||||
TypeId t = TypeId(type);
|
||||
if ( object->tag() == 0x9286
|
||||
&& object->group() == Group::exif
|
||||
&& t == undefined) {
|
||||
t = comment;
|
||||
}
|
||||
Value::AutoPtr v = Value::create(t);
|
||||
Value::AutoPtr v = Value::create(typeId);
|
||||
assert(v.get());
|
||||
v->read(pData, size, byteOrder());
|
||||
|
||||
@ -1431,8 +1425,8 @@ namespace Exiv2 {
|
||||
{
|
||||
assert(object != 0);
|
||||
|
||||
uint16_t type = object->elTypeId();
|
||||
uint32_t size = TypeInfo::typeSize(TypeId(type));
|
||||
TypeId typeId = toTypeId(object->elTiffType(), object->tag(), object->group());
|
||||
uint32_t size = TypeInfo::typeSize(typeId);
|
||||
// Hack: Exif.CanonCs.Lens has 3 components
|
||||
if (object->group() == Group::canoncs && object->tag() == 0x0017) {
|
||||
size *= 3;
|
||||
@ -1452,7 +1446,7 @@ namespace Exiv2 {
|
||||
|
||||
ByteOrder bo = object->elByteOrder();
|
||||
if (bo == invalidByteOrder) bo = byteOrder();
|
||||
Value::AutoPtr v = Value::create(TypeId(type));
|
||||
Value::AutoPtr v = Value::create(typeId);
|
||||
assert(v.get());
|
||||
v->read(pData, size, bo);
|
||||
|
||||
|
||||
@ -51,55 +51,64 @@ EXIV2_RCSID("@(#) $Id$")
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
TypeInfoTable::TypeInfoTable(TypeId typeId, const char* name, long size)
|
||||
: typeId_(typeId), name_(name), size_(size)
|
||||
{
|
||||
}
|
||||
|
||||
//! Lookup list of supported IFD type information
|
||||
const TypeInfoTable TypeInfo::typeInfoTable_[] = {
|
||||
TypeInfoTable(invalidTypeId, "Invalid", 0),
|
||||
TypeInfoTable(unsignedByte, "Byte", 1),
|
||||
TypeInfoTable(asciiString, "Ascii", 1),
|
||||
TypeInfoTable(unsignedShort, "Short", 2),
|
||||
TypeInfoTable(unsignedLong, "Long", 4),
|
||||
TypeInfoTable(unsignedRational, "Rational", 8),
|
||||
TypeInfoTable(signedByte, "SByte", 1),
|
||||
TypeInfoTable(undefined, "Undefined", 1),
|
||||
TypeInfoTable(signedShort, "SShort", 2),
|
||||
TypeInfoTable(signedLong, "SLong", 4),
|
||||
TypeInfoTable(signedRational, "SRational", 8),
|
||||
TypeInfoTable(string, "String", 1),
|
||||
TypeInfoTable(date, "Date", 8),
|
||||
TypeInfoTable(time, "Time", 11),
|
||||
TypeInfoTable(comment, "Comment", 1),
|
||||
TypeInfoTable(directory, "Directory", 1),
|
||||
TypeInfoTable(xmpText, "XmpText", 1),
|
||||
TypeInfoTable(xmpAlt, "XmpAlt", 1),
|
||||
TypeInfoTable(xmpBag, "XmpBag", 1),
|
||||
TypeInfoTable(xmpSeq, "XmpSeq", 1),
|
||||
TypeInfoTable(langAlt, "LangAlt", 1),
|
||||
{ invalidTypeId, "Invalid", 0 },
|
||||
{ unsignedByte, "Byte", 1 },
|
||||
{ asciiString, "Ascii", 1 },
|
||||
{ unsignedShort, "Short", 2 },
|
||||
{ unsignedLong, "Long", 4 },
|
||||
{ unsignedRational, "Rational", 8 },
|
||||
{ signedByte, "SByte", 1 },
|
||||
{ undefined, "Undefined", 1 },
|
||||
{ signedShort, "SShort", 2 },
|
||||
{ signedLong, "SLong", 4 },
|
||||
{ signedRational, "SRational", 8 },
|
||||
{ tiffFloat, "Float", 4 },
|
||||
{ tiffDouble, "Double", 8 },
|
||||
{ string, "String", 1 },
|
||||
{ date, "Date", 8 },
|
||||
{ time, "Time", 11 },
|
||||
{ comment, "Comment", 1 },
|
||||
{ directory, "Directory", 1 },
|
||||
{ xmpText, "XmpText", 1 },
|
||||
{ xmpAlt, "XmpAlt", 1 },
|
||||
{ xmpBag, "XmpBag", 1 },
|
||||
{ xmpSeq, "XmpSeq", 1 },
|
||||
{ langAlt, "LangAlt", 1 },
|
||||
// End of list marker
|
||||
TypeInfoTable(lastTypeId, "(Unknown)", 0)
|
||||
{ lastTypeId, "(Unknown)", 0 }
|
||||
};
|
||||
|
||||
bool TypeInfoTable::operator==(TypeId typeId) const
|
||||
{
|
||||
return typeId_ == typeId;
|
||||
}
|
||||
|
||||
bool TypeInfoTable::operator==(const std::string& name) const
|
||||
{
|
||||
return std::string(name_) == name;
|
||||
}
|
||||
|
||||
const char* TypeInfo::typeName(TypeId typeId)
|
||||
{
|
||||
return typeInfoTable_[ typeId < lastTypeId ? typeId : 0 ].name_;
|
||||
const TypeInfoTable* tit = find(typeInfoTable_, typeId);
|
||||
if (!tit) return 0;
|
||||
return tit->name_;
|
||||
}
|
||||
|
||||
TypeId TypeInfo::typeId(const std::string& typeName)
|
||||
{
|
||||
int i = 0;
|
||||
for (; typeInfoTable_[i].typeId_ != lastTypeId
|
||||
&& typeInfoTable_[i].name_ != typeName; ++i) {}
|
||||
return typeInfoTable_[i].typeId_ == lastTypeId ?
|
||||
invalidTypeId : typeInfoTable_[i].typeId_;
|
||||
const TypeInfoTable* tit = find(typeInfoTable_, typeName);
|
||||
if (!tit) return invalidTypeId;
|
||||
return tit->typeId_;
|
||||
}
|
||||
|
||||
long TypeInfo::typeSize(TypeId typeId)
|
||||
{
|
||||
return typeInfoTable_[ typeId < lastTypeId ? typeId : 0 ].size_;
|
||||
const TypeInfoTable* tit = find(typeInfoTable_, typeId);
|
||||
if (!tit) return 0;
|
||||
return tit->size_;
|
||||
}
|
||||
|
||||
DataBuf::DataBuf(DataBuf& rhs)
|
||||
|
||||
@ -99,15 +99,38 @@ namespace Exiv2 {
|
||||
//! An identifier for each mode of metadata support
|
||||
enum AccessMode { amNone=0, amRead=1, amWrite=2, amReadWrite=3 };
|
||||
|
||||
//! Type identifiers for IFD format types
|
||||
enum TypeId { invalidTypeId, unsignedByte, asciiString, unsignedShort,
|
||||
unsignedLong, unsignedRational, signedByte, undefined,
|
||||
signedShort, signedLong, signedRational,
|
||||
string, date, time,
|
||||
comment,
|
||||
directory,
|
||||
xmpText, xmpAlt, xmpBag, xmpSeq, langAlt,
|
||||
lastTypeId };
|
||||
/*!
|
||||
@brief %Exiv2 value type identifiers.
|
||||
|
||||
Used primarily as identifiers when creating %Exiv2 Value instances.
|
||||
See Value::create. 0x0000 to 0xffff are reserved for TIFF (Exif) types.
|
||||
*/
|
||||
enum TypeId {
|
||||
unsignedByte = 1, //!< Exif BYTE type, 8-bit unsigned integer.
|
||||
asciiString = 2, //!< Exif ASCII type, 8-bit byte.
|
||||
unsignedShort = 3, //!< Exif SHORT type, 16-bit (2-byte) unsigned integer.
|
||||
unsignedLong = 4, //!< Exif LONG type, 32-bit (4-byte) unsigned integer.
|
||||
unsignedRational = 5, //!< Exif RATIONAL type, two LONGs: numerator and denumerator of a fraction.
|
||||
signedByte = 6, //!< Exif SBYTE type, an 8-bit signed (twos-complement) integer.
|
||||
undefined = 7, //!< Exif UNDEFINED type, an 8-bit byte that may contain anything.
|
||||
signedShort = 8, //!< Exif SSHORT type, a 16-bit (2-byte) signed (twos-complement) integer.
|
||||
signedLong = 9, //!< Exif SLONG type, a 32-bit (4-byte) signed (twos-complement) integer.
|
||||
signedRational =10, //!< Exif SRATIONAL type, two SLONGs: numerator and denumerator of a fraction.
|
||||
tiffFloat =11, //!< TIFF FLOAT type, single precision (4-byte) IEEE format.
|
||||
tiffDouble =12, //!< TIFF DOUBLE type, double precision (8-byte) IEEE format.
|
||||
string =0x10000, //!< IPTC string type.
|
||||
date =0x10001, //!< IPTC date type.
|
||||
time =0x10002, //!< IPTC time type.
|
||||
comment =0x10003, //!< %Exiv2 type for the Exif user comment.
|
||||
directory =0x10004, //!< %Exiv2 type for a CIFF directory.
|
||||
xmpText =0x10005, //!< XMP text type.
|
||||
xmpAlt =0x10006, //!< XMP alternative type.
|
||||
xmpBag =0x10007, //!< XMP bag type.
|
||||
xmpSeq =0x10008, //!< XMP sequence type.
|
||||
langAlt =0x10009, //!< XMP language alternative type.
|
||||
invalidTypeId =0x1fffe, //!< Invalid type id.
|
||||
lastTypeId =0x1ffff //!< Last type id.
|
||||
};
|
||||
|
||||
// Todo: decentralize IfdId, so that new ids can be defined elsewhere
|
||||
//! Type to specify the IFD to which a metadata belongs
|
||||
@ -133,13 +156,15 @@ namespace Exiv2 {
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
//! Information pertaining to the defined types
|
||||
//! Information pertaining to the defined %Exiv2 value type identifiers.
|
||||
struct TypeInfoTable {
|
||||
//! Constructor
|
||||
TypeInfoTable(TypeId typeId, const char* name, long size);
|
||||
TypeId typeId_; //!< Type id
|
||||
const char* name_; //!< Name of the type
|
||||
long size_; //!< Bytes per data entry
|
||||
//! Comparison operator for \em typeId
|
||||
bool operator==(TypeId typeId) const;
|
||||
//! Comparison operator for \em name
|
||||
bool operator==(const std::string& name) const;
|
||||
}; // struct TypeInfoTable
|
||||
|
||||
//! Type information lookup functions. Implemented as a static class.
|
||||
|
||||
@ -68,10 +68,11 @@ namespace Exiv2 {
|
||||
AutoPtr value;
|
||||
switch (typeId) {
|
||||
case invalidTypeId:
|
||||
value = AutoPtr(new DataValue(invalidTypeId));
|
||||
break;
|
||||
case signedByte:
|
||||
case unsignedByte:
|
||||
value = AutoPtr(new DataValue(unsignedByte));
|
||||
case tiffFloat:
|
||||
case tiffDouble:
|
||||
value = AutoPtr(new DataValue(typeId));
|
||||
break;
|
||||
case asciiString:
|
||||
value = AutoPtr(new AsciiValue);
|
||||
@ -85,9 +86,6 @@ namespace Exiv2 {
|
||||
case unsignedRational:
|
||||
value = AutoPtr(new ValueType<URational>);
|
||||
break;
|
||||
case signedByte:
|
||||
value = AutoPtr(new DataValue(signedByte));
|
||||
break;
|
||||
case undefined:
|
||||
value = AutoPtr(new DataValue);
|
||||
break;
|
||||
|
||||
@ -217,6 +217,8 @@ namespace Exiv2 {
|
||||
<TR><TD class="indexkey">signedShort</TD><TD class="indexvalue">%ValueType < int16_t ></TD></TR>
|
||||
<TR><TD class="indexkey">signedLong</TD><TD class="indexvalue">%ValueType < int32_t ></TD></TR>
|
||||
<TR><TD class="indexkey">signedRational</TD><TD class="indexvalue">%ValueType < Rational ></TD></TR>
|
||||
<TR><TD class="indexkey">tiffFloat</TD><TD class="indexvalue">%DataValue(tiffFloat)</TD></TR>
|
||||
<TR><TD class="indexkey">tiffDouble</TD><TD class="indexvalue">%DataValue(tiffDouble)</TD></TR>
|
||||
<TR><TD class="indexkey">date</TD><TD class="indexvalue">%DateValue</TD></TR>
|
||||
<TR><TD class="indexkey">time</TD><TD class="indexvalue">%TimeValue</TD></TR>
|
||||
<TR><TD class="indexkey">comment</TD><TD class="indexvalue">%CommentValue</TD></TR>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user