~ubuntu-branches/ubuntu/precise/exiv2/precise

« back to all changes in this revision

Viewing changes to src/exif.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Mercatante
  • Date: 2006-12-07 18:40:10 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20061207184010-0ouu8v0dr8nznob9
Tags: 0.12-0ubuntu1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 */
21
21
/*
22
22
  File:      exif.cpp
23
 
  Version:   $Rev: 808 $
 
23
  Version:   $Rev: 994 $
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
27
27
 */
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 $")
31
31
 
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;
469
469
 
470
470
        // Copy the data buffer
471
 
        delete[] pData_;
472
 
        pData_ = new byte[len];
473
 
        memcpy(pData_, buf, len);
474
 
        size_ = len;
 
471
        DataBuf tmpData(len);
 
472
        memcpy(tmpData.pData_, buf, len);
475
473
 
476
474
        // Read the TIFF header
477
 
        delete pTiffHeader_;
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;
482
480
 
483
481
        // Read IFD0
484
 
        delete pIfd0_;
485
 
        pIfd0_ = new Ifd(ifd0Id, 0, false);
486
 
        assert(pIfd0_ != 0);
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_,
 
485
                           tmpData.size_,
 
486
                           tmpTiffHeader->offset(), 
 
487
                           tmpTiffHeader->byteOrder());
488
488
        if (rc) return rc; // no point to continue if there is no IFD0
489
489
 
490
 
        delete pExifIfd_;
491
 
        pExifIfd_ = 0;
 
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.
 
493
 
 
494
        this->clear(); // Deletes existing pointers
 
495
        pData_ = tmpData.pData_;
 
496
        size_ = tmpData.size_;
 
497
        tmpData.release();
 
498
        pTiffHeader_ = tmpTiffHeader.release();
 
499
        pIfd0_ = tmpIfd0.release();
 
500
 
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
496
505
        if (0 == rc) {
497
506
            pExifIfd_ = tmpExif.release();
498
507
        }
 
508
 
499
509
        if (pExifIfd_) {
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);
504
 
            delete pMakerNote_;
505
 
            pMakerNote_ = 0;
506
514
            MakerNote::AutoPtr tmpMakerNote;
507
515
            if (   pos  != pExifIfd_->end()
508
516
                && make != pIfd0_->end() && model != pIfd0_->end()) {
538
546
                pExifIfd_->erase(pos);
539
547
            }
540
548
 
541
 
            delete pIopIfd_;
542
 
            pIopIfd_ = 0;
543
549
            std::auto_ptr<Ifd> tmpIop(new Ifd(iopIfdId, 0, false));
544
550
            assert(tmpIop.get() != 0);
545
551
            // Find and read Interoperability IFD in ExifIFD
549
555
            }
550
556
        } // if (pExifIfd_)
551
557
 
552
 
        delete pGpsIfd_;
553
 
        pGpsIfd_ = 0;
554
558
        std::auto_ptr<Ifd> tmpGps(new Ifd(gpsIfdId, 0, false));
555
559
        assert(tmpGps.get() != 0);
556
560
        // Find and read GPSInfo sub-IFD in IFD0
559
563
            pGpsIfd_ = tmpGps.release();
560
564
        }
561
565
 
562
 
        delete pIfd1_;
563
 
        pIfd1_ = 0;
564
566
        std::auto_ptr<Ifd> tmpIfd1(new Ifd(ifd1Id, 0, false));
565
567
        assert(tmpIfd1.get() != 0);
566
568
        // Read IFD1
575
577
            Ifd::iterator pos = pIfd1_->findTag(0x8769);
576
578
            if (pos != pIfd1_->end()) {
577
579
                pIfd1_->erase(pos);
578
 
                rc = 7;
579
580
            }
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);
584
 
                rc = 7;
585
585
            }
586
586
        }
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_) {
599
598
        // Read the thumbnail (but don't worry whether it was successful or not)
600
599
        readThumbnail();
601
600
 
602
 
        return rc;
 
601
        return 0;
603
602
    } // ExifData::load
604
603
 
605
604
    DataBuf ExifData::copy()
721
720
        }
722
721
 
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();
 
728
 
 
729
        // Return an empty buffer without TIFF header if there is nothing to write
 
730
        if (size == 0) return DataBuf(0);
 
731
 
 
732
        size += tiffHeader.size();
730
733
        DataBuf buf(size);
731
734
 
732
735
        // Copy the TIFF header, all IFDs, MakerNote and thumbnail to the buffer
806
809
                            FindMetadatumByIfdIdIdx(ifdId, idx));
807
810
    }
808
811
 
 
812
    void ExifData::clear()
 
813
    {
 
814
        eraseThumbnail();
 
815
        exifMetadata_.clear();
 
816
        delete pTiffHeader_;
 
817
        pTiffHeader_ = 0;
 
818
        delete pIfd0_;
 
819
        pIfd0_ = 0;
 
820
        delete pExifIfd_;
 
821
        pExifIfd_ = 0;
 
822
        delete pIopIfd_;
 
823
        pIopIfd_ = 0;
 
824
        delete pGpsIfd_;
 
825
        pGpsIfd_ = 0;
 
826
        delete pIfd1_;
 
827
        pIfd1_ = 0;
 
828
        delete pMakerNote_;
 
829
        pMakerNote_ = 0;
 
830
        delete[] pData_;
 
831
        pData_ = 0;
 
832
    }
 
833
 
809
834
    void ExifData::sortByKey()
810
835
    {
811
836
        std::sort(exifMetadata_.begin(), exifMetadata_.end(), cmpMetadataByKey);