24
24
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
25
25
History: 26-Jan-04, ahu: created
26
26
11-Feb-04, ahu: isolated as a component
28
28
// *****************************************************************************
29
29
#include "rcsid.hpp"
30
EXIV2_RCSID("@(#) $Id: exif.cpp 808 2006-06-01 15:09:39Z ahuggel $");
30
EXIV2_RCSID("@(#) $Id: exif.cpp 994 2006-11-25 15:38:38Z ahuggel $")
32
32
// Define DEBUG_MAKERNOTE to output debug information to std::cerr, e.g, by
33
33
// calling make like this: make DEFS=-DDEBUG_MAKERNOTE exif.o
468
468
if (!buf || len == 0) return -1;
470
470
// Copy the data buffer
472
pData_ = new byte[len];
473
memcpy(pData_, buf, len);
471
DataBuf tmpData(len);
472
memcpy(tmpData.pData_, buf, len);
476
474
// Read the TIFF header
478
pTiffHeader_ = new TiffHeader;
479
assert(pTiffHeader_ != 0);
480
int rc = pTiffHeader_->read(pData_);
475
std::auto_ptr<TiffHeader> tmpTiffHeader(new TiffHeader);
476
assert(tmpTiffHeader.get() != 0);
477
if (tmpData.size_ < tmpTiffHeader->size()) return 1;
478
int rc = tmpTiffHeader->read(tmpData.pData_);
481
479
if (rc) return rc;
485
pIfd0_ = new Ifd(ifd0Id, 0, false);
487
rc = pIfd0_->read(pData_, size_, pTiffHeader_->offset(), byteOrder());
482
std::auto_ptr<Ifd> tmpIfd0(new Ifd(ifd0Id, 0, false));
483
assert(tmpIfd0.get() != 0);
484
rc = tmpIfd0->read(tmpData.pData_,
486
tmpTiffHeader->offset(),
487
tmpTiffHeader->byteOrder());
488
488
if (rc) return rc; // no point to continue if there is no IFD0
490
// We have at least a valid IFD0, so replace old metadata with new now
491
// After this point we only return 0 (success), although parts of the
492
// Exif data may be missing due to problems reading specific IFDs.
494
this->clear(); // Deletes existing pointers
495
pData_ = tmpData.pData_;
496
size_ = tmpData.size_;
498
pTiffHeader_ = tmpTiffHeader.release();
499
pIfd0_ = tmpIfd0.release();
492
501
std::auto_ptr<Ifd> tmpExif(new Ifd(exifIfdId, 0, false));
493
502
assert(tmpExif.get() != 0);
494
503
// Find and read ExifIFD sub-IFD of IFD0
497
506
pExifIfd_ = tmpExif.release();
500
510
// Find MakerNote in ExifIFD, create a MakerNote class
501
511
Ifd::iterator pos = pExifIfd_->findTag(0x927c);
502
512
Ifd::iterator make = pIfd0_->findTag(0x010f);
503
513
Ifd::iterator model = pIfd0_->findTag(0x0110);
506
514
MakerNote::AutoPtr tmpMakerNote;
507
515
if ( pos != pExifIfd_->end()
508
516
&& make != pIfd0_->end() && model != pIfd0_->end()) {
575
577
Ifd::iterator pos = pIfd1_->findTag(0x8769);
576
578
if (pos != pIfd1_->end()) {
577
579
pIfd1_->erase(pos);
580
581
// Find and delete GPSInfo sub-IFD in IFD1
581
582
pos = pIfd1_->findTag(0x8825);
582
583
if (pos != pIfd1_->end()) {
583
584
pIfd1_->erase(pos);
587
587
// Copy all entries from the IFDs and the MakerNote to the metadata
588
exifMetadata_.clear();
589
588
add(pIfd0_->begin(), pIfd0_->end(), byteOrder());
590
589
if (pExifIfd_) add(pExifIfd_->begin(), pExifIfd_->end(), byteOrder());
591
590
if (pMakerNote_) {
723
722
// Allocate a data buffer big enough for all metadata
724
long size = tiffHeader.size();
725
size += ifd0.size() + ifd0.dataSize();
723
long size = ifd0.size() + ifd0.dataSize();
726
724
size += exifIfd.size() + exifIfd.dataSize();
727
725
size += iopIfd.size() + iopIfd.dataSize();
728
726
size += gpsIfd.size() + gpsIfd.dataSize();
729
727
size += ifd1.size() + ifd1.dataSize();
729
// Return an empty buffer without TIFF header if there is nothing to write
730
if (size == 0) return DataBuf(0);
732
size += tiffHeader.size();
730
733
DataBuf buf(size);
732
735
// Copy the TIFF header, all IFDs, MakerNote and thumbnail to the buffer
806
809
FindMetadatumByIfdIdIdx(ifdId, idx));
812
void ExifData::clear()
815
exifMetadata_.clear();
809
834
void ExifData::sortByKey()
811
836
std::sort(exifMetadata_.begin(), exifMetadata_.end(), cmpMetadataByKey);