commit 39bca86f3e9afd58ab3adfe8ea5b4ccbed6991f9
parent 8ab5bae320cde8181b3735287a7e7042bfb3e751
Author: Christian Grothoff <christian@grothoff.org>
Date: Sun, 12 Apr 2009 02:44:45 +0000
changing code to use libexiv2 directly
Diffstat:
51 files changed, 30 insertions(+), 18510 deletions(-)
diff --git a/src/plugins/exiv2/Makefile.am b/src/plugins/exiv2/Makefile.am
@@ -9,31 +9,33 @@ libextractor_exiv2_la_LDFLAGS = \
$(XTRA_CPPLIBS) -lpthread \
$(PLUGINFLAGS) $(retaincommand)
libextractor_exiv2_la_LIBADD = \
- $(top_builddir)/src/main/libextractor.la -lpthread
+ $(top_builddir)/src/main/libextractor.la -lpthread -lexiv2
libextractor_exiv2_la_SOURCES = \
-exiv2extractor.cc exv_conf.h exv_msvc.h \
-basicio.cpp basicio.hpp \
-canonmn.cpp canonmn.hpp \
-datasets.cpp datasets.hpp \
-error.cpp error.hpp \
-exif.cpp exif.hpp \
-fujimn.cpp fujimn.hpp \
-futils.cpp futils.hpp \
-ifd.cpp ifd.hpp \
-image.cpp image.hpp \
-iptc.cpp iptc.hpp \
-jpgimage.cpp jpgimage.hpp \
-makernote.cpp makernote.hpp \
-metadatum.cpp metadatum.hpp \
-mn.hpp \
-nikonmn.cpp nikonmn.hpp \
-olympusmn.cpp olympusmn.hpp \
-panasonicmn.cpp panasonicmn.hpp \
-rcsid.hpp \
-sigmamn.cpp sigmamn.hpp \
-sonymn.cpp sonymn.hpp \
-tags.cpp tags.hpp \
-types.cpp types.hpp \
-value.cpp value.hpp
+ exiv2extractor.cc
+
+#exv_conf.h exv_msvc.h \
+#basicio.cpp basicio.hpp \
+#canonmn.cpp canonmn.hpp \
+#datasets.cpp datasets.hpp \
+#error.cpp error.hpp \
+#exif.cpp exif.hpp \
+#fujimn.cpp fujimn.hpp \
+#futils.cpp futils.hpp \
+#ifd.cpp ifd.hpp \
+#image.cpp image.hpp \
+#iptc.cpp iptc.hpp \
+#jpgimage.cpp jpgimage.hpp \
+#makernote.cpp makernote.hpp \
+#metadatum.cpp metadatum.hpp \
+#mn.hpp \
+#nikonmn.cpp nikonmn.hpp \
+#olympusmn.cpp olympusmn.hpp \
+#panasonicmn.cpp panasonicmn.hpp \
+#rcsid.hpp \
+#sigmamn.cpp sigmamn.hpp \
+#sonymn.cpp sonymn.hpp \
+#tags.cpp tags.hpp \
+#types.cpp types.hpp \
+#value.cpp value.hpp
diff --git a/src/plugins/exiv2/README b/src/plugins/exiv2/README
@@ -1,14 +0,0 @@
-This is an initial import of exiv2 (0.7,
-http://home.arcor.de/ahuggel/exiv2) into libextractor.
-
-The current code has the following issues:
-
-* more memory leaks than the rest of LE combined and squared,
- thus cannot be added by default
-* previously generated header file is used (exv_conf.h),
- should be merged with Extractor's config.h where needed;
- unnecessary or bad checks should be eliminated
-* lots of dead code
-* possibly contains code that prints to stdout/stderr
-* not sure if the parser is robust enough (needs testing)
-
diff --git a/src/plugins/exiv2/Todo b/src/plugins/exiv2/Todo
@@ -1,40 +0,0 @@
-Library Features:
-+ rename erase* methods that access a file to remove*
-+ add ExifData::erase(tag)
-+ Thumbnail support: set (re-calculate)
-+ operator>> for Value, since we already have read()?
-+ Use size_t where appropriate
-+ Support TIFF type ids
-+ Support for broken IFD makernotes (which have corrupted IFD offsets)
-+ Support non-intrusive deletion of entries from an IFD.
-+ Write an example using low level IFD classes to print summary Exif info
-+ Extended JPEG support (actual resolution of the image)
-+ Implement proper error handling
-+ Complete support to create Exif data from scratch:
- + set thumbnail, write thumbnail tags
-+ Make it possible to force write from metadata (just an optional arg to write?)
-
-+ Make Image::doWriteMetadata do its work in a single pass
-
-+ Revise Image and IptcData+ExifData API (aka turn it inside out)
-+ Add PSD images support (and TIFF, NEF, CRW...)
-+ Add support for XML metadata files
-
-Exiv2 functionality
-+ Add offset to value for hexdump (requires metadata to have an offset)
-
-Bugs:
-+ Handle all Todo's
-+ Cleanup and fix implementation of JpegImage (must be able to read any APP0/1),
- should be able to insert exv into extracted thumbs (usually w/o APP0/1)
-+ Review Image interface. Is it really necessary to have so many functions there?
-+ Review the handling of type ids? What if we encounter type 27 in an IFD?
-+ Rational and other output operators (see Josuttis, p653)
-+ Through ExifData::iterator and Metadatum::operator= it is possible to have
- multiple copies of one metadatum in the metadata container
-+ Checks and non-intrusive updates must be atomic, i.e., not change anything
- if the metadata is not compatible
-+ Review: Exception safety
-+ Review: Ifd1 only at Thumbnail, do we really need Thumbnail::update() ?
-+ Is the hexdump output of exiv2 byte-swapped??
-+ Should JpegImage differ between NO Jpeg comment and an empty Jpeg comment??
diff --git a/src/plugins/exiv2/basicio.cpp b/src/plugins/exiv2/basicio.cpp
@@ -1,502 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: basicio.cpp
- Version: $Rev: 566 $
- Author(s): Brad Schick (brad) <brad@robotbattle.com>
- History: 04-Dec-04, brad: created
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: basicio.cpp 566 2005-04-26 15:27:41Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#ifdef _MSC_VER
-# include "exv_msvc.h"
-#else
-# include "exv_conf.h"
-#endif
-
-#include "basicio.hpp"
-#include "futils.hpp"
-#include "types.hpp"
-#include "error.hpp"
-
-// + standard includes
-#include <string>
-#include <cassert>
-#include <cstdio> // for remove()
-#include <sys/types.h> // for stat()
-#include <sys/stat.h> // for stat()
-#ifdef EXV_HAVE_PROCESS_H
-# include <process.h>
-#endif
-#ifdef EXV_HAVE_UNISTD_H
-# include <unistd.h> // for getpid, stat
-#endif
-
-#if defined WIN32 && !defined __CYGWIN__
-# include <io.h>
-#endif
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- FileIo::FileIo(const std::string& path) :
- path_(path), fp_(0), opMode_(opSeek)
- {
- }
-
- FileIo::~FileIo()
- {
- close();
- }
-
- BasicIo::AutoPtr FileIo::temporary() const
- {
- BasicIo::AutoPtr basicIo;
-
- struct stat buf;
- int ret = stat(path_.c_str(), &buf);
-
- // If file is > 1MB then use a file, otherwise use memory buffer
- if (ret != 0 || buf.st_size > 1048576) {
- pid_t pid = getpid();
- std::string tmpname = path_ + toString(pid);
- std::auto_ptr<FileIo> fileIo(new FileIo(tmpname));
- if (fileIo->open("w+b") != 0) {
- throw Error(10, path_, "w+b", strError());
- }
- basicIo = fileIo;
- }
- else {
- basicIo.reset(new MemIo);
- }
-
- return basicIo;
- }
-
- int FileIo::switchMode(OpMode opMode)
- {
- assert(fp_ != 0);
- if (opMode_ == opMode) return 0;
- OpMode oldOpMode = opMode_;
- opMode_ = opMode;
-
- bool reopen = true;
- std::string mode = "r+b";
-
- switch(opMode) {
- case opRead:
- // Flush if current mode allows reading, else reopen (in mode "r+b"
- // as in this case we know that we can write to the file)
- if ( openMode_[0] == 'r'
- || openMode_.substr(0, 2) == "w+"
- || openMode_.substr(0, 2) == "a+") reopen = false;
- break;
- case opWrite:
- // Flush if current mode allows writing, else reopen
- if ( openMode_.substr(0, 2) == "r+"
- || openMode_[0] == 'w'
- || openMode_[0] == 'a') reopen = false;
- break;
- case opSeek:
- reopen = false;
- break;
- }
-
- if (!reopen) {
- // Don't do anything when switching _from_ opSeek mode; we
- // flush when switching _to_ opSeek.
- if (oldOpMode == opSeek) return 0;
-
- // Flush. On msvcrt fflush does not do the job
- fseek(fp_, 0, SEEK_CUR);
- return 0;
- }
-
- // Reopen the file
- long offset = ftell(fp_);
- if (offset == -1) return -1;
- if (open(mode) != 0) return 1;
- return fseek(fp_, offset, SEEK_SET);
- }
-
- long FileIo::write(const byte* data, long wcount)
- {
- assert(fp_ != 0);
- if (switchMode(opWrite) != 0) return 0;
- return (long)fwrite(data, 1, wcount, fp_);
- }
-
- long FileIo::write(BasicIo& src)
- {
- assert(fp_ != 0);
- if (static_cast<BasicIo*>(this) == &src) return 0;
- if (!src.isopen()) return 0;
- if (switchMode(opWrite) != 0) return 0;
-
- byte buf[4096];
- long readCount = 0;
- long writeCount = 0;
- long writeTotal = 0;
- while ((readCount = src.read(buf, sizeof(buf)))) {
- writeTotal += writeCount = (long)fwrite(buf, 1, readCount, fp_);
- if (writeCount != readCount) {
- // try to reset back to where write stopped
- src.seek(writeCount-readCount, BasicIo::cur);
- break;
- }
- }
-
- return writeTotal;
- }
-
- void FileIo::transfer(BasicIo& src)
- {
- const bool wasOpen = (fp_ != 0);
- const std::string lastMode(openMode_);
-
- FileIo *fileIo = dynamic_cast<FileIo*>(&src);
- if (fileIo) {
- // Optimization if this is another instance of FileIo
- close();
- fileIo->close();
- // MSVCRT rename that does not overwrite existing files
- if (remove(path_.c_str()) != 0) {
- throw Error(2, path_, strError(), "::remove");
- }
- if (rename(fileIo->path_.c_str(), path_.c_str()) == -1) {
- throw Error(17, fileIo->path_, path_, strError());
- }
- remove(fileIo->path_.c_str());
- }
- else{
- // Generic handling, reopen both to reset to start
- if (open("w+b") != 0) {
- throw Error(10, path_, "w+b", strError());
- }
- if (src.open() != 0) {
- throw Error(9, src.path(), strError());
- }
- write(src);
- src.close();
- }
-
- if (wasOpen) {
- if (open(lastMode) != 0) {
- throw Error(10, path_, lastMode, strError());
- }
- }
- else close();
-
- if (error() || src.error()) throw Error(18, path_, strError());
- }
-
- int FileIo::putb(byte data)
- {
- assert(fp_ != 0);
- if (switchMode(opWrite) != 0) return EOF;
- return putc(data, fp_);
- }
-
- int FileIo::seek(long offset, Position pos)
- {
- assert(fp_ != 0);
- int fileSeek;
- if (pos == BasicIo::cur) {
- fileSeek = SEEK_CUR;
- }
- else if (pos == BasicIo::beg) {
- fileSeek = SEEK_SET;
- }
- else {
- assert(pos == BasicIo::end);
- fileSeek = SEEK_END;
- }
-
- if (switchMode(opSeek) != 0) return 1;
- return fseek(fp_, offset, fileSeek);
- }
-
- long FileIo::tell() const
- {
- assert(fp_ != 0);
- return ftell(fp_);
- }
-
-
- long FileIo::size() const
- {
- if (fp_ != 0) {
- fflush(fp_);
-#if defined WIN32 && !defined __CYGWIN__
- // This is required on msvcrt before stat after writing to a file
- _commit(_fileno(fp_));
-#endif
- }
-
- struct stat buf;
- int ret = stat(path_.c_str(), &buf);
-
- if (ret != 0) return -1;
- return buf.st_size;
- }
-
- int FileIo::open()
- {
- // Default open is in read-only binary mode
- return open("rb");
- }
-
- int FileIo::open(const std::string& mode)
- {
- if (fp_ != 0) {
- fclose(fp_);
- }
-
- openMode_ = mode;
- opMode_ = opSeek;
- fp_ = fopen(path_.c_str(), mode.c_str());
- if (!fp_) return 1;
- return 0;
- }
-
- bool FileIo::isopen() const
- {
- return fp_ != 0;
- }
-
- int FileIo::close()
- {
- if (fp_ != 0) {
- fclose(fp_);
- fp_= 0;
- }
- return 0;
- }
-
- DataBuf FileIo::read(long rcount)
- {
- assert(fp_ != 0);
- DataBuf buf(rcount);
- long readCount = read(buf.pData_, buf.size_);
- buf.size_ = readCount;
- return buf;
- }
-
- long FileIo::read(byte* buf, long rcount)
- {
- assert(fp_ != 0);
- if (switchMode(opRead) != 0) return 0;
- return (long)fread(buf, 1, rcount, fp_);
- }
-
- int FileIo::getb()
- {
- assert(fp_ != 0);
- if (switchMode(opRead) != 0) return EOF;
- return getc(fp_);
- }
-
- int FileIo::error() const
- {
- return fp_ != 0 ? ferror(fp_) : 0;
- }
-
- bool FileIo::eof() const
- {
- assert(fp_ != 0);
- return feof(fp_) != 0;
- }
-
- std::string FileIo::path() const
- {
- return path_;
- }
-
- MemIo::MemIo(const byte* data, long size)
- : data_(const_cast<byte*>(data)),
- idx_(0),
- size_(size),
- sizeAlloced_(0),
- isMalloced_(false)
- {
- }
-
- void MemIo::wrap(const byte *data, long size)
- {
- data_ = (byte *) data;
- size_ = size;
- isMalloced_ = false;
- }
-
- BasicIo::AutoPtr MemIo::temporary() const
- {
- return BasicIo::AutoPtr(new MemIo);
- }
-
- void MemIo::checkSize(long wcount)
- {
- long need = wcount + idx_;
- if (need > size_) {
- if (need > sizeAlloced_) {
- // Allocate in blocks of 32kB
- long want = 32768 * (1 + need / 32768);
- if (size_ > 0) {
- if (!isMalloced_) {
- // "copy-on-expand"
- byte* data = (byte*)malloc(want);
- memcpy(data, data_, size_);
- data_ = data;
- }
- else {
- data_ = (byte*)realloc(data_, want);
- }
- }
- else {
- data_ = (byte*)malloc(want);
- }
- sizeAlloced_ = want;
- isMalloced_ = true;
- }
- size_ = need;
- }
- }
-
- void MemIo::transfer(BasicIo& src)
- {
- MemIo *memIo = dynamic_cast<MemIo*>(&src);
- if (memIo) {
- // Optimization if this is another instance of MemIo
- if (memIo->isMalloced_)
- {
- isMalloced_ = true;
- memIo->isMalloced_ = false;
- }
- else
- isMalloced_ = false;
-
- data_ = memIo->data_;
- idx_ = 0;
- }
- else{
- // Generic reopen to reset position to start
- free(data_);
- idx_ = 0;
- if (src.open() != 0) {
- throw Error(9, src.path(), strError());
- }
- write(src);
- src.close();
- }
- if (error() || src.error()) throw Error(19, strError());
- }
-
- int MemIo::seek(long offset, Position pos)
- {
- long newIdx;
-
- if (pos == BasicIo::cur ) {
- newIdx = idx_ + offset;
- }
- else if (pos == BasicIo::beg) {
- newIdx = offset;
- }
- else {
- assert(pos == BasicIo::end);
- newIdx = size_ + offset;
- }
-
- if (newIdx < 0 || newIdx > size_) return 1;
- idx_ = newIdx;
- return 0;
- }
-
- long MemIo::tell() const
- {
- return idx_;
- }
-
- long MemIo::size() const
- {
- return size_;
- }
-
- int MemIo::open()
- {
- idx_ = 0;
- return 0;
- }
-
- bool MemIo::isopen() const
- {
- return true;
- }
-
- int MemIo::close()
- {
- return 0;
- }
-
- DataBuf MemIo::read(long rcount)
- {
- DataBuf buf(rcount);
- long readCount = read(buf.pData_, buf.size_);
- buf.size_ = readCount;
- return buf;
- }
-
- long MemIo::read(byte* buf, long rcount)
- {
- long avail = size_ - idx_;
- long allow = std::min(rcount, avail);
-
- memcpy(buf, &data_[idx_], allow);
- idx_ += allow;
- return allow;
- }
-
- int MemIo::getb()
- {
- if (idx_ == size_)
- return EOF;
- return data_[idx_++];
- }
-
- int MemIo::error() const
- {
- return 0;
- }
-
- bool MemIo::eof() const
- {
- return idx_ == size_;
- }
-
- std::string MemIo::path() const
- {
- return "MemIo";
- }
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/basicio.hpp b/src/plugins/exiv2/basicio.hpp
@@ -1,649 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file basicio.hpp
- @brief Simple binary IO abstraction
- @version $Rev: 565 $
- @author Brad Schick (brad)
- <a href="mailto:brad@robotbattle.com">brad@robotbattle.com</a>
- @date 04-Dec-04, brad: created
- */
-#ifndef BASICIO_HPP_
-#define BASICIO_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-
-// + standard includes
-#include <cstdlib>
-#include <memory>
-#include <string>
-#include <vector>
-#include <cstdio>
-#include <memory>
-#include <string.h>
-#include <stdlib.h>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class definitions
-
- /*!
- @brief An interface for simple binary IO.
-
- Designed to have semantics and names similar to those of C style FILE*
- operations. Subclasses should all behave the same so that they can be
- interchanged.
- */
- class BasicIo
- {
- public:
- //! BasicIo auto_ptr type
- typedef std::auto_ptr<BasicIo> AutoPtr;
-
- //! Seek starting positions
- enum Position { beg, cur, end };
-
- //! @name Creators
- //@{
- //! Destructor
- virtual ~BasicIo() {}
- //@}
-
- //! @name Manipulators
- //@{
- /*!
- @brief Open the IO source using the default access mode. The
- default mode should allow for reading and writing.
-
- This method can also be used to "reopen" an IO source which will
- flush any unwritten data and reset the IO position to the start.
- Subclasses may provide custom methods to allow for
- opening IO sources differently.
-
- @return 0 if successful;<BR>
- Nonzero if failure.
- */
- virtual int open() = 0;
- /*!
- @brief Close the IO source. After closing a BasicIo instance can not
- be read or written. Closing flushes any unwritten data. It is
- safe to call close on a closed instance.
- @return 0 if successful;<BR>
- Nonzero if failure.
- */
- virtual int close() = 0;
- /*!
- @brief Write data to the IO source. Current IO position is advanced
- by the number of bytes written.
- @param data Pointer to data. Data must be at least \em wcount
- bytes long
- @param wcount Number of bytes to be written.
- @return Number of bytes written to IO source successfully;<BR>
- 0 if failure;
- */
- virtual long write(const byte* data, long wcount) = 0;
- /*!
- @brief Write data that is read from another BasicIo instance to
- the IO source. Current IO position is advanced by the number
- of bytes written.
- @param src Reference to another BasicIo instance. Reading start
- at the source's current IO position
- @return Number of bytes written to IO source successfully;<BR>
- 0 if failure;
- */
- virtual long write(BasicIo& src) = 0;
- /*!
- @brief Write one byte to the IO source. Current IO position is
- advanced by one byte.
- @param data The single byte to be written.
- @return The value of the byte written if successful;<BR>
- EOF if failure;
- */
- virtual int putb(byte data) = 0;
- /*!
- @brief Read data from the IO source. Reading starts at the current
- IO position and the position is advanced by the number of bytes
- read.
- @param rcount Maximum number of bytes to read. Fewer bytes may be
- read if \em rcount bytes are not available.
- @return DataBuf instance containing the bytes read. Use the
- DataBuf::size_ member to find the number of bytes read.
- DataBuf::size_ will be 0 on failure.
- */
- virtual DataBuf read(long rcount) = 0;
- /*!
- @brief Read data from the IO source. Reading starts at the current
- IO position and the position is advanced by the number of bytes
- read.
- @param buf Pointer to a block of memory into which the read data
- is stored. The memory block must be at least \em rcount bytes
- long.
- @param rcount Maximum number of bytes to read. Fewer bytes may be
- read if \em rcount bytes are not available.
- @return Number of bytes read from IO source successfully;<BR>
- 0 if failure;
- */
- virtual long read(byte *buf, long rcount) = 0;
- /*!
- @brief Read one byte from the IO source. Current IO position is
- advanced by one byte.
- @return The byte read from the IO source if successful;<BR>
- EOF if failure;
- */
- virtual int getb() = 0;
- /*!
- @brief Remove all data from this object's IO source and then transfer
- data from the \em src BasicIo object into this object.
-
- The source object is invalidated by this operation and should not be
- used after this method returns. This method exists primarily to
- be used with the BasicIo::temporary() method.
-
- @param src Reference to another BasicIo instance. The entire contents
- of src are transferred to this object. The \em src object is
- invalidated by the method.
- @throw Error In case of failure
- */
- virtual void transfer(BasicIo& src) = 0;
- /*!
- @brief Move the current IO position.
- @param offset Number of bytes to move the position relative
- to the starting position specified by \em pos
- @param pos Position from which the seek should start
- @return 0 if successful;<BR>
- Nonzero if failure;
- */
- virtual int seek(long offset, Position pos) = 0;
- //@}
-
- //! @name Accessors
- //@{
- /*!
- @brief Get the current IO position.
- @return Offset from the start of IO if successful;<BR>
- -1 if failure;
- */
- virtual long tell() const = 0;
- /*!
- @brief Get the current size of the IO source in bytes.
- @return Size of the IO source in bytes;<BR>
- -1 if failure;
- */
- virtual long size() const = 0;
- //!Returns true if the IO source is open, otherwise false.
- virtual bool isopen() const = 0;
- //!Returns 0 if the IO source is in a valid state, otherwise nonzero.
- virtual int error() const = 0;
- //!Returns true if the IO position has reach the end, otherwise false.
- virtual bool eof() const = 0;
- /*!
- @brief Return the path to the IO resource. Often used to form
- comprehensive error messages where only a BasicIo instance is
- available.
- */
- virtual std::string path() const =0;
- /*!
- @brief Returns a temporary data storage location. This is often
- needed to rewrite an IO source.
-
- For example, data may be read from the original IO source, modified
- in some way, and then saved to the temporary instance. After the
- operation is complete, the BasicIo::transfer method can be used to
- replace the original IO source with the modified version. Subclasses
- are free to return any class that derives from BasicIo.
-
- @return An instance of BasicIo on success
- @throw Error In case of failure
- */
- virtual BasicIo::AutoPtr temporary() const = 0;
- //@}
-
- protected:
- //! @name Creators
- //@{
- //! Default Constructor
- BasicIo() {}
- //@}
- }; // class BasicIo
-
- /*!
- @brief Utility class that closes a BasicIo instance upon destruction.
- Meant to be used as a stack variable in functions that need to
- ensure BasicIo instances get closed. Useful when functions return
- errors from many locations.
- */
- class IoCloser {
- public:
- //! @name Creators
- //@{
- //! Constructor, takes a BasicIo reference
- IoCloser(BasicIo &bio) : bio_(bio) {}
- //! Destructor, closes the BasicIo reference
- ~IoCloser() { close(); }
- //@}
-
- //! @name Manipulators
- //@{
- //! Close the BasicIo if it is open
- void close() { if (bio_.isopen()) bio_.close(); }
- //@}
-
- // DATA
- //! The BasicIo reference
- BasicIo &bio_;
- private:
- // Not implemented
- //! Copy constructor
- IoCloser(const IoCloser&);
- //! Assignment operator
- IoCloser& operator=(const IoCloser&);
- }; // class IoCloser
-
-
- /*!
- @brief Provides binary file IO by implementing the BasicIo
- interface.
- */
- class FileIo : public BasicIo
- {
- public:
- //! @name Creators
- //@{
- /*!
- @brief Constructor that accepts the file path on which IO will be
- performed. The constructor does not open the file, and
- therefore never failes.
- @param path The full path of a file
- */
- FileIo(const std::string& path);
- //! Destructor. Flushes and closes an open file.
- virtual ~FileIo();
- //@}
-
- //! @name Manipulators
- //@{
- /*!
- @brief Open the file using using the specified mode.
-
- This method can also be used to "reopen" a file which will flush any
- unwritten data and reset the IO position to the start. Although
- files can be opened in binary or text mode, this class has
- only been tested carefully in binary mode.
-
- @param mode Specified that type of access allowed on the file.
- Valid values match those of the C fopen command exactly.
- @return 0 if successful;<BR>
- Nonzero if failure.
- */
- int open(const std::string& mode);
- /*!
- @brief Open the file using using the default access mode of "rb".
- This method can also be used to "reopen" a file which will flush
- any unwritten data and reset the IO position to the start.
- @return 0 if successful;<BR>
- Nonzero if failure.
- */
- virtual int open();
- /*!
- @brief Flush and unwritten data and close the file . It is
- safe to call close on an already closed instance.
- @return 0 if successful;<BR>
- Nonzero if failure;
- */
- virtual int close();
- /*!
- @brief Write data to the file. The file position is advanced
- by the number of bytes written.
- @param data Pointer to data. Data must be at least \em wcount
- bytes long
- @param wcount Number of bytes to be written.
- @return Number of bytes written to the file successfully;<BR>
- 0 if failure;
- */
- virtual long write(const byte* data, long wcount);
- /*!
- @brief Write data that is read from another BasicIo instance to
- the file. The file position is advanced by the number
- of bytes written.
- @param src Reference to another BasicIo instance. Reading start
- at the source's current IO position
- @return Number of bytes written to the file successfully;<BR>
- 0 if failure;
- */
- virtual long write(BasicIo& src);
- /*!
- @brief Write one byte to the file. The file position is
- advanced by one byte.
- @param data The single byte to be written.
- @return The value of the byte written if successful;<BR>
- EOF if failure;
- */
- virtual int putb(byte data);
- /*!
- @brief Read data from the file. Reading starts at the current
- file position and the position is advanced by the number of
- bytes read.
- @param rcount Maximum number of bytes to read. Fewer bytes may be
- read if \em rcount bytes are not available.
- @return DataBuf instance containing the bytes read. Use the
- DataBuf::size_ member to find the number of bytes read.
- DataBuf::size_ will be 0 on failure.
- */
- virtual DataBuf read(long rcount);
- /*!
- @brief Read data from the file. Reading starts at the current
- file position and the position is advanced by the number of
- bytes read.
- @param buf Pointer to a block of memory into which the read data
- is stored. The memory block must be at least \em rcount bytes
- long.
- @param rcount Maximum number of bytes to read. Fewer bytes may be
- read if \em rcount bytes are not available.
- @return Number of bytes read from the file successfully;<BR>
- 0 if failure;
- */
- virtual long read(byte *buf, long rcount);
- /*!
- @brief Read one byte from the file. The file position is
- advanced by one byte.
- @return The byte read from the file if successful;<BR>
- EOF if failure;
- */
- virtual int getb();
- /*!
- @brief Remove the contents of the file and then transfer data from
- the \em src BasicIo object into the empty file.
-
- This method is optimized to simply rename the source file if the
- source object is another FileIo instance. The source BasicIo object
- is invalidated by this operation and should not be used after this
- method returns. This method exists primarily to be used with
- the BasicIo::temporary() method.
-
- @param src Reference to another BasicIo instance. The entire contents
- of src are transferred to this object. The \em src object is
- invalidated by the method.
- @throw Error In case of failure
- */
- virtual void transfer(BasicIo& src);
- /*!
- @brief Move the current file position.
- @param offset Number of bytes to move the file position
- relative to the starting position specified by \em pos
- @param pos Position from which the seek should start
- @return 0 if successful;<BR>
- Nonzero if failure;
- */
- virtual int seek(long offset, Position pos);
- //@}
-
- //! @name Accessors
- //@{
- /*!
- @brief Get the current file position.
- @return Offset from the start of the file if successful;<BR>
- -1 if failure;
- */
- virtual long tell() const;
- /*!
- @brief Flush any buffered writes and get the current file size
- in bytes.
- @note On Win32 systems the file must be closed prior to calling this
- function.
- @return Size of the file in bytes;<BR>
- -1 if failure;
- */
- virtual long size() const;
- //! Returns true if the file is open, otherwise false.
- virtual bool isopen() const;
- //! Returns 0 if the file is in a valid state, otherwise nonzero.
- virtual int error() const;
- //! Returns true if the file position has reach the end, otherwise false.
- virtual bool eof() const;
- //! Returns the path of the file
- virtual std::string path() const;
- /*!
- @brief Returns a temporary data storage location. The actual type
- returned depends upon the size of the file represented a FileIo
- object. For small files, a MemIo is returned while for large files
- a FileIo is returned. Callers should not rely on this behavior,
- however, since it may change.
- @return An instance of BasicIo on success
- @throw Error If opening the temporary file fails
- */
- virtual BasicIo::AutoPtr temporary() const;
- //@}
-
- private:
- // NOT IMPLEMENTED
- //! Copy constructor
- FileIo(FileIo& rhs);
- //! Assignment operator
- FileIo& operator=(const FileIo& rhs);
-
- // Enumeration
- enum OpMode { opRead, opWrite, opSeek };
-
- // DATA
- std::string path_;
- std::string openMode_;
- FILE *fp_;
- OpMode opMode_;
-
- // METHODS
- /*!
- @brief Switch to a new access mode, reopening the file if needed.
- Optimized to only reopen the file when it is really necessary.
- @param opMode The mode to switch to.
- @return 0 if successful
- */
- int switchMode(OpMode opMode);
-
- }; // class FileIo
-
- /*!
- @brief Provides binary IO on blocks of memory by implementing the
- BasicIo interface. The current implementation makes a copy of
- any data passed to its constructors. If writes are performed, the
- changed data can be retrieved using the read methods (since the
- data used in construction is never modified).
-
- @note If read only usage of this class is common, it might be worth
- creating a specialized readonly class or changing this one to
- have a readonly mode.
- */
- class MemIo : public BasicIo
- {
- public:
- //! @name Creators
- //@{
- //! Default constructor that results in an empty object
- MemIo() : data_(0), idx_(0), size_(0), sizeAlloced_(0), isMalloced_(false) {}
- /*!
- @brief Constructor that accepts a block of memory to be copied.
- IO operations are performed on the copied memory.
- @param data Pointer to data. Data must be at least \em size
- bytes long
- @param size Number of bytes to copy.
- */
- MemIo(const byte* data, long size);
- //! Destructor. Releases all managed memory
- ~MemIo() {if (isMalloced_) free(data_);}
-
- void wrap(const byte *data, long size);
-
- //@}
-
- //! @name Manipulators
- //@{
- /*!
- @brief Memory IO is always open for reading and writing. This method
- therefore only resets the IO position to the start.
-
- @return 0
- */
- virtual int open();
- /*!
- @brief Does nothing on MemIo objects.
- @return 0
- */
- virtual int close();
- /*!
- @brief Write data to the memory block. If needed, the size of the
- internal memory block is expanded. The IO position is advanced
- by the number of bytes written.
- @param data Pointer to data. Data must be at least \em wcount
- bytes long
- @param wcount Number of bytes to be written.
- @return Number of bytes written to the memory block successfully;<BR>
- 0 if failure;
- */
- virtual long write(const byte* data, long wcount) { return 0; }
- /*!
- @brief Write data that is read from another BasicIo instance to
- the memory block. If needed, the size of the internal memory
- block is expanded. The IO position is advanced by the number
- of bytes written.
- @param src Reference to another BasicIo instance. Reading start
- at the source's current IO position
- @return Number of bytes written to the memory block successfully;<BR>
- 0 if failure;
- */
- virtual long write(BasicIo& src) { return 0; }
- /*!
- @brief Write one byte to the memory block. The IO position is
- advanced by one byte.
- @param data The single byte to be written.
- @return The value of the byte written if successful;<BR>
- EOF if failure;
- */
- virtual int putb(byte data) { return EOF; }
- /*!
- @brief Read data from the memory block. Reading starts at the current
- IO position and the position is advanced by the number of
- bytes read.
- @param rcount Maximum number of bytes to read. Fewer bytes may be
- read if \em rcount bytes are not available.
- @return DataBuf instance containing the bytes read. Use the
- DataBuf::size_ member to find the number of bytes read.
- DataBuf::size_ will be 0 on failure.
- */
- virtual DataBuf read(long rcount);
- /*!
- @brief Read data from the memory block. Reading starts at the current
- IO position and the position is advanced by the number of
- bytes read.
- @param buf Pointer to a block of memory into which the read data
- is stored. The memory block must be at least \em rcount bytes
- long.
- @param rcount Maximum number of bytes to read. Fewer bytes may be
- read if \em rcount bytes are not available.
- @return Number of bytes read from the memory block successfully;<BR>
- 0 if failure;
- */
- virtual long read(byte *buf, long rcount);
- /*!
- @brief Read one byte from the memory block. The IO position is
- advanced by one byte.
- @return The byte read from the memory block if successful;<BR>
- EOF if failure;
- */
- virtual int getb();
- /*!
- @brief Clear the memory clock and then transfer data from
- the \em src BasicIo object into a new block of memory.
-
- This method is optimized to simply swap memory block if the source
- object is another MemIo instance. The source BasicIo instance
- is invalidated by this operation and should not be used after this
- method returns. This method exists primarily to be used with
- the BasicIo::temporary() method.
-
- @param src Reference to another BasicIo instance. The entire contents
- of src are transferred to this object. The \em src object is
- invalidated by the method.
- @throw Error In case of failure
- */
- virtual void transfer(BasicIo& src);
- /*!
- @brief Move the current IO position.
- @param offset Number of bytes to move the IO position
- relative to the starting position specified by \em pos
- @param pos Position from which the seek should start
- @return 0 if successful;<BR>
- Nonzero if failure;
- */
- virtual int seek(long offset, Position pos);
- //@}
-
- //! @name Accessors
- //@{
- /*!
- @brief Get the current IO position.
- @return Offset from the start of the memory block
- */
- virtual long tell() const;
- /*!
- @brief Get the current memory buffer size in bytes.
- @return Size of the in memory data in bytes;<BR>
- -1 if failure;
- */
- virtual long size() const;
- //!Always returns true
- virtual bool isopen() const;
- //!Always returns 0
- virtual int error() const;
- //!Returns true if the IO position has reach the end, otherwise false.
- virtual bool eof() const;
- //! Returns a dummy path, indicating that memory access is used
- virtual std::string path() const;
- /*!
- @brief Returns a temporary data storage location. Currently returns
- an empty MemIo object, but callers should not rely on this
- behavior since it may change.
- @return An instance of BasicIo
- */
- virtual BasicIo::AutoPtr temporary() const;
- //@}
- private:
- // NOT IMPLEMENTED
- //! Copy constructor
- MemIo(MemIo& rhs);
- //! Assignment operator
- MemIo& operator=(const MemIo& rhs);
-
- byte *data_;
- long idx_;
- long size_;
- long sizeAlloced_; //!< Size of the allocated buffer
- bool isMalloced_; //!< Was the buffer allocated?
-
- // METHODS
- void checkSize(long wcount);
- }; // class MemIo
-} // namespace Exiv2
-
-#endif // #ifndef BASICIO_HPP_
diff --git a/src/plugins/exiv2/canonmn.cpp b/src/plugins/exiv2/canonmn.cpp
@@ -1,931 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: canonmn.cpp
- Version: $Rev: 600 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 18-Feb-04, ahu: created
- 07-Mar-04, ahu: isolated as a separate component
- Credits: Canon MakerNote implemented according to the specification
- "EXIF MakerNote of Canon" <http://www.burren.cx/david/canon.html>
- by David Burren
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: canonmn.cpp 600 2005-07-09 10:38:09Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "canonmn.hpp"
-#include "makernote.hpp"
-#include "value.hpp"
-#include "ifd.hpp"
-
-// + standard includes
-#include <string>
-#include <sstream>
-#include <iomanip>
-#include <algorithm>
-#include <cassert>
-#include <cstring>
-#include <cmath>
-
-// *****************************************************************************
-// local declarations
-namespace {
- /*
- @brief Convert Canon hex-based EV (modulo 0x20) to real number
- Ported from Phil Harvey's Image::ExifTool::Canon::CanonEv
- by Will Stokes
-
- 0x00 -> 0
- 0x0c -> 0.33333
- 0x10 -> 0.5
- 0x14 -> 0.66666
- 0x20 -> 1
- ..
- 160 -> 5
- 128 -> 4
- 143 -> 4.46875
- */
- float canonEv(long val);
-}
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- //! @cond IGNORE
- CanonMakerNote::RegisterMn::RegisterMn()
- {
- MakerNoteFactory::registerMakerNote("Canon", "*", createCanonMakerNote);
-
- MakerNoteFactory::registerMakerNote(
- canonIfdId, MakerNote::AutoPtr(new CanonMakerNote));
- MakerNoteFactory::registerMakerNote(
- canonCs1IfdId, MakerNote::AutoPtr(new CanonMakerNote));
- MakerNoteFactory::registerMakerNote(
- canonCs2IfdId, MakerNote::AutoPtr(new CanonMakerNote));
- MakerNoteFactory::registerMakerNote(
- canonCfIfdId, MakerNote::AutoPtr(new CanonMakerNote));
-
- ExifTags::registerMakerTagInfo(canonIfdId, tagInfo_);
- ExifTags::registerMakerTagInfo(canonCs1IfdId, tagInfoCs1_);
- ExifTags::registerMakerTagInfo(canonCs2IfdId, tagInfoCs2_);
- ExifTags::registerMakerTagInfo(canonCfIfdId, tagInfoCf_);
- }
- //! @endcond
-
- // Canon MakerNote Tag Info
- const TagInfo CanonMakerNote::tagInfo_[] = {
- TagInfo(0x0000, "0x0000", "Unknown", canonIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0001, "CameraSettings1", "Various camera settings (1)", canonIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0002, "0x0002", "Unknown", canonIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0003, "0x0003", "Unknown", canonIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0004, "CameraSettings2", "Various camera settings (2)", canonIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0006, "ImageType", "Image type", canonIfdId, makerTags, asciiString, printValue),
- TagInfo(0x0007, "FirmwareVersion", "Firmware version", canonIfdId, makerTags, asciiString, printValue),
- TagInfo(0x0008, "ImageNumber", "Image number", canonIfdId, makerTags, unsignedLong, print0x0008),
- TagInfo(0x0009, "OwnerName", "Owner Name", canonIfdId, makerTags, asciiString, printValue),
- TagInfo(0x000c, "SerialNumber", "Camera serial number", canonIfdId, makerTags, unsignedLong, print0x000c),
- TagInfo(0x000d, "0x000d", "Unknown", canonIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x000f, "CustomFunctions", "Custom Functions", canonIfdId, makerTags, unsignedShort, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownCanonMakerNoteTag)", "Unknown CanonMakerNote tag", canonIfdId, makerTags, invalidTypeId, printValue)
- };
-
- // Canon Camera Settings 1 Tag Info
- const TagInfo CanonMakerNote::tagInfoCs1_[] = {
- TagInfo(0x0001, "Macro", "Macro mode", canonCs1IfdId, makerTags, unsignedShort, printCs10x0001),
- TagInfo(0x0002, "Selftimer", "Self timer", canonCs1IfdId, makerTags, unsignedShort, printCs10x0002),
- TagInfo(0x0003, "Quality", "Quality", canonCs1IfdId, makerTags, unsignedShort, printCs10x0003),
- TagInfo(0x0004, "FlashMode", "Flash mode setting", canonCs1IfdId, makerTags, unsignedShort, printCs10x0004),
- TagInfo(0x0005, "DriveMode", "Drive mode setting", canonCs1IfdId, makerTags, unsignedShort, printCs10x0005),
- TagInfo(0x0006, "0x0006", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0007, "FocusMode", "Focus mode setting", canonCs1IfdId, makerTags, unsignedShort, printCs10x0007),
- TagInfo(0x0008, "0x0008", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0009, "0x0009", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x000a, "ImageSize", "Image size", canonCs1IfdId, makerTags, unsignedShort, printCs10x000a),
- TagInfo(0x000b, "EasyMode", "Easy shooting mode", canonCs1IfdId, makerTags, unsignedShort, printCs10x000b),
- TagInfo(0x000c, "DigitalZoom", "Digital zoom", canonCs1IfdId, makerTags, unsignedShort, printCs10x000c),
- TagInfo(0x000d, "Contrast", "Contrast setting", canonCs1IfdId, makerTags, unsignedShort, printCs1Lnh),
- TagInfo(0x000e, "Saturation", "Saturation setting", canonCs1IfdId, makerTags, unsignedShort, printCs1Lnh),
- TagInfo(0x000f, "Sharpness", "Sharpness setting", canonCs1IfdId, makerTags, unsignedShort, printCs1Lnh),
- TagInfo(0x0010, "ISOSpeed", "ISO speed setting", canonCs1IfdId, makerTags, unsignedShort, printCs10x0010),
- TagInfo(0x0011, "MeteringMode", "Metering mode setting", canonCs1IfdId, makerTags, unsignedShort, printCs10x0011),
- TagInfo(0x0012, "FocusType", "Focus type setting", canonCs1IfdId, makerTags, unsignedShort, printCs10x0012),
- TagInfo(0x0013, "AFPoint", "AF point selected", canonCs1IfdId, makerTags, unsignedShort, printCs10x0013),
- TagInfo(0x0014, "ExposureProgram", "Exposure mode setting", canonCs1IfdId, makerTags, unsignedShort, printCs10x0014),
- TagInfo(0x0015, "0x0015", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0016, "0x0016", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0017, "Lens", "'long' and 'short' focal length of lens (in 'focal units') and 'focal units' per mm", canonCs1IfdId, makerTags, unsignedShort, printCs1Lens),
- TagInfo(0x0018, "0x0018", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0019, "0x0019", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x001a, "0x001a", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x001b, "0x001b", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x001c, "FlashActivity", "Flash activity", canonCs1IfdId, makerTags, unsignedShort, printCs10x001c),
- TagInfo(0x001d, "FlashDetails", "Flash details", canonCs1IfdId, makerTags, unsignedShort, printCs10x001d),
- TagInfo(0x001e, "0x001e", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x001f, "0x001f", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0020, "FocusMode", "Focus mode setting", canonCs1IfdId, makerTags, unsignedShort, printCs10x0020),
- TagInfo(0x0021, "0x0021", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0022, "0x0022", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0023, "0x0023", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0024, "0x0024", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0025, "0x0025", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0026, "0x0026", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0027, "0x0027", "Unknown", canonCs1IfdId, makerTags, unsignedShort, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownCanonCs1Tag)", "Unknown Canon Camera Settings 1 tag", canonCs1IfdId, makerTags, invalidTypeId, printValue)
- };
-
- // Canon Camera Settings 2 Tag Info
- const TagInfo CanonMakerNote::tagInfoCs2_[] = {
- TagInfo(0x0001, "0x0001", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0002, "ISOSpeed", "ISO speed used", canonCs2IfdId, makerTags, unsignedShort, printCs20x0002),
- TagInfo(0x0003, "0x0003", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0004, "0x0004", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0005, "0x0005", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0006, "0x0006", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0007, "WhiteBalance", "White balance setting", canonCs2IfdId, makerTags, unsignedShort, printCs20x0007),
- TagInfo(0x0008, "0x0008", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0009, "Sequence", "Sequence number (if in a continuous burst)", canonCs2IfdId, makerTags, unsignedShort, printCs20x0009),
- TagInfo(0x000a, "0x000a", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x000b, "0x000b", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x000c, "0x000c", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x000d, "0x000d", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x000e, "AFPointUsed", "AF point used", canonCs2IfdId, makerTags, unsignedShort, printCs20x000e),
- TagInfo(0x000f, "FlashBias", "Flash bias", canonCs2IfdId, makerTags, unsignedShort, printCs20x000f),
- TagInfo(0x0010, "0x0010", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0011, "0x0011", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0012, "0x0012", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0013, "SubjectDistance", "Subject distance (units are not clear)", canonCs2IfdId, makerTags, unsignedShort, printCs20x0013),
- TagInfo(0x0014, "0x0014", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0015, "0x0015", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0016, "0x0016", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0017, "0x0017", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0018, "0x0018", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0019, "0x0019", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x001a, "0x001a", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownCanonCs2Tag)", "Unknown Canon Camera Settings 2 tag", canonCs2IfdId, makerTags, invalidTypeId, printValue)
- };
-
- // Canon Custom Function Tag Info
- const TagInfo CanonMakerNote::tagInfoCf_[] = {
- TagInfo(0x0001, "NoiseReduction", "Long exposure noise reduction", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0002, "ShutterAeLock", "Shutter/AE lock buttons", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0003, "MirrorLockup", "Mirror lockup", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0004, "ExposureLevelIncrements", "Tv/Av and exposure level", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0005, "AFAssist", "AF assist light", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0006, "FlashSyncSpeedAv", "Shutter speed in Av mode", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0007, "AEBSequence", "AEB sequence/auto cancellation", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0008, "ShutterCurtainSync", "Shutter curtain sync", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0009, "LensAFStopButton", "Lens AF stop button Fn. Switch", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x000a, "FillFlashAutoReduction", "Auto reduction of fill flash", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x000b, "MenuButtonReturn", "Menu button return position", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x000c, "SetButtonFunction", "SET button func. when shooting", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x000d, "SensorCleaning", "Sensor cleaning", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x000e, "SuperimposedDisplay", "Superimposed display", canonCfIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x000f, "ShutterReleaseNoCFCard", "Shutter Release W/O CF Card", canonCfIfdId, makerTags, unsignedShort, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownCanonCfTag)", "Unknown Canon Custom Function tag", canonCfIfdId, makerTags, invalidTypeId, printValue)
- };
-
- int CanonMakerNote::read(const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset)
- {
- int rc = IfdMakerNote::read(buf, len, byteOrder, offset);
- if (rc) return rc;
-
- // Decode camera settings 1 and add settings as additional entries
- Entries::iterator cs = ifd_.findTag(0x0001);
- if (cs != ifd_.end() && cs->type() == unsignedShort) {
- for (uint16_t c = 1; cs->count() > c; ++c) {
- if (c == 23 && cs->count() > 25) {
- // Pack related lens info into one tag
- addCsEntry(canonCs1IfdId, c, cs->offset() + c*2,
- cs->data() + c*2, 3);
- c += 2;
- }
- else {
- addCsEntry(canonCs1IfdId, c, cs->offset() + c*2,
- cs->data() + c*2, 1);
- }
- }
- // Discard the original entry
- ifd_.erase(cs);
- }
-
- // Decode camera settings 2 and add settings as additional entries
- cs = ifd_.findTag(0x0004);
- if (cs != ifd_.end() && cs->type() == unsignedShort) {
- for (uint16_t c = 1; cs->count() > c; ++c) {
- addCsEntry(canonCs2IfdId, c, cs->offset() + c*2,
- cs->data() + c*2, 1);
- }
- // Discard the original entry
- ifd_.erase(cs);
- }
-
- // Decode custom functions and add each as an additional entry
- cs = ifd_.findTag(0x000f);
- if (cs != ifd_.end() && cs->type() == unsignedShort) {
- for (uint16_t c = 1; cs->count() > c; ++c) {
- addCsEntry(canonCfIfdId, c, cs->offset() + c*2,
- cs->data() + c*2, 1);
- }
- // Discard the original entry
- ifd_.erase(cs);
- }
-
- // Copy remaining ifd entries
- entries_.insert(entries_.begin(), ifd_.begin(), ifd_.end());
-
- // Set idx
- int idx = 0;
- Entries::iterator e = entries_.end();
- for (Entries::iterator i = entries_.begin(); i != e; ++i) {
- i->setIdx(++idx);
- }
-
- return 0;
- }
-
- void CanonMakerNote::addCsEntry(IfdId ifdId,
- uint16_t tag,
- long offset,
- const byte* data,
- int count)
- {
- Entry e(false);
- e.setIfdId(ifdId);
- e.setTag(tag);
- e.setOffset(offset);
- e.setValue(unsignedShort, count, data, 2*count);
- add(e);
- }
-
- void CanonMakerNote::add(const Entry& entry)
- {
- assert(alloc_ == entry.alloc());
- assert( entry.ifdId() == canonIfdId
- || entry.ifdId() == canonCs1IfdId
- || entry.ifdId() == canonCs2IfdId
- || entry.ifdId() == canonCfIfdId);
- // allow duplicates
- entries_.push_back(entry);
- }
-
- long CanonMakerNote::copy(byte* buf, ByteOrder byteOrder, long offset)
- {
- if (byteOrder_ == invalidByteOrder) byteOrder_ = byteOrder;
-
- assert(ifd_.alloc());
- ifd_.clear();
-
- // Add all standard Canon entries to the IFD
- Entries::const_iterator end = entries_.end();
- for (Entries::const_iterator i = entries_.begin(); i != end; ++i) {
- if (i->ifdId() == canonIfdId) {
- ifd_.add(*i);
- }
- }
- // Collect camera settings 1 entries and add the original Canon tag
- Entry cs1;
- if (assemble(cs1, canonCs1IfdId, 0x0001, byteOrder_)) {
- ifd_.erase(0x0001);
- ifd_.add(cs1);
- }
- // Collect camera settings 2 entries and add the original Canon tag
- Entry cs2;
- if (assemble(cs2, canonCs2IfdId, 0x0004, byteOrder_)) {
- ifd_.erase(0x0004);
- ifd_.add(cs2);
- }
- // Collect custom function entries and add the original Canon tag
- Entry cf;
- if (assemble(cf, canonCfIfdId, 0x000f, byteOrder_)) {
- ifd_.erase(0x000f);
- ifd_.add(cf);
- }
-
- return IfdMakerNote::copy(buf, byteOrder_, offset);
- } // CanonMakerNote::copy
-
- void CanonMakerNote::updateBase(byte* pNewBase)
- {
- byte* pBase = ifd_.updateBase(pNewBase);
- if (absOffset_ && !alloc_) {
- Entries::iterator end = entries_.end();
- for (Entries::iterator pos = entries_.begin(); pos != end; ++pos) {
- pos->updateBase(pBase, pNewBase);
- }
- }
- } // CanonMakerNote::updateBase
-
- long CanonMakerNote::size() const
- {
- Ifd ifd(canonIfdId, 0, alloc_); // offset doesn't matter
-
- // Add all standard Canon entries to the IFD
- Entries::const_iterator end = entries_.end();
- for (Entries::const_iterator i = entries_.begin(); i != end; ++i) {
- if (i->ifdId() == canonIfdId) {
- ifd.add(*i);
- }
- }
- // Collect camera settings 1 entries and add the original Canon tag
- Entry cs1(alloc_);
- if (assemble(cs1, canonCs1IfdId, 0x0001, littleEndian)) {
- ifd.erase(0x0001);
- ifd.add(cs1);
- }
- // Collect camera settings 2 entries and add the original Canon tag
- Entry cs2(alloc_);
- if (assemble(cs2, canonCs2IfdId, 0x0004, littleEndian)) {
- ifd.erase(0x0004);
- ifd.add(cs2);
- }
- // Collect custom function entries and add the original Canon tag
- Entry cf(alloc_);
- if (assemble(cf, canonCfIfdId, 0x000f, littleEndian)) {
- ifd.erase(0x000f);
- ifd.add(cf);
- }
-
- return headerSize() + ifd.size() + ifd.dataSize();
- } // CanonMakerNote::size
-
- long CanonMakerNote::assemble(Entry& e,
- IfdId ifdId,
- uint16_t tag,
- ByteOrder byteOrder) const
- {
- DataBuf buf(1024);
- memset(buf.pData_, 0x0, 1024);
- uint16_t len = 0;
- Entries::const_iterator end = entries_.end();
- for (Entries::const_iterator i = entries_.begin(); i != end; ++i) {
- if (i->ifdId() == ifdId) {
- uint16_t pos = i->tag() * 2;
- uint16_t size = pos + static_cast<uint16_t>(i->size());
- assert(size <= 1024);
- memcpy(buf.pData_ + pos, i->data(), i->size());
- if (len < size) len = size;
- }
- }
- if (len > 0) {
- // Number of shorts in the buffer (rounded up)
- uint16_t s = (len+1) / 2;
- us2Data(buf.pData_, s*2, byteOrder);
-
- e.setIfdId(canonIfdId);
- e.setIdx(0); // don't care
- e.setTag(tag);
- e.setOffset(0); // will be calculated when the IFD is written
- e.setValue(unsignedShort, s, buf.pData_, s*2);
- }
- return len;
- } // CanonMakerNote::assemble
-
- Entries::const_iterator CanonMakerNote::findIdx(int idx) const
- {
- return std::find_if(entries_.begin(), entries_.end(),
- FindEntryByIdx(idx));
- }
-
- CanonMakerNote::CanonMakerNote(bool alloc)
- : IfdMakerNote(canonIfdId, alloc)
- {
- }
-
- CanonMakerNote::CanonMakerNote(const CanonMakerNote& rhs)
- : IfdMakerNote(rhs)
- {
- entries_ = rhs.entries_;
- }
-
- CanonMakerNote::AutoPtr CanonMakerNote::create(bool alloc) const
- {
- return AutoPtr(create_(alloc));
- }
-
- CanonMakerNote* CanonMakerNote::create_(bool alloc) const
- {
- return new CanonMakerNote(alloc);
- }
-
- CanonMakerNote::AutoPtr CanonMakerNote::clone() const
- {
- return AutoPtr(clone_());
- }
-
- CanonMakerNote* CanonMakerNote::clone_() const
- {
- return new CanonMakerNote(*this);
- }
-
- std::ostream& CanonMakerNote::print0x0008(std::ostream& os,
- const Value& value)
- {
- std::string n = value.toString();
- return os << n.substr(0, n.length() - 4) << "-"
- << n.substr(n.length() - 4);
- }
-
- std::ostream& CanonMakerNote::print0x000c(std::ostream& os,
- const Value& value)
- {
- std::istringstream is(value.toString());
- uint32_t l;
- is >> l;
- return os << std::setw(4) << std::setfill('0') << std::hex
- << ((l & 0xffff0000) >> 16)
- << std::setw(5) << std::setfill('0') << std::dec
- << (l & 0x0000ffff);
- }
-
- std::ostream& CanonMakerNote::printCs10x0001(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 1: os << "On"; break;
- case 2: os << "Off"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x0002(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- if (l == 0) {
- os << "Off";
- }
- else {
- os << l / 10.0 << " s";
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x0003(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 2: os << "Normal"; break;
- case 3: os << "Fine"; break;
- case 5: os << "Superfine"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x0004(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0: os << "Off"; break;
- case 1: os << "Auto"; break;
- case 2: os << "On"; break;
- case 3: os << "Red-eye"; break;
- case 4: os << "Slow sync"; break;
- case 5: os << "Auto + red-eye"; break;
- case 6: os << "On + red-eye"; break;
- case 16: os << "External"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x0005(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0: os << "Single / timer"; break;
- case 1: os << "Continuous"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x0007(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0: os << "One shot"; break;
- case 1: os << "AI servo"; break;
- case 2: os << "AI Focus"; break;
- case 3: os << "MF"; break;
- case 4: os << "Single"; break;
- case 5: os << "Continuous"; break;
- case 6: os << "MF"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x000a(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0: os << "Large"; break;
- case 1: os << "Medium"; break;
- case 2: os << "Small"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x000b(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0: os << "Full auto"; break;
- case 1: os << "Manual"; break;
- case 2: os << "Landscape"; break;
- case 3: os << "Fast shutter"; break;
- case 4: os << "Slow shutter"; break;
- case 5: os << "Night"; break;
- case 6: os << "B&W"; break;
- case 7: os << "Sepia"; break;
- case 8: os << "Portrait"; break;
- case 9: os << "Sports"; break;
- case 10: os << "Macro / close-up"; break;
- case 11: os << "Pan focus"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x000c(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0: os << "None"; break;
- case 1: os << "2x"; break;
- case 2: os << "4x"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs1Lnh(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0xffff: os << "Low"; break;
- case 0x0000: os << "Normal"; break;
- case 0x0001: os << "High"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x0010(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0: os << "n/a"; break;
- case 15: os << "Auto"; break;
- case 16: os << "50"; break;
- case 17: os << "100"; break;
- case 18: os << "200"; break;
- case 19: os << "400"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x0011(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 3: os << "Evaluative"; break;
- case 4: os << "Partial"; break;
- case 5: os << "Center weighted"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x0012(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0: os << "Manual"; break;
- case 1: os << "Auto"; break;
- case 3: os << "Close-up (macro)"; break;
- case 8: os << "Locked (pan mode)"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x0013(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0x3000: os << "None (MF)"; break;
- case 0x3001: os << "Auto-selected"; break;
- case 0x3002: os << "Right"; break;
- case 0x3003: os << "Center"; break;
- case 0x3004: os << "Left"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x0014(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0: os << "Easy shooting"; break;
- case 1: os << "Program"; break;
- case 2: os << "Shutter priority"; break;
- case 3: os << "Aperture priority"; break;
- case 4: os << "Manual"; break;
- case 5: os << "A-DEP"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x001c(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0: os << "Did not fire"; break;
- case 1: os << "Fired"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x001d(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- bool coma = false;
- if (l & 0x4000) {
- if (coma) os << ", ";
- os << "External TTL";
- coma = true;
- }
- if (l & 0x2000) {
- if (coma) os << ", ";
- os << "Internal flash";
- coma = true;
- }
- if (l & 0x0800) {
- if (coma) os << ", ";
- os << "FP sync used";
- coma = true;
- }
- if (l & 0x0080) {
- if (coma) os << ", ";
- os << "Rear curtain sync used";
- coma = true;
- }
- if (l & 0x0010) {
- if (coma) os << ", ";
- os << "FP sync enabled";
- coma = true;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs10x0020(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0: os << "Single"; break;
- case 1: os << "Continuous"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs1Lens(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- if (value.count() < 3) return os << value;
-
- float fu = value.toFloat(2);
- float len1 = value.toLong(0) / fu;
- float len2 = value.toLong(1) / fu;
- std::ostringstream oss;
- oss.copyfmt(os);
- os << std::fixed << std::setprecision(1)
- << len2 << " - " << len1 << " mm";
- os.copyfmt(oss);
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs20x0002(std::ostream& os,
- const Value& value)
- {
- // Ported from Exiftool by Will Stokes
- return os << exp(canonEv(value.toLong()) * log(2.0)) * 100.0 / 32.0;
- }
-
- std::ostream& CanonMakerNote::printCs20x0007(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0: os << "Auto"; break;
- case 1: os << "Sunny"; break;
- case 2: os << "Cloudy"; break;
- case 3: os << "Tungsten"; break;
- case 4: os << "Fluorescent"; break;
- case 5: os << "Flash"; break;
- case 6: os << "Custom"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs20x0009(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- os << l << "";
- // Todo: determine unit
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs20x000e(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- long num = (l & 0xf000) >> 12;
- os << num << " focus points; ";
- long used = l & 0x0fff;
- if (used == 0) {
- os << "none";
- }
- else {
- bool coma = false;
- if (l & 0x0004) {
- if (coma) os << ", ";
- os << "left";
- coma = true;
- }
- if (l & 0x0002) {
- if (coma) os << ", ";
- os << "center";
- coma = true;
- }
- if (l & 0x0001) {
- if (coma) os << ", ";
- os << "right";
- coma = true;
- }
- }
- os << " used";
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs20x000f(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- switch (l) {
- case 0xffc0: os << "-2 EV"; break;
- case 0xffcc: os << "-1.67 EV"; break;
- case 0xffd0: os << "-1.50 EV"; break;
- case 0xffd4: os << "-1.33 EV"; break;
- case 0xffe0: os << "-1 EV"; break;
- case 0xffec: os << "-0.67 EV"; break;
- case 0xfff0: os << "-0.50 EV"; break;
- case 0xfff4: os << "-0.33 EV"; break;
- case 0x0000: os << "0 EV"; break;
- case 0x000c: os << "0.33 EV"; break;
- case 0x0010: os << "0.50 EV"; break;
- case 0x0014: os << "0.67 EV"; break;
- case 0x0020: os << "1 EV"; break;
- case 0x002c: os << "1.33 EV"; break;
- case 0x0030: os << "1.50 EV"; break;
- case 0x0034: os << "1.67 EV"; break;
- case 0x0040: os << "2 EV"; break;
- default: os << "(" << l << ")"; break;
- }
- return os;
- }
-
- std::ostream& CanonMakerNote::printCs20x0013(std::ostream& os,
- const Value& value)
- {
- if (value.typeId() != unsignedShort) return os << value;
- long l = value.toLong();
- if (l == 0xffff) {
- os << "Infinite";
- }
- else {
- os << l << "";
- }
- return os;
- }
-
-// *****************************************************************************
-// free functions
-
- MakerNote::AutoPtr createCanonMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset)
- {
- return MakerNote::AutoPtr(new CanonMakerNote(alloc));
- }
-
-} // namespace Exiv2
-
-// *****************************************************************************
-// local definitions
-namespace {
-
- float canonEv(long val)
- {
- // temporarily remove sign
- int sign = 1;
- if (val < 0) {
- sign = -1;
- val = -val;
- }
- // remove fraction
- float frac = static_cast<float>(val & 0x1f);
- val -= long(frac);
- // convert 1/3 (0x0c) and 2/3 (0x14) codes
- if (frac == 0x0c) {
- frac = 32.0f / 3;
- }
- else if (frac == 0x14) {
- frac = 64.0f / 3;
- }
- return sign * (val + frac) / 32.0f;
- }
-
-}
diff --git a/src/plugins/exiv2/canonmn.hpp b/src/plugins/exiv2/canonmn.hpp
@@ -1,238 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file canonmn.hpp
- @brief Canon MakerNote implemented according to the specification
- <a href="http://www.burren.cx/david/canon.html">
- EXIF MakerNote of Canon</a> by David Burren<br>
- and with reference to tag information from
- <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/">
- ExifTool</a> by Phil Harvey
- @version $Rev: 569 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 18-Feb-04, ahu: created<BR>
- 07-Mar-04, ahu: isolated as a separate component
- */
-#ifndef CANONMN_HPP_
-#define CANONMN_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "makernote.hpp"
-#include "tags.hpp"
-
-// + standard includes
-#include <string>
-#include <iosfwd>
-#include <memory>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class declarations
- class Value;
-
-// *****************************************************************************
-// free functions
-
- /*!
- @brief Return an auto-pointer to a newly created empty MakerNote
- initialized to operate in the memory management model indicated.
- The caller owns this copy and the auto-pointer ensures that it
- will be deleted.
-
- @param alloc Memory management model for the new MakerNote. Determines if
- memory required to store data should be allocated and deallocated
- (true) or not (false). If false, only pointers to the buffer
- provided to read() will be kept. See Ifd for more background on
- this concept.
- @param buf Pointer to the makernote character buffer (not used).
- @param len Length of the makernote character buffer (not used).
- @param byteOrder Byte order in which the Exif data (and possibly the
- makernote) is encoded (not used).
- @param offset Offset from the start of the TIFF header of the makernote
- buffer (not used).
-
- @return An auto-pointer to a newly created empty MakerNote. The caller
- owns this copy and the auto-pointer ensures that it will be
- deleted.
- */
- MakerNote::AutoPtr createCanonMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset);
-
-// *****************************************************************************
-// class definitions
-
- //! MakerNote for Canon cameras
- class CanonMakerNote : public IfdMakerNote {
- public:
- //! Shortcut for a %CanonMakerNote auto pointer.
- typedef std::auto_ptr<CanonMakerNote> AutoPtr;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor. Allows to choose whether or not memory management
- is required for the makernote entries.
- */
- CanonMakerNote(bool alloc =true);
- //! Copy constructor
- CanonMakerNote(const CanonMakerNote& rhs);
- //! Virtual destructor
- virtual ~CanonMakerNote() {}
- //@}
-
- //! @name Manipulators
- //@{
- int read(const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset);
- long copy(byte* buf, ByteOrder byteOrder, long offset);
- void add(const Entry& entry);
- Entries::iterator begin() { return entries_.begin(); }
- Entries::iterator end() { return entries_.end(); }
- void updateBase(byte* pNewBase);
- //@}
-
- //! @name Accessors
- //@{
- Entries::const_iterator begin() const { return entries_.begin(); }
- Entries::const_iterator end() const { return entries_.end(); }
- Entries::const_iterator findIdx(int idx) const;
- long size() const;
- AutoPtr create(bool alloc =true) const;
- AutoPtr clone() const;
- //@}
-
- //! @name Print functions for Canon %MakerNote tags
- //@{
- //! Print the image number
- static std::ostream& print0x0008(std::ostream& os, const Value& value);
- //! Print the serial number of the camera
- static std::ostream& print0x000c(std::ostream& os, const Value& value);
-
- //! Macro mode
- static std::ostream& printCs10x0001(std::ostream& os, const Value& value);
- //! Self timer
- static std::ostream& printCs10x0002(std::ostream& os, const Value& value);
- //! Quality
- static std::ostream& printCs10x0003(std::ostream& os, const Value& value);
- //! Flash mode
- static std::ostream& printCs10x0004(std::ostream& os, const Value& value);
- //! Drive mode
- static std::ostream& printCs10x0005(std::ostream& os, const Value& value);
- //! Focus mode (G1 seems to use field 32 in preference to this)
- static std::ostream& printCs10x0007(std::ostream& os, const Value& value);
- //! Image size
- static std::ostream& printCs10x000a(std::ostream& os, const Value& value);
- //! Easy shooting
- static std::ostream& printCs10x000b(std::ostream& os, const Value& value);
- //! Digital zoom
- static std::ostream& printCs10x000c(std::ostream& os, const Value& value);
- //! ISO
- static std::ostream& printCs10x0010(std::ostream& os, const Value& value);
- //! Metering mode
- static std::ostream& printCs10x0011(std::ostream& os, const Value& value);
- //! Focus type
- static std::ostream& printCs10x0012(std::ostream& os, const Value& value);
- //! AF point selected
- static std::ostream& printCs10x0013(std::ostream& os, const Value& value);
- //! Exposure mode
- static std::ostream& printCs10x0014(std::ostream& os, const Value& value);
- //! Flash activity
- static std::ostream& printCs10x001c(std::ostream& os, const Value& value);
- //! Flash details
- static std::ostream& printCs10x001d(std::ostream& os, const Value& value);
- //! Focus mode (G1 seems to use this in preference to field 7)
- static std::ostream& printCs10x0020(std::ostream& os, const Value& value);
- //! Low, normal, high print function
- static std::ostream& printCs1Lnh(std::ostream& os, const Value& value);
- //! Camera lens information
- static std::ostream& printCs1Lens(std::ostream& os, const Value& value);
- //! ISO speed used
- static std::ostream& printCs20x0002(std::ostream& os, const Value& value);
- //! White balance
- static std::ostream& printCs20x0007(std::ostream& os, const Value& value);
- //! Sequence number
- static std::ostream& printCs20x0009(std::ostream& os, const Value& value);
- //! AF point used
- static std::ostream& printCs20x000e(std::ostream& os, const Value& value);
- //! Flash bias
- static std::ostream& printCs20x000f(std::ostream& os, const Value& value);
- //! Subject distance
- static std::ostream& printCs20x0013(std::ostream& os, const Value& value);
- //@}
-
- //! @cond IGNORE
- // Public only so that we can create a static instance
- struct RegisterMn {
- RegisterMn();
- };
- //! @endcond
-
- private:
- //! @name Manipulators
- //@{
- //! Add a camera settings entry to the makernote entries
- void addCsEntry(IfdId ifdId,
- uint16_t tag,
- long offset,
- const byte* data,
- int count);
- //@}
-
- //! @name Accessors
- //@{
- //! Assemble special Canon entries into an entry with the original tag
- long assemble(Entry& e,
- IfdId ifdId,
- uint16_t tag,
- ByteOrder byteOrder) const;
- //! Internal virtual create function.
- CanonMakerNote* create_(bool alloc =true) const;
- //! Internal virtual copy constructor.
- CanonMakerNote* clone_() const;
- //@}
-
- // DATA
- //! Container to store Makernote entries (instead of Ifd)
- Entries entries_;
-
- //! Tag information
- static const TagInfo tagInfo_[];
- static const TagInfo tagInfoCs1_[];
- static const TagInfo tagInfoCs2_[];
- static const TagInfo tagInfoCf_[];
-
- }; // class CanonMakerNote
-
- static CanonMakerNote::RegisterMn registerCanonMakerNote;
-} // namespace Exiv2
-
-#endif // #ifndef CANONMN_HPP_
diff --git a/src/plugins/exiv2/datasets.cpp b/src/plugins/exiv2/datasets.cpp
@@ -1,392 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: datasets.cpp
- Version: $Rev: 560 $
- Author(s): Brad Schick (brad) <brad@robotbattle.com>
- History: 24-Jul-04, brad: created
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: datasets.cpp 560 2005-04-17 11:51:32Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "datasets.hpp"
-#include "error.hpp"
-#include "types.hpp"
-#include "value.hpp"
-#include "metadatum.hpp"
-
-#include <iostream>
-#include <iomanip>
-#include <sstream>
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- DataSet::DataSet(
- uint16_t number,
- const char* name,
- const char* desc,
- bool mandatory,
- bool repeatable,
- uint32_t minbytes,
- uint32_t maxbytes,
- TypeId type,
- uint16_t recordId,
- const char* photoshop
- )
- : number_(number), name_(name), desc_(desc), mandatory_(mandatory),
- repeatable_(repeatable), minbytes_(minbytes), maxbytes_(maxbytes),
- type_(type), recordId_(recordId), photoshop_(photoshop)
- {
- }
-
- RecordInfo::RecordInfo(
- uint16_t recordId,
- const char* name,
- const char* desc
- )
- : recordId_(recordId), name_(name), desc_(desc)
- {
- }
-
- const RecordInfo IptcDataSets::recordInfo_[] = {
- RecordInfo(IptcDataSets::invalidRecord, "(invalid)", "(invalid)"),
- RecordInfo(IptcDataSets::envelope, "Envelope", "IIM envelope record"),
- RecordInfo(IptcDataSets::application2, "Application2", "IIM application record 2"),
- };
-
- static const DataSet envelopeRecord[] = {
- DataSet(IptcDataSets::ModelVersion, "ModelVersion", "Version of IIM part 1", true, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::envelope, ""),
- DataSet(IptcDataSets::Destination, "Destination", "Routing information", false, true, 0, 1024, Exiv2::string, IptcDataSets::envelope, ""),
- DataSet(IptcDataSets::FileFormat, "FileFormat", "IIM appendix A file format", true, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::envelope, ""),
- DataSet(IptcDataSets::FileVersion, "FileVersion", "File format version", true, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::envelope, ""),
- DataSet(IptcDataSets::ServiceId, "ServiceId", "Identifies the provider and product", true, false, 0, 10, Exiv2::string, IptcDataSets::envelope, ""),
- DataSet(IptcDataSets::EnvelopeNumber, "EnvelopeNumber", "Combined unique identification", true, false, 8, 8, Exiv2::string, IptcDataSets::envelope, ""),
- DataSet(IptcDataSets::ProductId, "ProductId", "Identifies service subset", false, true, 0, 32, Exiv2::string, IptcDataSets::envelope, ""),
- DataSet(IptcDataSets::EnvelopePriority, "EnvelopePriority", "Envelope handling priority", false, false, 1, 1, Exiv2::string, IptcDataSets::envelope, ""),
- DataSet(IptcDataSets::DateSent, "DateSent", "Date material was sent", true, false, 8, 8, Exiv2::date, IptcDataSets::envelope, ""),
- DataSet(IptcDataSets::TimeSent, "TimeSent", "Time material was sent", false, false, 11, 11, Exiv2::time, IptcDataSets::envelope, ""),
- DataSet(IptcDataSets::CharacterSet, "CharacterSet", "Specifies character sets", false, false, 0, 32, Exiv2::undefined, IptcDataSets::envelope, ""),
- DataSet(IptcDataSets::UNO, "UNO", "Unique Name of Object", false, false, 14, 80, Exiv2::string, IptcDataSets::envelope, ""),
- DataSet(IptcDataSets::ARMId, "ARMId", "Abstract Relationship Method identifier", false, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::envelope, ""),
- DataSet(IptcDataSets::ARMVersion, "ARMVersion", "Abstract Relationship Method version", false, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::envelope, ""),
- DataSet(0xffff, "(Invalid)", "(Invalid)", false, false, 0, 0, Exiv2::unsignedShort, IptcDataSets::envelope, "")
- };
-
- static const DataSet application2Record[] = {
- DataSet(IptcDataSets::RecordVersion, "RecordVersion", "Version of IIM part 2", true, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ObjectType, "ObjectType", "IIM appendix G object type", false, false, 3, 67, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ObjectAttribute, "ObjectAttribute", "IIM appendix G object attribute", false, true, 4, 68, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ObjectName, "ObjectName", "Shorthand reference of content", false, false, 0, 64, Exiv2::string, IptcDataSets::application2, "Document title"),
- DataSet(IptcDataSets::EditStatus, "EditStatus", "Content status", false, false, 0, 64, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::EditorialUpdate, "EditorialUpdate", "Indicates the type of update", false, false, 2, 2, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::Urgency, "Urgency", "Editorial urgency of content", false, false, 1, 1, Exiv2::string, IptcDataSets::application2, "Urgency"),
- DataSet(IptcDataSets::Subject, "Subject", "Structured definition of the subject", false, true, 13, 236, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::Category, "Category", "Identifies the subject", false, false, 0, 3, Exiv2::string, IptcDataSets::application2, "Category"),
- DataSet(IptcDataSets::SuppCategory, "SuppCategory", "Refines the subject", false, true, 0, 32, Exiv2::string, IptcDataSets::application2, "Supplemental Categories"),
- DataSet(IptcDataSets::FixtureId, "FixtureId", "Identifies content that recurs", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::Keywords, "Keywords", "Information retrieval words", false, true, 0, 64, Exiv2::string, IptcDataSets::application2, "Keywords"),
- DataSet(IptcDataSets::LocationCode, "LocationCode", "ISO country code for content", false, true, 3, 3, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::LocationName, "LocationName", "Full country name for content", false, true, 0, 64, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ReleaseDate, "ReleaseDate", "Earliest intended usable date", false, false, 8, 8, Exiv2::date, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ReleaseTime, "ReleaseTime", "Earliest intended usable time", false, false, 11, 11, Exiv2::time, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ExpirationDate, "ExpirationDate", "Latest intended usable date", false, false, 8, 8, Exiv2::date, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ExpirationTime, "ExpirationTime", "Latest intended usable time", false, false, 11, 11, Exiv2::time, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::SpecialInstructions, "SpecialInstructions", "Editorial usage instructions", false, false, 0, 256, Exiv2::string, IptcDataSets::application2, "Instructions"),
- DataSet(IptcDataSets::ActionAdvised, "ActionAdvised", "Action provided to previous data", false, false, 2, 2, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ReferenceService, "ReferenceService", "Service Identifier of a prior envelope", false, true, 0, 10, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ReferenceDate, "ReferenceDate", "Date of a prior envelope", false, true, 8, 8, Exiv2::date, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ReferenceNumber, "ReferenceNumber", "Envelope Number of a prior envelope", false, true, 8, 8, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::DateCreated, "DateCreated", "Creation date of intellectual content", false, false, 8, 8, Exiv2::date, IptcDataSets::application2, "Date created"),
- DataSet(IptcDataSets::TimeCreated, "TimeCreated", "Creation time of intellectual content", false, false, 11, 11, Exiv2::time, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::DigitizationDate, "DigitizationDate", "Creation date of digital representation", false, false, 8, 8, Exiv2::date, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::DigitizationTime, "DigitizationTime", "Creation time of digital representation", false, false, 11, 11, Exiv2::time, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::Program, "Program", "Content creation program", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ProgramVersion, "ProgramVersion", "Content creation program version", false, false, 0, 10, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ObjectCycle, "ObjectCycle", "Morning, evening, or both", false, false, 1, 1, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::Byline, "Byline", "Name of content creator", false, true, 0, 32, Exiv2::string, IptcDataSets::application2, "Author"),
- DataSet(IptcDataSets::BylineTitle, "BylineTitle", "Title of content creator", false, true, 0, 32, Exiv2::string, IptcDataSets::application2, "Authors Position"),
- DataSet(IptcDataSets::City, "City", "City of content origin", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, "City"),
- DataSet(IptcDataSets::SubLocation, "SubLocation", "Location within city", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ProvinceState, "ProvinceState", "Province/State of content origin", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, "State/Province"),
- DataSet(IptcDataSets::CountryCode, "CountryCode", "ISO country code of content origin", false, false, 3, 3, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::CountryName, "CountryName", "Full country name of content origin", false, false, 0, 64, Exiv2::string, IptcDataSets::application2, "Country"),
- DataSet(IptcDataSets::TransmissionReference, "TransmissionReference", "Location of original transmission", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, "Transmission Reference"),
- DataSet(IptcDataSets::Headline, "Headline", "Content synopsis", false, false, 0, 256, Exiv2::string, IptcDataSets::application2, "Headline"),
- DataSet(IptcDataSets::Credit, "Credit", "Content provider", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, "Credit"),
- DataSet(IptcDataSets::Source, "Source", "Original owner of content", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, "Source"),
- DataSet(IptcDataSets::Copyright, "Copyright", "Necessary copyright notice", false, false, 0, 128, Exiv2::string, IptcDataSets::application2, "Copyright notice"),
- DataSet(IptcDataSets::Contact, "Contact", "Person or organisation to contact", false, true, 0, 128, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::Caption, "Caption", "Content description", false, false, 0, 2000, Exiv2::string, IptcDataSets::application2, "Description"),
- DataSet(IptcDataSets::Writer, "Writer", "Person responsible for caption", false, true, 0, 32, Exiv2::string, IptcDataSets::application2, "Description writer"),
- DataSet(IptcDataSets::RasterizedCaption, "RasterizedCaption", "Black and white caption image", false, false, 7360, 7360, Exiv2::undefined, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ImageType, "ImageType", "Color components in an image", false, false, 2, 2, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::ImageOrientation, "ImageOrientation", "Indicates the layout of an image", false, false, 1, 1, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::Language, "Language", "ISO 639:1988 language code", false, false, 2, 3, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::AudioType, "AudioType", "Information about audio content", false, false, 2, 2, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::AudioRate, "AudioRate", "Sampling rate of audio content", false, false, 6, 6, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::AudioResolution, "AudioResolution", "Sampling resolution of audio content", false, false, 2, 2, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::AudioDuration, "AudioDuration", "Duration of audio content", false, false, 6, 6, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::AudioOutcue, "AudioOutcue", "Final words or sounds of audio content", false, false, 0, 64, Exiv2::string, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::PreviewFormat, "PreviewFormat", "IIM appendix A file format of preview", false, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::PreviewVersion, "PreviewVersion", "File format version of preview", false, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::application2, ""),
- DataSet(IptcDataSets::Preview, "Preview", "Binary preview data", false, false, 0, 256000, Exiv2::undefined, IptcDataSets::application2, ""),
- DataSet(0xffff, "(Invalid)", "(Invalid)", false, false, 0, 0, Exiv2::unsignedShort, IptcDataSets::application2, "")
- };
-
- static const DataSet unknownDataSet(0xffff, "Unknown dataset", "Unknown dataset", false, true, 0, 0xffffffff, Exiv2::string, IptcDataSets::invalidRecord, "Unknown dataset");
-
- // Dataset lookup lists.This is an array with pointers to one list per IIM4 Record.
- // The record id is used as the index into the array.
- const DataSet* IptcDataSets::records_[] = {
- 0,
- envelopeRecord, application2Record,
- 0
- };
-
- int IptcDataSets::dataSetIdx(uint16_t number, uint16_t recordId)
- {
- if( recordId != envelope && recordId != application2 ) return -1;
- const DataSet* dataSet = records_[recordId];
- if (dataSet == 0) return -1;
- int idx;
- for (idx = 0; dataSet[idx].number_ != number; ++idx) {
- if (dataSet[idx].number_ == 0xffff) return -1;
- }
- return idx;
- }
-
- int IptcDataSets::dataSetIdx(const std::string& dataSetName, uint16_t recordId)
- {
- if( recordId != envelope && recordId != application2 ) return -1;
- const DataSet* dataSet = records_[recordId];
- if (dataSet == 0) return -1;
- int idx;
- for (idx = 0; dataSet[idx].name_ != dataSetName; ++idx) {
- if (dataSet[idx].number_ == 0xffff) return -1;
- }
- return idx;
- }
-
- TypeId IptcDataSets::dataSetType(uint16_t number, uint16_t recordId)
- {
- int idx = dataSetIdx(number, recordId);
- if (idx == -1) return unknownDataSet.type_;
- return records_[recordId][idx].type_;
- }
-
- std::string IptcDataSets::dataSetName(uint16_t number, uint16_t recordId)
- {
- int idx = dataSetIdx(number, recordId);
- if (idx != -1) return records_[recordId][idx].name_;
-
- std::ostringstream os;
- os << "0x" << std::setw(4) << std::setfill('0') << std::right
- << std::hex << number;
- return os.str();
- }
-
- const char* IptcDataSets::dataSetDesc(uint16_t number, uint16_t recordId)
- {
- int idx = dataSetIdx(number, recordId);
- if (idx == -1) return unknownDataSet.desc_;
- return records_[recordId][idx].desc_;
- }
-
- const char* IptcDataSets::dataSetPsName(uint16_t number, uint16_t recordId)
- {
- int idx = dataSetIdx(number, recordId);
- if (idx == -1) return unknownDataSet.photoshop_;
- return records_[recordId][idx].photoshop_;
- }
-
- bool IptcDataSets::dataSetRepeatable(uint16_t number, uint16_t recordId)
- {
- int idx = dataSetIdx(number, recordId);
- if (idx == -1) return unknownDataSet.repeatable_;
- return records_[recordId][idx].repeatable_;
- }
-
- uint16_t IptcDataSets::dataSet(const std::string& dataSetName,
- uint16_t recordId)
- {
- uint16_t dataSet;
- int idx = dataSetIdx(dataSetName, recordId);
- if (idx != -1) {
- // dataSetIdx checks the range of recordId
- dataSet = records_[recordId][idx].number_;
- }
- else {
- if (!isHex(dataSetName, 4, "0x")) throw Error(4, dataSetName);
- std::istringstream is(dataSetName);
- is >> std::hex >> dataSet;
- }
- return dataSet;
- }
-
- std::string IptcDataSets::recordName(uint16_t recordId)
- {
- if (recordId == envelope || recordId == application2) {
- return recordInfo_[recordId].name_;
- }
-
- std::ostringstream os;
- os << "0x" << std::setw(4) << std::setfill('0') << std::right
- << std::hex << recordId;
- return os.str();
- }
-
- const char* IptcDataSets::recordDesc(uint16_t recordId)
- {
- if (recordId != envelope && recordId != application2) {
- return unknownDataSet.desc_;
- }
- return recordInfo_[recordId].desc_;
- }
-
- uint16_t IptcDataSets::recordId(const std::string& recordName)
- {
- uint16_t i;
- for (i = application2; i > 0; --i) {
- if (recordInfo_[i].name_ == recordName) break;
- }
- if (i == 0) {
- if (!isHex(recordName, 4, "0x")) throw Error(5, recordName);
- std::istringstream is(recordName);
- is >> std::hex >> i;
- }
- return i;
- }
-
- void IptcDataSets::dataSetList(std::ostream& os)
- {
- const int count = sizeof(records_)/sizeof(records_[0]);
- for (int i=0; i < count; ++i) {
- const DataSet *record = records_[i];
- for (int j=0; record != 0 && record[j].number_ != 0xffff; ++j) {
- os << record[j] << "\n";
- }
- }
- } // IptcDataSets::dataSetList
-
- const char* IptcKey::familyName_ = "Iptc";
-
- IptcKey::IptcKey(const std::string& key)
- : key_(key)
- {
- decomposeKey();
- }
-
- IptcKey::IptcKey(uint16_t tag, uint16_t record)
- : tag_(tag), record_(record)
- {
- makeKey();
- }
-
- IptcKey::IptcKey(const IptcKey& rhs)
- : tag_(rhs.tag_), record_(rhs.record_), key_(rhs.key_)
- {
- }
-
- IptcKey& IptcKey::operator=(const IptcKey& rhs)
- {
- if (this == &rhs) return *this;
- Key::operator=(rhs);
- tag_ = rhs.tag_;
- record_ = rhs.record_;
- key_ = rhs.key_;
- return *this;
- }
-
- IptcKey::AutoPtr IptcKey::clone() const
- {
- return AutoPtr(clone_());
- }
-
- IptcKey* IptcKey::clone_() const
- {
- return new IptcKey(*this);
- }
-
- void IptcKey::decomposeKey()
- {
- // Get the family name, record name and dataSet name parts of the key
- std::string::size_type pos1 = key_.find('.');
- if (pos1 == std::string::npos) throw Error(6, key_);
- std::string familyName = key_.substr(0, pos1);
- if (familyName != std::string(familyName_)) {
- throw Error(6, key_);
- }
- std::string::size_type pos0 = pos1 + 1;
- pos1 = key_.find('.', pos0);
- if (pos1 == std::string::npos) throw Error(6, key_);
- std::string recordName = key_.substr(pos0, pos1 - pos0);
- if (recordName == "") throw Error(6, key_);
- std::string dataSetName = key_.substr(pos1 + 1);
- if (dataSetName == "") throw Error(6, key_);
-
- // Use the parts of the key to find dataSet and recordId
- uint16_t recId = IptcDataSets::recordId(recordName);
- uint16_t dataSet = IptcDataSets::dataSet(dataSetName, recId);
-
- // Possibly translate hex name parts (0xabcd) to real names
- recordName = IptcDataSets::recordName(recId);
- dataSetName = IptcDataSets::dataSetName(dataSet, recId);
-
- tag_ = dataSet;
- record_ = recId;
- key_ = familyName + "." + recordName + "." + dataSetName;
- } // IptcKey::decomposeKey
-
- void IptcKey::makeKey()
- {
- key_ = std::string(familyName_)
- + "." + IptcDataSets::recordName(record_)
- + "." + IptcDataSets::dataSetName(tag_, record_);
- }
-
- // *************************************************************************
- // free functions
-
- std::ostream& operator<<(std::ostream& os, const DataSet& dataSet)
- {
- IptcKey iptcKey(dataSet.number_, dataSet.recordId_);
- return os << dataSet.name_ << ", "
- << std::dec << dataSet.number_ << ", "
- << "0x" << std::setw(4) << std::setfill('0')
- << std::right << std::hex << dataSet.number_ << ", "
- << IptcDataSets::recordName(dataSet.recordId_) << ", "
- << std::boolalpha << dataSet.mandatory_ << ", "
- << dataSet.repeatable_ << ", "
- << std::dec << dataSet.minbytes_ << ", "
- << dataSet.maxbytes_ << ", "
- << iptcKey.key() << ", "
- << TypeInfo::typeName(
- IptcDataSets::dataSetType(dataSet.number_,
- dataSet.recordId_)) << ", "
- << dataSet.desc_;
- }
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/datasets.hpp b/src/plugins/exiv2/datasets.hpp
@@ -1,358 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file datasets.hpp
- @brief Iptc dataSet and type information
- @version $Rev: 560 $
- @author Brad Schick (brad) <brad@robotbattle.com>
- @date 24-Jul-04, brad: created
- */
-#ifndef DATASETS_HPP_
-#define DATASETS_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "metadatum.hpp"
-
-// + standard includes
-#include <string>
-#include <utility> // for std::pair
-#include <iosfwd>
-#include <memory>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class definitions
-
- //! Contains information about one record
- struct RecordInfo {
- //! Constructor
- RecordInfo(uint16_t recordId, const char* name, const char* desc);
- uint16_t recordId_; //!< Record id
- const char* name_; //!< Record name (one word)
- const char* desc_; //!< Record description
- };
-
- //! Dataset information
- struct DataSet {
- //! Constructor
- DataSet(
- uint16_t number,
- const char* name,
- const char* desc,
- bool mandatory,
- bool repeatable,
- uint32_t minbytes,
- uint32_t maxbytes,
- TypeId type,
- uint16_t recordId,
- const char* photoshop
- );
- uint16_t number_; //!< Dataset number
- const char* name_; //!< Dataset name
- const char* desc_; //!< Dataset description
- bool mandatory_; //!< True if dataset is mandatory
- bool repeatable_; //!< True if dataset is repeatable
- uint32_t minbytes_; //!< Minimum number of bytes
- uint32_t maxbytes_; //!< Maximum number of bytes
- TypeId type_; //!< Exiv2 default type
- uint16_t recordId_; //!< Record id
- const char* photoshop_; //!< Photoshop string
- }; // struct DataSet
-
- //! Container for Iptc dataset information. Implemented as a static class.
- class IptcDataSets {
- public:
- /*!
- @name Record identifiers
- @brief Record identifiers to logically group dataSets. There are other
- possible record types, but they are not standardized by the Iptc
- IIM4 standard (and not commonly used in images).
- */
- //@{
- static const uint16_t invalidRecord = 0;
- static const uint16_t envelope = 1;
- static const uint16_t application2 = 2;
- //@}
-
- //! @name Dataset identifiers
- //@{
- static const uint16_t ModelVersion = 0;
- static const uint16_t Destination = 5;
- static const uint16_t FileFormat = 20;
- static const uint16_t FileVersion = 22;
- static const uint16_t ServiceId = 30;
- static const uint16_t EnvelopeNumber = 40;
- static const uint16_t ProductId = 50;
- static const uint16_t EnvelopePriority = 60;
- static const uint16_t DateSent = 70;
- static const uint16_t TimeSent = 80;
- static const uint16_t CharacterSet = 90;
- static const uint16_t UNO = 100;
- static const uint16_t ARMId = 120;
- static const uint16_t ARMVersion = 122;
- static const uint16_t RecordVersion = 0;
- static const uint16_t ObjectType = 3;
- static const uint16_t ObjectAttribute = 4;
- static const uint16_t ObjectName = 5;
- static const uint16_t EditStatus = 7;
- static const uint16_t EditorialUpdate = 8;
- static const uint16_t Urgency = 10;
- static const uint16_t Subject = 12;
- static const uint16_t Category = 15;
- static const uint16_t SuppCategory = 20;
- static const uint16_t FixtureId = 22;
- static const uint16_t Keywords = 25;
- static const uint16_t LocationCode = 26;
- static const uint16_t LocationName = 27;
- static const uint16_t ReleaseDate = 30;
- static const uint16_t ReleaseTime = 35;
- static const uint16_t ExpirationDate = 37;
- static const uint16_t ExpirationTime = 38;
- static const uint16_t SpecialInstructions = 40;
- static const uint16_t ActionAdvised = 42;
- static const uint16_t ReferenceService = 45;
- static const uint16_t ReferenceDate = 47;
- static const uint16_t ReferenceNumber = 50;
- static const uint16_t DateCreated = 55;
- static const uint16_t TimeCreated = 60;
- static const uint16_t DigitizationDate = 62;
- static const uint16_t DigitizationTime = 63;
- static const uint16_t Program = 65;
- static const uint16_t ProgramVersion = 70;
- static const uint16_t ObjectCycle = 75;
- static const uint16_t Byline = 80;
- static const uint16_t BylineTitle = 85;
- static const uint16_t City = 90;
- static const uint16_t SubLocation = 92;
- static const uint16_t ProvinceState = 95;
- static const uint16_t CountryCode = 100;
- static const uint16_t CountryName = 101;
- static const uint16_t TransmissionReference = 103;
- static const uint16_t Headline = 105;
- static const uint16_t Credit = 110;
- static const uint16_t Source = 115;
- static const uint16_t Copyright = 116;
- static const uint16_t Contact = 118;
- static const uint16_t Caption = 120;
- static const uint16_t Writer = 122;
- static const uint16_t RasterizedCaption = 125;
- static const uint16_t ImageType = 130;
- static const uint16_t ImageOrientation = 131;
- static const uint16_t Language = 135;
- static const uint16_t AudioType = 150;
- static const uint16_t AudioRate = 151;
- static const uint16_t AudioResolution = 152;
- static const uint16_t AudioDuration = 153;
- static const uint16_t AudioOutcue = 154;
- static const uint16_t PreviewFormat = 200;
- static const uint16_t PreviewVersion = 201;
- static const uint16_t Preview = 202;
- //@}
-
- private:
- //! Prevent construction: not implemented.
- IptcDataSets() {}
- //! Prevent copy-construction: not implemented.
- IptcDataSets(const IptcDataSets& rhs);
- //! Prevent assignment: not implemented.
- IptcDataSets& operator=(const IptcDataSets& rhs);
-
- public:
- /*!
- @brief Return the name of the dataset.
- @param number The dataset number
- @param recordId The Iptc record Id
- @return The name of the dataset or a string containing the hexadecimal
- value of the dataset in the form "0x01ff", if this is an unknown
- dataset.
- */
- static std::string dataSetName(uint16_t number, uint16_t recordId);
- /*!
- @brief Return the description of the dataset.
- @param number The dataset number
- @param recordId The Iptc record Id
- @return The description of the dataset
- */
- static const char* dataSetDesc(uint16_t number, uint16_t recordId);
- /*!
- @brief Return the photohsop name of a given dataset.
- @param number The dataset number
- @param recordId The Iptc record Id
- @return The name used by photoshop for a dataset or an empty
- string if photoshop does not use the dataset.
- */
- static const char* dataSetPsName(uint16_t number, uint16_t recordId);
- /*!
- @brief Check if a given dataset is repeatable
- @param number The dataset number
- @param recordId The Iptc record Id
- @return true if the given dataset is repeatable otherwise false
- */
- static bool dataSetRepeatable(uint16_t number, uint16_t recordId);
- /*!
- @brief Return the dataSet number for dataset name and record id
-
- @param dataSetName dataSet name
- @param recordId recordId
-
- @return dataSet number
-
- @throw Error if the \em dataSetName or \em recordId are invalid
- */
- static uint16_t dataSet(const std::string& dataSetName, uint16_t recordId);
- //! Return the type for dataSet number and Record id
- static TypeId dataSetType(uint16_t number, uint16_t recordId);
- /*!
- @brief Return the name of the Record
- @param recordId The record id
- @return The name of the record or a string containing the hexadecimal
- value of the record in the form "0x01ff", if this is an
- unknown record.
- */
- static std::string recordName(uint16_t recordId);
- /*!
- @brief Return the description of a record
- @param recordId Record Id number
- @return the description of the Record
- */
- static const char* recordDesc(uint16_t recordId);
- /*!
- @brief Return the Id number of a record
- @param recordName Name of a record type
- @return the Id number of a Record
- @throw Error if the record is not known;
- */
- static uint16_t recordId(const std::string& recordName);
- //! Print a list of all dataSets to output stream
- static void dataSetList(std::ostream& os);
-
- private:
- static int dataSetIdx(uint16_t number, uint16_t recordId);
- static int dataSetIdx(const std::string& dataSetName, uint16_t recordId);
-
- static const DataSet* records_[];
- static const RecordInfo recordInfo_[];
-
- }; // class IptcDataSets
-
- /*!
- @brief Concrete keys for Iptc metadata.
- */
- class IptcKey : public Key {
- public:
- //! Shortcut for an %IptcKey auto pointer.
- typedef std::auto_ptr<IptcKey> AutoPtr;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor to create an Iptc key from a key string.
-
- @param key The key string.
- @throw Error if the first part of the key is not '<b>Iptc</b>' or
- the remaining parts of the key cannot be parsed and
- converted to a record name and a dataset name.
- */
- explicit IptcKey(const std::string& key);
- /*!
- @brief Constructor to create an Iptc key from dataset and record ids.
- @param tag Dataset id
- @param record Record id
- */
- IptcKey(uint16_t tag, uint16_t record);
- //! Copy constructor
- IptcKey(const IptcKey& rhs);
- //@}
-
- //! @name Manipulators
- //@{
- /*!
- @brief Assignment operator.
- */
- IptcKey& operator=(const IptcKey& rhs);
- //@}
-
- //! @name Accessors
- //@{
- virtual std::string key() const { return key_; }
- virtual const char* familyName() const { return familyName_; }
- /*!
- @brief Return the name of the group (the second part of the key).
- For Iptc keys, the group name is the record name.
- */
- virtual std::string groupName() const { return recordName(); }
- virtual std::string tagName() const
- { return IptcDataSets::dataSetName(tag_, record_); }
- virtual uint16_t tag() const { return tag_; }
-
- AutoPtr clone() const;
- //! Return the name of the record
- std::string recordName() const
- { return IptcDataSets::recordName(record_); }
- //! Return the record id
- uint16_t record() const { return record_; }
- //@}
-
- protected:
- //! @name Manipulators
- //@{
- /*!
- @brief Set the key corresponding to the dataset and record id.
- The key is of the form '<b>Iptc</b>.recordName.dataSetName'.
- */
- void makeKey();
- /*!
- @brief Parse and convert the key string into dataset and record id.
- Updates data members if the string can be decomposed, or throws
- \em Error.
-
- @throw Error if the key cannot be decomposed.
- */
- void decomposeKey();
- //@}
-
- private:
- //! Internal virtual copy constructor.
- virtual IptcKey* clone_() const;
-
- // DATA
- static const char* familyName_;
-
- uint16_t tag_; //!< Tag value
- uint16_t record_; //!< Record value
- std::string key_; //!< Key
-
- }; // class IptcKey
-
-// *****************************************************************************
-// free functions
-
- //! Output operator for dataSet
- std::ostream& operator<<(std::ostream& os, const DataSet& dataSet);
-
-} // namespace Exiv2
-
-#endif // #ifndef DATASETS_HPP_
diff --git a/src/plugins/exiv2/error.cpp b/src/plugins/exiv2/error.cpp
@@ -1,121 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: error.cpp
- Version: $Rev: 563 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 02-Apr-05, ahu: created
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: error.cpp 563 2005-04-21 07:21:53Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "error.hpp"
-
-// + standard includes
-#include <string>
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- const ErrMsg Error::errMsg_[] = {
- ErrMsg( -1, "Error %0: arg1=%1, arg2=%2, arg3=%3."),
- ErrMsg( 0, "Success"),
- ErrMsg( 1, "%1"), // %1=error message
-
- ErrMsg( 2, "%1: %2 (%3)"), // %1=path, %2=strerror, %3=function that failed
- // ErrMsg( 3, ""),
-
- ErrMsg( 4, "Invalid dataset name `%1'"), // %1=dataset name
- ErrMsg( 5, "Invalid record name `%1'"), // %1=record name
- ErrMsg( 6, "Invalid key `%1'"), // %1=key
- ErrMsg( 7, "Invalid tag name or ifdId `%1', ifdId %2"), // %1=tag name, %2=ifdId
- ErrMsg( 8, "Value not set"),
- ErrMsg( 9, "%1: Failed to open the data source: %2"), // %1=path, %2=strerror
- ErrMsg( 10, "%1: Failed to open file (%2): %3"), // %1=path, %2=mode, %3=strerror
- ErrMsg( 11, "%1: The file contains data of an unknown image type"), // %1=path
- ErrMsg( 12, "The memory contains data of an unknown image type"),
- ErrMsg( 13, "Image type %1 is not supported"), // %1=image type
- ErrMsg( 14, "Failed to read image data"),
- ErrMsg( 15, "This does not look like a JPEG image"),
- ErrMsg( 16, "MakerTagInfo registry full"),
- ErrMsg( 17, "%1: Failed to rename file to %2: %3"), // %1=old path, %2=new path, %3=strerror
- ErrMsg( 18, "%1: Transfer failed: %2"), // %1=path, %2=strerror
- ErrMsg( 19, "Memory transfer failed: %1"), // %1=strerror
- ErrMsg( 20, "Failed to read input data"),
- ErrMsg( 21, "Failed to write image"),
- ErrMsg( 22, "Input data does not contain a valid image"),
- ErrMsg( 23, "Failed to create Makernote for ifdId %1"), // %1=ifdId
- ErrMsg( 24, "Entry::setValue: Value too large (tag=%1, size=%2, requested=%3)"), // %1=tag, %2=dataSize, %3=required size
- ErrMsg( 25, "Entry::setDataArea: Value too large (tag=%1, size=%2, requested=%3)"), // %1=tag, %2=dataAreaSize, %3=required size
- ErrMsg( 26, "Offset out of range"),
- ErrMsg( 27, "Unsupported data area offset type"),
- ErrMsg( 28, "Invalid charset: `%1'"), // %1=charset name
- ErrMsg( 29, "Unsupported date format"),
- ErrMsg( 30, "Unsupported time format"),
-
- // Last error message (message is not used)
- ErrMsg( -2, "(Unknown Error)")
- };
-
- int Error::errorIdx(int code)
- {
- int idx;
- for (idx = 0; errMsg_[idx].code_ != code; ++idx) {
- if (errMsg_[idx].code_ == -2) return 0;
- }
- return idx;
- }
-
- std::string Error::what() const
- {
- int idx = errorIdx(code_);
- std::string msg = std::string(errMsg_[idx].message_);
- std::string::size_type pos;
- pos = msg.find("%0");
- if (pos != std::string::npos) {
- msg.replace(pos, 2, toString(code_));
- }
- if (count_ > 0) {
- pos = msg.find("%1");
- if (pos != std::string::npos) {
- msg.replace(pos, 2, arg1_);
- }
- }
- if (count_ > 1) {
- pos = msg.find("%2");
- if (pos != std::string::npos) {
- msg.replace(pos, 2, arg2_);
- }
- }
- if (count_ > 2) {
- pos = msg.find("%3");
- if (pos != std::string::npos) {
- msg.replace(pos, 2, arg3_);
- }
- }
- return msg;
- }
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/error.hpp b/src/plugins/exiv2/error.hpp
@@ -1,148 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file error.hpp
- @brief Error class for exceptions
- @version $Rev: 560 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 15-Jan-04, ahu: created<BR>
- 11-Feb-04, ahu: isolated as a component
- */
-#ifndef ERROR_HPP_
-#define ERROR_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-
-// + standard includes
-#include <string>
-#include <iosfwd>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class definitions
-
- //! Helper structure defining an error message
- struct ErrMsg {
- //! Constructor
- ErrMsg(int code, const char* message)
- : code_(code), message_(message)
- {
- }
- int code_; //!< Error code
- const char* message_; //!< Error message
- };
-
- /*!
- @brief Error class interface. Allows the definition and use of a hierarchy
- of error classes which can all be handled in one catch block.
- */
- class AnyError {
- public:
- //! @name Creators
- //@{
- //! Virtual destructor.
- virtual ~AnyError()
- {
- }
- //@}
-
- //! @name Accessors
- //@{
- //! Return the error code.
- virtual int code() const =0;
- /*!
- @brief Return the error message. Consider using the output operator
- operator<<(std::ostream &os, const AnyError& error) instead.
- @note Unlike std::exception::what(), this function returns an
- std::string.
- */
- virtual std::string what() const =0;
- }; // AnyError
-
- //! %AnyBase output operator
- inline std::ostream& operator<<(std::ostream& os, const AnyError& error)
- {
- return os << error.what();
- }
-
- /*!
- @brief Simple error class used for exceptions. An output operator is
- provided to print errors to a stream.
- */
- class Error : public AnyError {
- public:
- //! @name Creators
- //@{
- //! Constructor taking only an error code
- explicit Error(int code)
- : code_(code), count_(0)
- {
- }
- //! Constructor taking an error code and one argument
- template<typename A>
- Error(int code, const A& arg1)
- : code_(code), count_(1), arg1_(toString(arg1))
- {
- }
- //! Constructor taking an error code and two arguments
- template<typename A, typename B>
- Error(int code, const A& arg1, const B& arg2)
- : code_(code), count_(2),
- arg1_(toString(arg1)), arg2_(toString(arg2))
- {
- }
- //! Constructor taking an error code and three arguments
- template<typename A, typename B, typename C>
- Error(int code, const A& arg1, const B& arg2, const C& arg3)
- : code_(code), count_(3),
- arg1_(toString(arg1)), arg2_(toString(arg2)), arg3_(toString(arg3))
- {
- }
- //@}
-
- //! @name Accessors
- //@{
- virtual int code() const { return code_; }
- virtual std::string what() const;
- //@}
-
- private:
- static int errorIdx(int code);
-
- // DATA
- int code_; //!< Error code
- int count_; //!< Number of arguments
- std::string arg1_; //!< First argument
- std::string arg2_; //!< Second argument
- std::string arg3_; //!< Third argument
-
- static const ErrMsg errMsg_[]; //!< List of error messages
- }; // class Error
-
-} // namespace Exiv2
-
-#endif // #ifndef ERROR_HPP_
diff --git a/src/plugins/exiv2/exif.cpp b/src/plugins/exiv2/exif.cpp
@@ -1,1237 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: exif.cpp
- Version: $Rev: 600 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 26-Jan-04, ahu: created
- 11-Feb-04, ahu: isolated as a component
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: exif.cpp 600 2005-07-09 10:38:09Z ahuggel $");
-
-// Define DEBUG_MAKERNOTE to output debug information to std::cerr, e.g, by
-// calling make like this: make DEFS=-DDEBUG_MAKERNOTE exif.o
-//#define DEBUG_MAKERNOTE
-
-// *****************************************************************************
-// included header files
-#ifdef _MSC_VER
-# include "exv_msvc.h"
-#else
-# include "exv_conf.h"
-#endif
-
-#include "exif.hpp"
-#include "types.hpp"
-#include "basicio.hpp"
-#include "error.hpp"
-#include "value.hpp"
-#include "ifd.hpp"
-#include "tags.hpp"
-#include "jpgimage.hpp"
-#include "makernote.hpp"
-#include "futils.hpp"
-
-// + standard includes
-#include <iostream>
-#include <sstream>
-#include <utility>
-#include <algorithm>
-#include <map>
-#include <cstring>
-#include <cassert>
-#include <cstdio>
-#include <sys/types.h> // for stat()
-#include <sys/stat.h> // for stat()
-#ifdef EXV_HAVE_UNISTD_H
-# include <unistd.h> // for stat()
-#endif
-
-// *****************************************************************************
-// local declarations
-namespace {
-
- /*
- Set the data of the entry identified by tag in ifd to an unsigned long
- with the value of offset. If no entry with this tag exists in ifd, an
- entry of type unsigned long with one component is created.
- */
- void setOffsetTag(Exiv2::Ifd& ifd,
- int idx,
- uint16_t tag,
- uint32_t offset,
- Exiv2::ByteOrder byteOrder);
-
- // Read file path into a DataBuf, which is returned.
- Exiv2::DataBuf readFile(const std::string& path);
-
-}
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- Exifdatum::Exifdatum(const Entry& e, ByteOrder byteOrder)
- : key_(ExifKey::AutoPtr(new ExifKey(e)))
- {
- setValue(e, byteOrder);
- }
-
- Exifdatum::Exifdatum(const ExifKey& key, const Value* pValue)
- : key_(key.clone())
- {
- if (pValue) value_ = pValue->clone();
- }
-
- Exifdatum::~Exifdatum()
- {
- }
-
- Exifdatum::Exifdatum(const Exifdatum& rhs)
- : Metadatum(rhs)
- {
- if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy
- if (rhs.value_.get() != 0) value_ = rhs.value_->clone(); // deep copy
- }
-
- const Value& Exifdatum::value() const
- {
- if (value_.get() == 0) throw Error(8);
- return *value_;
- }
-
- Exifdatum& Exifdatum::operator=(const Exifdatum& rhs)
- {
- if (this == &rhs) return *this;
- Metadatum::operator=(rhs);
-
- key_.reset();
- if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy
-
- value_.reset();
- if (rhs.value_.get() != 0) value_ = rhs.value_->clone(); // deep copy
-
- return *this;
- } // Exifdatum::operator=
-
- Exifdatum& Exifdatum::operator=(const std::string& value)
- {
- setValue(value);
- return *this;
- }
-
- Exifdatum& Exifdatum::operator=(const uint16_t& value)
- {
- return Exiv2::setValue(*this, value);
- }
-
- Exifdatum& Exifdatum::operator=(const uint32_t& value)
- {
- return Exiv2::setValue(*this, value);
- }
-
- Exifdatum& Exifdatum::operator=(const URational& value)
- {
- return Exiv2::setValue(*this, value);
- }
-
- Exifdatum& Exifdatum::operator=(const int16_t& value)
- {
- return Exiv2::setValue(*this, value);
- }
-
- Exifdatum& Exifdatum::operator=(const int32_t& value)
- {
- return Exiv2::setValue(*this, value);
- }
-
- Exifdatum& Exifdatum::operator=(const Rational& value)
- {
- return Exiv2::setValue(*this, value);
- }
-
- Exifdatum& Exifdatum::operator=(const Value& value)
- {
- setValue(&value);
- return *this;
- }
-
- void Exifdatum::setValue(const Value* pValue)
- {
- value_.reset();
- if (pValue) value_ = pValue->clone();
- }
-
- void Exifdatum::setValue(const Entry& e, ByteOrder byteOrder)
- {
- value_ = Value::create(TypeId(e.type()));
- value_->read(e.data(), e.count() * e.typeSize(), byteOrder);
- value_->setDataArea(e.dataArea(), e.sizeDataArea());
- }
-
- void Exifdatum::setValue(const std::string& value)
- {
- if (value_.get() == 0) {
- TypeId type = ExifTags::tagType(tag(), ifdId());
- value_ = Value::create(type);
- }
- value_->read(value);
- }
-
- int TiffThumbnail::setDataArea(ExifData& exifData, Ifd* pIfd1,
- const byte* buf, long len) const
- {
- // Create a DataBuf that can hold all strips
- ExifData::const_iterator sizes;
- ExifKey key("Exif.Thumbnail.StripByteCounts");
- sizes = exifData.findKey(key);
- if (sizes == exifData.end()) return 2;
-
- long totalSize = 0;
- for (long i = 0; i < sizes->count(); ++i) {
- totalSize += sizes->toLong(i);
- }
- DataBuf stripsBuf(totalSize);
-
- // Copy all strips into the data buffer. For each strip remember its
- // offset from the start of the data buffer
- ExifData::iterator stripOffsets;
- key = ExifKey("Exif.Thumbnail.StripOffsets");
- stripOffsets = exifData.findKey(key);
- if (stripOffsets == exifData.end()) return 2;
- if (stripOffsets->count() != sizes->count()) return 2;
-
- std::ostringstream os; // for the strip offsets
- long currentOffset = 0;
- long firstOffset = stripOffsets->toLong(0);
- long lastOffset = 0;
- long lastSize = 0;
- for (long i = 0; i < stripOffsets->count(); ++i) {
- long offset = stripOffsets->toLong(i);
- lastOffset = offset;
- long size = sizes->toLong(i);
- lastSize = size;
- if (len < offset + size) return 1;
-
- memcpy(stripsBuf.pData_ + currentOffset, buf + offset, size);
- os << currentOffset << " ";
- currentOffset += size;
- }
-
- // Set StripOffsets data area and relative offsets
- stripOffsets->setDataArea(stripsBuf.pData_, stripsBuf.size_);
- stripOffsets->setValue(os.str());
-
- // Set corresponding data area at IFD1, if it is a contiguous area
- if (pIfd1 && firstOffset + totalSize == lastOffset + lastSize) {
- Ifd::iterator pos = pIfd1->findTag(0x0111);
- assert(pos != pIfd1->end());
- pos->setDataArea(buf + firstOffset, totalSize);
- }
-
- return 0;
- } // TiffThumbnail::read
-
- const char* TiffThumbnail::format() const
- {
- return "TIFF";
- }
-
- const char* TiffThumbnail::extension() const
- {
- return ".tif";
- }
-
- DataBuf TiffThumbnail::copy(const ExifData& exifData) const
- {
- // Create a TIFF header and IFD1
- TiffHeader tiffHeader(exifData.byteOrder());
- Ifd ifd1(ifd1Id);
-
- // Populate IFD (without Exif and GPS tags) from metadata
- addToIfd(ifd1, exifData.begin(), exifData.end(), exifData.byteOrder());
- ifd1.erase(0x8769);
- ifd1.erase(0x8825);
- ifd1.sortByTag();
-
- long size = tiffHeader.size() + ifd1.size() + ifd1.dataSize();
- DataBuf buf(size);
- long len = tiffHeader.copy(buf.pData_);
- len += ifd1.copy(buf.pData_ + len, exifData.byteOrder(), len);
- assert(len == size);
- return buf;
- }
-
- int JpegThumbnail::setDataArea(ExifData& exifData, Ifd* pIfd1,
- const byte* buf, long len) const
- {
- ExifKey key("Exif.Thumbnail.JPEGInterchangeFormat");
- ExifData::iterator format = exifData.findKey(key);
- if (format == exifData.end()) return 1;
- long offset = format->toLong();
- key = ExifKey("Exif.Thumbnail.JPEGInterchangeFormatLength");
- ExifData::const_iterator length = exifData.findKey(key);
- if (length == exifData.end()) return 1;
- long size = length->toLong();
- if (len < offset + size) return 2;
- format->setDataArea(buf + offset, size);
- format->setValue("0");
- if (pIfd1) {
- Ifd::iterator pos = pIfd1->findTag(0x0201);
- assert(pos != pIfd1->end());
- pos->setDataArea(buf + offset, size);
- }
- return 0;
- } // JpegThumbnail::setDataArea
-
- const char* JpegThumbnail::format() const
- {
- return "JPEG";
- }
-
- const char* JpegThumbnail::extension() const
- {
- return ".jpg";
- }
-
- DataBuf JpegThumbnail::copy(const ExifData& exifData) const
- {
- ExifKey key("Exif.Thumbnail.JPEGInterchangeFormat");
- ExifData::const_iterator format = exifData.findKey(key);
- if (format == exifData.end()) return DataBuf();
- return format->dataArea();
- }
-
- ExifData::ExifData()
- : pTiffHeader_(0),
- pIfd0_(0), pExifIfd_(0), pIopIfd_(0), pGpsIfd_(0), pIfd1_(0),
- pMakerNote_(0), size_(0), pData_(0), compatible_(true)
- {
- }
-
- ExifData::ExifData(const ExifData& rhs)
- : exifMetadata_(rhs.exifMetadata_), pTiffHeader_(0),
- pIfd0_(0), pExifIfd_(0), pIopIfd_(0), pGpsIfd_(0), pIfd1_(0),
- pMakerNote_(0), size_(0), pData_(0), compatible_(rhs.compatible_)
- {
- pData_ = new byte[rhs.size_];
- size_ = rhs.size_;
- memcpy(pData_, rhs.pData_, rhs.size_);
-
- if (rhs.pTiffHeader_) {
- pTiffHeader_ = new TiffHeader(*rhs.pTiffHeader_);
- }
- if (rhs.pIfd0_) {
- pIfd0_ = new Ifd(*rhs.pIfd0_);
- pIfd0_->updateBase(pData_);
- }
- if (rhs.pExifIfd_) {
- pExifIfd_ = new Ifd(*rhs.pExifIfd_);
- pExifIfd_->updateBase(pData_);
- }
- if (rhs.pIopIfd_) {
- pIopIfd_ = new Ifd(*rhs.pIopIfd_);
- pIopIfd_->updateBase(pData_);
- }
- if (rhs.pGpsIfd_) {
- pGpsIfd_ = new Ifd(*rhs.pGpsIfd_);
- pGpsIfd_->updateBase(pData_);
- }
- if (rhs.pIfd1_) {
- pIfd1_ = new Ifd(*rhs.pIfd1_);
- pIfd1_->updateBase(pData_);
- }
- if (rhs.pMakerNote_) {
- pMakerNote_ = rhs.pMakerNote_->clone().release();
- pMakerNote_->updateBase(pData_);
- }
- }
-
- ExifData::~ExifData()
- {
- delete pTiffHeader_;
- delete pIfd0_;
- delete pExifIfd_;
- delete pIopIfd_;
- delete pGpsIfd_;
- delete pIfd1_;
- delete pMakerNote_;
- delete[] pData_;
- }
-
- ExifData& ExifData::operator=(const ExifData& rhs)
- {
- if (this == &rhs) return *this;
-
- exifMetadata_ = rhs.exifMetadata_;
-
- size_ = 0;
- delete[] pData_;
- pData_ = new byte[rhs.size_];
- size_ = rhs.size_;
- memcpy(pData_, rhs.pData_, rhs.size_);
-
- delete pTiffHeader_;
- pTiffHeader_ = 0;
- if (rhs.pTiffHeader_) {
- pTiffHeader_ = new TiffHeader(*rhs.pTiffHeader_);
- }
- delete pIfd0_;
- pIfd0_ = 0;
- if (rhs.pIfd0_) {
- pIfd0_ = new Ifd(*rhs.pIfd0_);
- pIfd0_->updateBase(pData_);
- }
- delete pExifIfd_;
- pExifIfd_ = 0;
- if (rhs.pExifIfd_) {
- pExifIfd_ = new Ifd(*rhs.pExifIfd_);
- pExifIfd_->updateBase(pData_);
- }
- delete pIopIfd_;
- pIopIfd_ = 0;
- if (rhs.pIopIfd_) {
- pIopIfd_ = new Ifd(*rhs.pIopIfd_);
- pIopIfd_->updateBase(pData_);
- }
- delete pGpsIfd_;
- pGpsIfd_ = 0;
- if (rhs.pGpsIfd_) {
- pGpsIfd_ = new Ifd(*rhs.pGpsIfd_);
- pGpsIfd_->updateBase(pData_);
- }
- delete pIfd1_;
- pIfd1_ = 0;
- if (rhs.pIfd1_) {
- pIfd1_ = new Ifd(*rhs.pIfd1_);
- pIfd1_->updateBase(pData_);
- }
- delete pMakerNote_;
- pMakerNote_ = 0;
- if (rhs.pMakerNote_) {
- pMakerNote_ = rhs.pMakerNote_->clone().release();
- pMakerNote_->updateBase(pData_);
- }
-
- compatible_ = rhs.compatible_;
- return *this;
- }
-
- Exifdatum& ExifData::operator[](const std::string& key)
- {
- ExifKey exifKey(key);
- iterator pos = findKey(exifKey);
- if (pos == end()) {
- add(Exifdatum(exifKey));
- pos = findKey(exifKey);
- }
- return *pos;
- }
-
- int ExifData::load(const byte* buf, long len)
- {
- // Copy the data buffer
- delete[] pData_;
- pData_ = new byte[len];
- memcpy(pData_, buf, len);
- size_ = len;
-
- // Read the TIFF header
- delete pTiffHeader_;
- pTiffHeader_ = new TiffHeader;
- assert(pTiffHeader_ != 0);
- int rc = pTiffHeader_->read(pData_);
- if (rc) return rc;
-
- // Read IFD0
- delete pIfd0_;
- pIfd0_ = new Ifd(ifd0Id, 0, false);
- assert(pIfd0_ != 0);
- rc = pIfd0_->read(pData_ + pTiffHeader_->offset(),
- size_ - pTiffHeader_->offset(),
- byteOrder(),
- pTiffHeader_->offset());
- if (rc) return rc;
-
- delete pExifIfd_;
- pExifIfd_ = new Ifd(exifIfdId, 0, false);
- assert(pExifIfd_ != 0);
- // Find and read ExifIFD sub-IFD of IFD0
- rc = pIfd0_->readSubIfd(*pExifIfd_, pData_, size_, byteOrder(), 0x8769);
- if (rc) return rc;
- // Find MakerNote in ExifIFD, create a MakerNote class
- Ifd::iterator pos = pExifIfd_->findTag(0x927c);
- Ifd::iterator make = pIfd0_->findTag(0x010f);
- Ifd::iterator model = pIfd0_->findTag(0x0110);
- if ( pos != pExifIfd_->end()
- && make != pIfd0_->end() && model != pIfd0_->end()) {
- // Todo: The conversion to string assumes that there is a \0 at the end
- // Todo: How to avoid the cast (is that a MSVC thing?)
- pMakerNote_ = MakerNoteFactory::create(
- reinterpret_cast<const char*>(make->data()),
- reinterpret_cast<const char*>(model->data()),
- false,
- pos->data(),
- pos->size(),
- byteOrder(),
- pExifIfd_->offset() + pos->offset()).release();
- }
- // Read the MakerNote
- if (pMakerNote_) {
- rc = pMakerNote_->read(pos->data(),
- pos->size(),
- byteOrder(),
- pExifIfd_->offset() + pos->offset());
- if (rc) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Warning: Failed to read Makernote, rc = "
- << rc << "\n";
-#endif
- delete pMakerNote_;
- pMakerNote_ = 0;
- }
- }
- // If we successfully parsed the MakerNote, delete the raw MakerNote,
- // the parsed MakerNote is the primary MakerNote from now on
- if (pMakerNote_) {
- pExifIfd_->erase(pos);
- }
-
- delete pIopIfd_;
- pIopIfd_ = new Ifd(iopIfdId, 0, false);
- assert(pIopIfd_ != 0);
- // Find and read Interoperability IFD in ExifIFD
- rc = pExifIfd_->readSubIfd(*pIopIfd_, pData_, size_, byteOrder(), 0xa005);
- if (rc) return rc;
-
- delete pGpsIfd_;
- pGpsIfd_ = new Ifd(gpsIfdId, 0, false);
- assert(pGpsIfd_ != 0);
- // Find and read GPSInfo sub-IFD in IFD0
- rc = pIfd0_->readSubIfd(*pGpsIfd_, pData_, size_, byteOrder(), 0x8825);
- if (rc) return rc;
-
- delete pIfd1_;
- pIfd1_ = new Ifd(ifd1Id, 0, false);
- assert(pIfd1_ != 0);
- // Read IFD1
- if (pIfd0_->next()) {
- rc = pIfd1_->read(pData_ + pIfd0_->next(),
- size_ - pIfd0_->next(),
- byteOrder(),
- pIfd0_->next());
- if (rc) return rc;
- }
- // Find and delete ExifIFD sub-IFD of IFD1
- pos = pIfd1_->findTag(0x8769);
- if (pos != pIfd1_->end()) {
- pIfd1_->erase(pos);
- rc = 7;
- }
- // Find and delete GPSInfo sub-IFD in IFD1
- pos = pIfd1_->findTag(0x8825);
- if (pos != pIfd1_->end()) {
- pIfd1_->erase(pos);
- rc = 7;
- }
- // Copy all entries from the IFDs and the MakerNote to the metadata
- exifMetadata_.clear();
- add(pIfd0_->begin(), pIfd0_->end(), byteOrder());
- add(pExifIfd_->begin(), pExifIfd_->end(), byteOrder());
- if (pMakerNote_) {
- add(pMakerNote_->begin(), pMakerNote_->end(),
- (pMakerNote_->byteOrder() == invalidByteOrder ?
- byteOrder() : pMakerNote_->byteOrder()));
- }
- add(pIopIfd_->begin(), pIopIfd_->end(), byteOrder());
- add(pGpsIfd_->begin(), pGpsIfd_->end(), byteOrder());
- add(pIfd1_->begin(), pIfd1_->end(), byteOrder());
- // Read the thumbnail (but don't worry whether it was successful or not)
- readThumbnail();
-
- return rc;
- } // ExifData::load
-
-
- DataBuf ExifData::copy()
- {
- DataBuf buf;
- // If we can update the internal IFDs and the underlying data buffer
- // from the metadata without changing the data size, then it is enough
- // to copy the data buffer.
- if (compatible_ && updateEntries()) {
-#ifdef DEBUG_MAKERNOTE
- std::cerr << "->>>>>> using non-intrusive writing <<<<<<-\n";
-#endif
- buf.alloc(size_);
- memcpy(buf.pData_, pData_, size_);
- }
- // Else we have to do it the hard way...
- else {
-#ifdef DEBUG_MAKERNOTE
- std::cerr << "->>>>>> writing from metadata <<<<<<-\n";
-#endif
- buf = copyFromMetadata();
- }
- return buf;
- }
-
- DataBuf ExifData::copyFromMetadata()
- {
- // Build IFD0
- Ifd ifd0(ifd0Id);
- addToIfd(ifd0, begin(), end(), byteOrder());
-
- // Build Exif IFD from metadata
- Ifd exifIfd(exifIfdId);
- addToIfd(exifIfd, begin(), end(), byteOrder());
- MakerNote::AutoPtr makerNote;
- if (pMakerNote_) {
- // Build MakerNote from metadata
- makerNote = pMakerNote_->create();
- addToMakerNote(makerNote.get(),
- begin(), end(),
- (pMakerNote_->byteOrder() == invalidByteOrder ?
- byteOrder() : pMakerNote_->byteOrder()));
- // Create a placeholder MakerNote entry of the correct size and
- // add it to the Exif IFD (because we don't know the offset yet)
- Entry e;
- e.setIfdId(exifIfd.ifdId());
- e.setTag(0x927c);
- DataBuf tmpBuf(makerNote->size());
- memset(tmpBuf.pData_, 0x0, tmpBuf.size_);
- e.setValue(undefined, tmpBuf.size_, tmpBuf.pData_, tmpBuf.size_);
- exifIfd.erase(0x927c);
- exifIfd.add(e);
- }
-
- // Build Interoperability IFD from metadata
- Ifd iopIfd(iopIfdId);
- addToIfd(iopIfd, begin(), end(), byteOrder());
-
- // Build GPSInfo IFD from metadata
- Ifd gpsIfd(gpsIfdId);
- addToIfd(gpsIfd, begin(), end(), byteOrder());
-
- // build IFD1 from metadata
- Ifd ifd1(ifd1Id);
- addToIfd(ifd1, begin(), end(), byteOrder());
- // Set a temporary dummy offset in IFD0
- if (ifd1.size() > 0) {
- ifd0.setNext(1, byteOrder());
- }
-
- // Compute the new IFD offsets
- int exifIdx = ifd0.erase(0x8769);
- int gpsIdx = ifd0.erase(0x8825);
- int iopIdx = exifIfd.erase(0xa005);
-
- TiffHeader tiffHeader(byteOrder());
- long ifd0Offset = tiffHeader.size();
- bool addOffsetTag = false;
- long exifIfdOffset = ifd0Offset + ifd0.size() + ifd0.dataSize();
- if (exifIfd.size() > 0 || iopIfd.size() > 0) {
- exifIfdOffset += 12;
- addOffsetTag = true;
- }
- if (gpsIfd.size() > 0) {
- exifIfdOffset += 12;
- addOffsetTag = true;
- }
- if (ifd0.size() == 0 && addOffsetTag) {
- exifIfdOffset += 6;
- }
- addOffsetTag = false;
- long iopIfdOffset = exifIfdOffset + exifIfd.size() + exifIfd.dataSize();
- if (iopIfd.size() > 0) {
- iopIfdOffset += 12;
- addOffsetTag = true;
- }
- if (exifIfd.size() == 0 && addOffsetTag) {
- iopIfdOffset += 6;
- }
- long gpsIfdOffset = iopIfdOffset + iopIfd.size() + iopIfd.dataSize();
- long ifd1Offset = gpsIfdOffset + gpsIfd.size() + gpsIfd.dataSize();
-
- // Set the offset to IFD1 in IFD0
- if (ifd1.size() > 0) {
- ifd0.setNext(ifd1Offset, byteOrder());
- }
-
- // Set the offset to the Exif IFD in IFD0
- if (exifIfd.size() > 0 || iopIfd.size() > 0) {
- setOffsetTag(ifd0, exifIdx, 0x8769, exifIfdOffset, byteOrder());
- }
- // Set the offset to the GPSInfo IFD in IFD0
- if (gpsIfd.size() > 0) {
- setOffsetTag(ifd0, gpsIdx, 0x8825, gpsIfdOffset, byteOrder());
- }
- // Set the offset to the Interoperability IFD in Exif IFD
- if (iopIfd.size() > 0) {
- setOffsetTag(exifIfd, iopIdx, 0xa005, iopIfdOffset, byteOrder());
- }
-
- // Allocate a data buffer big enough for all metadata
- long size = tiffHeader.size();
- size += ifd0.size() + ifd0.dataSize();
- size += exifIfd.size() + exifIfd.dataSize();
- size += iopIfd.size() + iopIfd.dataSize();
- size += gpsIfd.size() + gpsIfd.dataSize();
- size += ifd1.size() + ifd1.dataSize();
- DataBuf buf(size);
-
- // Copy the TIFF header, all IFDs, MakerNote and thumbnail to the buffer
- size = tiffHeader.copy(buf.pData_);
- ifd0.sortByTag();
- size += ifd0.copy(buf.pData_ + ifd0Offset, byteOrder(), ifd0Offset);
- exifIfd.sortByTag();
- size += exifIfd.copy(buf.pData_ + exifIfdOffset, byteOrder(), exifIfdOffset);
- if (makerNote.get() != 0) {
- // Copy the MakerNote over the placeholder data
- Entries::iterator mn = exifIfd.findTag(0x927c);
- // Do _not_ sort the makernote; vendors (at least Canon), don't seem
- // to bother about this TIFF standard requirement, so writing the
- // makernote as is might result in fewer deviations from the original
- makerNote->copy(buf.pData_ + exifIfdOffset + mn->offset(),
- byteOrder(),
- exifIfdOffset + mn->offset());
- }
- iopIfd.sortByTag();
- size += iopIfd.copy(buf.pData_ + iopIfdOffset, byteOrder(), iopIfdOffset);
- gpsIfd.sortByTag();
- size += gpsIfd.copy(buf.pData_ + gpsIfdOffset, byteOrder(), gpsIfdOffset);
- ifd1.sortByTag();
- size += ifd1.copy(buf.pData_ + ifd1Offset, byteOrder(), ifd1Offset);
- assert(size == buf.size_);
- return buf;
- } // ExifData::copyFromMetadata
-
- void ExifData::add(Entries::const_iterator begin,
- Entries::const_iterator end,
- ByteOrder byteOrder)
- {
- Entries::const_iterator i = begin;
- for (; i != end; ++i) {
- add(Exifdatum(*i, byteOrder));
- }
- }
-
- void ExifData::add(const ExifKey& key, const Value* pValue)
- {
- add(Exifdatum(key, pValue));
- }
-
- void ExifData::add(const Exifdatum& exifdatum)
- {
- if (ExifTags::isMakerIfd(exifdatum.ifdId())) {
- if (pMakerNote_ == 0) {
- pMakerNote_ = MakerNoteFactory::create(exifdatum.ifdId()).release();
- }
- if (pMakerNote_ == 0) throw Error(23, exifdatum.ifdId());
- }
- // allow duplicates
- exifMetadata_.push_back(exifdatum);
- }
-
- ExifData::const_iterator ExifData::findKey(const ExifKey& key) const
- {
- return std::find_if(exifMetadata_.begin(), exifMetadata_.end(),
- FindMetadatumByKey(key.key()));
- }
-
- ExifData::iterator ExifData::findKey(const ExifKey& key)
- {
- return std::find_if(exifMetadata_.begin(), exifMetadata_.end(),
- FindMetadatumByKey(key.key()));
- }
-
- ExifData::const_iterator ExifData::findIfdIdIdx(IfdId ifdId, int idx) const
- {
- return std::find_if(exifMetadata_.begin(), exifMetadata_.end(),
- FindMetadatumByIfdIdIdx(ifdId, idx));
- }
-
- ExifData::iterator ExifData::findIfdIdIdx(IfdId ifdId, int idx)
- {
- return std::find_if(exifMetadata_.begin(), exifMetadata_.end(),
- FindMetadatumByIfdIdIdx(ifdId, idx));
- }
-
- void ExifData::sortByKey()
- {
- std::sort(exifMetadata_.begin(), exifMetadata_.end(), cmpMetadataByKey);
- }
-
- void ExifData::sortByTag()
- {
- std::sort(exifMetadata_.begin(), exifMetadata_.end(), cmpMetadataByTag);
- }
-
- ExifData::iterator ExifData::erase(ExifData::iterator pos)
- {
- return exifMetadata_.erase(pos);
- }
-
- void ExifData::setJpegThumbnail(const byte* buf, long size)
- {
- (*this)["Exif.Thumbnail.Compression"] = uint16_t(6);
- Exifdatum& format = (*this)["Exif.Thumbnail.JPEGInterchangeFormat"];
- format = uint32_t(0);
- format.setDataArea(buf, size);
- (*this)["Exif.Thumbnail.JPEGInterchangeFormatLength"] = uint32_t(size);
- }
-
- void ExifData::setJpegThumbnail(const byte* buf, long size,
- URational xres, URational yres, uint16_t unit)
- {
- setJpegThumbnail(buf, size);
- (*this)["Exif.Thumbnail.XResolution"] = xres;
- (*this)["Exif.Thumbnail.YResolution"] = yres;
- (*this)["Exif.Thumbnail.ResolutionUnit"] = unit;
- }
-
- void ExifData::setJpegThumbnail(const std::string& path)
- {
- DataBuf thumb = readFile(path); // may throw
- setJpegThumbnail(thumb.pData_, thumb.size_);
- }
-
- void ExifData::setJpegThumbnail(const std::string& path,
- URational xres, URational yres, uint16_t unit)
- {
- DataBuf thumb = readFile(path); // may throw
- setJpegThumbnail(thumb.pData_, thumb.size_, xres, yres, unit);
- }
-
- long ExifData::eraseThumbnail()
- {
- // First, determine if the thumbnail is at the end of the Exif data
- bool stp = stdThumbPosition();
- // Delete all Exif.Thumbnail.* (IFD1) metadata
- ExifMetadata::iterator i = begin();
- while (i != end()) {
- if (i->ifdId() == ifd1Id) {
- i = erase(i);
- }
- else {
- ++i;
- }
- }
- long delta = 0;
- if (stp) {
- delta = size_;
- if (size_ > 0 && pIfd0_ && pIfd0_->next() > 0) {
- // Truncate IFD1 and thumbnail data from the data buffer
- size_ = pIfd0_->next();
- pIfd0_->setNext(0, byteOrder());
- if (pIfd1_) pIfd1_->clear();
- }
- delta -= size_;
- }
- else {
- // We will have to write the hard way and re-arrange the data
- compatible_ = false;
- if (pIfd1_) delta = pIfd1_->size() + pIfd1_->dataSize();
- }
- return delta;
- } // ExifData::eraseThumbnail
-
- bool ExifData::stdThumbPosition() const
- {
- if ( pIfd0_ == 0 || pExifIfd_ == 0 || pIopIfd_ == 0
- || pGpsIfd_ == 0 || pIfd1_ == 0) return true;
-
- // Todo: There is still an invalid assumption here: The data of an IFD
- // can be stored in multiple non-contiguous blocks. In this case,
- // dataOffset + dataSize does not point to the end of the IFD data.
- // in particular, this is potentially the case for the remaining Exif
- // data in the presence of a known Makernote.
- bool rc = true;
- Thumbnail::AutoPtr thumbnail = getThumbnail();
- if (thumbnail.get()) {
- long maxOffset;
- maxOffset = std::max(pIfd0_->offset(), pIfd0_->dataOffset());
- maxOffset = std::max(maxOffset, pExifIfd_->offset());
- maxOffset = std::max(maxOffset, pExifIfd_->dataOffset()
- + pExifIfd_->dataSize());
- if (pMakerNote_) {
- maxOffset = std::max(maxOffset, pMakerNote_->offset()
- + pMakerNote_->size());
- }
- maxOffset = std::max(maxOffset, pIopIfd_->offset());
- maxOffset = std::max(maxOffset, pIopIfd_->dataOffset()
- + pIopIfd_->dataSize());
- maxOffset = std::max(maxOffset, pGpsIfd_->offset());
- maxOffset = std::max(maxOffset, pGpsIfd_->dataOffset()
- + pGpsIfd_->dataSize());
-
- if ( maxOffset > pIfd1_->offset()
- || maxOffset > pIfd1_->dataOffset() && pIfd1_->dataOffset() > 0)
- rc = false;
- /*
- Todo: Removed condition from the above if(). Should be re-added...
- || maxOffset > pThumbnail_->offset()
- */
- }
- return rc;
- } // ExifData::stdThumbPosition
-
- ByteOrder ExifData::byteOrder() const
- {
- if (pTiffHeader_) return pTiffHeader_->byteOrder();
- return littleEndian;
- }
-
- int ExifData::writeThumbnail(const std::string& path) const
- {
- Thumbnail::AutoPtr thumbnail = getThumbnail();
- if (thumbnail.get() == 0) return 8;
-
- std::string name = path + thumbnail->extension();
- FileIo file(name);
- if (file.open("wb") != 0) {
- throw Error(10, name, "wb", strError());
- }
-
- DataBuf buf(thumbnail->copy(*this));
- if (file.write(buf.pData_, buf.size_) != buf.size_) {
- throw Error(2, name, strError(), "FileIo::write");
- }
-
- return 0;
- } // ExifData::writeThumbnail
-
- DataBuf ExifData::copyThumbnail() const
- {
- Thumbnail::AutoPtr thumbnail = getThumbnail();
- if (thumbnail.get() == 0) return DataBuf();
- return thumbnail->copy(*this);
- }
-
- const char* ExifData::thumbnailFormat() const
- {
- Thumbnail::AutoPtr thumbnail = getThumbnail();
- if (thumbnail.get() == 0) return "";
- return thumbnail->format();
- }
-
- const char* ExifData::thumbnailExtension() const
- {
- Thumbnail::AutoPtr thumbnail = getThumbnail();
- if (thumbnail.get() == 0) return "";
- return thumbnail->extension();
- }
-
- Thumbnail::AutoPtr ExifData::getThumbnail() const
- {
- Thumbnail::AutoPtr thumbnail;
- const_iterator pos = findKey(ExifKey("Exif.Thumbnail.Compression"));
- if (pos != end()) {
- long compression = pos->toLong();
- if (compression == 6) {
- thumbnail = Thumbnail::AutoPtr(new JpegThumbnail);
- }
- else {
- thumbnail = Thumbnail::AutoPtr(new TiffThumbnail);
- }
- }
- return thumbnail;
-
- } // ExifData::getThumbnail
-
- int ExifData::readThumbnail()
- {
- int rc = -1;
- Thumbnail::AutoPtr thumbnail = getThumbnail();
- if (thumbnail.get() != 0) {
- rc = thumbnail->setDataArea(*this, pIfd1_, pData_, size_);
- }
- return rc;
-
- } // ExifData::readThumbnail
-
- bool ExifData::updateEntries()
- {
- if ( pIfd0_ == 0 || pExifIfd_ == 0 || pIopIfd_ == 0
- || pGpsIfd_ == 0 || pIfd1_ == 0) return false;
- if (!this->compatible()) return false;
-
- bool compatible = true;
- compatible &= updateRange(pIfd0_->begin(), pIfd0_->end(), byteOrder());
- compatible &= updateRange(pExifIfd_->begin(), pExifIfd_->end(), byteOrder());
- if (pMakerNote_) {
- compatible &= updateRange(pMakerNote_->begin(),
- pMakerNote_->end(),
- (pMakerNote_->byteOrder() == invalidByteOrder ?
- byteOrder() : pMakerNote_->byteOrder()));
- }
- compatible &= updateRange(pIopIfd_->begin(), pIopIfd_->end(), byteOrder());
- compatible &= updateRange(pGpsIfd_->begin(), pGpsIfd_->end(), byteOrder());
- compatible &= updateRange(pIfd1_->begin(), pIfd1_->end(), byteOrder());
-
- return compatible;
- } // ExifData::updateEntries
-
- bool ExifData::updateRange(const Entries::iterator& begin,
- const Entries::iterator& end,
- ByteOrder byteOrder)
- {
- bool compatible = true;
- for (Entries::iterator entry = begin; entry != end; ++entry) {
- // find the corresponding Exifdatum
- const_iterator md = findIfdIdIdx(entry->ifdId(), entry->idx());
- if (md == this->end()) {
- // corresponding Exifdatum was deleted: this is not (yet) a
- // supported non-intrusive write operation.
- compatible = false;
- continue;
- }
- if (entry->count() == 0 && md->count() == 0) {
- // Special case: don't do anything if both the entry and
- // Exifdatum have no data. This is to preserve the original
- // data in the offset field of an IFD entry with count 0,
- // if the Exifdatum was not changed.
- }
- else if ( entry->size() < md->size()
- || entry->sizeDataArea() < md->sizeDataArea()) {
- compatible = false;
- continue;
- }
- else {
- // Hack: Set the entry's value only if there is no data area.
- // This ensures that the original offsets are not overwritten
- // with relative offsets from the Exifdatum (which require
- // conversion to offsets relative to the start of the TIFF
- // header and that is currently only done in intrusive write
- // mode). On the other hand, it is thus now not possible to
- // change the offsets of an entry with a data area in
- // non-intrusive mode. This can be considered a bug.
- // Todo: Fix me!
- if (md->sizeDataArea() == 0) {
- DataBuf buf(md->size());
- md->copy(buf.pData_, byteOrder);
- entry->setValue(static_cast<uint16_t>(md->typeId()),
- md->count(),
- buf.pData_, md->size());
- }
- // Always set the data area
- DataBuf dataArea(md->dataArea());
- entry->setDataArea(dataArea.pData_, dataArea.size_);
- }
- }
- return compatible;
- } // ExifData::updateRange
-
- bool ExifData::compatible() const
- {
- bool compatible = true;
- // For each Exifdatum, check if it is compatible with the corresponding
- // IFD or MakerNote entry
- for (const_iterator md = begin(); md != this->end(); ++md) {
- std::pair<bool, Entries::const_iterator> rc;
- rc = findEntry(md->ifdId(), md->idx());
- // Make sure that we have an entry
- if (!rc.first) {
- compatible = false;
- break;
- }
- // Make sure that the size of the Exifdatum fits the available size
- // of the entry
- if ( md->size() > rc.second->size()
- || md->sizeDataArea() > rc.second->sizeDataArea()) {
- compatible = false;
- break;
- }
- }
- return compatible;
- } // ExifData::compatible
-
- std::pair<bool, Entries::const_iterator>
- ExifData::findEntry(IfdId ifdId, int idx) const
- {
- Entries::const_iterator entry;
- std::pair<bool, Entries::const_iterator> rc(false, entry);
-
- if (ExifTags::isMakerIfd(ifdId) && pMakerNote_) {
- entry = pMakerNote_->findIdx(idx);
- if (entry != pMakerNote_->end()) {
- rc.first = true;
- rc.second = entry;
- }
- return rc;
- }
- const Ifd* ifd = getIfd(ifdId);
- if (ifd && isExifIfd(ifdId)) {
- entry = ifd->findIdx(idx);
- if (entry != ifd->end()) {
- rc.first = true;
- rc.second = entry;
- }
- }
- return rc;
- } // ExifData::findEntry
-
- const Ifd* ExifData::getIfd(IfdId ifdId) const
- {
- const Ifd* ifd = 0;
- switch (ifdId) {
- case ifd0Id:
- ifd = pIfd0_;
- break;
- case exifIfdId:
- ifd = pExifIfd_;
- break;
- case iopIfdId:
- ifd = pIopIfd_;
- break;
- case gpsIfdId:
- ifd = pGpsIfd_;
- break;
- case ifd1Id:
- ifd = pIfd1_;
- break;
- default:
- ifd = 0;
- break;
- }
- return ifd;
- } // ExifData::getIfd
-
- // *************************************************************************
- // free functions
-
- void addToIfd(Ifd& ifd,
- ExifMetadata::const_iterator begin,
- ExifMetadata::const_iterator end,
- ByteOrder byteOrder)
- {
- for (ExifMetadata::const_iterator i = begin; i != end; ++i) {
- // add only metadata with matching IFD id
- if (i->ifdId() == ifd.ifdId()) {
- addToIfd(ifd, *i, byteOrder);
- }
- }
- } // addToIfd
-
- void addToIfd(Ifd& ifd, const Exifdatum& md, ByteOrder byteOrder)
- {
- assert(ifd.alloc());
-
- Entry e;
- e.setIfdId(md.ifdId());
- e.setIdx(md.idx());
- e.setTag(md.tag());
- e.setOffset(0); // will be calculated when the IFD is written
-
- DataBuf buf(md.size());
- md.copy(buf.pData_, byteOrder);
- e.setValue(static_cast<uint16_t>(md.typeId()), md.count(),
- buf.pData_, buf.size_);
-
- DataBuf dataArea(md.dataArea());
- e.setDataArea(dataArea.pData_, dataArea.size_);
-
- ifd.add(e);
- } // addToIfd
-
- void addToMakerNote(MakerNote* makerNote,
- ExifMetadata::const_iterator begin,
- ExifMetadata::const_iterator end,
- ByteOrder byteOrder)
- {
- for (ExifMetadata::const_iterator i = begin; i != end; ++i) {
- if (ExifTags::isMakerIfd(i->ifdId())) {
- addToMakerNote(makerNote, *i, byteOrder);
- }
- }
- } // addToMakerNote
-
- void addToMakerNote(MakerNote* makerNote,
- const Exifdatum& md,
- ByteOrder byteOrder)
- {
- Entry e;
- e.setIfdId(md.ifdId());
- e.setIdx(md.idx());
- e.setTag(md.tag());
- e.setOffset(0); // will be calculated when the makernote is written
-
- DataBuf buf(md.size());
- md.copy(buf.pData_, byteOrder);
- e.setValue(static_cast<uint16_t>(md.typeId()), md.count(),
- buf.pData_, md.size());
-
- DataBuf dataArea(md.dataArea());
- e.setDataArea(dataArea.pData_, dataArea.size_);
-
- makerNote->add(e);
- } // addToMakerNote
-
- std::ostream& operator<<(std::ostream& os, const Exifdatum& md)
- {
- return ExifTags::printTag(os, md.tag(), md.ifdId(), md.value());
- }
-} // namespace Exiv2
-
-// *****************************************************************************
-// local definitions
-namespace {
-
- void setOffsetTag(Exiv2::Ifd& ifd,
- int idx,
- uint16_t tag,
- uint32_t offset,
- Exiv2::ByteOrder byteOrder)
- {
- Exiv2::Ifd::iterator pos = ifd.findTag(tag);
- if (pos == ifd.end()) {
- Exiv2::Entry e(ifd.alloc());
- e.setIfdId(ifd.ifdId());
- e.setIdx(idx);
- e.setTag(tag);
- e.setOffset(0); // will be calculated when the IFD is written
- ifd.add(e);
- pos = ifd.findTag(tag);
- }
- pos->setValue(offset, byteOrder);
- }
-
- Exiv2::DataBuf readFile(const std::string& path)
- {
- Exiv2::FileIo file(path);
- if (file.open("rb") != 0) {
- throw Exiv2::Error(10, path, "rb", Exiv2::strError());
- }
- struct stat st;
- if (0 != stat(path.c_str(), &st)) {
- throw Exiv2::Error(2, path, Exiv2::strError(), "::stat");
- }
- Exiv2::DataBuf buf(st.st_size);
- long len = file.read(buf.pData_, buf.size_);
- if (len != buf.size_) {
- throw Exiv2::Error(2, path, Exiv2::strError(), "FileIo::read");
- }
- return buf;
- }
-
-}
diff --git a/src/plugins/exiv2/exif.hpp b/src/plugins/exiv2/exif.hpp
@@ -1,908 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file exif.hpp
- @brief Encoding and decoding of Exif data
- @version $Rev: 599 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 09-Jan-04, ahu: created
- */
-#ifndef EXIF_HPP_
-#define EXIF_HPP_
-
-// *****************************************************************************
-// included header files
-#include "metadatum.hpp"
-#include "types.hpp"
-#include "error.hpp"
-#include "value.hpp"
-#include "ifd.hpp"
-#include "tags.hpp"
-
-// + standard includes
-#include <string>
-#include <vector>
-#include <memory>
-
-// *****************************************************************************
-// namespace extensions
-/*!
- @brief Provides classes and functions to encode and decode Exif and Iptc data.
- This namespace corresponds to the <b>libexiv2</b> library.
-
- */
-namespace Exiv2 {
-
-// *****************************************************************************
-// class declarations
- class ExifData;
- class MakerNote;
- class TiffHeader;
-
-// *****************************************************************************
-// class definitions
-
- /*!
- @brief Information related to one Exif tag. An Exif metadatum consists of
- an ExifKey and a Value and provides methods to manipulate these.
- */
- class Exifdatum : public Metadatum {
- friend std::ostream& operator<<(std::ostream&, const Exifdatum&);
- template<typename T> friend Exifdatum& setValue(Exifdatum&, const T&);
- public:
- //! @name Creators
- //@{
- /*!
- @brief Constructor for new tags created by an application. The
- %Exifdatum is created from a \em key / value pair. %Exifdatum copies
- (clones) the \em key and value if one is provided. Alternatively,
- a program can create an 'empty' %Exifdatum with only a key
- and set the value using setValue().
-
- @param key %ExifKey.
- @param pValue Pointer to an %Exifdatum value.
- @throw Error if the key cannot be parsed and converted.
- */
- explicit Exifdatum(const ExifKey& key, const Value* pValue =0);
- //! Constructor to build an %Exifdatum from an IFD entry.
- Exifdatum(const Entry& e, ByteOrder byteOrder);
- //! Copy constructor
- Exifdatum(const Exifdatum& rhs);
- //! Destructor
- virtual ~Exifdatum();
- //@}
-
- //! @name Manipulators
- //@{
- //! Assignment operator
- Exifdatum& operator=(const Exifdatum& rhs);
- /*!
- @brief Assign \em value to the %Exifdatum. The type of the new Value
- is set to UShortValue.
- */
- Exifdatum& operator=(const uint16_t& value);
- /*!
- @brief Assign \em value to the %Exifdatum. The type of the new Value
- is set to ULongValue.
- */
- Exifdatum& operator=(const uint32_t& value);
- /*!
- @brief Assign \em value to the %Exifdatum. The type of the new Value
- is set to URationalValue.
- */
- Exifdatum& operator=(const URational& value);
- /*!
- @brief Assign \em value to the %Exifdatum. The type of the new Value
- is set to ShortValue.
- */
- Exifdatum& operator=(const int16_t& value);
- /*!
- @brief Assign \em value to the %Exifdatum. The type of the new Value
- is set to LongValue.
- */
- Exifdatum& operator=(const int32_t& value);
- /*!
- @brief Assign \em value to the %Exifdatum. The type of the new Value
- is set to RationalValue.
- */
- Exifdatum& operator=(const Rational& value);
- /*!
- @brief Assign \em value to the %Exifdatum.
- Calls setValue(const std::string&).
- */
- Exifdatum& operator=(const std::string& value);
- /*!
- @brief Assign \em value to the %Exifdatum.
- Calls setValue(const Value*).
- */
- Exifdatum& operator=(const Value& value);
- /*!
- @brief Set the value. This method copies (clones) the value pointed
- to by \em pValue.
- */
- void setValue(const Value* pValue);
- /*!
- @brief Set the value to the string \em value. Uses Value::read(const
- std::string&). If the %Exifdatum does not have a Value yet,
- then a %Value of the correct type for this %Exifdatum is
- created. An AsciiValue is created for unknown tags.
- */
- void setValue(const std::string& value);
- /*!
- @brief Set the value from an IFD entry.
- */
- void setValue(const Entry& e, ByteOrder byteOrder);
- /*!
- @brief Set the data area by copying (cloning) the buffer pointed to
- by \em buf.
-
- Values may have a data area, which can contain additional
- information besides the actual value. This method is used to set such
- a data area.
-
- @param buf Pointer to the source data area
- @param len Size of the data area
- @return Return -1 if the %Exifdatum does not have a value yet or the
- value has no data area, else 0.
- */
- int setDataArea(const byte* buf, long len)
- { return value_.get() == 0 ? -1 : value_->setDataArea(buf, len); }
- //@}
-
- //! @name Accessors
- //@{
- //! Return the key of the %Exifdatum.
- std::string key() const
- { return key_.get() == 0 ? "" : key_->key(); }
- //! Return the name of the group (the second part of the key)
- std::string groupName() const
- { return key_.get() == 0 ? "" : key_->groupName(); }
- //! Return the name of the tag (which is also the third part of the key)
- std::string tagName() const
- { return key_.get() == 0 ? "" : key_->tagName(); }
- //! Return the tag
- uint16_t tag() const
- { return key_.get() == 0 ? 0xffff : key_->tag(); }
- //! Return the IFD id
- IfdId ifdId() const
- { return key_.get() == 0 ? ifdIdNotSet : key_->ifdId(); }
- //! Return the name of the IFD
- const char* ifdName() const
- { return key_.get() == 0 ? "" : key_->ifdName(); }
- //! Return the related image item (deprecated)
- std::string ifdItem() const
- { return key_.get() == 0 ? "" : key_->ifdItem(); }
- //! Return the index (unique id of this key within the original IFD)
- int idx() const
- { return key_.get() == 0 ? 0 : key_->idx(); }
- /*!
- @brief Write value to a data buffer and return the number
- of bytes written.
-
- The user must ensure that the buffer has enough memory. Otherwise
- the call results in undefined behaviour.
-
- @param buf Data buffer to write to.
- @param byteOrder Applicable byte order (little or big endian).
- @return Number of characters written.
- */
- long copy(byte* buf, ByteOrder byteOrder) const
- { return value_.get() == 0 ? 0 : value_->copy(buf, byteOrder); }
- //! Return the type id of the value
- TypeId typeId() const
- { return value_.get() == 0 ? invalidTypeId : value_->typeId(); }
- //! Return the name of the type
- const char* typeName() const
- { return TypeInfo::typeName(typeId()); }
- //! Return the size in bytes of one component of this type
- long typeSize() const
- { return TypeInfo::typeSize(typeId()); }
- //! Return the number of components in the value
- long count() const
- { return value_.get() == 0 ? 0 : value_->count(); }
- //! Return the size of the value in bytes
- long size() const
- { return value_.get() == 0 ? 0 : value_->size(); }
- //! Return the value as a string.
- std::string toString() const
- { return value_.get() == 0 ? "" : value_->toString(); }
- /*!
- @brief Return the <EM>n</EM>-th component of the value converted to
- long. The return value is -1 if the value of the Exifdatum is
- not set and the behaviour of the method is undefined if there
- is no n-th component.
- */
- long toLong(long n =0) const
- { return value_.get() == 0 ? -1 : value_->toLong(n); }
- /*!
- @brief Return the <EM>n</EM>-th component of the value converted to
- float. The return value is -1 if the value of the Exifdatum is
- not set and the behaviour of the method is undefined if there
- is no n-th component.
- */
- float toFloat(long n =0) const
- { return value_.get() == 0 ? -1 : value_->toFloat(n); }
- /*!
- @brief Return the <EM>n</EM>-th component of the value converted to
- Rational. The return value is -1/1 if the value of the
- Exifdatum is not set and the behaviour of the method is
- undefined if there is no n-th component.
- */
- Rational toRational(long n =0) const
- { return value_.get() == 0 ? Rational(-1, 1) : value_->toRational(n); }
- /*!
- @brief Return an auto-pointer to a copy (clone) of the value. The
- caller owns this copy and the auto-pointer ensures that it will
- be deleted.
-
- This method is provided for users who need full control over the
- value. A caller may, e.g., downcast the pointer to the appropriate
- subclass of Value to make use of the interface of the subclass to set
- or modify its contents.
-
- @return An auto-pointer to a copy (clone) of the value, 0 if the value
- is not set.
- */
- Value::AutoPtr getValue() const
- { return value_.get() == 0 ? Value::AutoPtr(0) : value_->clone(); }
- /*!
- @brief Return a constant reference to the value.
-
- This method is provided mostly for convenient and versatile output of
- the value which can (to some extent) be formatted through standard
- stream manipulators. Do not attempt to write to the value through
- this reference.
-
- <b>Example:</b> <br>
- @code
- ExifData::const_iterator i = exifData.findKey(key);
- if (i != exifData.end()) {
- std::cout << i->key() << " " << std::hex << i->value() << "\n";
- }
- @endcode
-
- @return A constant reference to the value.
- @throw Error if the value is not set.
- */
- const Value& value() const;
- //! Return the size of the data area.
- long sizeDataArea() const
- { return value_.get() == 0 ? 0 : value_->sizeDataArea(); }
- /*!
- @brief Return a copy of the data area of the value. The caller owns
- this copy and %DataBuf ensures that it will be deleted.
-
- Values may have a data area, which can contain additional
- information besides the actual value. This method is used to access
- such a data area.
-
- @return A %DataBuf containing a copy of the data area or an empty
- %DataBuf if the value does not have a data area assigned or the
- value is not set.
- */
- DataBuf dataArea() const
- { return value_.get() == 0 ? DataBuf(0, 0) : value_->dataArea(); }
-
- //@}
-
- private:
- // DATA
- ExifKey::AutoPtr key_; //!< Key
- Value::AutoPtr value_; //!< Value
-
- }; // class Exifdatum
-
- /*!
- @brief Output operator for Exifdatum types, prints the interpreted
- tag value.
- */
- std::ostream& operator<<(std::ostream& os, const Exifdatum& md);
-
- /*!
- @brief Set the value of \em exifDatum to \em value. If the object already
- has a value, it is replaced. Otherwise a new ValueType\<T\> value
- is created and set to \em value.
-
- This is a helper function, called from Exifdatum members. It is meant to
- be used with T = (u)int16_t, (u)int32_t or (U)Rational. Do not use directly.
- */
- template<typename T>
- Exifdatum& setValue(Exifdatum& exifDatum, const T& value);
-
- /*!
- @brief Exif %Thumbnail image. This abstract base class provides the
- interface for the thumbnail image that is optionally embedded in
- the Exif data. This class is used internally by ExifData, it is
- probably not useful for a client as a standalone class. Instead,
- use an instance of ExifData to access the Exif thumbnail image.
- */
- class Thumbnail {
- public:
- //! Shortcut for a %Thumbnail auto pointer.
- typedef std::auto_ptr<Thumbnail> AutoPtr;
-
- //! @name Creators
- //@{
- //! Virtual destructor
- virtual ~Thumbnail() {}
- //@}
-
- //! @name Accessors
- //@{
- /*!
- @brief Set the image data as data area of the appropriate Exif
- metadatum. Read the thumbnail image data from data buffer
- \em buf. Return 0 if successful.
-
- @param exifData Exif data corresponding to the data buffer.
- @param pIfd1 Corresponding raw IFD1.
- @param buf Data buffer containing the thumbnail data. The buffer must
- start with the TIFF header.
- @param len Number of bytes in the data buffer.
- @return 0 if successful;<BR>
- 1 in case of inconsistent thumbnail Exif data; or<BR>
- 2 if the data area is outside of the data buffer
- */
- virtual int setDataArea(ExifData& exifData,
- Ifd* pIfd1,
- const byte* buf,
- long len) const =0;
- /*!
- @brief Return the thumbnail image in a %DataBuf. The caller owns the
- data buffer and %DataBuf ensures that it will be deleted.
- */
- virtual DataBuf copy(const ExifData& exifData) const =0;
- /*!
- @brief Return a short string for the format of the thumbnail
- ("TIFF", "JPEG").
- */
- virtual const char* format() const =0;
- /*!
- @brief Return the file extension for the format of the thumbnail
- (".tif", ".jpg").
- */
- virtual const char* extension() const =0;
- //@}
-
- protected:
- //! @name Manipulators
- //@{
- /*!
- @brief Assignment operator. Protected so that it can only be used
- by subclasses but not directly.
- */
- Thumbnail& operator=(const Thumbnail& rhs);
- //@}
-
- }; // class Thumbnail
-
- //! Exif thumbnail image in TIFF format
- class TiffThumbnail : public Thumbnail {
- public:
- //! Shortcut for a %TiffThumbnail auto pointer.
- typedef std::auto_ptr<TiffThumbnail> AutoPtr;
-
- //! @name Manipulators
- //@{
- //! Assignment operator.
- TiffThumbnail& operator=(const TiffThumbnail& rhs) { return *this; }
- //@}
-
- //! @name Accessors
- //@{
- int setDataArea(ExifData& exifData,
- Ifd* pIfd1,
- const byte* buf,
- long len) const;
- DataBuf copy(const ExifData& exifData) const;
- const char* format() const;
- const char* extension() const;
- //@}
-
- }; // class TiffThumbnail
-
- //! Exif thumbnail image in JPEG format
- class JpegThumbnail : public Thumbnail {
- public:
- //! Shortcut for a %JpegThumbnail auto pointer.
- typedef std::auto_ptr<JpegThumbnail> AutoPtr;
-
- //! @name Manipulators
- //@{
- //! Assignment operator.
- JpegThumbnail& operator=(const JpegThumbnail& rhs) { return *this; }
- //@}
-
- //! @name Accessors
- //@{
- int setDataArea(ExifData& exifData,
- Ifd* pIfd1,
- const byte* buf,
- long len) const;
- DataBuf copy(const ExifData& exifData) const;
- const char* format() const;
- const char* extension() const;
- //@}
-
- }; // class JpegThumbnail
-
- //! Container type to hold all metadata
- typedef std::vector<Exifdatum> ExifMetadata;
-
- //! Unary predicate that matches a Exifdatum with a given ifd id and idx
- class FindMetadatumByIfdIdIdx {
- public:
- //! Constructor, initializes the object with the ifd id and idx to look for
- FindMetadatumByIfdIdIdx(IfdId ifdId, int idx)
- : ifdId_(ifdId), idx_(idx) {}
- /*!
- @brief Returns true if the ifd id and idx of the argument
- \em exifdatum is equal to that of the object.
- */
- bool operator()(const Exifdatum& exifdatum) const
- { return ifdId_ == exifdatum.ifdId() && idx_ == exifdatum.idx(); }
-
- private:
- IfdId ifdId_;
- int idx_;
-
- }; // class FindMetadatumByIfdIdIdx
-
- /*!
- @brief A container for Exif data. This is a top-level class of the %Exiv2
- library. The container holds Exifdatum objects.
-
- Provide high-level access to the Exif data of an image:
- - read Exif information from JPEG files
- - access metadata through keys and standard C++ iterators
- - add, modify and delete metadata
- - write Exif data to JPEG files
- - extract Exif metadata to files, insert from these files
- - extract and delete Exif thumbnail (JPEG and TIFF thumbnails)
- */
- class ExifData {
- public:
- //! ExifMetadata iterator type
- typedef ExifMetadata::iterator iterator;
- //! ExifMetadata const iterator type
- typedef ExifMetadata::const_iterator const_iterator;
-
- //! @name Creators
- //@{
- //! Default constructor
- ExifData();
- //! Copy constructor (Todo: copy image data also)
- ExifData(const ExifData& rhs);
- //! Destructor
- ~ExifData();
- //@}
-
- //! @name Manipulators
- //@{
- //! Assignment operator (Todo: assign image data also)
- ExifData& operator=(const ExifData& rhs);
- /*!
- @brief Load the Exif data from a byte buffer. The data buffer
- must start with the TIFF header.
- @param buf Pointer to the data buffer to read from
- @param len Number of bytes in the data buffer
- @return 0 if successful.
- */
- int load(const byte* buf, long len);
- /*!
- @brief Write the Exif data to a data buffer, which is returned. The
- caller owns this copy and %DataBuf ensures that it will be
- deleted. The copied data starts with the TIFF header.
-
- Tries to update the original data buffer and write it back with
- minimal changes, in a 'non-intrusive' fashion, if possible. In this
- case, tag data that ExifData does not understand stand a good chance
- to remain valid. (In particular, if the Exif data contains a
- Makernote in IFD format, the offsets in its IFD will remain valid.)
- <BR>
- If 'non-intrusive' writing is not possible, the Exif data will be
- re-built from scratch, in which case the absolute position of the
- metadata entries within the data buffer may (and in most cases will)
- be different from their original position. Furthermore, in this case,
- the Exif data is updated with the metadata from the actual thumbnail
- image (overriding existing metadata).
-
- @return A %DataBuf containing the Exif data.
- */
- DataBuf copy();
- /*!
- @brief Returns a reference to the %Exifdatum that is associated with a
- particular \em key. If %ExifData does not already contain such
- an %Exifdatum, operator[] adds object \em Exifdatum(key).
-
- @note Since operator[] might insert a new element, it can't be a const
- member function.
- */
- Exifdatum& operator[](const std::string& key);
- /*!
- @brief Add all (IFD) entries in the range from iterator position begin
- to iterator position end to the Exif metadata. No duplicate
- checks are performed, i.e., it is possible to add multiple
- metadata with the same key.
- */
- void add(Entries::const_iterator begin,
- Entries::const_iterator end,
- ByteOrder byteOrder);
- /*!
- @brief Add an Exifdatum from the supplied key and value pair. This
- method copies (clones) key and value. No duplicate checks are
- performed, i.e., it is possible to add multiple metadata with
- the same key.
- */
- void add(const ExifKey& key, const Value* pValue);
- /*!
- @brief Add a copy of the \em exifdatum to the Exif metadata. No
- duplicate checks are performed, i.e., it is possible to add
- multiple metadata with the same key.
-
- @throw Error if the makernote cannot be created
- */
- void add(const Exifdatum& exifdatum);
- /*!
- @brief Delete the Exifdatum at iterator position \em pos, return the
- position of the next exifdatum. Note that iterators into
- the metadata, including \em pos, are potentially invalidated
- by this call.
- */
- iterator erase(iterator pos);
- /*!
- @brief Delete all Exifdatum instances resulting in an empty container.
- Note that this also removes thumbnails.
- */
- void clear() { eraseThumbnail(); exifMetadata_.clear(); }
- //! Sort metadata by key
- void sortByKey();
- //! Sort metadata by tag
- void sortByTag();
- //! Begin of the metadata
- iterator begin() { return exifMetadata_.begin(); }
- //! End of the metadata
- iterator end() { return exifMetadata_.end(); }
- /*!
- @brief Find a Exifdatum with the given \em key, return an iterator to
- it. If multiple metadata with the same key exist, it is
- undefined which of the matching metadata is found.
- */
- iterator findKey(const ExifKey& key);
- /*!
- @brief Find the Exifdatum with the given \em ifdId and \em idx,
- return an iterator to it.
-
- This method can be used to uniquely identify an exifdatum that was
- created from an IFD or from the makernote (with idx greater than
- 0). Metadata created by an application (not read from an IFD or a
- makernote) all have their idx field set to 0, i.e., they cannot be
- uniquely identified with this method. If multiple metadata with the
- same key exist, it is undefined which of the matching metadata is
- found.
- */
- iterator findIfdIdIdx(IfdId ifdId, int idx);
- /*!
- @brief Set the Exif thumbnail to the Jpeg image \em path. Set
- XResolution, YResolution and ResolutionUnit to \em xres,
- \em yres and \em unit, respectively.
-
- This results in the minimal thumbnail tags being set for a Jpeg
- thumbnail, as mandated by the Exif standard.
-
- @throw Error if reading the file fails.
-
- @note No checks on the file format or size are performed.
- @note Additional existing Exif thumbnail tags are not modified.
- @note The Jpeg image inserted as thumbnail image should not
- itself contain Exif data (or other metadata), as existing
- applications may have problems with that. (The preview
- application that comes with OS X for one.) - David Harvey.
- */
- void setJpegThumbnail(const std::string& path,
- URational xres, URational yres, uint16_t unit);
- /*!
- @brief Set the Exif thumbnail to the Jpeg image pointed to by \em buf,
- and size \em size. Set XResolution, YResolution and
- ResolutionUnit to \em xres, \em yres and \em unit, respectively.
-
- This results in the minimal thumbnail tags being set for a Jpeg
- thumbnail, as mandated by the Exif standard.
-
- @throw Error if reading the file fails.
-
- @note No checks on the image format or size are performed.
- @note Additional existing Exif thumbnail tags are not modified.
- @note The Jpeg image inserted as thumbnail image should not
- itself contain Exif data (or other metadata), as existing
- applications may have problems with that. (The preview
- application that comes with OS X for one.) - David Harvey.
- */
- void setJpegThumbnail(const byte* buf, long size,
- URational xres, URational yres, uint16_t unit);
- /*!
- @brief Set the Exif thumbnail to the Jpeg image \em path.
-
- This sets only the Compression, JPEGInterchangeFormat and
- JPEGInterchangeFormatLength tags, which is not all the thumbnail
- Exif information mandatory according to the Exif standard. (But it's
- enough to work with the thumbnail.)
-
- @throw Error if reading the file fails.
-
- @note No checks on the file format or size are performed.
- @note Additional existing Exif thumbnail tags are not modified.
- */
- void setJpegThumbnail(const std::string& path);
- /*!
- @brief Set the Exif thumbnail to the Jpeg image pointed to by \em buf,
- and size \em size.
-
- This sets only the Compression, JPEGInterchangeFormat and
- JPEGInterchangeFormatLength tags, which is not all the thumbnail
- Exif information mandatory according to the Exif standard. (But it's
- enough to work with the thumbnail.)
-
- @note No checks on the image format or size are performed.
- @note Additional existing Exif thumbnail tags are not modified.
- */
- void setJpegThumbnail(const byte* buf, long size);
- /*!
- @brief Delete the thumbnail from the Exif data. Removes all
- Exif.%Thumbnail.*, i.e., IFD1 metadata.
-
- @return The number of bytes of thumbnail data erased from the original
- Exif data. Note that the original image size may differ from
- the size of the image after deleting the thumbnail by more
- than this number. This is the case if the Exif data contains
- extra bytes (often at the end of the Exif block) or gaps and
- the thumbnail is not located at the end of the Exif block so
- that non-intrusive writing of a truncated Exif block is not
- possible. Instead it is in this case necessary to write the
- Exif data, without the thumbnail, from the metadata and all
- extra bytes and gaps are lost, resulting in a smaller image.
- */
- long eraseThumbnail();
- //@}
-
- //! @name Accessors
- //@{
- //! Begin of the metadata
- const_iterator begin() const { return exifMetadata_.begin(); }
- //! End of the metadata
- const_iterator end() const { return exifMetadata_.end(); }
- /*!
- @brief Find an exifdatum with the given \em key, return a const
- iterator to it. If multiple metadata with the same key exist,
- it is undefined which of the matching metadata is found.
- */
- const_iterator findKey(const ExifKey& key) const;
- /*!
- @brief Find the exifdatum with the given \em ifdId and \em idx,
- return an iterator to it.
-
- This method can be used to uniquely identify a Exifdatum that was
- created from an IFD or from the makernote (with idx greater than
- 0). Metadata created by an application (not read from an IFD or a
- makernote) all have their idx field set to 0, i.e., they cannot be
- uniquely identified with this method. If multiple metadata with the
- same key exist, it is undefined which of the matching metadata is
- found.
- */
- const_iterator findIfdIdIdx(IfdId ifdId, int idx) const;
- //! Return true if there is no Exif metadata
- bool empty() const { return count() == 0; }
- //! Get the number of metadata entries
- long count() const { return static_cast<long>(exifMetadata_.size()); }
- /*!
- @brief Returns the byte order. Default is little endian.
- */
- ByteOrder byteOrder() const;
- /*!
- @brief Write the thumbnail image to a file. A filename extension
- is appended to \em path according to the image type of the
- thumbnail, so \em path should not include an extension.
- This will overwrite an existing file of the same name.
-
- @param path Path of the filename without image type extension
-
- @throw Error if writing to the file fails.
-
- @return 0 if successful;<BR>
- 8 if the Exif data does not contain a thumbnail.
- */
- int writeThumbnail(const std::string& path) const;
- /*!
- @brief Return the thumbnail image in a %DataBuf. The caller owns the
- data buffer and %DataBuf ensures that it will be deleted.
- */
- DataBuf copyThumbnail() const;
- /*!
- @brief Return a short string describing the format of the Exif
- thumbnail ("TIFF", "JPEG").
- */
- const char* thumbnailFormat() const;
- /*!
- @brief Return the file extension for the Exif thumbnail depending
- on the format (".tif", ".jpg").
- */
- const char* thumbnailExtension() const;
- /*!
- @brief Return a thumbnail object of the correct type, corresponding to
- the current Exif data. Caller owns this object and the auto
- pointer ensures that it will be deleted.
- */
- Thumbnail::AutoPtr getThumbnail() const;
- //@}
-
- private:
- //! @name Manipulators
- //@{
- /*!
- @brief Read the thumbnail from the data buffer. Assigns the thumbnail
- data area with the appropriate Exif tags. Return 0 if successful,
- i.e., if there is a thumbnail.
- */
- int readThumbnail();
- /*!
- @brief Check if the metadata changed and update the internal IFDs and
- the MakerNote if the changes are compatible with the existing
- data (non-intrusive write support).
-
- @return True if only compatible changes were detected in the metadata
- and the internal IFDs and MakerNote (and thus the data buffer)
- were updated successfully. Return false, if non-intrusive
- writing is not possible. The internal IFDs and the MakerNote
- (and thus the data buffer) may or may not be modified in this
- case.
- */
- bool updateEntries();
- /*!
- @brief Update the metadata for a range of entries. Called by
- updateEntries() for each of the internal IFDs and the MakerNote
- (if any).
- */
- bool updateRange(const Entries::iterator& begin,
- const Entries::iterator& end,
- ByteOrder byteOrder);
- /*!
- @brief Write the Exif data to a data buffer the hard way, return the
- data buffer. The caller owns this data buffer and %DataBuf
- ensures that it will be deleted.
-
- Rebuilds the Exif data from scratch, using the TIFF header, metadata
- container and thumbnail. In particular, the internal IFDs and the
- original data buffer are not used. Furthermore, this method updates
- the Exif data with the metadata from the actual thumbnail image
- (overriding existing metadata).
-
- @return A %DataBuf containing the Exif data.
- */
- DataBuf copyFromMetadata();
- //@}
-
- //! @name Accessors
- //@{
- /*!
- @brief Check if the metadata is compatible with the internal IFDs for
- non-intrusive writing. Return true if compatible, false if not.
-
- @note This function does not detect deleted metadata as incompatible,
- although the deletion of metadata is not (yet) a supported
- non-intrusive write operation.
- */
- bool compatible() const;
- /*!
- @brief Find the IFD or makernote entry corresponding to ifd id and idx.
-
- @return A pair of which the first part determines if a match was found
- and, if true, the second contains an iterator to the entry.
- */
- std::pair<bool, Entries::const_iterator>
- findEntry(IfdId ifdId, int idx) const;
- //! Return a pointer to the internal IFD identified by its IFD id
- const Ifd* getIfd(IfdId ifdId) const;
- /*!
- @brief Check if IFD1, the IFD1 data and thumbnail data are located at
- the end of the Exif data. Return true, if they are or if there
- is no thumbnail at all, else return false.
- */
- bool stdThumbPosition() const;
- //@}
-
- // DATA
- ExifMetadata exifMetadata_;
-
- // The pointers below are used only if Exif data is read from a
- // raw data buffer
- TiffHeader* pTiffHeader_; //! Pointer to the TIFF header
- Ifd* pIfd0_; //! Pointer to Ifd0
- Ifd* pExifIfd_; //! Pointer to ExifIfd
- Ifd* pIopIfd_; //! Pointer to IopIfd
- Ifd* pGpsIfd_; //! Pointer to GpsIfd
- Ifd* pIfd1_; //! Pointer to Ifd1
- MakerNote* pMakerNote_; //! Pointer to the MakerNote, if any
-
- long size_; //!< Size of the Exif raw data in bytes
- byte* pData_; //!< Exif raw data buffer
-
- /*!
- Can be set to false to indicate that non-intrusive writing is not
- possible. If it is true (the default), then the compatibility checks
- will be performed to determine which writing method to use.
- */
- bool compatible_;
-
- }; // class ExifData
-
-// *****************************************************************************
-// template, inline and free functions
-
- template<typename T>
- Exifdatum& setValue(Exifdatum& exifDatum, const T& value)
- {
- std::auto_ptr<ValueType<T> > v
- = std::auto_ptr<ValueType<T> >(new ValueType<T>);
- v->value_.push_back(value);
- exifDatum.value_ = v;
- return exifDatum;
- }
- /*!
- @brief Add all metadata in the range from iterator position begin to
- iterator position end, which have an IFD id matching that of the
- IFD to the list of directory entries of ifd. No duplicate checks
- are performed, i.e., it is possible to add multiple metadata with
- the same key to an IFD.
- */
- void addToIfd(Ifd& ifd,
- ExifMetadata::const_iterator begin,
- ExifMetadata::const_iterator end,
- ByteOrder byteOrder);
- /*!
- @brief Add the Exifdatum to the IFD. No duplicate checks are performed,
- i.e., it is possible to add multiple metadata with the same key to
- an IFD.
- */
- void addToIfd(Ifd& ifd, const Exifdatum& exifdatum, ByteOrder byteOrder);
- /*!
- @brief Add all metadata in the range from iterator position begin to
- iterator position end with IFD id 'makerIfd' to the list of
- makernote entries of the object pointed to be makerNote. No
- duplicate checks are performed, i.e., it is possible to add
- multiple metadata with the same key to a makernote.
- */
- void addToMakerNote(MakerNote* makerNote,
- ExifMetadata::const_iterator begin,
- ExifMetadata::const_iterator end,
- ByteOrder byteOrder);
- /*!
- @brief Add the Exifdatum to makerNote, encoded in byte order byteOrder.
- No duplicate checks are performed, i.e., it is possible to add
- multiple metadata with the same key to a makernote.
- */
- void addToMakerNote(MakerNote* makerNote,
- const Exifdatum& exifdatum,
- ByteOrder byteOrder);
-
-} // namespace Exiv2
-
-#endif // #ifndef EXIF_HPP_
diff --git a/src/plugins/exiv2/exifcomment.cpp b/src/plugins/exiv2/exifcomment.cpp
@@ -1,68 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- Abstract : Sample program showing how to set the Exif comment of an image,
- Exif.Photo.UserComment
-
- File: exifcomment.cpp
- Version : $Rev: 560 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History : 10-May-04, ahu: created
- 16-Jan-05, ahu: updated using CommentValue and operator trickery
- */
-// *****************************************************************************
-// included header files
-#include "image.hpp"
-#include "exif.hpp"
-#include <iostream>
-#include <iomanip>
-#include <cstring>
-#include <cassert>
-
-// *****************************************************************************
-// Main
-int main(int argc, char* const argv[])
-try {
-
- if (argc != 2) {
- std::cout << "Usage: " << argv[0] << " file\n";
- return 1;
- }
-
- Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]);
- assert (image.get() != 0);
- image->readMetadata();
- Exiv2::ExifData &exifData = image->exifData();
-
- /*
- Exiv2 uses a CommentValue for Exif user comments. The format of the
- comment string includes an optional charset specification at the beginning:
-
- [charset=["]Ascii|Jis|Unicode|Undefined["] ]comment
-
- Undefined is used as a default if the comment doesn't start with a charset
- definition.
-
- Following are a few examples of valid comments. The last one is written to
- the file.
- */
- exifData["Exif.Photo.UserComment"]
- = "charset=\"Unicode\" An Unicode Exif comment added with Exiv2";
- exifData["Exif.Photo.UserComment"]
- = "charset=\"Undefined\" An undefined Exif comment added with Exiv2";
- exifData["Exif.Photo.UserComment"]
- = "Another undefined Exif comment added with Exiv2";
- exifData["Exif.Photo.UserComment"]
- = "charset=Ascii An ASCII Exif comment added with Exiv2";
-
- std::cout << "Writing user comment '"
- << exifData["Exif.Photo.UserComment"]
- << "' back to the image\n";
-
- image->writeMetadata();
-
- return 0;
-}
-catch (Exiv2::AnyError& e) {
- std::cout << "Caught Exiv2 exception '" << e << "'\n";
- return -1;
-}
diff --git a/src/plugins/exiv2/exiv2extractor.cc b/src/plugins/exiv2/exiv2extractor.cc
@@ -32,9 +32,9 @@
#include "platform.h"
#include "extractor.h"
-#include "exif.hpp"
-#include "image.hpp"
-#include "futils.hpp"
+#include "exiv2/exif.hpp"
+#include "exiv2/image.hpp"
+#include "exiv2/futils.hpp"
#define WORKAROUND_905 1
#if WORKAROUND_905
diff --git a/src/plugins/exiv2/exv_conf.h b/src/plugins/exiv2/exv_conf.h
@@ -1,32 +0,0 @@
-#include "config.h"
-
-#define SUPPRESS_WARNINGS 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define EXV_HAVE_UNISTD_H HAVE_UNISTD_H
-
-#define EXV_HAVE_STDINT_H HAVE_STDINT_H
-
-/* Define to the address where bug reports for this package should be
- sent. */
-#define EXV_PACKAGE_BUGREPORT PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#define EXV_PACKAGE_NAME PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#define EXV_PACKAGE_STRING PACKAGE_STRING
-
-/* Define to the version of this package. */
-#define EXV_PACKAGE_VERSION PACKAGE_VERSION
-
-/* File path seperator */
-#define EXV_SEPERATOR_STR DIR_SEPARATOR_STR
-#define EXV_SEPERATOR_CHR DIR_SEPARATOR
-
-#if defined __CYGWIN32__ && !defined __CYGWIN__
- /* For backwards compatibility with Cygwin b19 and
- earlier, we define __CYGWIN__ here, so that
- we can rely on checking just for that macro. */
-#define __CYGWIN__ __CYGWIN32__
-#endif
diff --git a/src/plugins/exiv2/exv_msvc.h b/src/plugins/exiv2/exv_msvc.h
@@ -1,32 +0,0 @@
-#include "config.h"
-
-#define SUPPRESS_WARNINGS 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define EXV_HAVE_UNISTD_H HAVE_UNISTD_H
-
-#define EXV_HAVE_STDINT_H HAVE_STDINT_H
-
-/* Define to the address where bug reports for this package should be
- sent. */
-#define EXV_PACKAGE_BUGREPORT PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#define EXV_PACKAGE_NAME PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#define EXV_PACKAGE_STRING PACKAGE_STRING
-
-/* Define to the version of this package. */
-#define EXV_PACKAGE_VERSION PACKAGE_VERSION
-
-/* File path seperator */
-#define EXV_SEPERATOR_STR DIR_SEPARATOR_STR
-#define EXV_SEPERATOR_CHR DIR_SEPARATOR
-
-#if defined __CYGWIN32__ && !defined __CYGWIN__
- /* For backwards compatibility with Cygwin b19 and
- earlier, we define __CYGWIN__ here, so that
- we can rely on checking just for that macro. */
-#define __CYGWIN__ __CYGWIN32__
-#endif
diff --git a/src/plugins/exiv2/fujimn.cpp b/src/plugins/exiv2/fujimn.cpp
@@ -1,275 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: fujimn.cpp
- Version: $Rev: 600 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 18-Feb-04, ahu: created
- 07-Mar-04, ahu: isolated as a separate component
- Credits: Fujifilm MakerNote implemented according to the specification
- in "Appendix 4: Makernote of Fujifilm" of the document
- "Exif file format" by TsuruZoh Tachibanaya
- <http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html>
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: fujimn.cpp 600 2005-07-09 10:38:09Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "fujimn.hpp"
-#include "makernote.hpp"
-#include "value.hpp"
-
-// + standard includes
-#include <string>
-#include <sstream>
-#include <iomanip>
-#include <cassert>
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- //! @cond IGNORE
- FujiMakerNote::RegisterMn::RegisterMn()
- {
- MakerNoteFactory::registerMakerNote("FUJIFILM", "*", createFujiMakerNote);
- MakerNoteFactory::registerMakerNote(
- fujiIfdId, MakerNote::AutoPtr(new FujiMakerNote));
-
- ExifTags::registerMakerTagInfo(fujiIfdId, tagInfo_);
- }
- //! @endcond
-
- // Fujifilm MakerNote Tag Info
- const TagInfo FujiMakerNote::tagInfo_[] = {
- TagInfo(0x0000, "Version", "Fujifilm Makernote version", fujiIfdId, makerTags, undefined, printValue),
- TagInfo(0x1000, "Quality", "Image quality setting", fujiIfdId, makerTags, asciiString, printValue),
- TagInfo(0x1001, "Sharpness", "Sharpness setting", fujiIfdId, makerTags, unsignedShort, print0x1001),
- TagInfo(0x1002, "WhiteBalance", "White balance setting", fujiIfdId, makerTags, unsignedShort, print0x1002),
- TagInfo(0x1003, "Color", "Chroma saturation setting", fujiIfdId, makerTags, unsignedShort, print0x1003),
- TagInfo(0x1004, "Tone", "Contrast setting", fujiIfdId, makerTags, unsignedShort, print0x1004),
- TagInfo(0x1010, "FlashMode", "Flash firing mode setting", fujiIfdId, makerTags, unsignedShort, print0x1010),
- TagInfo(0x1011, "FlashStrength", "Flash firing strength compensation setting", fujiIfdId, makerTags, signedRational, printValue),
- TagInfo(0x1020, "Macro", "Macro mode setting", fujiIfdId, makerTags, unsignedShort, printOffOn),
- TagInfo(0x1021, "FocusMode", "Focusing mode setting", fujiIfdId, makerTags, unsignedShort, print0x1021),
- TagInfo(0x1022, "0x1022", "Unknown", fujiIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1030, "SlowSync", "Slow synchro mode setting", fujiIfdId, makerTags, unsignedShort, printOffOn),
- TagInfo(0x1031, "PictureMode", "Picture mode setting", fujiIfdId, makerTags, unsignedShort, print0x1031),
- TagInfo(0x1032, "0x1032", "Unknown", fujiIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1100, "Continuous", "Continuous shooting or auto bracketing setting", fujiIfdId, makerTags, unsignedShort, printOffOn),
- TagInfo(0x1101, "0x1101", "Unknown", fujiIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1200, "0x1200", "Unknown", fujiIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1300, "BlurWarning", "Blur warning status", fujiIfdId, makerTags, unsignedShort, printOffOn),
- TagInfo(0x1301, "FocusWarning", "Auto Focus warning status", fujiIfdId, makerTags, unsignedShort, printOffOn),
- TagInfo(0x1302, "AeWarning", "Auto Exposure warning status", fujiIfdId, makerTags, unsignedShort, printOffOn),
- // End of list marker
- TagInfo(0xffff, "(UnknownFujiMakerNoteTag)", "Unknown FujiMakerNote tag", fujiIfdId, makerTags, invalidTypeId, printValue)
- };
-
- FujiMakerNote::FujiMakerNote(bool alloc)
- : IfdMakerNote(fujiIfdId, alloc)
- {
- byteOrder_ = littleEndian;
- absOffset_ = false;
- byte buf[] = {
- 'F', 'U', 'J', 'I', 'F', 'I', 'L', 'M', 0x0c, 0x00, 0x00, 0x00
- };
- readHeader(buf, 12, byteOrder_);
- }
-
- FujiMakerNote::FujiMakerNote(const FujiMakerNote& rhs)
- : IfdMakerNote(rhs)
- {
- }
-
- int FujiMakerNote::readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder)
- {
- if (len < 12) return 1;
-
- header_.alloc(12);
- memcpy(header_.pData_, buf, header_.size_);
- // Read the offset relative to the start of the makernote from the header
- // Note: we ignore the byteOrder paramter
- adjOffset_ = getUShort(header_.pData_ + 8, byteOrder_);
- return 0;
- }
-
- int FujiMakerNote::checkHeader() const
- {
- int rc = 0;
- // Check the FUJIFILM prefix
- if ( header_.size_ < 12
- || std::string(reinterpret_cast<char*>(header_.pData_), 8)
- != std::string("FUJIFILM", 8)) {
- rc = 2;
- }
- return rc;
- }
-
- FujiMakerNote::AutoPtr FujiMakerNote::create(bool alloc) const
- {
- return AutoPtr(create_(alloc));
- }
-
- FujiMakerNote* FujiMakerNote::create_(bool alloc) const
- {
- AutoPtr makerNote = AutoPtr(new FujiMakerNote(alloc));
- assert(makerNote.get() != 0);
- makerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
- return makerNote.release();
- }
-
- FujiMakerNote::AutoPtr FujiMakerNote::clone() const
- {
- return AutoPtr(clone_());
- }
-
- FujiMakerNote* FujiMakerNote::clone_() const
- {
- return new FujiMakerNote(*this);
- }
-
- std::ostream& FujiMakerNote::printOffOn(std::ostream& os,
- const Value& value)
- {
- switch (value.toLong()) {
- case 0: os << "Off"; break;
- case 1: os << "On"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& FujiMakerNote::print0x1001(std::ostream& os,
- const Value& value)
- {
- switch (value.toLong()) {
- case 1: // fallthrough
- case 2: os << "Soft"; break;
- case 3: os << "Normal"; break;
- case 4: // fallthrough
- case 5: os << "Hard"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& FujiMakerNote::print0x1002(std::ostream& os,
- const Value& value)
- {
- switch (value.toLong()) {
- case 0: os << "Auto"; break;
- case 256: os << "Daylight"; break;
- case 512: os << "Cloudy"; break;
- case 768: os << "Fluorescent (daylight)"; break;
- case 769: os << "Fluorescent (warm white)"; break;
- case 770: os << "Fluorescent (cool white)"; break;
- case 1024: os << "Incandescent"; break;
- case 3480: os << "Custom"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& FujiMakerNote::print0x1003(std::ostream& os,
- const Value& value)
- {
- switch (value.toLong()) {
- case 0: os << "Standard"; break;
- case 256: os << "High"; break;
- case 512: os << "Original"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& FujiMakerNote::print0x1004(std::ostream& os,
- const Value& value)
- {
- switch (value.toLong()) {
- case 0: os << "Standard"; break;
- case 256: os << "Hard"; break;
- case 512: os << "Original"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& FujiMakerNote::print0x1010(std::ostream& os,
- const Value& value)
- {
- switch (value.toLong()) {
- case 0: os << "Auto"; break;
- case 1: os << "On"; break;
- case 2: os << "Off"; break;
- case 3: os << "Red-eye"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& FujiMakerNote::print0x1021(std::ostream& os,
- const Value& value)
- {
- switch (value.toLong()) {
- case 0: os << "Auto"; break;
- case 1: os << "Manual"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& FujiMakerNote::print0x1031(std::ostream& os,
- const Value& value)
- {
- switch (value.toLong()) {
- case 0: os << "Auto"; break;
- case 1: os << "Portrait"; break;
- case 2: os << "Landscape"; break;
- case 4: os << "Sports"; break;
- case 5: os << "Night"; break;
- case 6: os << "Program"; break;
- case 256: os << "Aperture priority"; break;
- case 512: os << "Shutter priority"; break;
- case 768: os << "Manual"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
-// *****************************************************************************
-// free functions
-
- MakerNote::AutoPtr createFujiMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset)
- {
- return MakerNote::AutoPtr(new FujiMakerNote(alloc));
- }
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/fujimn.hpp b/src/plugins/exiv2/fujimn.hpp
@@ -1,162 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file fujimn.hpp
- @brief Fujifilm MakerNote implemented according to the specification
- in Appendix 4: Makernote of Fujifilm of the document
- <a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html">
- Exif file format</a> by TsuruZoh Tachibanaya
- @version $Rev: 569 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 11-Feb-04, ahu: created
- */
-#ifndef FUJIMN_HPP_
-#define FUJIMN_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "makernote.hpp"
-#include "tags.hpp"
-
-// + standard includes
-#include <string>
-#include <iosfwd>
-#include <memory>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class declarations
- class Value;
-
-// *****************************************************************************
-// free functions
-
- /*!
- @brief Return an auto-pointer to a newly created empty MakerNote
- initialized to operate in the memory management model indicated.
- The caller owns this copy and the auto-pointer ensures that it
- will be deleted.
-
- @param alloc Memory management model for the new MakerNote. Determines if
- memory required to store data should be allocated and deallocated
- (true) or not (false). If false, only pointers to the buffer
- provided to read() will be kept. See Ifd for more background on
- this concept.
- @param buf Pointer to the makernote character buffer (not used).
- @param len Length of the makernote character buffer (not used).
- @param byteOrder Byte order in which the Exif data (and possibly the
- makernote) is encoded (not used).
- @param offset Offset from the start of the TIFF header of the makernote
- buffer (not used).
-
- @return An auto-pointer to a newly created empty MakerNote. The caller
- owns this copy and the auto-pointer ensures that it will be
- deleted.
- */
- MakerNote::AutoPtr createFujiMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset);
-
-// *****************************************************************************
-// class definitions
-
- //! MakerNote for Fujifilm cameras
- class FujiMakerNote : public IfdMakerNote {
- public:
- //! Shortcut for a %FujiMakerNote auto pointer.
- typedef std::auto_ptr<FujiMakerNote> AutoPtr;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor. Allows to choose whether or not memory management
- is required for the makernote entries.
- */
- FujiMakerNote(bool alloc =true);
- //! Copy constructor
- FujiMakerNote(const FujiMakerNote& rhs);
- //! Virtual destructor
- virtual ~FujiMakerNote() {}
- //@}
-
- //! @name Manipulators
- //@{
- int readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder);
- //@}
-
- //! @name Accessors
- //@{
- int checkHeader() const;
- AutoPtr create(bool alloc =true) const;
- AutoPtr clone() const;
- //@}
-
- //! @name Print functions for Fujifilm %MakerNote tags
- //@{
- //! Print Off or On status
- static std::ostream& printOffOn(std::ostream& os, const Value& value);
- //! Print sharpness
- static std::ostream& print0x1001(std::ostream& os, const Value& value);
- //! Print white balance
- static std::ostream& print0x1002(std::ostream& os, const Value& value);
- //! Print color
- static std::ostream& print0x1003(std::ostream& os, const Value& value);
- //! Print tone
- static std::ostream& print0x1004(std::ostream& os, const Value& value);
- //! Print flash mode
- static std::ostream& print0x1010(std::ostream& os, const Value& value);
- //! Print focus mode
- static std::ostream& print0x1021(std::ostream& os, const Value& value);
- //! Print picture mode
- static std::ostream& print0x1031(std::ostream& os, const Value& value);
- //@}
-
- //! @cond IGNORE
- // Public only so that we can create a static instance
- struct RegisterMn {
- RegisterMn();
- };
- //! @endcond
-
- private:
- //! Internal virtual create function.
- FujiMakerNote* create_(bool alloc =true) const;
- //! Internal virtual copy constructor.
- FujiMakerNote* clone_() const;
-
- //! Tag information
- static const TagInfo tagInfo_[];
-
- }; // class FujiMakerNote
-
- static FujiMakerNote::RegisterMn registerFujiMakerNote;
-} // namespace Exiv2
-
-#endif // #ifndef FUJIMN_HPP_
diff --git a/src/plugins/exiv2/futils.cpp b/src/plugins/exiv2/futils.cpp
@@ -1,78 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: utils.cpp
- Version: $Rev: 560 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 08-Dec-03, ahu: created
- 02-Apr-05, ahu: moved to Exiv2 namespace
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: futils.cpp 560 2005-04-17 11:51:32Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#ifdef _MSC_VER
-# include "exv_msvc.h"
-#else
-# include "exv_conf.h"
-#endif
-
-#include "futils.hpp"
-
-// + standard includes
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef _MSC_VER
-# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#endif
-#ifdef EXV_HAVE_UNISTD_H
-# include <unistd.h> // for stat()
-#endif
-
-#include <cerrno>
-#include <cstring>
-#include <sstream>
-
-namespace Exiv2 {
-
-// *****************************************************************************
-// free functions
-
- bool fileExists(const std::string& path, bool ct)
- {
- struct stat buf;
- int ret = stat(path.c_str(), &buf);
- if (0 != ret) return false;
- if (ct && !S_ISREG(buf.st_mode)) return false;
- return true;
- } // fileExists
-
- std::string strError()
- {
- int error = errno;
- std::ostringstream os;
- os << strerror(error) << " (" << error << ")";
- return os.str();
- } // strError
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/futils.hpp b/src/plugins/exiv2/futils.hpp
@@ -1,66 +0,0 @@
-// ********************************************************* -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file futils.hpp
- @brief Basic file utility functions required by Exiv2
- @version $Rev: 560 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 12-Dec-03, ahu: created<BR>
- 02-Apr-05, ahu: moved to Exiv2 namespace
- */
-#ifndef FUTILS_HPP_
-#define FUTILS_HPP_
-
-// *********************************************************************
-// included header files
-// + standard includes
-#include <string>
-
-// *********************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *********************************************************************
-// free functions
-
- /*!
- @brief Test if a file exists.
-
- @param path Name of file to verify.
- @param ct Flag to check if <i>path</i> is a regular file.
- @return true if <i>path</i> exists and, if <i>ct</i> is set,
- is a regular file, else false.
-
- @note The function calls <b>stat()</b> test for <i>path</i>
- and its type, see stat(2). <b>errno</b> is left unchanged
- in case of an error.
- */
- bool fileExists(const std::string& path, bool ct =false);
- /*!
- @brief Return a system error message and the error code (errno).
- See %strerror(3).
- */
- std::string strError();
-
-} // namespace Exiv2
-
-#endif // #ifndef FUTILS_HPP_
diff --git a/src/plugins/exiv2/ifd.cpp b/src/plugins/exiv2/ifd.cpp
@@ -1,723 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: ifd.cpp
- Version: $Rev: 600 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 26-Jan-04, ahu: created
- 11-Feb-04, ahu: isolated as a component
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: ifd.cpp 600 2005-07-09 10:38:09Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "ifd.hpp"
-#include "types.hpp"
-#include "error.hpp"
-#include "tags.hpp" // for ExifTags::ifdName
-
-// + standard includes
-#include <iostream>
-#include <iomanip>
-#include <sstream>
-#include <vector>
-#include <algorithm>
-#include <cstring>
-#include <cassert>
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- Entry::Entry(bool alloc)
- : alloc_(alloc), ifdId_(ifdIdNotSet), idx_(0),
- tag_(0), type_(0), count_(0), offset_(0), size_(0), pData_(0),
- sizeDataArea_(0), pDataArea_(0)
- {
- }
-
- Entry::~Entry()
- {
- if (alloc_) {
- delete[] pData_;
- delete[] pDataArea_;
- }
- }
-
- Entry::Entry(const Entry& rhs)
- : alloc_(rhs.alloc_), ifdId_(rhs.ifdId_), idx_(rhs.idx_),
- tag_(rhs.tag_), type_(rhs.type_),
- count_(rhs.count_), offset_(rhs.offset_), size_(rhs.size_), pData_(0),
- sizeDataArea_(rhs.sizeDataArea_), pDataArea_(0)
- {
- if (alloc_) {
- if (rhs.pData_) {
- pData_ = new byte[rhs.size()];
- memcpy(pData_, rhs.pData_, rhs.size());
- }
- if (rhs.pDataArea_) {
- pDataArea_ = new byte[rhs.sizeDataArea()];
- memcpy(pDataArea_, rhs.pDataArea_, rhs.sizeDataArea());
- }
- }
- else {
- pData_ = rhs.pData_;
- pDataArea_ = rhs.pDataArea_;
- }
- }
-
- Entry& Entry::operator=(const Entry& rhs)
- {
- if (this == &rhs) return *this;
- alloc_ = rhs.alloc_;
- ifdId_ = rhs.ifdId_;
- idx_ = rhs.idx_;
- tag_ = rhs.tag_;
- type_ = rhs.type_;
- count_ = rhs.count_;
- offset_ = rhs.offset_;
- size_ = rhs.size_;
- sizeDataArea_ = rhs.sizeDataArea_;
- if (alloc_) {
- delete[] pData_;
- pData_ = 0;
- if (rhs.pData_) {
- pData_ = new byte[rhs.size()];
- memcpy(pData_, rhs.pData_, rhs.size());
- }
- delete[] pDataArea_;
- pDataArea_ = 0;
- if (rhs.pDataArea_) {
- pDataArea_ = new byte[rhs.sizeDataArea()];
- memcpy(pDataArea_, rhs.pDataArea_, rhs.sizeDataArea());
- }
- }
- else {
- pData_ = rhs.pData_;
- pDataArea_ = rhs.pDataArea_;
- }
- return *this;
- } // Entry::operator=
-
- void Entry::setValue(uint32_t data, ByteOrder byteOrder)
- {
- if (pData_ == 0 || size_ < 4) {
- assert(alloc_);
- size_ = 4;
- delete[] pData_;
- pData_ = new byte[size_];
- }
- ul2Data(pData_, data, byteOrder);
- // do not change size_
- type_ = unsignedLong;
- count_ = 1;
- }
-
- void Entry::setValue(uint16_t type, uint32_t count, const byte* buf, long len)
- {
- long dataSize = count * TypeInfo::typeSize(TypeId(type));
- // No minimum size requirement, but make sure the buffer can hold the data
- if (len < dataSize) throw Error(24, tag(), dataSize, len);
- if (alloc_) {
- delete[] pData_;
- pData_ = new byte[len];
- memset(pData_, 0x0, len);
- memcpy(pData_, buf, dataSize);
- size_ = len;
- }
- else {
- if (size_ == 0) {
- // Set the data pointer of a virgin entry
- pData_ = const_cast<byte*>(buf);
- size_ = len;
- }
- else {
- // Overwrite existing data if it fits into the buffer
- if (size_ < dataSize) throw Error(24, tag(), dataSize, size_);
- memset(pData_, 0x0, size_);
- memcpy(pData_, buf, dataSize);
- // do not change size_
- }
- }
- type_ = type;
- count_ = count;
- } // Entry::setValue
-
- void Entry::setDataArea(const byte* buf, long len)
- {
- if (alloc_) {
- delete[] pDataArea_;
- pDataArea_ = new byte[len];
- memcpy(pDataArea_, buf, len);
- sizeDataArea_ = len;
- }
- else {
- if (sizeDataArea_ == 0) {
- // Set the data area pointer of a virgin entry
- pDataArea_ = const_cast<byte*>(buf);
- sizeDataArea_ = len;
- }
- else {
- // Overwrite existing data if it fits into the buffer
- if (sizeDataArea_ < len) {
- throw Error(25, tag(), sizeDataArea_, len);
- }
- memset(pDataArea_, 0x0, sizeDataArea_);
- memcpy(pDataArea_, buf, len);
- // do not change sizeDataArea_
- }
- }
- } // Entry::setDataArea
-
- void Entry::setDataAreaOffsets(uint32_t offset, ByteOrder byteOrder)
- {
- for (uint32_t i = 0; i < count(); ++i) {
- byte* buf = pData_ + i * typeSize();
- switch(TypeId(type())) {
- case unsignedShort: {
- uint16_t d = getUShort(buf, byteOrder);
- if (d + offset > 0xffff) throw Error(26);
- us2Data(buf, d + static_cast<uint16_t>(offset), byteOrder);
- break;
- }
- case unsignedLong: {
- ul2Data(buf, getULong(buf, byteOrder) + offset, byteOrder);
- break;
- }
- case unsignedRational: {
- URational d = getURational(buf, byteOrder);
- d.first = d.first + offset * d.second;
- ur2Data(buf, d, byteOrder);
- break;
- }
- case signedShort: {
- int16_t d = getShort(buf, byteOrder);
- if (d + static_cast<int32_t>(offset) > 0xffff) throw Error(26);
- s2Data(buf, d + static_cast<int16_t>(offset), byteOrder);
- break;
- }
- case signedLong: {
- int32_t d = getLong(buf, byteOrder);
- l2Data(buf, d + static_cast<int32_t>(offset), byteOrder);
- break;
- }
- case signedRational: {
- Rational d = getRational(buf, byteOrder);
- d.first = d.first + static_cast<int32_t>(offset) * d.second;
- r2Data(buf, d, byteOrder);
- break;
- }
- default:
- throw Error(27);
- break;
- }
- }
- } // Entry::setDataAreaOffsets
-
- void Entry::updateBase(byte* pOldBase, byte* pNewBase)
- {
- if (!alloc_) {
- if (pDataArea_) {
- pDataArea_ = pDataArea_ - pOldBase + pNewBase;
- }
- if (pData_) {
- pData_ = pData_ - pOldBase + pNewBase;
- }
- }
- } // Entry::updateBase
-
- const byte* Entry::component(uint32_t n) const
- {
- if (n >= count()) return 0;
- return data() + n * typeSize();
- } // Entry::component
-
- Ifd::Ifd(IfdId ifdId)
- : alloc_(true), ifdId_(ifdId), pBase_(0), offset_(0),
- dataOffset_(0), hasNext_(true), pNext_(0), next_(0)
- {
- pNext_ = new byte[4];
- memset(pNext_, 0x0, 4);
- }
-
- Ifd::Ifd(IfdId ifdId, long offset)
- : alloc_(true), ifdId_(ifdId), pBase_(0), offset_(offset),
- dataOffset_(0), hasNext_(true), pNext_(0), next_(0)
- {
- pNext_ = new byte[4];
- memset(pNext_, 0x0, 4);
- }
-
- Ifd::Ifd(IfdId ifdId, long offset, bool alloc, bool hasNext)
- : alloc_(alloc), ifdId_(ifdId), pBase_(0), offset_(offset),
- dataOffset_(0), hasNext_(hasNext), pNext_(0), next_(0)
- {
- if (alloc_ && hasNext_) {
- pNext_ = new byte[4];
- memset(pNext_, 0x0, 4);
- }
- }
-
- Ifd::~Ifd()
- {
- // do not delete pBase_
- if (alloc_ && hasNext_) delete[] pNext_;
- }
-
- Ifd::Ifd(const Ifd& rhs)
- : alloc_(rhs.alloc_), entries_(rhs.entries_), ifdId_(rhs.ifdId_),
- pBase_(rhs.pBase_), offset_(rhs.offset_), dataOffset_(rhs.dataOffset_),
- hasNext_(rhs.hasNext_), pNext_(rhs.pNext_), next_(rhs.next_)
- {
- if (alloc_ && hasNext_) {
- pNext_ = new byte[4];
- memset(pNext_, 0x0, 4);
- if (rhs.pNext_) memcpy(pNext_, rhs.pNext_, 4);
- }
- }
-
- int Ifd::read(const byte* buf, long len, ByteOrder byteOrder, long offset)
- {
- // Todo: This is a hack to work around bug #424 - fix it properly!
- if (ifdId_ == olympusIfdId) len = 65535;
-
- int rc = 0;
- long o = 0;
- Ifd::PreEntries preEntries;
-
- if (len < 2) rc = 6;
- if (rc == 0) {
- offset_ = offset;
- int n = getUShort(buf, byteOrder);
- o = 2;
-
- for (int i = 0; i < n; ++i) {
- if (len < o + 12) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Error: " << ExifTags::ifdName(ifdId_)
- << " entry " << i
- << " lies outside of the IFD memory buffer.\n";
-#endif
- rc = 6;
- break;
- }
- Ifd::PreEntry pe;
- pe.tag_ = getUShort(buf + o, byteOrder);
- pe.type_ = getUShort(buf + o + 2, byteOrder);
- pe.count_ = getULong(buf + o + 4, byteOrder);
- pe.size_ = pe.count_ * TypeInfo::typeSize(TypeId(pe.type_));
- pe.offsetLoc_ = o + 8;
- pe.offset_ = pe.size_ > 4 ? getLong(buf + o + 8, byteOrder) : 0;
- preEntries.push_back(pe);
- o += 12;
- }
- }
- if (rc == 0 && hasNext_) {
- if (len < o + 4) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Error: " << ExifTags::ifdName(ifdId_)
- << " memory of the pointer to the next IFD"
- << " lies outside of the IFD memory buffer.\n";
-#endif
- rc = 6;
- }
- else {
- if (alloc_) {
- memcpy(pNext_, buf + o, 4);
- }
- else {
- pNext_ = const_cast<byte*>(buf + o);
- }
- next_ = getULong(buf + o, byteOrder);
- }
- }
- // Set the offset of the first data entry outside of the IFD.
- // At the same time we guess the offset of the IFD, if it was not
- // given. The guess is based on the assumption that the smallest offset
- // points to a data buffer directly following the IFD. Subsequently all
- // offsets of IFD entries will need to be recalculated.
- if (rc == 0 && preEntries.size() > 0) {
- // Find the entry with the smallest offset
- Ifd::PreEntries::const_iterator i = std::min_element(
- preEntries.begin(), preEntries.end(), cmpPreEntriesByOffset);
- // Only do something if there is at least one entry with data
- // outside the IFD directory itself.
- if (i->size_ > 4) {
- if (offset_ == 0) {
- // Set the 'guessed' IFD offset
- offset_ = i->offset_
- - (2 + 12 * static_cast<long>(preEntries.size())
- + (hasNext_ ? 4 : 0));
- }
- // Set the offset of the first data entry outside of the IFD
- if (i->offset_ - offset_ >= len) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Error: Offset of the 1st data entry of "
- << ExifTags::ifdName(ifdId_)
- << " is out of bounds:\n"
- << " Offset = 0x" << std::setw(8)
- << std::setfill('0') << std::hex
- << i->offset_ - offset_
- << ", exceeds buffer size by "
- << std::dec << i->offset_ - len
- << " Bytes\n";
-#endif
- rc = 6;
- }
- else {
- dataOffset_ = i->offset_;
- }
- }
- }
- // Convert the pre-IFD entries to the actual entries, assign the data
- // to each IFD entry and calculate relative offsets, relative to the
- // start of the IFD
- if (rc == 0) {
- entries_.clear();
- int idx = 0;
- const Ifd::PreEntries::iterator begin = preEntries.begin();
- const Ifd::PreEntries::iterator end = preEntries.end();
- for (Ifd::PreEntries::iterator i = begin; i != end; ++i) {
- Entry e(alloc_);
- e.setIfdId(ifdId_);
- e.setIdx(++idx);
- e.setTag(i->tag_);
- long tmpOffset =
- i->size_ > 4 ? i->offset_ - offset_ : i->offsetLoc_;
- if (tmpOffset + i->size_ > len) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Warning: Upper boundary of data for "
- << ExifTags::ifdName(ifdId_)
- << " entry " << static_cast<int>(i - begin)
- << " is out of bounds:\n"
- << " Offset = 0x" << std::setw(8)
- << std::setfill('0') << std::hex
- << tmpOffset
- << ", size = " << std::dec << i->size_
- << ", exceeds buffer size by "
- << tmpOffset + i->size_ - len
- << " Bytes; Truncating the data.\n";
-#endif
- // Truncate the entry
- i->size_ = 0;
- i->count_ = 0;
- tmpOffset = i->offsetLoc_;
- }
- // Set the offset to the data, relative to start of IFD
- e.setOffset(tmpOffset);
- // Set the size to at least for bytes to accomodate offset-data
- e.setValue(i->type_, i->count_, buf + e.offset(),
- std::max(long(4), i->size_));
- this->add(e);
- }
- }
- if (!alloc_) pBase_ = const_cast<byte*>(buf) - offset_;
- if (rc) this->clear();
-
- return rc;
- } // Ifd::read
-
- Ifd::const_iterator Ifd::findIdx(int idx) const
- {
- return std::find_if(entries_.begin(), entries_.end(),
- FindEntryByIdx(idx));
- }
-
- Ifd::iterator Ifd::findIdx(int idx)
- {
- return std::find_if(entries_.begin(), entries_.end(),
- FindEntryByIdx(idx));
- }
-
- Ifd::const_iterator Ifd::findTag(uint16_t tag) const
- {
- return std::find_if(entries_.begin(), entries_.end(),
- FindEntryByTag(tag));
- }
-
- Ifd::iterator Ifd::findTag(uint16_t tag)
- {
- return std::find_if(entries_.begin(), entries_.end(),
- FindEntryByTag(tag));
- }
-
- void Ifd::sortByTag()
- {
- std::sort(entries_.begin(), entries_.end(), cmpEntriesByTag);
- }
-
- int Ifd::readSubIfd(
- Ifd& dest, const byte* buf, long len, ByteOrder byteOrder, uint16_t tag
- ) const
- {
- int rc = 0;
- const_iterator pos = findTag(tag);
- if (pos != entries_.end()) {
- long offset = getULong(pos->data(), byteOrder);
- if (len < offset) {
- rc = 6;
- }
- else {
- rc = dest.read(buf + offset, len - offset, byteOrder, offset);
- }
- }
- return rc;
- } // Ifd::readSubIfd
-
- long Ifd::copy(byte* buf, ByteOrder byteOrder, long offset)
- {
- if (entries_.size() == 0 && next_ == 0) return 0;
- if (offset != 0) offset_ = offset;
-
- // Add the number of entries to the data buffer
- us2Data(buf, static_cast<uint16_t>(entries_.size()), byteOrder);
- long o = 2;
-
- // Add all directory entries to the data buffer
- long dataSize = 0;
- long dataAreaSize = 0;
- long totalDataSize = 0;
- const iterator b = entries_.begin();
- const iterator e = entries_.end();
- iterator i;
- for (i = b; i != e; ++i) {
- if (i->size() > 4) {
- totalDataSize += i->size();
- }
- }
- for (i = b; i != e; ++i) {
- us2Data(buf + o, i->tag(), byteOrder);
- us2Data(buf + o + 2, i->type(), byteOrder);
- ul2Data(buf + o + 4, i->count(), byteOrder);
- if (i->sizeDataArea() > 0) {
- long dataAreaOffset = offset_+size()+totalDataSize+dataAreaSize;
- i->setDataAreaOffsets(dataAreaOffset, byteOrder);
- dataAreaSize += i->sizeDataArea();
- }
- if (i->size() > 4) {
- // Set the offset of the entry, data immediately follows the IFD
- i->setOffset(size() + dataSize);
- l2Data(buf + o + 8, offset_ + i->offset(), byteOrder);
- dataSize += i->size();
- }
- else {
- // Copy data into the offset field
- memset(buf + o + 8, 0x0, 4);
- memcpy(buf + o + 8, i->data(), i->size());
- }
- o += 12;
- }
-
- if (hasNext_) {
- // Add the offset to the next IFD to the data buffer
- if (pNext_) {
- memcpy(buf + o, pNext_, 4);
- }
- else {
- memset(buf + o, 0x0, 4);
- }
- o += 4;
- }
-
- // Add the data of all IFD entries to the data buffer
- for (i = b; i != e; ++i) {
- if (i->size() > 4) {
- memcpy(buf + o, i->data(), i->size());
- o += i->size();
- }
- }
-
- // Add all data areas to the data buffer
- for (i = b; i != e; ++i) {
- if (i->sizeDataArea() > 0) {
- memcpy(buf + o, i->dataArea(), i->sizeDataArea());
- o += i->sizeDataArea();
- }
- }
-
- return o;
- } // Ifd::copy
-
- void Ifd::clear()
- {
- entries_.clear();
- offset_ = 0;
- dataOffset_ = 0;
- if (hasNext_) {
- if (alloc_) {
- memset(pNext_, 0x0, 4);
- }
- else {
- pBase_ = 0;
- pNext_ = 0;
- }
- next_ = 0;
- }
- } // Ifd::clear
-
- void Ifd::setNext(uint32_t next, ByteOrder byteOrder)
- {
- if (hasNext_) {
- assert(pNext_);
- ul2Data(pNext_, next, byteOrder);
- next_ = next;
- }
- }
-
- void Ifd::add(const Entry& entry)
- {
- assert(alloc_ == entry.alloc());
- assert(ifdId_ == entry.ifdId());
- // allow duplicates
- entries_.push_back(entry);
- }
-
- int Ifd::erase(uint16_t tag)
- {
- int idx = 0;
- iterator pos = findTag(tag);
- if (pos != end()) {
- idx = pos->idx();
- erase(pos);
- }
- return idx;
- }
-
- Ifd::iterator Ifd::erase(iterator pos)
- {
- return entries_.erase(pos);
- }
-
- byte* Ifd::updateBase(byte* pNewBase)
- {
- byte *pOld = 0;
- if (!alloc_) {
- iterator end = this->end();
- for (iterator pos = begin(); pos != end; ++pos) {
- pos->updateBase(pBase_, pNewBase);
- }
- if (hasNext_) {
- pNext_ = pNext_ - pBase_ + pNewBase;
- }
- pOld = pBase_;
- pBase_ = pNewBase;
- }
- return pOld;
- }
-
- long Ifd::size() const
- {
- if (entries_.size() == 0 && next_ == 0) return 0;
- return static_cast<long>(2 + 12 * entries_.size() + (hasNext_ ? 4 : 0));
- }
-
- long Ifd::dataSize() const
- {
- long dataSize = 0;
- const_iterator end = this->end();
- for (const_iterator i = begin(); i != end; ++i) {
- if (i->size() > 4) dataSize += i->size();
- dataSize += i->sizeDataArea();
- }
- return dataSize;
- }
-
- void Ifd::print(std::ostream& os, const std::string& prefix) const
- {
- if (entries_.size() == 0) return;
- // Print a header
- os << prefix << "IFD Offset: 0x"
- << std::setw(8) << std::setfill('0') << std::hex << std::right
- << offset_
- << ", IFD Entries: "
- << std::setfill(' ') << std::dec << std::right
- << static_cast<unsigned int>(entries_.size()) << "\n"
- << prefix << "Entry Tag Format (Bytes each) Number Offset\n"
- << prefix << "----- ------ --------------------- ------ -----------\n";
- // Print IFD entries
- const const_iterator b = entries_.begin();
- const const_iterator e = entries_.end();
- const_iterator i = b;
- for (; i != e; ++i) {
- std::ostringstream offset;
- if (i->size() > 4) {
- offset << " 0x" << std::setw(8) << std::setfill('0')
- << std::hex << std::right << i->offset();
- }
- else {
- const byte* data = i->data();
- for (int k = 0; k < i->size(); ++k) {
- offset << std::setw(2) << std::setfill('0') << std::hex
- << (int)data[k] << " ";
- }
- }
- os << prefix << std::setw(5) << std::setfill(' ') << std::dec
- << std::right << static_cast<int>(i - b)
- << " 0x" << std::setw(4) << std::setfill('0') << std::hex
- << std::right << i->tag()
- << " " << std::setw(17) << std::setfill(' ')
- << std::left << i->typeName()
- << " (" << std::dec << i->typeSize() << ")"
- << " " << std::setw(6) << std::setfill(' ') << std::dec
- << std::right << i->count()
- << " " << offset.str()
- << "\n";
- }
- if (hasNext_) {
- os << prefix << "Next IFD: 0x"
- << std::setw(8) << std::setfill('0') << std::hex
- << std::right << next() << "\n";
- }
- // Print data of IFD entries
- for (i = b; i != e; ++i) {
- if (i->size() > 4) {
- os << "Data of entry " << static_cast<int>(i - b) << ":\n";
- hexdump(os, i->data(), i->size(), offset_ + i->offset());
- }
- }
-
- } // Ifd::print
-
- // *************************************************************************
- // free functions
-
- bool cmpEntriesByTag(const Entry& lhs, const Entry& rhs)
- {
- return lhs.tag() < rhs.tag();
- }
-
- bool cmpPreEntriesByOffset(const Ifd::PreEntry& lhs, const Ifd::PreEntry& rhs)
- {
- // We need to ignore entries with size <= 4, so by definition,
- // entries with size <= 4 are greater than those with size > 4
- // when compared by their offset.
- if (lhs.size_ <= 4) {
- return false; // lhs is greater by definition, or they are equal
- }
- if (rhs.size_ <= 4) {
- return true; // rhs is greater by definition (they cannot be equal)
- }
- return lhs.offset_ < rhs.offset_;
- } // cmpPreEntriesByOffset
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/ifd.hpp b/src/plugins/exiv2/ifd.hpp
@@ -1,601 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file ifd.hpp
- @brief Encoding and decoding of IFD (%Image File Directory) data
- @version $Rev: 562 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 09-Jan-04, ahu: created<BR>
- 11-Feb-04, ahu: isolated as a component
- */
-#ifndef IFD_HPP_
-#define IFD_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-
-// + standard includes
-#include <string>
-#include <vector>
-#include <iosfwd>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class declarations
- class Ifd;
-
-// *****************************************************************************
-// class definitions
-
- /*!
- @brief Data structure for one IFD directory entry. See the description of
- class Ifd for an explanation of the supported modes for memory
- allocation.
- */
- class Entry {
- public:
- //! @name Creators
- //@{
- /*!
- @brief Default constructor. The entry allocates memory for its
- data if alloc is true (the default), otherwise it remembers
- just the pointers into a read and writeable data buffer which
- it doesn't allocate or delete.
- */
- explicit Entry(bool alloc =true);
- //! Destructor
- ~Entry();
- //! Copy constructor
- Entry(const Entry& rhs);
- //@}
-
- //! @name Manipulators
- //@{
- //! Assignment operator
- Entry& operator=(const Entry& rhs);
- //! Set the tag
- void setTag(uint16_t tag) { tag_ = tag; }
- //! Set the IFD id
- void setIfdId(IfdId ifdId) { ifdId_ = ifdId; }
- //! Set the index (unique id of an entry within one IFD)
- void setIdx(int idx) { idx_ = idx; }
- //! Set the offset. The offset is relative to the start of the IFD.
- void setOffset(long offset) { offset_ = offset; }
- /*!
- @brief Set the value of the entry to a single unsigned long component,
- i.e., set the type of the entry to unsigned long, number of
- components to one and the value according to the data provided.
-
- The size of the data buffer is set to at least four bytes, but is left
- unchanged if it can accomodate the pointer. This method can be used
- to set the value of a tag which contains a pointer (offset) to a
- location in the Exif data (like e.g., ExifTag, 0x8769 in IFD0, which
- contains a pointer to the Exif IFD).
- <BR>This method cannot be used to set the value of a newly created
- %Entry in non-alloc mode.
-
- @note This method is now deprecated, use data area related methods
- instead.
- */
- void setValue(uint32_t data, ByteOrder byteOrder);
- /*!
- @brief Set type, count, the data buffer and its size.
-
- Copies the provided buffer when called in memory allocation mode.
- <BR>In non-alloc mode, use this method to initialise the data of a
- newly created %Entry. In this case, only the pointer to the buffer is
- copied, i.e., the buffer must remain valid throughout the life of the
- %Entry. Subsequent calls in non-alloc mode will overwrite the data
- pointed to by this pointer with the data provided, i.e., the buffer
- provided in subsequent calls can be deleted after the call.
- <BR>In either memory allocation mode, the data buffer provided must be
- large enough to hold count components of type. The size of the buffer
- will be as indicated in the size argument. I.e., it is possible to
- allocate (set) a data buffer larger than required to hold count
- components of the given type.
-
- @param type The type of the data.
- @param count Number of components in the buffer.
- @param data Pointer to the data buffer.
- @param size Size of the desired data buffer in bytes.
- @throw Error if no memory allocation is allowed
- and the size of the data buffer is larger than the existing
- data buffer of the entry or if size is not large enough to hold
- count components of the given type.
- */
- void setValue(uint16_t type, uint32_t count, const byte* data, long size);
- /*!
- @brief Set the data area. Memory management as for
- setValue(uint16_t, uint32_t, const byte*, long)
-
- For certain tags the regular value of an IFD entry is an offset to a
- data area outside of the IFD. Examples are Exif tag 0x8769 in IFD0
- (Exif.Image.ExifTag) or tag 0x0201 in IFD1
- (Exif.Thumbnail.JPEGInterchangeFormat). The offset of ExifTag points
- to a data area containing the Exif IFD. That of JPEGInterchangeFormat
- contains the JPEG thumbnail image.
- This method sets the data area of a tag in accordance with the memory
- allocation mode.
-
- @param buf Pointer to the data area.
- @param len Size of the data area.
-
- @throw Error in non-alloc mode, if there already is a dataarea but the
- size of the existing dataarea is not large enough for the
- new buffer.
- */
- void setDataArea(const byte* buf, long len);
- /*!
- @brief Set the offset(s) to the data area of an entry.
-
- Add @em offset to each data component of the entry. This is used by
- Ifd::copy to convert the data components of an entry containing
- offsets relative to the data area to become offsets from the start of
- the TIFF header. Usually, entries with a data area have exactly one
- unsigned long data component, which is 0.
-
- @param offset Offset
- @param byteOrder Byte order
-
- @throw Error if the offset is out of range for the data type of the
- tag or the data type is not supported.
- */
- void setDataAreaOffsets(uint32_t offset, ByteOrder byteOrder);
- /*!
- @brief Update the base pointer of the Entry from \em pOldBase
- to \em pNewBase.
-
- Allows to re-locate the underlying data buffer to a new location
- \em pNewBase. This method only has an effect in non-alloc mode.
-
- @param pOldBase Base pointer of the old data buffer
- @param pNewBase Base pointer of the new data buffer
- */
- void updateBase(byte* pOldBase, byte* pNewBase);
- //@}
-
- //! @name Accessors
- //@{
- //! Return the tag
- uint16_t tag() const { return tag_; }
- //! Return the type id.
- uint16_t type() const { return type_; }
- //! Return the name of the type
- const char* typeName() const
- { return TypeInfo::typeName(TypeId(type_)); }
- //! Return the size in bytes of one element of this type
- long typeSize() const
- { return TypeInfo::typeSize(TypeId(type_)); }
- //! Return the IFD id
- IfdId ifdId() const { return ifdId_; }
- //! Return the index (unique id >0 of an entry within an IFD, 0 if not set)
- int idx() const { return idx_; }
- //! Return the number of components in the value
- uint32_t count() const { return count_; }
- /*!
- @brief Return the size of the data buffer in bytes.
- @note There is no minimum size for the data buffer, except that it
- must be large enough to hold the data.
- */
- long size() const { return size_; }
- //! Return the offset from the start of the IFD to the data of the entry
- long offset() const { return offset_; }
- /*!
- @brief Return a pointer to the data buffer. Do not attempt to write
- to this pointer.
- */
- const byte* data() const { return pData_; }
- /*!
- @brief Return a pointer to the n-th component, 0 if there is no
- n-th component. Do not attempt to write to this pointer.
- */
- const byte* component(uint32_t n) const;
- //! Get the memory allocation mode
- bool alloc() const { return alloc_; }
- //! Return the size of the data area.
- long sizeDataArea() const { return sizeDataArea_; }
- /*!
- @brief Return a pointer to the data area. Do not attempt to write to
- this pointer.
-
- For certain tags the regular value of an IFD entry is an offset to a
- data area outside of the IFD. Examples are Exif tag 0x8769 in IFD0
- (Exif.Image.ExifTag) or tag 0x0201 in IFD1
- (Exif.Thumbnail.JPEGInterchangeFormat). The offset of ExifTag points
- to a data area containing the Exif IFD. That of JPEGInterchangeFormat
- contains the JPEG thumbnail image.
- Use this method to access (read-only) the data area of a tag. Use
- setDataArea() to write to the data area.
-
- @return Return a pointer to the data area.
- */
- const byte* dataArea() const { return pDataArea_; }
- //@}
-
- private:
- // DATA
- /*!
- True: Requires memory allocation and deallocation,<BR>
- False: No memory management needed.
- */
- bool alloc_;
- //! Redundant IFD id (it is also at the IFD)
- IfdId ifdId_;
- //! Unique id of an entry within an IFD (0 if not set)
- int idx_;
- //! Tag
- uint16_t tag_;
- //! Type
- uint16_t type_;
- //! Number of components
- uint32_t count_;
- //! Offset from the start of the IFD to the data
- long offset_;
- /*!
- Size of the data buffer holding the value in bytes, there is
- no minimum size.
- */
- long size_;
- //! Pointer to the data buffer
- byte* pData_;
- //! Size of the data area
- long sizeDataArea_;
- //! Pointer to the data area
- byte* pDataArea_;
-
- }; // class Entry
-
- //! Container type to hold all IFD directory entries
- typedef std::vector<Entry> Entries;
-
- //! Unary predicate that matches an Entry with a given index
- class FindEntryByIdx {
- public:
- //! Constructor, initializes the object with the index to look for
- FindEntryByIdx(int idx) : idx_(idx) {}
- /*!
- @brief Returns true if the idx of the argument entry is equal
- to that of the object.
- */
- bool operator()(const Entry& entry) const
- { return idx_ == entry.idx(); }
-
- private:
- int idx_;
-
- }; // class FindEntryByIdx
-
- //! Unary predicate that matches an Entry with a given tag
- class FindEntryByTag {
- public:
- //! Constructor, initializes the object with the tag to look for
- FindEntryByTag(uint16_t tag) : tag_(tag) {}
- /*!
- @brief Returns true if the tag of the argument entry is equal
- to that of the object.
- */
- bool operator()(const Entry& entry) const
- { return tag_ == entry.tag(); }
-
- private:
- uint16_t tag_;
-
- }; // class FindEntryByTag
-
- /*!
- @brief Models an IFD (%Image File Directory)
-
- This class models an IFD as described in the TIFF 6.0 specification.
-
- An instance of class %Ifd can operate in two modes, one that allocates and
- deallocates the memory required to store data, and one that doesn't
- perform such memory management.
- <BR>An external data buffer (not managed by %Ifd) is needed for an instance
- of %Ifd which operates in no memory management mode. The %Ifd will
- maintain only pointers into this buffer.
- <BR> The mode without memory management is used to make "non-intrusive
- write support" possible. This allows writing to Exif data of an image
- without changing the data layout of the Exif data, to maximize chances
- that tag data, which the Exif reader may not understand (e.g., the
- Makernote) remains valid. A "non-intrusive write operation" is the
- modification of tag data without increasing the data size.
-
- @note Use the mode with memory management (the default) if you are unsure
- or if these memory management considerations are of no concern to you.
-
- @note The two different modes imply completely different copy and
- assignment behaviours, with the first resulting in entirely separate
- classes and the second mode resulting in multiple classes using one
- and the same data buffer.
- */
- class Ifd {
- //! @name Not implemented
- //@{
- //! Assignment not allowed (memory management mode alloc_ is const)
- Ifd& operator=(const Ifd& rhs);
- //@}
-
- public:
- //! %Entries const iterator type
- typedef Entries::const_iterator const_iterator;
- //! %Entries iterator type
- typedef Entries::iterator iterator;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor. Allows to set the IFD identifier. Memory management
- is enabled, offset is set to 0. Serves as default constructor.
- */
- explicit Ifd(IfdId ifdId =ifdIdNotSet);
- /*!
- @brief Constructor. Allows to set the IFD identifier and the offset of
- the IFD from the start of TIFF header. Memory management is
- enabled.
- */
- Ifd(IfdId ifdId, long offset);
- /*!
- @brief Constructor. Allows to set the IFD identifier, offset of the
- IFD from the start of TIFF header, choose whether or not
- memory management is required for the Entries, and decide
- whether this IFD has a next pointer.
- */
- Ifd(IfdId ifdId, long offset, bool alloc, bool hasNext =true);
- //! Copy constructor
- Ifd(const Ifd& rhs);
- //! Destructor
- ~Ifd();
- //@}
-
- //! @name Manipulators
- //@{
- /*!
- @brief Read a complete IFD and its data from a data buffer
-
- @param buf Pointer to the data to decode. The buffer must start with the
- IFD data (unlike the readSubIfd() method).
- @param len Number of bytes in the data buffer
- @param byteOrder Applicable byte order (little or big endian).
- @param offset (Optional) offset of the IFD from the start of the TIFF
- header, if known. If not given, the offset will be guessed
- using the assumption that the smallest offset of all IFD
- directory entries points to a data buffer immediately follwing
- the IFD.
-
- @return 0 if successful;<BR>
- 6 if the data buffer is too small, e.g., if an offset points
- beyond the provided buffer. The IFD is cleared in this
- case.
- */
- int read(const byte* buf, long len, ByteOrder byteOrder, long offset =0);
- /*!
- @brief Copy the IFD to a data array, update the offsets of the IFD and
- all its entries, return the number of bytes written.
-
- First the number of IFD entries is written (2 bytes), followed
- by all directory entries: tag (2), type (2), number of data
- components (4) and offset to the data or the data, if it
- occupies not more than four bytes (4). The directory entries
- are followed by the offset of the next IFD (4). All these
- fields are encoded according to the byte order argument. Data
- that doesn't fit into the offset fields follows immediately
- after the IFD entries. The offsets in the IFD are set to
- correctly point to the data fields, using the offset parameter
- or the offset of the IFD.
-
- @param buf Pointer to the data buffer. The user must ensure that the
- buffer has enough memory. Otherwise the call results in
- undefined behaviour.
- @param byteOrder Applicable byte order (little or big endian).
- @param offset Target offset from the start of the TIFF header of the
- data array. The IFD offsets will be adjusted as necessary. If
- not given, then it is assumed that the IFD will remain at its
- original position, i.e., the offset of the IFD will be used.
- @return Returns the number of characters written.
- */
- long copy(byte* buf, ByteOrder byteOrder, long offset =0);
- /*!
- @brief Reset the IFD. Delete all IFD entries from the class and put
- the object in a state where it can accept completely new
- entries.
- */
- void clear();
- /*!
- @brief Set the offset of the next IFD. Byte order is needed to update
- the underlying data buffer in non-alloc mode. This method only
- has an effect if the IFD was instantiated with hasNext = true.
- */
- void setNext(uint32_t next, ByteOrder byteOrder);
- /*!
- @brief Add the entry to the IFD. No duplicate-check is performed,
- i.e., it is possible to add multiple entries with the same tag.
- The memory allocation mode of the entry to be added must match
- that of the IFD and the IFD ids of the IFD and entry must
- match.
- */
- void add(const Entry& entry);
- /*!
- @brief Delete the directory entry with the given tag. Return the index
- of the deleted entry or 0 if no entry with tag was found.
- */
- int erase(uint16_t tag);
- /*!
- @brief Delete the directory entry at iterator position pos, return the
- position of the next entry. Note that iterators into the
- directory, including pos, are potentially invalidated by this
- call.
- */
- iterator erase(iterator pos);
- //! Sort the IFD entries by tag
- void sortByTag();
- //! The first entry
- iterator begin() { return entries_.begin(); }
- //! End of the entries
- iterator end() { return entries_.end(); }
- //! Find an IFD entry by idx, return an iterator into the entries list
- iterator findIdx(int idx);
- //! Find an IFD entry by tag, return an iterator into the entries list
- iterator findTag(uint16_t tag);
- /*!
- @brief Update the base pointer of the Ifd and all entries to \em pNewBase.
-
- Allows to re-locate the underlying data buffer to a new location
- \em pNewBase. This method only has an effect in non-alloc mode.
-
- @param pNewBase Pointer to the new data buffer
-
- @return Old base pointer or 0 if called in alloc mode
- */
- byte* updateBase(byte* pNewBase);
- //@}
-
- //! @name Accessors
- //@{
- /*!
- @brief Read a sub-IFD from the location pointed to by the directory entry
- with the given tag.
-
- @param dest References the destination IFD.
- @param buf The data buffer to read from. The buffer must contain all Exif
- data starting from the TIFF header (unlike the read() method).
- @param len Number of bytes in the data buffer
- @param byteOrder Applicable byte order (little or big endian).
- @param tag Tag to look for.
-
- @return 0 if successful;<BR>
- 6 if reading the sub-IFD failed (see read() above) or
- the location pointed to by the directory entry with the
- given tag is outside of the data buffer.
-
- @note It is not considered an error if the tag cannot be found in the
- IFD. 0 is returned and no action is taken in this case.
- */
- int readSubIfd(
- Ifd& dest, const byte* buf, long len, ByteOrder byteOrder, uint16_t tag
- ) const;
- //! Get the memory allocation mode, see the Ifd class description for details
- bool alloc() const { return alloc_; }
- //! The first entry
- const_iterator begin() const { return entries_.begin(); }
- //! End of the entries
- const_iterator end() const { return entries_.end(); }
- //! Find an IFD entry by idx, return a const iterator into the entries list
- const_iterator findIdx(int idx) const;
- //! Find an IFD entry by tag, return a const iterator into the entries list
- const_iterator findTag(uint16_t tag) const;
- //! Get the IfdId of the IFD
- IfdId ifdId() const { return ifdId_; }
- //! Get the offset of the IFD from the start of the TIFF header
- long offset() const { return offset_; }
- /*!
- @brief Get the offset of the first data entry outside of the IFD from
- the start of the TIFF header, return 0 if there is none. The
- data offset is determined when the IFD is read.
- */
- long dataOffset() const { return dataOffset_; }
- //! Get the offset to the next IFD from the start of the TIFF header
- uint32_t next() const { return next_; }
- //! Get the number of directory entries in the IFD
- long count() const { return static_cast<long>(entries_.size()); }
- //! Get the size of this IFD in bytes (IFD only, without data)
- long size() const;
- /*!
- @brief Return the total size of the data of this IFD in bytes; sums
- the size of all directory entries where size is greater than
- four plus the size of all data areas, i.e., all data that
- requires memory outside the IFD directory entries is counted.
- */
- long dataSize() const;
- /*!
- @brief Print the IFD in human readable format to the given stream;
- begin each line with prefix.
- */
- void print(std::ostream& os, const std::string& prefix ="") const;
- //@}
-
- private:
- //! Helper structure to build IFD entries
- struct PreEntry {
- uint16_t tag_;
- uint16_t type_;
- uint32_t count_;
- long size_;
- long offsetLoc_;
- long offset_;
- };
-
- //! cmpPreEntriesByOffset needs to know about PreEntry, that's all.
- friend bool cmpPreEntriesByOffset(const PreEntry&, const PreEntry&);
-
- //! Container for 'pre-entries'
- typedef std::vector<PreEntry> PreEntries;
-
- // DATA
- /*!
- True: requires memory allocation and deallocation,
- False: no memory management needed.
- */
- const bool alloc_;
- //! IFD entries
- Entries entries_;
- //! IFD Id
- IfdId ifdId_;
- //! Pointer to IFD from the start of the TIFF header
- byte* pBase_;
- //! Offset of the IFD from the start of the TIFF header
- long offset_;
- //! Offset of the first data entry outside of the IFD directory
- long dataOffset_;
- //! Indicates whether the IFD has a next pointer
- bool hasNext_;
- //! Pointer to the offset of next IFD from the start of the TIFF header
- byte* pNext_;
- //! The offset of the next IFD as data value (always in sync with *pNext_)
- uint32_t next_;
-
- }; // class Ifd
-
-// *****************************************************************************
-// free functions
-
- /*!
- @brief Compare two IFD entries by tag. Return true if the tag of entry
- lhs is less than that of rhs.
- */
- bool cmpEntriesByTag(const Entry& lhs, const Entry& rhs);
-
- /*!
- @brief Compare two 'pre-IFD entries' by offset, taking care of special
- cases where one or both of the entries don't have an offset.
- Return true if the offset of entry lhs is less than that of rhs,
- else false. By definition, entries without an offset are greater
- than those with an offset.
- */
- bool cmpPreEntriesByOffset(const Ifd::PreEntry& lhs, const Ifd::PreEntry& rhs);
-
-} // namespace Exiv2
-
-#endif // #ifndef IFD_HPP_
diff --git a/src/plugins/exiv2/image.cpp b/src/plugins/exiv2/image.cpp
@@ -1,246 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: image.cpp
- Version: $Rev: 598 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- Brad Schick (brad) <brad@robotbattle.com>
- History: 26-Jan-04, ahu: created
- 11-Feb-04, ahu: isolated as a component
- 19-Jul-04, brad: revamped to be more flexible and support Iptc
- 15-Jan-05, brad: inside-out design changes
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: image.cpp 598 2005-07-08 15:29:11Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#ifdef _MSC_VER
-# include "exv_msvc.h"
-#else
-# include "exv_conf.h"
-#endif
-
-#include "image.hpp"
-#include "error.hpp"
-#include "futils.hpp"
-
-// Ensure registration with factory
-#include "jpgimage.hpp"
-
-// + standard includes
-#include <cerrno>
-#include <cstdio>
-#include <cstring>
-#include <cstdio> // for rename, remove
-#include <cassert>
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef _MSC_VER
-# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#endif
-#ifdef EXV_HAVE_UNISTD_H
-# include <unistd.h> // stat
-#endif
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- int ImageFactory::Init::count = 0;
-
- ImageFactory::Init::Init()
- {
- ++count;
- }
-
- ImageFactory::Init::~Init()
- {
- if (--count == 0) {
- Exiv2::ImageFactory::cleanup();
- }
- }
-
- ImageFactory::Registry* ImageFactory::registry_ = 0;
-
- void ImageFactory::cleanup()
- {
- delete registry_;
- registry_ = 0;
- }
-
- void ImageFactory::init()
- {
- if (0 == registry_) {
- registry_ = new Registry;
- }
- }
-
- void ImageFactory::registerImage(Image::Type type,
- NewInstanceFct newInst, IsThisTypeFct isType)
- {
- init();
- assert (newInst && isType);
- (*registry_)[type] = ImageFcts(newInst, isType);
- }
-
- Image::Type ImageFactory::getType(const std::string& path)
- {
- FileIo fileIo(path);
- return getType(fileIo);
- }
-
- Image::Type ImageFactory::getType(const byte* data, long size)
- {
- MemIo memIo(data, size);
- return getType(memIo);
- }
-
- Image::Type ImageFactory::getType(BasicIo& io)
- {
- if (io.open() != 0) return Image::none;
- IoCloser closer(io);
- Image::Type type = Image::none;
- Registry::const_iterator b = registry_->begin();
- Registry::const_iterator e = registry_->end();
- for (Registry::const_iterator i = b; i != e; ++i)
- {
- if (i->second.isThisType(io, false)) {
- type = i->first;
- break;
- }
- }
- return type;
- } // ImageFactory::getType
-
- Image::AutoPtr ImageFactory::open(const std::string& path)
- {
- BasicIo::AutoPtr io(new FileIo(path));
- Image::AutoPtr image = open(io); // may throw
- if (image.get() == 0) throw Error(11, path);
- return image;
- }
-
- Image::AutoPtr ImageFactory::open(const byte* data, long size)
- {
- MemIo *mem = new MemIo();
- mem->wrap(data, size);
-
- BasicIo::AutoPtr io(mem);
- Image::AutoPtr image = open(io); // may throw
- if (image.get() == 0) throw Error(12);
- return image;
- }
-
- Image::AutoPtr ImageFactory::open(BasicIo::AutoPtr io)
- {
- if (io->open() != 0) {
- throw Error(9, io->path(), strError());
- }
- Image::AutoPtr image;
- Registry::const_iterator b = registry_->begin();
- Registry::const_iterator e = registry_->end();
- for (Registry::const_iterator i = b; i != e; ++i) {
- if (i->second.isThisType(*io, false)) {
- image = i->second.newInstance(io, false);
- break;
- }
- }
- return image;
- } // ImageFactory::open
-
- Image::AutoPtr ImageFactory::create(Image::Type type,
- const std::string& path)
- {
- std::auto_ptr<FileIo> fileIo(new FileIo(path));
- // Create or overwrite the file, then close it
- if (fileIo->open("w+b") != 0) {
- throw Error(10, path, "w+b", strError());
- }
- fileIo->close();
- BasicIo::AutoPtr io(fileIo);
- Image::AutoPtr image = create(type, io);
- if (image.get() == 0) throw Error(13, type);
- return image;
- }
-
- Image::AutoPtr ImageFactory::create(Image::Type type)
- {
- BasicIo::AutoPtr io(new MemIo);
- Image::AutoPtr image = create(type, io);
- if (image.get() == 0) throw Error(13, type);
- return image;
- }
-
- Image::AutoPtr ImageFactory::create(Image::Type type,
- BasicIo::AutoPtr io)
- {
- // BasicIo instance does not need to be open
- Registry::const_iterator i = registry_->find(type);
- if (i != registry_->end()) {
- return i->second.newInstance(io, true);
- }
- return Image::AutoPtr();
- } // ImageFactory::create
-
- TiffHeader::TiffHeader(ByteOrder byteOrder)
- : byteOrder_(byteOrder), tag_(0x002a), offset_(0x00000008)
- {
- }
-
- int TiffHeader::read(const byte* buf)
- {
- if (buf[0] == 0x49 && buf[1] == 0x49) {
- byteOrder_ = littleEndian;
- }
- else if (buf[0] == 0x4d && buf[1] == 0x4d) {
- byteOrder_ = bigEndian;
- }
- else {
- return 1;
- }
- tag_ = getUShort(buf+2, byteOrder_);
- offset_ = getULong(buf+4, byteOrder_);
- return 0;
- }
-
- long TiffHeader::copy(byte* buf) const
- {
- switch (byteOrder_) {
- case littleEndian:
- buf[0] = 0x49;
- buf[1] = 0x49;
- break;
- case bigEndian:
- buf[0] = 0x4d;
- buf[1] = 0x4d;
- break;
- case invalidByteOrder:
- // do nothing
- break;
- }
- us2Data(buf+2, 0x002a, byteOrder_);
- ul2Data(buf+4, 0x00000008, byteOrder_);
- return size();
- } // TiffHeader::copy
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/image.hpp b/src/plugins/exiv2/image.hpp
@@ -1,493 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file image.hpp
- @brief Class JpegImage to access JPEG images
- @version $Rev: 598 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @author Brad Schick (brad)
- <a href="mailto:brad@robotbattle.com">brad@robotbattle.com</a>
- @date 09-Jan-04, ahu: created<BR>
- 11-Feb-04, ahu: isolated as a component<BR>
- 19-Jul-04, brad: revamped to be more flexible and support Iptc
- 15-Jan-05, brad: inside-out design changes
- */
-#ifndef IMAGE_HPP_
-#define IMAGE_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "basicio.hpp"
-
-// + standard includes
-#include <string>
-#include <map>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class declarations
- class ExifData;
- class IptcData;
-
-// *****************************************************************************
-// class definitions
- /*!
- @brief Abstract base class defining the interface for an image. This is
- the top-level interface to the Exiv2 library.
-
- Most client apps will obtain an Image instance by calling a static
- ImageFactory method. The Image class can then be used to to
- read, write, and save metadata.
- */
- class Image {
- public:
- //! Supported image formats
- enum Type { none, jpeg, exv };
-
- //! Image auto_ptr type
- typedef std::auto_ptr<Image> AutoPtr;
-
- //! @name Creators
- //@{
- //! Virtual Destructor
- virtual ~Image() {}
- //@}
-
- //! @name Manipulators
- //@{
- /*!
- @brief Read metadata from assigned image. Before this method
- is called, the various metadata types (Iptc, Exif) will be empty.
- @throw Error In case of failure.
- */
- virtual void readMetadata() =0;
- /*!
- @brief Write metadata back to the image.
-
- All existing metadata sections in the image are either created,
- replaced, or erased. If values for a given metadata type have been
- assigned, a section for that metadata type will either be created or
- replaced. If no values have been assigned to a given metadata type,
- any exists section for that metadata type will be removed from the
- image.
-
- @throw Error if the operation fails
- */
- virtual void writeMetadata() =0;
- /*!
- @brief Assign new exif data. The new exif data is not written
- to the image until the writeMetadata() method is called.
- @param exifData An ExifData instance holding exif data to be copied
- */
- virtual void setExifData(const ExifData& exifData) =0;
- /*!
- @brief Erase any buffered Exif data. Exif data is not removed from
- the actual image until the writeMetadata() method is called.
- */
- virtual void clearExifData() =0;
- /*!
- @brief Assign new iptc data. The new iptc data is not written
- to the image until the writeMetadata() method is called.
- @param iptcData An IptcData instance holding iptc data to be copied
- */
- virtual void setIptcData(const IptcData& iptcData) =0;
- /*!
- @brief Erase any buffered Iptc data. Iptc data is not removed from
- the actual image until the writeMetadata() method is called.
- */
- virtual void clearIptcData() =0;
- /*!
- @brief Set the image comment. The new comment is not written
- to the image until the writeMetadata() method is called.
- @param comment String containing comment.
- */
- virtual void setComment(const std::string& comment) =0;
- /*!
- @brief Erase any buffered comment. Comment is not removed
- from the actual image until the writeMetadata() method is called.
- */
- virtual void clearComment() =0;
- /*!
- @brief Copy all existing metadata from source Image. The data is
- copied into internal buffers and is not written to the image
- until the writeMetadata() method is called.
- @param image Metadata source. All metadata types are copied.
- */
- virtual void setMetadata(const Image& image) =0;
- /*!
- @brief Erase all buffered metadata. Metadata is not removed
- from the actual image until the writeMetadata() method is called.
- */
- virtual void clearMetadata() =0;
- //@}
-
- //! @name Accessors
- //@{
- /*!
- @brief Check if the Image instance is valid. Use after object
- construction.
- @return true if the Image is in a valid state.
- */
- virtual bool good() const =0;
- /*!
- @brief Returns an ExifData instance containing currently buffered
- exif data.
-
- The exif data may have been read from the image by
- a previous call to readMetadata() or added directly. The exif
- data in the returned instance will be written to the image when
- writeMetadata() is called.
-
- @return read only ExifData instance containing exif values
- */
- virtual const ExifData& exifData() const =0;
- /*!
- @brief Returns an ExifData instance containing currently buffered
- exif data.
-
- The contained exif data may have been read from the image by
- a previous call to readMetadata() or added directly. The exif
- data in the returned instance will be written to the image when
- writeMetadata() is called.
-
- @return modifiable ExifData instance containing exif values
- */
- virtual ExifData& exifData() =0;
- /*!
- @brief Returns an IptcData instance containing currently buffered
- iptc data.
-
- The contained iptc data may have been read from the image by
- a previous call to readMetadata() or added directly. The iptc
- data in the returned instance will be written to the image when
- writeMetadata() is called.
-
- @return modifiable IptcData instance containing iptc values
- */
- virtual const IptcData& iptcData() const =0;
- /*!
- @brief Returns an ExifData instance containing currently buffered
- exif data.
-
- The contained iptc data may have been read from the image by
- a previous call to readMetadata() or added directly. The iptc
- data in the returned instance will be written to the image when
- writeMetadata() is called.
-
- @return modifiable IptcData instance containing iptc values
- */
- virtual IptcData& iptcData() =0;
- /*!
- @brief Return a copy of the image comment. May be an empty string.
- */
- virtual std::string comment() const =0;
- /*!
- @brief Return a reference to the BasicIo instance being used for Io.
-
- This refence is particularly useful to reading the results of
- operations on a MemIo instance. For example after metadata has
- been modified and the writeMetadata() method has been called,
- this method can be used to get access to the modified image.
-
- @return BasicIo instance that can be used to read or write image
- data directly.
- @note If the returned BasicIo is used to write to the image, the
- Image class will not see those changes until the readMetadata()
- method is called.
- */
- virtual BasicIo& io() const = 0;
- //@}
-
- protected:
- //! @name Creators
- //@{
- //! Default Constructor
- Image() {}
- //@}
-
- private:
- // NOT Implemented
- //! Copy constructor
- Image(const Image& rhs);
- //! Assignment operator
- Image& operator=(const Image& rhs);
-
- }; // class Image
-
- //! Type for function pointer that creates new Image instances
- typedef Image::AutoPtr (*NewInstanceFct)(BasicIo::AutoPtr io, bool create);
- //! Type for function pointer that checks image types
- typedef bool (*IsThisTypeFct)(BasicIo& iIo, bool advance);
-
- /*!
- @brief Returns an Image instance of the specified type.
-
- The factory is implemented as a singleton, which can be accessed
- through static member functions.
- */
- class ImageFactory {
- public:
- //! @name Manipulators
- //@{
- //! Destructor.
- static void cleanup();
- /*!
- @brief Register image type together with its function pointers.
-
- The image factory creates new images by calling their associated
- function pointer. Additional images can be added by registering
- new type and function pointers. If called for a type that already
- exists in the list, the corresponding functions are replaced.
-
- @param type Image type.
- @param newInst Function pointer for creating image instances.
- @param isType Function pointer to test for matching image types.
- */
- static void registerImage(Image::Type type,
- NewInstanceFct newInst,
- IsThisTypeFct isType);
- //@}
-
- //! @name Accessors
- //@{
- /*!
- @brief Create an Image subclass of the appropriate type by reading
- the specified file. %Image type is derived from the file
- contents.
- @param path %Image file. The contents of the file are tested to
- determine the image type. File extension is ignored.
- @return An auto-pointer that owns an Image instance whose type
- matches that of the file.
- @throw Error If opening the file fails or it contains data of an
- unknown image type.
- */
- static Image::AutoPtr open(const std::string& path);
- /*!
- @brief Create an Image subclass of the appropriate type by reading
- the provided memory. %Image type is derived from the memory
- contents.
- @param data Pointer to a data buffer containing an image. The contents
- of the memory are tested to determine the image type.
- @param size Number of bytes pointed to by \em data.
- @return An auto-pointer that owns an Image instance whose type
- matches that of the data buffer.
- @throw Error If the memory contains data of an unknown image type.
- */
- static Image::AutoPtr open(const byte* data, long size);
- /*!
- @brief Create an Image subclass of the appropriate type by reading
- the provided BasicIo instance. %Image type is derived from the
- data provided by \em io. The passed in \em io instance is
- (re)opened by this method.
- @param io An auto-pointer that owns a BasicIo instance that provides
- image data. The contents of the image data are tested to determine
- the type.
- @note This method takes ownership of the passed
- in BasicIo instance through the auto-pointer. Callers should not
- continue to use the BasicIo instance after it is passed to this method.
- Use the Image::io() method to get a temporary reference.
- @return An auto-pointer that owns an Image instance whose type
- matches that of the \em io data. If no image type could be
- determined, the pointer is 0.
- @throw Error If opening the BasicIo fails
- */
- static Image::AutoPtr open(BasicIo::AutoPtr io);
- /*!
- @brief Create an Image subclass of the requested type by creating a
- new image file. If the file already exists, it will be overwritten.
- @param type Type of the image to be created.
- @param path %Image file to create. File extension is ignored.
- @return An auto-pointer that owns an Image instance of the requested
- type.
- @throw Error If the image type is not supported.
- */
- static Image::AutoPtr create(Image::Type type, const std::string& path);
- /*!
- @brief Create an Image subclass of the requested type by creating a
- new image in memory.
- @param type Type of the image to be created.
- @return An auto-pointer that owns an Image instance of the requested
- type.
- @throw Error If the image type is not supported
- */
- static Image::AutoPtr create(Image::Type type);
- /*!
- @brief Create an Image subclass of the requested type by writing a
- new image to a BasicIo instance. If the BasicIo instance already
- contains data, it will be overwritten.
- @param type Type of the image to be created.
- @param io An auto-pointer that owns a BasicIo instance that will
- be written to when creating a new image.
- @note This method takes ownership of the passed in BasicIo instance
- through the auto-pointer. Callers should not continue to use the
- BasicIo instance after it is passed to this method. Use the
- Image::io() method to get a temporary reference.
- @return An auto-pointer that owns an Image instance of the requested
- type. If the image type is not supported, the pointer is 0.
- */
- static Image::AutoPtr create(Image::Type type, BasicIo::AutoPtr io);
- /*!
- @brief Returns the image type of the provided file.
- @param path %Image file. The contents of the file are tested to
- determine the image type. File extension is ignored.
- @return %Image type or Image::none if the type is not recognized.
- */
- static Image::Type getType(const std::string& path);
- /*!
- @brief Returns the image type of the provided data buffer.
- @param data Pointer to a data buffer containing an image. The contents
- of the memory are tested to determine the image type.
- @param size Number of bytes pointed to by \em data.
- @return %Image type or Image::none if the type is not recognized.
- */
- static Image::Type getType(const byte* data, long size);
- /*!
- @brief Returns the image type of data provided by a BasicIo instance.
- The passed in \em io instance is (re)opened by this method.
- @param io A BasicIo instance that provides image data. The contents
- of the image data are tested to determine the type.
- @return %Image type or Image::none if the type is not recognized.
- */
- static Image::Type getType(BasicIo& io);
- //@}
-
- /*!
- @brief Class Init is used to execute initialisation and termination
- code exactly once, at the begin and end of the program.
-
- See Bjarne Stroustrup, 'The C++ Programming Language 3rd
- Edition', section 21.5.2 for details about this pattern.
- */
- class Init {
- static int count; //!< Counts calls to constructor
- public:
- //! @name Creators
- //@{
- //! Perform one-time initialisations.
- Init();
- //! Perform one-time cleanup operations.
- ~Init();
- //@}
- };
-
- private:
- //! @name Creators
- //@{
- //! Prevent construction other than through instance().
- ImageFactory();
- //! Prevent copy construction: not implemented.
- ImageFactory(const ImageFactory& rhs);
- //! Creates the private static instance
- static void init();
- //@}
-
- //! Struct for storing image function pointers.
- struct ImageFcts
- {
- NewInstanceFct newInstance;
- IsThisTypeFct isThisType;
- ImageFcts(NewInstanceFct newInst, IsThisTypeFct isType)
- : newInstance(newInst), isThisType(isType) {}
- ImageFcts() : newInstance(0), isThisType(0) {}
- };
-
- // DATA
- //! Type used to store Image creation functions
- typedef std::map<Image::Type, ImageFcts> Registry;
- //! List of image types and corresponding creation functions.
- static Registry* registry_;
- }; // class ImageFactory
-
-
- //! Helper class modelling the TIFF header structure.
- class TiffHeader {
- public:
- //! @name Creators
- //@{
- /*!
- @brief Default constructor. Optionally sets the byte order
- (default: little endian).
- */
- explicit TiffHeader(ByteOrder byteOrder =littleEndian);
- //@}
-
- //! @name Manipulators
- //@{
- //! Read the TIFF header from a data buffer. Returns 0 if successful.
- int read(const byte* buf);
- //@}
-
- //! @name Accessors
- //@{
- /*!
- @brief Write a standard TIFF header into buf as a data string, return
- number of bytes copied.
-
- Only the byte order of the TIFF header varies, the values written for
- offset and tag are constant, i.e., independent of the values possibly
- read before a call to this function. The value 0x00000008 is written
- for the offset, tag is set to 0x002a.
-
- @param buf The data buffer to write to.
- @return The number of bytes written.
- */
- long copy(byte* buf) const;
- //! Return the size of the TIFF header in bytes.
- long size() const { return 8; }
- //! Return the byte order (little or big endian).
- ByteOrder byteOrder() const { return byteOrder_; }
- //! Return the tag value.
- uint16_t tag() const { return tag_; }
- /*!
- @brief Return the offset to IFD0 from the start of the TIFF header.
- The offset is 0x00000008 if IFD0 begins immediately after the
- TIFF header.
- */
- uint32_t offset() const { return offset_; }
- //@}
-
- private:
- ByteOrder byteOrder_;
- uint16_t tag_;
- uint32_t offset_;
-
- }; // class TiffHeader
-
-} // namespace Exiv2
-
-namespace {
- /*!
- Each translation unit that includes image.hpp declares its own
- Init object. The destructor ensures that the factory is properly
- freed exactly once.
-
- See Bjarne Stroustrup, 'The C++ Programming Language 3rd
- Edition', section 21.5.2 for details about this pattern.
- */
- Exiv2::ImageFactory::Init imageFactoryInit;
-}
-
-#endif // #ifndef IMAGE_HPP_
diff --git a/src/plugins/exiv2/iptc.cpp b/src/plugins/exiv2/iptc.cpp
@@ -1,301 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: iptc.cpp
- Version: $Rev: 600 $
- Author(s): Brad Schick (brad) <brad@robotbattle.com>
- History: 31-July-04, brad: created
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: iptc.cpp 600 2005-07-09 10:38:09Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "iptc.hpp"
-#include "types.hpp"
-#include "error.hpp"
-#include "value.hpp"
-#include "datasets.hpp"
-#include "jpgimage.hpp"
-
-// + standard includes
-#include <iostream>
-#include <algorithm>
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- Iptcdatum::Iptcdatum(const IptcKey& key,
- const Value* pValue)
- : key_(key.clone())
- {
- if (pValue) value_ = pValue->clone();
- }
-
- Iptcdatum::Iptcdatum(const Iptcdatum& rhs)
- : Metadatum(rhs)
- {
- if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy
- if (rhs.value_.get() != 0) value_ = rhs.value_->clone(); // deep copy
- }
-
- Iptcdatum::~Iptcdatum()
- {
- }
-
- const Value& Iptcdatum::value() const
- {
- if (value_.get() == 0) throw Error(8);
- return *value_;
- }
-
- Iptcdatum& Iptcdatum::operator=(const Iptcdatum& rhs)
- {
- if (this == &rhs) return *this;
- Metadatum::operator=(rhs);
-
- key_.reset();
- if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy
-
- value_.reset();
- if (rhs.value_.get() != 0) value_ = rhs.value_->clone(); // deep copy
-
- return *this;
- } // Iptcdatum::operator=
-
- Iptcdatum& Iptcdatum::operator=(const uint16_t& value)
- {
- UShortValue::AutoPtr v = UShortValue::AutoPtr(new UShortValue);
- v->value_.push_back(value);
- value_ = v;
- return *this;
- }
-
- Iptcdatum& Iptcdatum::operator=(const std::string& value)
- {
- setValue(value);
- return *this;
- }
-
- Iptcdatum& Iptcdatum::operator=(const Value& value)
- {
- setValue(&value);
- return *this;
- }
-
- void Iptcdatum::setValue(const Value* pValue)
- {
- value_.reset();
- if (pValue) value_ = pValue->clone();
- }
-
- void Iptcdatum::setValue(const std::string& value)
- {
- if (value_.get() == 0) {
- TypeId type = IptcDataSets::dataSetType(tag(), record());
- value_ = Value::create(type);
- }
- value_->read(value);
- }
-
- const byte IptcData::marker_ = 0x1C; // Dataset marker
-
- Iptcdatum& IptcData::operator[](const std::string& key)
- {
- IptcKey iptcKey(key);
- iterator pos = findKey(iptcKey);
- if (pos == end()) {
- add(Iptcdatum(iptcKey));
- pos = findKey(iptcKey);
- }
- return *pos;
- }
-
- int IptcData::load(const byte* buf, long len)
- {
- const byte* pRead = buf;
- iptcMetadata_.clear();
-
- int rc = 0;
- uint16_t record = 0;
- uint16_t dataSet = 0;
- uint32_t sizeData = 0;
- byte extTest = 0;
-
- while (pRead + 3 < buf + len) {
- if (*pRead++ != marker_) return 5;
- record = *pRead++;
- dataSet = *pRead++;
-
- extTest = *pRead;
- if (extTest & 0x80) {
- // extended dataset
- uint16_t sizeOfSize = (getUShort(pRead, bigEndian) & 0x7FFF);
- if (sizeOfSize > 4) return 5;
- pRead += 2;
- sizeData = 0;
- for (; sizeOfSize > 0; --sizeOfSize) {
- sizeData |= *pRead++ << (8 *(sizeOfSize-1));
- }
- }
- else {
- // standard dataset
- sizeData = getUShort(pRead, bigEndian);
- pRead += 2;
- }
- rc = readData(dataSet, record, pRead, sizeData);
- if( rc ) return rc;
- pRead += sizeData;
- }
-
- return rc;
- } // IptcData::read
-
- int IptcData::readData(uint16_t dataSet, uint16_t record,
- const byte* data, uint32_t sizeData)
- {
- Value::AutoPtr value;
- TypeId type = IptcDataSets::dataSetType(dataSet, record);
- value = Value::create(type);
- value->read(data, sizeData, bigEndian);
- IptcKey key(dataSet, record);
- add(key, value.get());
- return 0;
- }
-
- DataBuf IptcData::copy()
- {
- DataBuf buf(size());
- byte *pWrite = buf.pData_;
-
- const_iterator iter = iptcMetadata_.begin();
- const_iterator end = iptcMetadata_.end();
- for ( ; iter != end; ++iter) {
- // marker, record Id, dataset num
- *pWrite++ = marker_;
- *pWrite++ = static_cast<byte>(iter->record());
- *pWrite++ = static_cast<byte>(iter->tag());
-
- // extended or standard dataset?
- long dataSize = iter->size();
- if (dataSize > 32767) {
- // always use 4 bytes for extended length
- uint16_t sizeOfSize = 4 | 0x8000;
- us2Data(pWrite, sizeOfSize, bigEndian);
- pWrite += 2;
- ul2Data(pWrite, dataSize, bigEndian);
- pWrite += 4;
- }
- else {
- us2Data(pWrite, static_cast<uint16_t>(dataSize), bigEndian);
- pWrite += 2;
- }
-
- pWrite += iter->value().copy(pWrite, bigEndian);
- }
-
- return buf;
- } // IptcData::updateBuffer
-
- long IptcData::size() const
- {
- long newSize = 0;
- const_iterator iter = iptcMetadata_.begin();
- const_iterator end = iptcMetadata_.end();
- for ( ; iter != end; ++iter) {
- // marker, record Id, dataset num, first 2 bytes of size
- newSize += 5;
- long dataSize = iter->size();
- newSize += dataSize;
- if (dataSize > 32767) {
- // extended dataset (we always use 4 bytes)
- newSize += 4;
- }
- }
- return newSize;
- } // IptcData::size
-
- int IptcData::add(const IptcKey& key, Value* value)
- {
- return add(Iptcdatum(key, value));
- }
-
- int IptcData::add(const Iptcdatum& iptcDatum)
- {
- if (!IptcDataSets::dataSetRepeatable(
- iptcDatum.tag(), iptcDatum.record()) &&
- findId(iptcDatum.tag(), iptcDatum.record()) != end()) {
- return 6;
- }
- // allow duplicates
- iptcMetadata_.push_back(iptcDatum);
- return 0;
- }
-
- IptcData::const_iterator IptcData::findKey(const IptcKey& key) const
- {
- return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(),
- FindMetadatumById(key.tag(), key.record()));
- }
-
- IptcData::iterator IptcData::findKey(const IptcKey& key)
- {
- return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(),
- FindMetadatumById(key.tag(), key.record()));
- }
-
- IptcData::const_iterator IptcData::findId(uint16_t dataset, uint16_t record) const
- {
- return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(),
- FindMetadatumById(dataset, record));
- }
-
- IptcData::iterator IptcData::findId(uint16_t dataset, uint16_t record)
- {
- return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(),
- FindMetadatumById(dataset, record));
- }
-
- void IptcData::sortByKey()
- {
- std::sort(iptcMetadata_.begin(), iptcMetadata_.end(), cmpMetadataByKey);
- }
-
- void IptcData::sortByTag()
- {
- std::sort(iptcMetadata_.begin(), iptcMetadata_.end(), cmpMetadataByTag);
- }
-
- IptcData::iterator IptcData::erase(IptcData::iterator pos)
- {
- return iptcMetadata_.erase(pos);
- }
-
- // *************************************************************************
- // free functions
- std::ostream& operator<<(std::ostream& os, const Iptcdatum& md)
- {
- return os << md.value();
- }
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/iptc.hpp b/src/plugins/exiv2/iptc.hpp
@@ -1,415 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file iptc.hpp
- @brief Encoding and decoding of Iptc data
- @version $Rev: 599 $
- @author Brad Schick (brad)
- <a href="mailto:brad@robotbattle.com">brad@robotbattle.com</a>
- @date 31-Jul-04, brad: created
- */
-#ifndef IPTC_HPP_
-#define IPTC_HPP_
-
-// *****************************************************************************
-// included header files
-#include "metadatum.hpp"
-#include "types.hpp"
-#include "error.hpp"
-#include "value.hpp"
-#include "datasets.hpp"
-
-// + standard includes
-#include <string>
-#include <vector>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class definitions
-
- /*!
- @brief Information related to one Iptc dataset. An Iptc metadatum consists
- of an IptcKey and a Value and provides methods to manipulate these.
- */
- class Iptcdatum : public Metadatum {
- public:
- //! @name Creators
- //@{
- /*!
- @brief Constructor for new tags created by an application. The
- %Iptcdatum is created from a key / value pair. %Iptcdatum
- copies (clones) the value if one is provided. Alternatively, a
- program can create an 'empty' %Iptcdatum with only a key and
- set the value using setValue().
-
- @param key The key of the %Iptcdatum.
- @param pValue Pointer to a %Iptcdatum value.
- @throw Error if the key cannot be parsed and converted
- to a tag number and record id.
- */
- explicit Iptcdatum(const IptcKey& key,
- const Value* pValue =0);
- //! Copy constructor
- Iptcdatum(const Iptcdatum& rhs);
- //! Destructor
- virtual ~Iptcdatum();
- //@}
-
- //! @name Manipulators
- //@{
- //! Assignment operator
- Iptcdatum& operator=(const Iptcdatum& rhs);
- /*!
- @brief Assign \em value to the %Iptcdatum. The type of the new Value
- is set to UShortValue.
- */
- Iptcdatum& operator=(const uint16_t& value);
- /*!
- @brief Assign \em value to the %Iptcdatum.
- Calls setValue(const std::string&).
- */
- Iptcdatum& operator=(const std::string& value);
- /*!
- @brief Assign \em value to the %Iptcdatum.
- Calls setValue(const Value*).
- */
- Iptcdatum& operator=(const Value& value);
- /*!
- @brief Set the Value. This method copies (clones) the %Value pointed
- to by \em pValue.
- */
- void setValue(const Value* pValue);
- /*!
- @brief Set the value to the string \em value, using
- Value::read(const std::string&).
- If the %Iptcdatum does not have a Value yet, then a %Value of
- the correct type for this %Iptcdatum is created. If that
- fails (because of an unknown dataset), a StringValue is
- created.
- */
- void setValue(const std::string& value);
- //@}
-
- //! @name Accessors
- //@{
- /*!
- @brief Write value to a data buffer and return the number
- of bytes written.
-
- The user must ensure that the buffer has enough memory. Otherwise
- the call results in undefined behaviour.
-
- @param buf Data buffer to write to.
- @param byteOrder Applicable byte order (little or big endian).
- @return Number of characters written.
- */
- long copy(byte* buf, ByteOrder byteOrder) const
- { return value_.get() == 0 ? 0 : value_->copy(buf, byteOrder); }
- /*!
- @brief Return the key of the Iptcdatum. The key is of the form
- '<b>Iptc</b>.recordName.datasetName'. Note however that the key
- is not necessarily unique, i.e., an IptcData may contain
- multiple metadata with the same key.
- */
- std::string key() const { return key_.get() == 0 ? "" : key_->key(); }
- /*!
- @brief Return the name of the record
- @return record name
- */
- std::string recordName() const
- { return key_.get() == 0 ? "" : key_->recordName(); }
- /*!
- @brief Return the record id
- @return record id
- */
- uint16_t record() const
- { return key_.get() == 0 ? 0 : key_->record(); }
- /*!
- @brief Return the name of the tag (aka dataset)
- @return tag name
- */
- std::string tagName() const
- { return key_.get() == 0 ? "" : key_->tagName(); }
- //! Return the tag (aka dataset) number
- uint16_t tag() const
- { return key_.get() == 0 ? 0 : key_->tag(); }
- //! Return the type id of the value
- TypeId typeId() const
- { return value_.get() == 0 ? invalidTypeId : value_->typeId(); }
- //! Return the name of the type
- const char* typeName() const { return TypeInfo::typeName(typeId()); }
- //! Return the size in bytes of one component of this type
- long typeSize() const { return TypeInfo::typeSize(typeId()); }
- //! Return the number of components in the value
- long count() const { return value_.get() == 0 ? 0 : value_->count(); }
- //! Return the size of the value in bytes
- long size() const { return value_.get() == 0 ? 0 : value_->size(); }
- //! Return the value as a string.
- std::string toString() const
- { return value_.get() == 0 ? "" : value_->toString(); }
- /*!
- @brief Return the n-th component of the value converted to long. The
- return value is -1 if the value of the Iptcdatum is not set and
- the behaviour of the method is undefined if there is no n-th
- component.
- */
- long toLong(long n =0) const
- { return value_.get() == 0 ? -1 : value_->toLong(n); }
- /*!
- @brief Return the n-th component of the value converted to float. The
- return value is -1 if the value of the Iptcdatum is not set and
- the behaviour of the method is undefined if there is no n-th
- component.
- */
- float toFloat(long n =0) const
- { return value_.get() == 0 ? -1 : value_->toFloat(n); }
- /*!
- @brief Return the n-th component of the value converted to
- Rational. The return value is -1/1 if the value of the
- Iptcdatum is not set and the behaviour of the method is
- undefined if there is no n-th component.
- */
- Rational toRational(long n =0) const
- { return value_.get() == 0 ? Rational(-1, 1) : value_->toRational(n); }
- /*!
- @brief Return an auto-pointer to a copy (clone) of the value. The
- caller owns this copy and the auto-pointer ensures that it will
- be deleted.
-
- This method is provided for users who need full control over the
- value. A caller may, e.g., downcast the pointer to the appropriate
- subclass of Value to make use of the interface of the subclass to set
- or modify its contents.
-
- @return An auto-pointer to a copy (clone) of the value, 0 if the value
- is not set.
- */
- Value::AutoPtr getValue() const
- { return value_.get() == 0 ? Value::AutoPtr(0) : value_->clone(); }
- /*!
- @brief Return a constant reference to the value.
-
- This method is provided mostly for convenient and versatile output of
- the value which can (to some extent) be formatted through standard
- stream manipulators. Do not attempt to write to the value through
- this reference.
-
- <b>Example:</b> <br>
- @code
- IptcData::const_iterator i = iptcData.findKey(key);
- if (i != iptcData.end()) {
- std::cout << i->key() << " " << std::hex << i->value() << "\n";
- }
- @endcode
-
- @return A constant reference to the value.
- @throw Error If the value is not set.
- */
- const Value& value() const;
- //@}
-
- private:
- // DATA
- IptcKey::AutoPtr key_; //!< Key
- Value::AutoPtr value_; //!< Value
-
- }; // class Iptcdatum
-
- /*!
- @brief Output operator for Iptcdatum types, printing the interpreted
- tag value.
- */
- std::ostream& operator<<(std::ostream& os, const Iptcdatum& md);
-
- //! Container type to hold all metadata
- typedef std::vector<Iptcdatum> IptcMetadata;
-
- //! Unary predicate that matches an Iptcdatum with given record and dataset
- class FindMetadatumById {
- public:
- //! Constructor, initializes the object with the record and dataset id
- FindMetadatumById(uint16_t dataset, uint16_t record)
- : dataset_(dataset), record_(record) {}
- /*!
- @brief Returns true if the record and dataset id of the argument
- Iptcdatum is equal to that of the object.
- */
- bool operator()(const Iptcdatum& iptcdatum) const
- { return dataset_ == iptcdatum.tag() && record_ == iptcdatum.record(); }
-
- private:
- uint16_t dataset_;
- uint16_t record_;
-
- }; // class FindMetadatumById
-
- /*!
- @brief A container for Iptc data. This is a top-level class of
- the %Exiv2 library.
-
- Provide high-level access to the Iptc data of an image:
- - read Iptc information from JPEG files
- - access metadata through keys and standard C++ iterators
- - add, modify and delete metadata
- - write Iptc data to JPEG files
- - extract Iptc metadata to files, insert from these files
- */
- class IptcData {
- public:
- //! IptcMetadata iterator type
- typedef IptcMetadata::iterator iterator;
- //! IptcMetadata const iterator type
- typedef IptcMetadata::const_iterator const_iterator;
-
- // Use the compiler generated constructors and assignment operator
-
- //! @name Manipulators
- //@{
- /*!
- @brief Load the Iptc data from a byte buffer. The format must follow
- the IPTC IIM4 standard.
- @param buf Pointer to the data buffer to read from
- @param len Number of bytes in the data buffer
- @return 0 if successful;<BR>
- 5 if Iptc data is invalid or corrupt;<BR>
- */
- int load(const byte* buf, long len);
- /*!
- @brief Write the Iptc data to a data buffer and return the data buffer.
- Caller owns this buffer. The copied data follows the IPTC IIM4
- standard.
- @return Data buffer containing the Iptc data.
- */
- DataBuf copy();
- /*!
- @brief Returns a reference to the %Iptcdatum that is associated with a
- particular \em key. If %IptcData does not already contain such
- an %Iptcdatum, operator[] adds object \em Iptcdatum(key).
-
- @note Since operator[] might insert a new element, it can't be a const
- member function.
- */
- Iptcdatum& operator[](const std::string& key);
- /*!
- @brief Add an %Iptcdatum from the supplied key and value pair. This
- method copies (clones) the value. A check for non-repeatable
- datasets is performed.
- @return 0 if successful;<BR>
- 6 if the dataset already exists and is not repeatable
- */
- int add(const IptcKey& key, Value* value);
- /*!
- @brief Add a copy of the Iptcdatum to the Iptc metadata. A check
- for non-repeatable datasets is performed.
- @return 0 if successful;<BR>
- 6 if the dataset already exists and is not repeatable;<BR>
- */
- int add(const Iptcdatum& iptcdatum);
- /*!
- @brief Delete the Iptcdatum at iterator position pos, return the
- position of the next Iptcdatum. Note that iterators into
- the metadata, including pos, are potentially invalidated
- by this call.
- */
- iterator erase(iterator pos);
- /*!
- @brief Delete all Iptcdatum instances resulting in an empty container.
- */
- void clear() { iptcMetadata_.clear(); }
- //! Sort metadata by key
- void sortByKey();
- //! Sort metadata by tag (aka dataset)
- void sortByTag();
- //! Begin of the metadata
- iterator begin() { return iptcMetadata_.begin(); }
- //! End of the metadata
- iterator end() { return iptcMetadata_.end(); }
- /*!
- @brief Find a Iptcdatum with the given key, return an iterator to it.
- If multiple entries with the same key exist, it is undefined
- which of the matching metadata is found.
- */
- iterator findKey(const IptcKey& key);
- /*!
- @brief Find a Iptcdatum with the given record and dataset it,
- return a const iterator to it. If multiple entries with the
- same Ids exists, it is undefined which of the matching
- metadata is found.
- */
- iterator findId(uint16_t dataset,
- uint16_t record = IptcDataSets::application2);
- //@}
-
- //! @name Accessors
- //@{
- //! Begin of the metadata
- const_iterator begin() const { return iptcMetadata_.begin(); }
- //! End of the metadata
- const_iterator end() const { return iptcMetadata_.end(); }
- /*!
- @brief Find an Iptcdatum with the given key, return a const iterator
- to it. If multiple metadata with the same key exist it is
- undefined which of the matching metadata is found.
- */
- const_iterator findKey(const IptcKey& key) const;
- /*!
- @brief Find a Iptcdatum with the given record and dataset number,
- return a const iterator to it. If multiple metadata with the
- same Ids exist it is undefined which of the matching
- metadata is found.
- */
- const_iterator findId(uint16_t dataset,
- uint16_t record = IptcDataSets::application2) const;
- //! Return true if there is no Iptc metadata
- bool empty() const { return count() == 0; }
- //! Get the number of metadata entries
- long count() const { return static_cast<long>(iptcMetadata_.size()); }
- /*!
- @brief Return the exact size of all contained Iptc metadata
- */
- long size() const;
- //@}
-
- private:
- /*!
- @brief Read a single dataset payload and create a new metadata entry
- @param dataSet DataSet number
- @param record Record Id
- @param data Pointer to the first byte of dataset payload
- @param sizeData Length in bytes of dataset payload
- @return 0 if successful.
- */
- int readData(uint16_t dataSet, uint16_t record,
- const byte* data, uint32_t sizeData);
-
- // Constant data
- static const byte marker_; // Dataset marker
-
- // DATA
- IptcMetadata iptcMetadata_;
- }; // class IptcData
-
-} // namespace Exiv2
-
-#endif // #ifndef IPTC_HPP_
diff --git a/src/plugins/exiv2/jpgimage.cpp b/src/plugins/exiv2/jpgimage.cpp
@@ -1,661 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: jpgimage.cpp
- Version: $Rev: 563 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- Brad Schick (brad) <brad@robotbattle.com>
- History: 15-Jan-05, brad: split out from image.cpp
-
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: jpgimage.cpp 563 2005-04-21 07:21:53Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#ifdef _MSC_VER
-# include "exv_msvc.h"
-#else
-# include "exv_conf.h"
-#endif
-
-#include "jpgimage.hpp"
-#include "error.hpp"
-#include "futils.hpp"
-
-// + standard includes
-#include <cstring>
-#include <cassert>
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- // Local functions. These could be static private functions on Image
- // subclasses but then ImageFactory needs to be made a friend.
- /*!
- @brief Create a new ExvImage instance and return an auto-pointer to it.
- Caller owns the returned object and the auto-pointer ensures that
- it will be deleted.
- */
- Image::AutoPtr newExvInstance(BasicIo::AutoPtr io, bool create);
- //! Check if the file iIo is an EXV file
- bool isExvType(BasicIo& iIo, bool advance);
- /*!
- @brief Create a new JpegImage instance and return an auto-pointer to it.
- Caller owns the returned object and the auto-pointer ensures that
- it will be deleted.
- */
- Image::AutoPtr newJpegInstance(BasicIo::AutoPtr io, bool create);
- //! Check if the file iIo is a JPEG image.
- bool isJpegType(BasicIo& iIo, bool advance);
-
- const byte JpegBase::sos_ = 0xda;
- const byte JpegBase::eoi_ = 0xd9;
- const byte JpegBase::app0_ = 0xe0;
- const byte JpegBase::app1_ = 0xe1;
- const byte JpegBase::app13_ = 0xed;
- const byte JpegBase::com_ = 0xfe;
- const uint16_t JpegBase::iptc_ = 0x0404;
- const char JpegBase::exifId_[] = "Exif\0\0";
- const char JpegBase::jfifId_[] = "JFIF\0";
- const char JpegBase::ps3Id_[] = "Photoshop 3.0\0";
- const char JpegBase::bimId_[] = "8BIM";
-
- JpegBase::JpegBase(BasicIo::AutoPtr io, bool create,
- const byte initData[], long dataSize)
- : io_(io)
- {
- if (create) {
- initImage(initData, dataSize);
- }
- }
-
- int JpegBase::initImage(const byte initData[], long dataSize)
- {
- if (io_->open() != 0) {
- return 4;
- }
- IoCloser closer(*io_);
- if (io_->write(initData, dataSize) != dataSize) {
- return 4;
- }
- return 0;
- }
-
- bool JpegBase::good() const
- {
- if (io_->open() != 0) return false;
- IoCloser closer(*io_);
- return isThisType(*io_, false);
- }
-
- void JpegBase::clearMetadata()
- {
- clearIptcData();
- clearExifData();
- clearComment();
- }
-
- void JpegBase::clearIptcData()
- {
- iptcData_.clear();
- }
-
- void JpegBase::clearExifData()
- {
- exifData_.clear();
- }
-
- void JpegBase::clearComment()
- {
- comment_.erase();
- }
-
- void JpegBase::setExifData(const ExifData& exifData)
- {
- exifData_ = exifData;
- }
-
- void JpegBase::setIptcData(const IptcData& iptcData)
- {
- iptcData_ = iptcData;
- }
-
- void JpegBase::setComment(const std::string& comment)
- {
- comment_ = comment;
- }
-
- void JpegBase::setMetadata(const Image& image)
- {
- setIptcData(image.iptcData());
- setExifData(image.exifData());
- setComment(image.comment());
- }
-
- int JpegBase::advanceToMarker() const
- {
- int c = -1;
- // Skips potential padding between markers
- while ((c=io_->getb()) != 0xff) {
- if (c == EOF) return -1;
- }
-
- // Markers can start with any number of 0xff
- while ((c=io_->getb()) == 0xff) {
- if (c == EOF) return -1;
- }
- return c;
- }
-
- void JpegBase::readMetadata()
- {
- if (io_->open() != 0) {
- throw Error(9, io_->path(), strError());
- }
- IoCloser closer(*io_);
- // Ensure that this is the correct image type
- if (!isThisType(*io_, true)) {
- if (io_->error() || io_->eof()) throw Error(14);
- throw Error(15);
- }
- clearMetadata();
- int search = 3;
- const long bufMinSize = 16;
- long bufRead = 0;
- DataBuf buf(bufMinSize);
-
- // Read section marker
- int marker = advanceToMarker();
- if (marker < 0) throw Error(15);
-
- while (marker != sos_ && marker != eoi_ && search > 0) {
- // Read size and signature (ok if this hits EOF)
- bufRead = io_->read(buf.pData_, bufMinSize);
- if (io_->error()) throw Error(14);
- uint16_t size = getUShort(buf.pData_, bigEndian);
-
- if (marker == app1_ && memcmp(buf.pData_ + 2, exifId_, 6) == 0) {
- if (size < 8) throw Error(15);
- // Seek to begining and read the Exif data
- io_->seek(8-bufRead, BasicIo::cur);
- long sizeExifData = size - 8;
- DataBuf rawExif(sizeExifData);
- io_->read(rawExif.pData_, sizeExifData);
- if (io_->error() || io_->eof()) throw Error(14);
- if (exifData_.load(rawExif.pData_, sizeExifData)) throw Error(15);
- --search;
- }
- else if (marker == app13_ && memcmp(buf.pData_ + 2, ps3Id_, 14) == 0) {
- if (size < 16) throw Error(15);
- // Read the rest of the APP13 segment
- // needed if bufMinSize!=16: io_->seek(16-bufRead, BasicIo::cur);
- DataBuf psData(size - 16);
- io_->read(psData.pData_, psData.size_);
- if (io_->error() || io_->eof()) throw Error(14);
- const byte *record = 0;
- uint16_t sizeIptc = 0;
- uint16_t sizeHdr = 0;
- // Find actual Iptc data within the APP13 segment
- if (!locateIptcData(psData.pData_, psData.size_, &record,
- &sizeHdr, &sizeIptc)) {
- assert(sizeIptc);
- if (iptcData_.load(record + sizeHdr, sizeIptc)) throw Error(15);
- }
- --search;
- }
- else if (marker == com_ && comment_.empty())
- {
- if (size < 2) throw Error(15);
- // Jpegs can have multiple comments, but for now only read
- // the first one (most jpegs only have one anyway). Comments
- // are simple single byte ISO-8859-1 strings.
- io_->seek(2-bufRead, BasicIo::cur);
- buf.alloc(size-2);
- io_->read(buf.pData_, size-2);
- if (io_->error() || io_->eof()) throw Error(14);
- comment_.assign(reinterpret_cast<char*>(buf.pData_), size-2);
- while ( comment_.length()
- && comment_.at(comment_.length()-1) == '\0') {
- comment_.erase(comment_.length()-1);
- }
- --search;
- }
- else {
- if (size < 2) throw Error(15);
- // Skip the remainder of the unknown segment
- if (io_->seek(size-bufRead, BasicIo::cur)) throw Error(15);
- }
- // Read the beginning of the next segment
- marker = advanceToMarker();
- if (marker < 0) throw Error(15);
- }
- } // JpegBase::readMetadata
-
-
- // Operates on raw data (rather than file streams) to simplify reuse
- int JpegBase::locateIptcData(const byte *pPsData,
- long sizePsData,
- const byte **record,
- uint16_t *const sizeHdr,
- uint16_t *const sizeIptc) const
- {
- assert(record);
- assert(sizeHdr);
- assert(sizeIptc);
- // Used for error checking
- long position = 0;
-
- // Data should follow Photoshop format, if not exit
- while (position <= (sizePsData - 14) &&
- memcmp(pPsData + position, bimId_, 4)==0) {
- const byte *hrd = pPsData + position;
- position += 4;
- uint16_t type = getUShort(pPsData+ position, bigEndian);
- position += 2;
-
- // Pascal string is padded to have an even size (including size byte)
- byte psSize = pPsData[position] + 1;
- psSize += (psSize & 1);
- position += psSize;
- if (position >= sizePsData) return -2;
-
- // Data is also padded to be even
- long dataSize = getULong(pPsData + position, bigEndian);
- position += 4;
- if (dataSize > sizePsData - position) return -2;
-
- if (type == iptc_) {
- *sizeIptc = static_cast<uint16_t>(dataSize);
- *sizeHdr = psSize + 10;
- *record = hrd;
- return 0;
- }
- position += dataSize + (dataSize & 1);
- }
- return 3;
- } // JpegBase::locateIptcData
-
- void JpegBase::writeMetadata()
- {
- if (io_->open() != 0) {
- throw Error(9, io_->path(), strError());
- }
- IoCloser closer(*io_);
- BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
- assert (tempIo.get() != 0);
-
- doWriteMetadata(*tempIo); // may throw
- io_->close();
- io_->transfer(*tempIo); // may throw
- } // JpegBase::writeMetadata
-
- void JpegBase::doWriteMetadata(BasicIo& outIo)
- {
- if (!io_->isopen()) throw Error(20);
- if (!outIo.isopen()) throw Error(21);
-
- // Ensure that this is the correct image type
- if (!isThisType(*io_, true)) {
- if (io_->error() || io_->eof()) throw Error(20);
- throw Error(22);
- }
-
- const long bufMinSize = 16;
- long bufRead = 0;
- DataBuf buf(bufMinSize);
- const long seek = io_->tell();
- int count = 0;
- int search = 0;
- int insertPos = 0;
- int skipApp1Exif = -1;
- int skipApp13Ps3 = -1;
- int skipCom = -1;
- DataBuf psData;
-
- // Write image header
- if (writeHeader(outIo)) throw Error(21);
-
- // Read section marker
- int marker = advanceToMarker();
- if (marker < 0) throw Error(22);
-
- // First find segments of interest. Normally app0 is first and we want
- // to insert after it. But if app0 comes after com, app1 and app13 then
- // don't bother.
- while (marker != sos_ && marker != eoi_ && search < 3) {
- // Read size and signature (ok if this hits EOF)
- bufRead = io_->read(buf.pData_, bufMinSize);
- if (io_->error()) throw Error(20);
- uint16_t size = getUShort(buf.pData_, bigEndian);
-
- if (marker == app0_) {
- if (size < 2) throw Error(22);
- insertPos = count + 1;
- if (io_->seek(size-bufRead, BasicIo::cur)) throw Error(22);
- }
- else if (marker == app1_ && memcmp(buf.pData_ + 2, exifId_, 6) == 0) {
- if (size < 8) throw Error(22);
- skipApp1Exif = count;
- ++search;
- if (io_->seek(size-bufRead, BasicIo::cur)) throw Error(22);
- }
- else if (marker == app13_ && memcmp(buf.pData_ + 2, ps3Id_, 14) == 0) {
- if (size < 16) throw Error(22);
- skipApp13Ps3 = count;
- ++search;
- // needed if bufMinSize!=16: io_->seek(16-bufRead, BasicIo::cur);
- psData.alloc(size - 16);
- // Load PS data now to allow reinsertion at any point
- io_->read(psData.pData_, psData.size_);
- if (io_->error() || io_->eof()) throw Error(20);
- }
- else if (marker == com_ && skipCom == -1) {
- if (size < 2) throw Error(22);
- // Jpegs can have multiple comments, but for now only handle
- // the first one (most jpegs only have one anyway).
- skipCom = count;
- ++search;
- if (io_->seek(size-bufRead, BasicIo::cur)) throw Error(22);
- }
- else {
- if (size < 2) throw Error(22);
- if (io_->seek(size-bufRead, BasicIo::cur)) throw Error(22);
- }
- marker = advanceToMarker();
- if (marker < 0) throw Error(22);
- ++count;
- }
-
- if (exifData_.count() > 0) ++search;
- if (iptcData_.count() > 0) ++search;
- if (!comment_.empty()) ++search;
-
- io_->seek(seek, BasicIo::beg);
- count = 0;
- marker = advanceToMarker();
- if (marker < 0) throw Error(22);
-
- // To simplify this a bit, new segments are inserts at either the start
- // or right after app0. This is standard in most jpegs, but has the
- // potential to change segment ordering (which is allowed).
- // Segments are erased if there is no assigned metadata.
- while (marker != sos_ && search > 0) {
- // Read size and signature (ok if this hits EOF)
- bufRead = io_->read(buf.pData_, bufMinSize);
- if (io_->error()) throw Error(20);
- // Careful, this can be a meaningless number for empty
- // images with only an eoi_ marker
- uint16_t size = getUShort(buf.pData_, bigEndian);
-
- if (insertPos == count) {
- byte tmpBuf[18];
- if (!comment_.empty()) {
- // Write COM marker, size of comment, and string
- tmpBuf[0] = 0xff;
- tmpBuf[1] = com_;
- us2Data(tmpBuf + 2,
- static_cast<uint16_t>(comment_.length()+3), bigEndian);
- if (outIo.write(tmpBuf, 4) != 4) throw Error(21);
- if (outIo.write((byte*)comment_.data(), (long)comment_.length())
- != (long)comment_.length()) throw Error(21);
- if (outIo.putb(0)==EOF) throw Error(21);
- if (outIo.error()) throw Error(21);
- --search;
- }
- if (exifData_.count() > 0) {
- // Write APP1 marker, size of APP1 field, Exif id and Exif data
- DataBuf rawExif(exifData_.copy());
- tmpBuf[0] = 0xff;
- tmpBuf[1] = app1_;
- us2Data(tmpBuf + 2,
- static_cast<uint16_t>(rawExif.size_+8),
- bigEndian);
- memcpy(tmpBuf + 4, exifId_, 6);
- if (outIo.write(tmpBuf, 10) != 10) throw Error(21);
- if (outIo.write(rawExif.pData_, rawExif.size_)
- != rawExif.size_) throw Error(21);
- if (outIo.error()) throw Error(21);
- --search;
- }
-
- const byte *record = psData.pData_;
- uint16_t sizeIptc = 0;
- uint16_t sizeHdr = 0;
- // Safe to call with zero psData.size_
- locateIptcData(psData.pData_, psData.size_, &record, &sizeHdr, &sizeIptc);
-
- // Data is rounded to be even
- const int sizeOldData = sizeHdr + sizeIptc + (sizeIptc & 1);
- if (psData.size_ > sizeOldData || iptcData_.count() > 0) {
- // rawIptc may have size of zero.
- DataBuf rawIptc(iptcData_.copy());
- // write app13 marker, new size, and ps3Id
- tmpBuf[0] = 0xff;
- tmpBuf[1] = app13_;
- const int sizeNewData = rawIptc.size_ ?
- rawIptc.size_ + (rawIptc.size_ & 1) + 12 : 0;
- us2Data(tmpBuf + 2,
- static_cast<uint16_t>(psData.size_-sizeOldData+sizeNewData+16),
- bigEndian);
- memcpy(tmpBuf + 4, ps3Id_, 14);
- if (outIo.write(tmpBuf, 18) != 18) throw Error(21);
- if (outIo.error()) throw Error(21);
-
- const long sizeFront = (long)(record - psData.pData_);
- const long sizeEnd = psData.size_ - sizeFront - sizeOldData;
- // write data before old record.
- if (outIo.write(psData.pData_, sizeFront) != sizeFront) throw Error(21);
-
- // write new iptc record if we have it
- if (iptcData_.count() > 0) {
- memcpy(tmpBuf, bimId_, 4);
- us2Data(tmpBuf+4, iptc_, bigEndian);
- tmpBuf[6] = 0;
- tmpBuf[7] = 0;
- ul2Data(tmpBuf + 8, rawIptc.size_, bigEndian);
- if (outIo.write(tmpBuf, 12) != 12) throw Error(21);
- if (outIo.write(rawIptc.pData_, rawIptc.size_)
- != rawIptc.size_) throw Error(21);
- // data is padded to be even (but not included in size)
- if (rawIptc.size_ & 1) {
- if (outIo.putb(0)==EOF) throw Error(21);
- }
- if (outIo.error()) throw Error(21);
- --search;
- }
-
- // write existing stuff after record
- if (outIo.write(record+sizeOldData, sizeEnd)
- != sizeEnd) throw Error(21);
- if (outIo.error()) throw Error(21);
- }
- }
- if (marker == eoi_) {
- break;
- }
- else if (skipApp1Exif==count || skipApp13Ps3==count || skipCom==count) {
- --search;
- io_->seek(size-bufRead, BasicIo::cur);
- }
- else {
- if (size < 2) throw Error(22);
- buf.alloc(size+2);
- io_->seek(-bufRead-2, BasicIo::cur);
- io_->read(buf.pData_, size+2);
- if (io_->error() || io_->eof()) throw Error(20);
- if (outIo.write(buf.pData_, size+2) != size+2) throw Error(21);
- if (outIo.error()) throw Error(21);
- }
-
- // Next marker
- marker = advanceToMarker();
- if (marker < 0) throw Error(22);
- ++count;
- }
-
- // Copy rest of the Io
- io_->seek(-2, BasicIo::cur);
- buf.alloc(4096);
- long readSize = 0;
- while ((readSize=io_->read(buf.pData_, buf.size_))) {
- if (outIo.write(buf.pData_, readSize) != readSize) throw Error(21);
- }
- if (outIo.error()) throw Error(21);
-
- } // JpegBase::doWriteMetadata
-
-
- const byte JpegImage::soi_ = 0xd8;
- const byte JpegImage::blank_[] = {
- 0xFF,0xD8,0xFF,0xDB,0x00,0x84,0x00,0x10,0x0B,0x0B,0x0B,0x0C,0x0B,0x10,0x0C,0x0C,
- 0x10,0x17,0x0F,0x0D,0x0F,0x17,0x1B,0x14,0x10,0x10,0x14,0x1B,0x1F,0x17,0x17,0x17,
- 0x17,0x17,0x1F,0x1E,0x17,0x1A,0x1A,0x1A,0x1A,0x17,0x1E,0x1E,0x23,0x25,0x27,0x25,
- 0x23,0x1E,0x2F,0x2F,0x33,0x33,0x2F,0x2F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
- 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x01,0x11,0x0F,0x0F,0x11,0x13,0x11,0x15,0x12,
- 0x12,0x15,0x14,0x11,0x14,0x11,0x14,0x1A,0x14,0x16,0x16,0x14,0x1A,0x26,0x1A,0x1A,
- 0x1C,0x1A,0x1A,0x26,0x30,0x23,0x1E,0x1E,0x1E,0x1E,0x23,0x30,0x2B,0x2E,0x27,0x27,
- 0x27,0x2E,0x2B,0x35,0x35,0x30,0x30,0x35,0x35,0x40,0x40,0x3F,0x40,0x40,0x40,0x40,
- 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0xC0,0x00,0x11,0x08,0x00,0x01,0x00,
- 0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,0x01,0xFF,0xC4,0x00,0x4B,0x00,
- 0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x07,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xDA,0x00,0x0C,0x03,0x01,0x00,0x02,
- 0x11,0x03,0x11,0x00,0x3F,0x00,0xA0,0x00,0x0F,0xFF,0xD9 };
-
- JpegImage::JpegImage(BasicIo::AutoPtr io, bool create)
- : JpegBase(io, create, blank_, sizeof(blank_))
- {
- }
-
- //! @cond IGNORE
- JpegImage::JpegRegister::JpegRegister()
- {
- ImageFactory::registerImage(
- Image::jpeg, newJpegInstance, isJpegType);
- }
- //! @endcond
-
- int JpegImage::writeHeader(BasicIo& outIo) const
- {
- // Jpeg header
- byte tmpBuf[2];
- tmpBuf[0] = 0xff;
- tmpBuf[1] = soi_;
- if (outIo.write(tmpBuf, 2) != 2) return 4;
- if (outIo.error()) return 4;
- return 0;
- }
-
- bool JpegImage::isThisType(BasicIo& iIo, bool advance) const
- {
- return isJpegType(iIo, advance);
- }
-
- Image::AutoPtr newJpegInstance(BasicIo::AutoPtr io, bool create)
- {
- Image::AutoPtr image = Image::AutoPtr(new JpegImage(io, create));
- if (!image->good()) {
- image.reset();
- }
- return image;
- }
-
- bool isJpegType(BasicIo& iIo, bool advance)
- {
- bool result = true;
- byte tmpBuf[2];
- iIo.read(tmpBuf, 2);
- if (iIo.error() || iIo.eof()) return false;
-
- if (0xff!=tmpBuf[0] || JpegImage::soi_!=tmpBuf[1]) {
- result = false;
- }
- if (!advance || !result ) iIo.seek(-2, BasicIo::cur);
- return result;
- }
-
- const char ExvImage::exiv2Id_[] = "Exiv2";
- const byte ExvImage::blank_[] = { 0xff,0x01,'E','x','i','v','2',0xff,0xd9 };
-
- ExvImage::ExvImage(BasicIo::AutoPtr io, bool create)
- : JpegBase(io, create, blank_, sizeof(blank_))
- {
- }
-
- //! @cond IGNORE
- ExvImage::ExvRegister::ExvRegister()
- {
- ImageFactory::registerImage(
- Image::exv, newExvInstance, isExvType);
- }
- //! @endcond
-
- int ExvImage::writeHeader(BasicIo& outIo) const
- {
- // Exv header
- byte tmpBuf[7];
- tmpBuf[0] = 0xff;
- tmpBuf[1] = 0x01;
- memcpy(tmpBuf + 2, exiv2Id_, 5);
- if (outIo.write(tmpBuf, 7) != 7) return 4;
- if (outIo.error()) return 4;
- return 0;
- }
-
- bool ExvImage::isThisType(BasicIo& iIo, bool advance) const
- {
- return isExvType(iIo, advance);
- }
-
- Image::AutoPtr newExvInstance(BasicIo::AutoPtr io, bool create)
- {
- Image::AutoPtr image;
- if (create) {
- image = Image::AutoPtr(new ExvImage(io, true));
- }
- else {
- image = Image::AutoPtr(new ExvImage(io, false));
- }
- if (!image->good()) image.reset();
- return image;
- }
-
- bool isExvType(BasicIo& iIo, bool advance)
- {
- bool result = true;
- byte tmpBuf[7];
- iIo.read(tmpBuf, 7);
- if (iIo.error() || iIo.eof()) return false;
-
- if ( 0xff != tmpBuf[0] || 0x01 != tmpBuf[1]
- || memcmp(tmpBuf + 2, ExvImage::exiv2Id_, 5) != 0) {
- result = false;
- }
- if (!advance || !result ) iIo.seek(-7, BasicIo::cur);
- return result;
- }
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/jpgimage.hpp b/src/plugins/exiv2/jpgimage.hpp
@@ -1,405 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file jpgimage.hpp
- @brief Class JpegImage to access JPEG images
- @version $Rev: 563 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @author Brad Schick (brad)
- <a href="mailto:brad@robotbattle.com">brad@robotbattle.com</a>
- @date 15-Jan-05, brad: split out from image.cpp
- */
-#ifndef JPGIMAGE_HPP_
-#define JPGIMAGE_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "image.hpp"
-#include "basicio.hpp"
-#include "exif.hpp"
-#include "iptc.hpp"
-
-// + standard includes
-#include <string>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-
-// *****************************************************************************
-// class definitions
-
- /*!
- @brief Abstract helper base class to access JPEG images.
- */
- class JpegBase : public Image {
- public:
- //! @name Creators
- //@{
- //! Virtual destructor.
- virtual ~JpegBase() {}
- //@}
- //! @name Manipulators
- //@{
- /*!
- @brief Read all metadata from the image. Before this method
- is called, the various metadata types (Iptc, Exif) will be empty.
-
- This method returns success even when no metadata is found in
- the image. Callers must therefore check the size of individual
- metadata types before accessing the data.
-
- @throw Error if opening or reading of the file fails or the image
- data is not valid (does not look like JPEG data).
- */
- void readMetadata();
- /*!
- @brief Write metadata back to the image.
-
- All existing metadata sections in the image are either created,
- replaced, or erased. If values for a given metadata type have been
- assigned, a section for that metadata type will either be created or
- replaced. If no values have been assigned to a given metadata type,
- any exists section for that metadata type will be removed from the
- image.
-
- @throw Error if the operation fails
- */
- void writeMetadata();
- /*!
- @brief Assign new exif data. The new exif data is not written
- to the image until the writeMetadata() method is called.
- @param exifData An ExifData instance holding exif data to be copied
- */
- void setExifData(const ExifData& exifData);
- void clearExifData();
- void setIptcData(const IptcData& iptcData);
- void clearIptcData();
- void setComment(const std::string& comment);
- void clearComment();
- void setMetadata(const Image& image);
- void clearMetadata();
- //@}
-
- //! @name Accessors
- //@{
- bool good() const;
- const ExifData& exifData() const { return exifData_; }
- ExifData& exifData() { return exifData_; }
- const IptcData& iptcData() const { return iptcData_; }
- IptcData& iptcData() { return iptcData_; }
- std::string comment() const { return comment_; }
- BasicIo& io() const { return *io_; }
- //@}
- protected:
- //! @name Creators
- //@{
- /*!
- @brief Constructor that can either open an existing image or create
- a new image from scratch. If a new image is to be created, any
- existing data is overwritten.
- @param io An auto-pointer that owns a BasicIo instance used for
- reading and writing image metadata. \b Important: The constructor
- takes ownership of the passed in BasicIo instance through the
- auto-pointer. Callers should not continue to use the BasicIo
- instance after it is passed to this method. Use the Image::io()
- method to get a temporary reference.
- @param create Specifies if an existing image should be read (false)
- or if a new image should be created (true).
- @param initData Data to initialize newly created images. Only used
- when \em create is true. Should contain data for the smallest
- valid image of the calling subclass.
- @param dataSize Size of initData in bytes.
- */
- JpegBase(BasicIo::AutoPtr io, bool create,
- const byte initData[], long dataSize);
- //@}
- //! @name Manipulators
- //@{
- /*!
- @brief Writes the image header (aka signature) to the BasicIo instance.
- @param oIo BasicIo instance that the header is written to.
- @return 0 if successful;<BR>
- 4 if the output file can not be written to;<BR>
- */
- virtual int writeHeader(BasicIo& oIo) const =0;
- //@}
- //! @name Accessors
- //@{
- /*!
- @brief Determine if the content of the BasicIo instance is of the
- type supported by this class.
-
- The advance flag determines if the read position in the stream is
- moved (see below). This applies only if the type matches and the
- function returns true. If the type does not match, the stream
- position is not changed. However, if reading from the stream fails,
- the stream position is undefined. Consult the stream state to obtain
- more information in this case.
-
- @param iIo BasicIo instance to read from.
- @param advance Flag indicating whether the position of the io
- should be advanced by the number of characters read to
- analyse the data (true) or left at its original
- position (false). This applies only if the type matches.
- @return true if the data matches the type of this class;<BR>
- false if the data does not match;<BR>
- */
- virtual bool isThisType(BasicIo& iIo, bool advance) const =0;
- //@}
-
- // Constant Data
- static const byte sos_; //!< JPEG SOS marker
- static const byte eoi_; //!< JPEG EOI marker
- static const byte app0_; //!< JPEG APP0 marker
- static const byte app1_; //!< JPEG APP1 marker
- static const byte app13_; //!< JPEG APP13 marker
- static const byte com_; //!< JPEG Comment marker
- static const char exifId_[]; //!< Exif identifier
- static const char jfifId_[]; //!< JFIF identifier
- static const char ps3Id_[]; //!< Photoshop marker
- static const char bimId_[]; //!< Photoshop marker
- static const uint16_t iptc_; //!< Photoshop Iptc marker
-
- private:
- // DATA
- BasicIo::AutoPtr io_; //!< Image data io pointer
- ExifData exifData_; //!< Exif data container
- IptcData iptcData_; //!< Iptc data container
- std::string comment_; //!< JPEG comment
-
- // METHODS
- /*!
- @brief Advances associated io instance to one byte past the next
- Jpeg marker and returns the marker. This method should be called
- when the BasicIo instance is positioned one byte past the end of a
- Jpeg segment.
- @return the next Jpeg segment marker if successful;<BR>
- -1 if a maker was not found before EOF;<BR>
- */
- int advanceToMarker() const;
- /*!
- @brief Locates Photoshop formated Iptc data in a memory buffer.
- Operates on raw data to simplify reuse.
- @param pPsData Pointer to buffer containing entire payload of
- Photoshop formated APP13 Jpeg segment.
- @param sizePsData Size in bytes of pPsData.
- @param record Output value that is set to the start of the Iptc
- data block within pPsData (may not be null).
- @param sizeHdr Output value that is set to the size of the header
- within the Iptc data block pointed to by record (may not
- be null).
- @param sizeIptc Output value that is set to the size of the actual
- Iptc data within the Iptc data block pointed to by record
- (may not be null).
- @return 0 if successful;<BR>
- 3 if no Iptc data was found in pPsData;<BR>
- -2 if the pPsData buffer does not contain valid data.
- */
- int locateIptcData(const byte *pPsData,
- long sizePsData,
- const byte **record,
- uint16_t *const sizeHdr,
- uint16_t *const sizeIptc) const;
- /*!
- @brief Initialize the image with the provided data.
- @param initData Data to be written to the associated BasicIo
- @param dataSize Size in bytes of data to be written
- @return 0 if successful;<BR>
- 4 if the image can not be written to.
- */
- int initImage(const byte initData[], long dataSize);
- /*!
- @brief Provides the main implementation of writeMetadata() by
- writing all buffered metadata to the provided BasicIo.
- @param oIo BasicIo instance to write to (a temporary location).
-
- @return 4 if opening or writing to the associated BasicIo fails
- */
- void doWriteMetadata(BasicIo& oIo);
-
- // NOT Implemented
- //! Default constructor.
- JpegBase();
- //! Copy constructor
- JpegBase(const JpegBase& rhs);
- //! Assignment operator
- JpegBase& operator=(const JpegBase& rhs);
- }; // class JpegBase
-
- /*!
- @brief Class to access JPEG images
- */
- class JpegImage : public JpegBase {
- friend bool isJpegType(BasicIo& iIo, bool advance);
- public:
- //! @name Creators
- //@{
- /*!
- @brief Constructor that can either open an existing Jpeg image or create
- a new image from scratch. If a new image is to be created, any
- existing data is overwritten. Since the constructor can not return
- a result, callers should check the good() method after object
- construction to determine success or failure.
- @param io An auto-pointer that owns a BasicIo instance used for
- reading and writing image metadata. \b Important: The constructor
- takes ownership of the passed in BasicIo instance through the
- auto-pointer. Callers should not continue to use the BasicIo
- instance after it is passed to this method. Use the Image::io()
- method to get a temporary reference.
- @param create Specifies if an existing image should be read (false)
- or if a new file should be created (true).
- */
- JpegImage(BasicIo::AutoPtr io, bool create);
- //! Destructor
- ~JpegImage() {}
- //@}
-
- //! @cond IGNORE
- // Public only so that we can create a static instance
- struct JpegRegister{
- JpegRegister();
- };
- //! @endcond
- protected:
- //! @name Accessors
- //@{
- /*!
- @brief Determine if the content of the BasicIo instance is a Jpeg image.
- See base class for more details.
- @param iIo BasicIo instance to read from.
- @param advance Flag indicating whether the position of the io
- should be advanced by the number of characters read to
- analyse the data (true) or left at its original
- position (false). This applies only if the type matches.
- @return true if the data matches a Jpeg image;<BR>
- false if the data does not match;<BR>
- */
- bool isThisType(BasicIo& iIo, bool advance) const;
- //@}
- //! @name Manipulators
- //@{
- /*!
- @brief Writes a Jpeg header (aka signature) to the BasicIo instance.
- @param oIo BasicIo instance that the header is written to.
- @return 0 if successful;<BR>
- 2 if the input image is invalid or can not be read;<BR>
- 4 if the temporary image can not be written to;<BR>
- -3 other temporary errors;<BR>
- */
- int writeHeader(BasicIo& oIo) const;
- //@}
- private:
- // Constant data
- static const byte soi_; // SOI marker
- static const byte blank_[]; // Minimal Jpeg image
-
- // NOT Implemented
- //! Default constructor
- JpegImage();
- //! Copy constructor
- JpegImage(const JpegImage& rhs);
- //! Assignment operator
- JpegImage& operator=(const JpegImage& rhs);
- }; // class JpegImage
-
- static JpegImage::JpegRegister jpegReg;
-
- //! Helper class to access %Exiv2 files
- class ExvImage : public JpegBase {
- friend bool isExvType(BasicIo& iIo, bool advance);
- public:
- //! @name Creators
- //@{
- /*!
- @brief Constructor that can either open an existing Exv image or create
- a new image from scratch. If a new image is to be created, any
- existing data is overwritten. Since the constructor can not return
- a result, callers should check the good() method after object
- construction to determine success or failure.
- @param io An auto-pointer that owns a BasicIo instance used for
- reading and writing image metadata. \b Important: The constructor
- takes ownership of the passed in BasicIo instance through the
- auto-pointer. Callers should not continue to use the BasicIo
- instance after it is passed to this method. Use the Image::io()
- method to get a temporary reference.
- @param create Specifies if an existing image should be read (false)
- or if a new file should be created (true).
- */
- ExvImage(BasicIo::AutoPtr io, bool create);
- //! Destructor
- ~ExvImage() {}
- //@}
-
- //! @cond IGNORE
- // Public only so that we can create a static instance
- struct ExvRegister{
- ExvRegister();
- };
- //! @endcond
- protected:
- //! @name Accessors
- //@{
- /*!
- @brief Determine if the content of the BasicIo instance is an Exv
- image. See base class for more details.
- @param iIo BasicIo instance to read from.
- @param advance Flag indicating whether the position of the io
- should be advanced by the number of characters read to
- analyse the data (true) or left at its original
- position (false). This applies only if the type matches.
- @return true if the data matches a Jpeg image;<BR>
- false if the data does not match;<BR>
- */
- virtual bool isThisType(BasicIo& iIo, bool advance) const;
- //@}
- //! @name Manipulators
- //@{
- /*!
- @brief Writes an Exv header (aka signature) to the BasicIo instance.
- @param oIo BasicIo instance that the header is written to.
- @return 0 if successful;<BR>
- 4 if the output file can not be written to;<BR>
- */
- int writeHeader(BasicIo& oIo) const;
- //@}
- private:
- // Constant data
- static const char exiv2Id_[]; // Exv identifier
- static const byte blank_[]; // Minimal exiv file
-
- // NOT Implemented
- //! Default constructor
- ExvImage();
- //! Copy constructor
- ExvImage(const ExvImage& rhs);
- //! Assignment operator
- ExvImage& operator=(const ExvImage& rhs);
- }; // class ExvImage
-
- static ExvImage::ExvRegister exvReg;
-} // namespace Exiv2
-
-
-#endif // #ifndef JPGIMAGE_HPP_
diff --git a/src/plugins/exiv2/makernote.cpp b/src/plugins/exiv2/makernote.cpp
@@ -1,462 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: makernote.cpp
- Version: $Rev: 600 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 18-Feb-04, ahu: created
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: makernote.cpp 600 2005-07-09 10:38:09Z ahuggel $");
-
-// Define DEBUG_* to output debug information to std::cerr, e.g, by calling
-// make like this: make DEFS=-DDEBUG_MAKERNOTE makernote.o
-//#define DEBUG_MAKERNOTE
-//#define DEBUG_REGISTRY
-
-// *****************************************************************************
-// included header files
-#include "makernote.hpp"
-#include "error.hpp"
-
-// + standard includes
-#include <string>
-#include <sstream>
-#include <iomanip>
-#include <iostream>
-#include <cassert>
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- MakerNote::MakerNote(bool alloc)
- : alloc_(alloc), offset_(0), byteOrder_(invalidByteOrder)
- {
- }
-
- MakerNote::AutoPtr MakerNote::create(bool alloc) const
- {
- return AutoPtr(create_(alloc));
- }
-
- MakerNote::AutoPtr MakerNote::clone() const
- {
- return AutoPtr(clone_());
- }
-
- IfdMakerNote::IfdMakerNote(IfdId ifdId, bool alloc, bool hasNext)
- : MakerNote(alloc),
- absOffset_(true), adjOffset_(0), ifd_(ifdId, 0, alloc, hasNext)
- {
- }
-
- IfdMakerNote::IfdMakerNote(const IfdMakerNote& rhs)
- : MakerNote(rhs), absOffset_(rhs.absOffset_), adjOffset_(rhs.adjOffset_),
- header_(rhs.header_.size_), ifd_(rhs.ifd_)
- {
- memcpy(header_.pData_, rhs.header_.pData_, header_.size_);
- }
-
- int IfdMakerNote::read(const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset)
- {
- // Remember the offset
- offset_ = offset;
- // Set byte order if none is set yet
- if (byteOrder_ == invalidByteOrder) byteOrder_ = byteOrder;
- // Read and check the header (and set offset adjustment)
- int rc = readHeader(buf, len, byteOrder);
- if (rc == 0) {
- rc = checkHeader();
- }
- // Adjust the offset
- offset = absOffset_ ? offset + adjOffset_ : adjOffset_;
- // Read the makernote IFD
- if (rc == 0) {
- rc = ifd_.read(buf + headerSize(),
- len - headerSize(),
- byteOrder_,
- offset);
- }
- if (rc == 0) {
- // IfdMakerNote currently does not support multiple IFDs
- if (ifd_.next() != 0) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Warning: Makernote IFD has a next pointer != 0 ("
- << ifd_.next()
- << "). Ignored.\n";
-#endif
- }
- }
-#ifdef DEBUG_MAKERNOTE
- hexdump(std::cerr, buf, len, offset);
- if (rc == 0) ifd_.print(std::cerr);
-#endif
-
- return rc;
- } // IfdMakerNote::read
-
- long IfdMakerNote::copy(byte* buf, ByteOrder byteOrder, long offset)
- {
- // Remember the new offset
- offset_ = offset;
- // Set byte order if none is set yet
- if (byteOrder_ == invalidByteOrder) byteOrder_ = byteOrder;
- // Adjust the offset
- offset = absOffset_ ? offset + adjOffset_ : adjOffset_;
-
- long len = 0;
- len += copyHeader(buf);
- len += ifd_.copy(buf + len, byteOrder_, offset);
-
- return len;
- } // IfdMakerNote::copy
-
- int IfdMakerNote::readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder)
- {
- // Default implementation does nothing, assuming there is no header
- return 0;
- }
-
- void IfdMakerNote::updateBase(byte* pNewBase)
- {
- if (absOffset_) {
- ifd_.updateBase(pNewBase);
- }
- }
-
- int IfdMakerNote::checkHeader() const
- {
- // Default implementation does nothing, assuming there is no header
- return 0;
- }
-
- long IfdMakerNote::copyHeader(byte* buf) const
- {
- if (header_.size_ != 0) memcpy(buf, header_.pData_, header_.size_);
- return header_.size_;
- }
-
- long IfdMakerNote::headerSize() const
- {
- return header_.size_;
- }
-
- Entries::const_iterator IfdMakerNote::findIdx(int idx) const
- {
- return ifd_.findIdx(idx);
- }
-
- long IfdMakerNote::size() const
- {
- return headerSize() + ifd_.size() + ifd_.dataSize();
- }
-
- IfdMakerNote::AutoPtr IfdMakerNote::create(bool alloc) const
- {
- return AutoPtr(create_(alloc));
- }
-
- IfdMakerNote::AutoPtr IfdMakerNote::clone() const
- {
- return AutoPtr(clone_());
- }
-
- int MakerNoteFactory::Init::count = 0;
-
- MakerNoteFactory::Init::Init()
- {
- ++count;
- }
-
- MakerNoteFactory::Init::~Init()
- {
- if (--count == 0) {
- Exiv2::MakerNoteFactory::cleanup();
- }
- }
-
- MakerNoteFactory::Registry* MakerNoteFactory::pRegistry_ = 0;
- MakerNoteFactory::IfdIdRegistry* MakerNoteFactory::pIfdIdRegistry_ = 0;
-
- void MakerNoteFactory::cleanup()
- {
- if (pRegistry_ != 0) {
- Registry::iterator e = pRegistry_->end();
- for (Registry::iterator i = pRegistry_->begin(); i != e; ++i) {
- delete i->second;
- }
- delete pRegistry_;
- }
-
- if (pIfdIdRegistry_ != 0) {
- IfdIdRegistry::iterator e = pIfdIdRegistry_->end();
- for (IfdIdRegistry::iterator i = pIfdIdRegistry_->begin(); i != e; ++i) {
- delete i->second;
- }
- delete pIfdIdRegistry_;
- }
- }
-
- void MakerNoteFactory::init()
- {
- if (0 == pRegistry_) {
- pRegistry_ = new Registry;
- }
- if (0 == pIfdIdRegistry_) {
- pIfdIdRegistry_ = new IfdIdRegistry;
- }
- } // MakerNoteFactory::init
-
- void MakerNoteFactory::registerMakerNote(IfdId ifdId,
- MakerNote::AutoPtr makerNote)
- {
- init();
- MakerNote* pMakerNote = makerNote.release();
- assert(pMakerNote);
- IfdIdRegistry::iterator pos = pIfdIdRegistry_->find(ifdId);
- if (pos != pIfdIdRegistry_->end()) {
- delete pos->second;
- pos->second = 0;
- }
- (*pIfdIdRegistry_)[ifdId] = pMakerNote;
- } // MakerNoteFactory::registerMakerNote
-
- MakerNote::AutoPtr MakerNoteFactory::create(IfdId ifdId, bool alloc)
- {
- assert(pIfdIdRegistry_ != 0);
- IfdIdRegistry::const_iterator i = pIfdIdRegistry_->find(ifdId);
- if (i == pIfdIdRegistry_->end()) return MakerNote::AutoPtr(0);
- assert(i->second);
- return i->second->create(alloc);
- } // MakerNoteFactory::create
-
- void MakerNoteFactory::registerMakerNote(const std::string& make,
- const std::string& model,
- CreateFct createMakerNote)
- {
-#ifdef DEBUG_REGISTRY
- std::cerr << "Registering MakerNote create function for \""
- << make << "\" and \"" << model << "\".\n";
-#endif
- init();
- // Todo: use case insensitive make and model comparisons
-
- // Find or create a registry entry for make
- ModelRegistry* pModelRegistry = 0;
- assert(pRegistry_ != 0);
- Registry::const_iterator end1 = pRegistry_->end();
- Registry::const_iterator pos1;
- for (pos1 = pRegistry_->begin(); pos1 != end1; ++pos1) {
- if (pos1->first == make) break;
- }
- if (pos1 != end1) {
- pModelRegistry = pos1->second;
- }
- else {
- pModelRegistry = new ModelRegistry;
- pRegistry_->push_back(std::make_pair(make, pModelRegistry));
- }
- // Find or create a registry entry for model
- ModelRegistry::iterator end2 = pModelRegistry->end();
- ModelRegistry::iterator pos2;
- for (pos2 = pModelRegistry->begin(); pos2 != end2; ++pos2) {
- if (pos2->first == model) break;
- }
- if (pos2 != end2) {
- pos2->second = createMakerNote;
- }
- else {
- pModelRegistry->push_back(std::make_pair(model, createMakerNote));
- }
- } // MakerNoteFactory::registerMakerNote
-
- MakerNote::AutoPtr MakerNoteFactory::create(const std::string& make,
- const std::string& model,
- bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset)
- {
-#ifdef DEBUG_REGISTRY
- std::cerr << "Entering MakerNoteFactory::create(\""
- << make << "\", \"" << model << "\", "
- << (alloc == true ? "true" : "false") << ")\n";
-#endif
- // loop through each make of the registry to find the best matching make
- int score = 0;
- ModelRegistry* pModelRegistry = 0;
-#ifdef DEBUG_REGISTRY
- std::string makeMatch;
- std::cerr << "Searching make registry...\n";
-#endif
- assert(pRegistry_ != 0);
- Registry::const_iterator end1 = pRegistry_->end();
- Registry::const_iterator pos1;
- for (pos1 = pRegistry_->begin(); pos1 != end1; ++pos1) {
- int rc = match(pos1->first, make);
- if (rc > score) {
- score = rc;
-#ifdef DEBUG_REGISTRY
- makeMatch = pos1->first;
-#endif
- pModelRegistry = pos1->second;
- }
- }
- if (pModelRegistry == 0) return MakerNote::AutoPtr(0);
-#ifdef DEBUG_REGISTRY
- std::cerr << "Best match is \"" << makeMatch << "\".\n";
-#endif
-
- // loop through each model of the model registry to find the best match
- score = 0;
- CreateFct createMakerNote = 0;
-#ifdef DEBUG_REGISTRY
- std::string modelMatch;
- std::cerr << "Searching model registry...\n";
-#endif
- ModelRegistry::const_iterator end2 = pModelRegistry->end();
- ModelRegistry::const_iterator pos2;
- for (pos2 = pModelRegistry->begin(); pos2 != end2; ++pos2) {
- int rc = match(pos2->first, model);
- if (rc > score) {
- score = rc;
-#ifdef DEBUG_REGISTRY
- modelMatch = pos2->first;
-#endif
- createMakerNote = pos2->second;
- }
- }
- if (createMakerNote == 0) return MakerNote::AutoPtr(0);
-#ifdef DEBUG_REGISTRY
- std::cerr << "Best match is \"" << modelMatch << "\".\n";
-#endif
-
- return createMakerNote(alloc, buf, len, byteOrder, offset);
- } // MakerNoteFactory::create
-
- int MakerNoteFactory::match(const std::string& regEntry,
- const std::string& key)
- {
-#ifdef DEBUG_REGISTRY
- std::cerr << " Matching registry entry \"" << regEntry << "\" ("
- << (int)regEntry.size() << ") with key \"" << key << "\" ("
- << (int)key.size() << "): ";
-#endif
- // Todo: make the comparisons case insensitive
-
- // Handle exact match (this is only necessary because of the different
- // return value - the following algorithm also finds exact matches)
- if (regEntry == key) {
-#ifdef DEBUG_REGISTRY
- std::cerr << "Exact match (score: " << (int)key.size() + 2 << ")\n";
-#endif
- return static_cast<int>(key.size()) + 2;
- }
- std::string uKey = key;
- std::string uReg = regEntry;
-
- int count = 0; // number of matching characters
- std::string::size_type ei = 0; // index in the registry entry
- std::string::size_type ki = 0; // index in the key
-
- while (ei != std::string::npos) {
-
- std::string::size_type pos = uReg.find('*', ei);
- if (pos != ei) {
- std::string ss = pos == std::string::npos ?
- uReg.substr(ei) : uReg.substr(ei, pos - ei);
-
- if (ki == std::string::npos) {
-#ifdef DEBUG_REGISTRY
- std::cerr << "Not a match.\n";
-#endif
- return 0;
- }
-
- bool found = false;
- // Find the substr ss in the key starting from index ki.
- // Take care of the special cases
- // + where the substr must match the key from beg to end,
- // + from beg,
- // + to end
- // + and where it can be anywhere in the key.
- // If found, ki is adjusted to the position in the key after ss.
- if (ei == 0 && pos == std::string::npos) { // ei == 0 => ki == 0
- if (0 == uKey.compare(ss)) {
- found = true;
- ki = std::string::npos;
- }
- }
- else if (ei == 0) { // ei == 0 => ki == 0
- if (0 == uKey.compare(0, ss.size(), ss)) {
- found = true;
- ki = ss.size();
- }
- }
- else if (pos == std::string::npos) {
- if ( ss.size() <= uKey.size()
- && ki <= uKey.size() - ss.size()) {
- if (0 == uKey.compare(
- uKey.size() - ss.size(), ss.size(), ss)) {
- found = true;
- ki = std::string::npos;
- }
- }
- }
- else {
- std::string::size_type idx = uKey.find(ss, ki);
- if (idx != std::string::npos) {
- found = true;
- ki = idx + ss.size();
- }
- }
-
- if (found) {
- count += static_cast<int>(ss.size());
- }
- else {
-#ifdef DEBUG_REGISTRY
- std::cerr << "Not a match.\n";
-#endif
- return 0;
- }
- } // if the substr is not empty
-
- ei = pos == std::string::npos ? std::string::npos : pos + 1;
-
- } // while ei doesn't point to the end of the registry entry
-
-#ifdef DEBUG_REGISTRY
- std::cerr << "Match (score: " << count + 1 << ")\n";
-#endif
- return count + 1;
-
- } // MakerNoteFactory::match
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/makernote.hpp b/src/plugins/exiv2/makernote.hpp
@@ -1,508 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file makernote.hpp
- @brief Contains the Exif %MakerNote interface, IFD %MakerNote and a
- MakerNote factory
- @version $Rev: 598 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 18-Feb-04, ahu: created
- */
-#ifndef MAKERNOTE_HPP_
-#define MAKERNOTE_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "ifd.hpp"
-
-// + standard includes
-#include <string>
-#include <iosfwd>
-#include <utility>
-#include <vector>
-#include <map>
-#include <memory>
-#include <string.h>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class declarations
- class Value;
-
-// *****************************************************************************
-// class definitions
-
- /*!
- @brief Exif makernote interface
-
- %MakerNote is a low-level container for makernote entries. The ExifData
- container uses makernote entries just like the other Exif metadata. Thus,
- clients can access Exif and makernote tags and their values uniformly
- through the ExifData interface. The role of %MakerNote is very similar to
- that of class Ifd (but makernotes do not need to be in IFD format, see
- below). In addition, it provides %MakerNote specific tag descriptions and
- print functions to interpret the makernote values.
-
- MakerNote holds methods and functionality to
- - read the makernote from a character buffer
- - copy the makernote to a character buffer
- - maintain a list of makernote entries (similar to IFD entries)
- - interpret (print) the values of makernote tags
-
- Makernotes can be added to the system by subclassing %MakerNote and
- registering a create function for the new subclass together with the
- camera make and model (which may contain wildcards) in the
- MakerNoteFactory. Since the majority of makernotes are in IFD format,
- subclass IfdMakerNote is provided. It contains an IFD container and
- implements all interface methods related to the makernote entries. <BR>
-
- To implement a new IFD makernote, all that you need to do is
- - subclass %IfdMakerNote,
- - implement methods to read and check the header (if any) as well as
- clone and create functions,
- - add a list of tag descriptions and appropriate print functions and
- - register the camera make/model and create function in the makernote factory.
- .
- See existing makernote implementations for examples, e.g., CanonMakerNote
- or FujiMakerNote.
-
- Finally, the header file which defines the static variable
- \em register*MakerNote needs to be included from mn.hpp, to ensure that
- the makernote is automatically registered in the factory.
- */
- class MakerNote {
- //! @name Not implemented
- //@{
- //! Assignment not allowed (memory management mode alloc_ is const)
- MakerNote& operator=(const MakerNote& rhs);
- //@}
-
- public:
- //! Shortcut for a %MakerNote auto pointer.
- typedef std::auto_ptr<MakerNote> AutoPtr;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor. Allows to choose whether or not memory management
- is required for the Entries.
- */
- explicit MakerNote(bool alloc =true);
- //! Virtual destructor.
- virtual ~MakerNote() {}
- //@}
-
- //! @name Manipulators
- //@{
- /*!
- @brief Read the makernote, including the makernote header, from
- character buffer buf of length len at position offset (from the
- start of the TIFF header) and encoded in byte order byteOrder.
- Return 0 if successful.
- */
- virtual int read(const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset) =0;
- /*!
- @brief Copy (write) the makerNote to the character buffer buf at
- position offset (from the start of the TIFF header), encoded
- in byte order byteOrder. Update internal offsets if necessary.
- Return the number of bytes written.
- */
- virtual long copy(byte* buf, ByteOrder byteOrder, long offset) =0;
- /*!
- @brief Add the entry to the makernote. No duplicate-check is performed,
- i.e., it is possible to add multiple entries with the same tag.
- The memory allocation mode of the entry to be added must be the
- same as that of the makernote and the IFD id of the entry must
- be set to 'makerIfd'.
- */
- virtual void add(const Entry& entry) =0;
- //! The first makernote entry
- virtual Entries::iterator begin() =0;
- //! End of the makernote entries
- virtual Entries::iterator end() =0;
- /*!
- @brief Update the base pointer of the %MakerNote and all its entries
- to \em pNewBase.
-
- Allows to re-locate the underlying data buffer to a new location
- \em pNewBase. This method only has an effect in non-alloc mode.
- */
- virtual void updateBase(byte* pNewBase) =0;
- //@}
-
- //! @name Accessors
- //@{
- //! Return the byte order (little or big endian).
- ByteOrder byteOrder() const { return byteOrder_; }
- //! Return the offset of the makernote from the start of the TIFF header
- long offset() const { return offset_; }
- /*!
- @brief Return an auto-pointer to an newly created, empty instance of
- the same type as this. The makernote entries are <B>not</B>
- copied. The caller owns the new object and the auto-pointer
- ensures that it will be deleted.
-
- @param alloc Memory management model for the newly created object.
- Indicates if memory required to store data should be allocated
- and deallocated (true) or not (false). If false, only pointers
- to the buffer provided to read() will be kept. See Ifd for more
- background on this concept.
- */
- AutoPtr create(bool alloc =true) const;
- /*!
- @brief Return an auto-pointer to a clone of this object. The caller
- owns the new object and the auto-pointer ensures that it will
- be deleted.
-
- @note In non-alloc mode the clone potentially contains pointers to
- the same data buffer as the original.
- Use updateBase(byte* pNewBase) to adjust them.
- */
- AutoPtr clone() const;
- //! The first makernote entry
- virtual Entries::const_iterator begin() const =0;
- //! End of the makernote entries
- virtual Entries::const_iterator end() const =0;
- //! Find an entry by idx, return a const iterator to the record
- virtual Entries::const_iterator findIdx(int idx) const =0;
- //! Return the size of the makernote in bytes
- virtual long size() const =0;
- //@}
-
- protected:
- // DATA
- /*!
- @brief Flag to control the memory management: <BR>
- True: requires memory allocation and deallocation, <BR>
- False: no memory management needed.
- */
- const bool alloc_;
- /*!
- @brief Offset of the makernote from the start of the TIFF header
- (for offset()).
- */
- long offset_;
- /*!
- @brief Alternative byte order to use, invalid if the byte order of the
- Exif block can be used
- */
- ByteOrder byteOrder_;
-
- private:
- //! Internal virtual create function.
- virtual MakerNote* create_(bool alloc =true) const =0;
- //! Internal virtual copy constructor.
- virtual MakerNote* clone_() const =0;
-
- }; // class MakerNote
-
- //! Type for a pointer to a function creating a makernote
- typedef MakerNote::AutoPtr (*CreateFct)(bool, const byte*, long, ByteOrder, long);
-
- /*!
- @brief Interface for MakerNotes in IFD format. See MakerNote.
- */
- class IfdMakerNote : public MakerNote {
- //! @name Not implemented
- //@{
- //! Assignment not allowed (Ifd does not have an assignment operator)
- IfdMakerNote& operator=(const IfdMakerNote& rhs);
- //@}
-
- public:
- //! Shortcut for an %IfdMakerNote auto pointer.
- typedef std::auto_ptr<IfdMakerNote> AutoPtr;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor. Requires an %Ifd id and allows to choose whether
- or not memory management is needed for the Entries and whether
- the IFD has a next pointer.
- */
- explicit IfdMakerNote(IfdId ifdId, bool alloc =true, bool hasNext =true);
- //! Copy constructor
- IfdMakerNote(const IfdMakerNote& rhs);
- //! Virtual destructor
- virtual ~IfdMakerNote() {}
- //@}
-
- //! @name Manipulators
- //@{
- virtual int read(const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset);
- /*!
- @brief Read the makernote header from the makernote databuffer. This
- method must set the offset adjustment (adjOffset_), if needed
- (assuming that the required information is in the header).
- Return 0 if successful.
- @note The default implementation does nothing, assuming there is no
- header
- */
- virtual int readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder);
- virtual long copy(byte* buf, ByteOrder byteOrder, long offset);
- virtual void add(const Entry& entry) { ifd_.add(entry); }
- virtual Entries::iterator begin() { return ifd_.begin(); }
- virtual Entries::iterator end() { return ifd_.end(); }
- virtual void updateBase(byte* pNewBase);
- //@}
-
- //! @name Accessors
- //@{
- virtual Entries::const_iterator begin() const { return ifd_.begin(); }
- virtual Entries::const_iterator end() const { return ifd_.end(); }
- virtual Entries::const_iterator findIdx(int idx) const;
- virtual long size() const;
- AutoPtr create(bool alloc =true) const;
- AutoPtr clone() const;
- /*!
- @brief Check the makernote header. This will typically check if a
- required prefix string is present in the header. Return 0 if
- successful.
- @note The default implementation does nothing, assuming there is no
- header
- */
- virtual int checkHeader() const;
- /*!
- @brief Write the makernote header to a character buffer, return the
- number of characters written.
- @note The default implementation copies the header_ buffer.
- */
- virtual long copyHeader(byte* buf) const;
- /*!
- @brief Return the size of the makernote header in bytes.
- @note The default implementation returns the size of the header_
- buffer.
- */
- virtual long headerSize() const;
- //@}
-
- protected:
- // DATA
- /*!
- @brief True: Adjustment of the IFD offsets is to be added to the
- offset from the start of the TIFF header (i.e., the
- start of the Exif data section),
- False: Adjustment of the IFD offsets is a suitable absolute
- value. Ignore the offset from the start of the TIFF
- header.
- */
- bool absOffset_;
- /*!
- @brief Adjustment of the IFD offsets relative to the start of the
- TIFF header or to the start of the makernote, depending on
- the setting of absOffset_.
- */
- long adjOffset_;
- //! Data buffer for the makernote header
- DataBuf header_;
- //! The makernote IFD
- Ifd ifd_;
-
- private:
- virtual IfdMakerNote* create_(bool alloc =true) const =0;
- virtual IfdMakerNote* clone_() const =0;
-
- }; // class IfdMakerNote
-
- /*!
- @brief Factory for MakerNote objects.
-
- Maintains an associative list (tree) of camera makes/models and
- corresponding %MakerNote create functions. Creates an instance of the
- %MakerNote for one camera make/model. The factory is implemented as a
- static class.
- */
- class MakerNoteFactory {
- public:
- //! Destructor.
- static void cleanup();
- /*!
- @brief Register a %MakerNote create function for a camera make and
- model.
-
- Registers a create function for a %MakerNote for a given make and
- model combination with the factory. Both the make and model strings
- may contain wildcards ('*', e.g., "Canon*"). If the make already
- exists in the registry, then a new branch for the model is added. If
- the model also already exists, then the new create function replaces
- the old one.
-
- @param make Camera manufacturer. (Typically the string from the Exif
- make tag.)
- @param model Camera model. (Typically the string from the Exif
- model tag.)
- @param createMakerNote Pointer to a function to create a new
- %MakerNote of a particular type.
- */
- static void registerMakerNote(const std::string& make,
- const std::string& model,
- CreateFct createMakerNote);
-
- //! Register a %MakerNote prototype in the IFD id registry.
- static void registerMakerNote(IfdId ifdId, MakerNote::AutoPtr makerNote);
-
- /*!
- @brief Create the appropriate %MakerNote based on camera make and
- model and possibly the contents of the makernote itself, return
- an auto-pointer to the newly created MakerNote instance. Return
- 0 if no %MakerNote is defined for the camera model.
-
- The method searches the make-model tree for a make and model
- combination in the registry that matches the search key. The search is
- case insensitive (Todo: implement case-insensitive comparisons) and
- wildcards in the registry entries are supported. First the best
- matching make is searched, then the best matching model for this make
- is searched. If there is no matching make or no matching model within
- the models registered for the best matching make, then no makernote
- is created and the function returns 0. If a match is found, the
- function invokes the registered create function and returns an
- auto-pointer to the newly created MakerNote. The makernote pointed to
- is owned by the caller of the function and the auto-pointer ensures
- that it is deleted. The best match is an exact match, then a match is
- rated according to the number of matching characters. The makernote
- buffer is passed on to the create function, which can based on its
- content, automatically determine the correct version or flavour of the
- makernote required. This is used, e.g., to determine which of the
- three Nikon makernotes to create.
-
- @param make Camera manufacturer. (Typically the string from the Exif
- make tag.)
- @param model Camera model. (Typically the string from the Exif
- model tag.)
- @param alloc Memory management model for the new MakerNote. Determines
- if memory required to store data should be allocated and
- deallocated (true) or not (false). If false, only pointers to
- the buffer provided to read() will be kept. See Ifd for more
- background on this concept.
- @param buf Pointer to the makernote character buffer.
- @param len Length of the makernote character buffer.
- @param byteOrder Byte order in which the Exif data (and possibly the
- makernote) is encoded.
- @param offset Offset from the start of the TIFF header of the makernote
- buffer.
-
- @return An auto-pointer that owns a %MakerNote for the camera model.
- If the camera is not supported, the pointer is 0.
- */
- static MakerNote::AutoPtr create(const std::string& make,
- const std::string& model,
- bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset);
-
- //! Create a %MakerNote for an IFD id.
- static MakerNote::AutoPtr create(IfdId ifdId, bool alloc =true);
-
- /*!
- @brief Match a registry entry with a key (used for make and model).
-
- The matching algorithm is case insensitive and wildcards ('*') in the
- registry entry are supported. The best match is an exact match, then
- a match is rated according to the number of matching characters.
-
- @return A score value indicating how good the key and registry entry
- match. 0 means no match, values greater than 0 indicate a
- match, larger values are better matches:<BR>
- 0: key and registry entry do not match<BR>
- 1: a pure wildcard match, i.e., the registry entry is just
- a wildcard.<BR>
- Score values greater than 1 are computed by adding 1 to the
- number of matching characters, except for an exact match,
- which scores 2 plus the number of matching characters.
- */
- static int match(const std::string& regEntry, const std::string& key);
-
- /*!
- @brief Class Init is used to execute initialisation and termination
- code exactly once, at the begin and end of the program.
-
- See Bjarne Stroustrup, 'The C++ Programming Language 3rd
- Edition', section 21.5.2 for details about this pattern.
- */
- class Init {
- static int count; //!< Counts calls to constructor
- public:
- //! @name Creators
- //@{
- //! Perform one-time initialisations.
- Init();
- //! Perform one-time cleanup operations.
- ~Init();
- //@}
- };
-
- private:
- //! @name Creators
- //@{
- //! Prevent construction: not implemented.
- MakerNoteFactory() {}
- //! Prevent copy construction: not implemented.
- MakerNoteFactory(const MakerNoteFactory& rhs);
- //@}
-
- //! Creates the private static instance
- static void init();
-
- //! Type used to store model labels and %MakerNote create functions
- typedef std::vector<std::pair<std::string, CreateFct> > ModelRegistry;
- //! Type used to store a list of make labels and model registries
- typedef std::vector<std::pair<std::string, ModelRegistry*> > Registry;
- //! Type used to store a list of IFD ids and %MakerNote prototypes
- typedef std::map<IfdId, MakerNote*> IfdIdRegistry;
-
- // DATA
- //! List of makernote types and corresponding makernote create functions.
- static Registry* pRegistry_;
- //! List of makernote IFD ids and corresponding create functions.
- static IfdIdRegistry* pIfdIdRegistry_;
-
- }; // class MakerNoteFactory
-
-} // namespace Exiv2
-
-namespace {
- /*!
- Each translation unit that includes makernote.hpp declares its own
- Init object. The destructor ensures that the factory is properly
- freed exactly once.
-
- See Bjarne Stroustrup, 'The C++ Programming Language 3rd
- Edition', section 21.5.2 for details about this pattern.
- */
- Exiv2::MakerNoteFactory::Init makerNoteFactoryInit;
-}
-
-#endif // #ifndef MAKERNOTE_HPP_
diff --git a/src/plugins/exiv2/metadatum.cpp b/src/plugins/exiv2/metadatum.cpp
@@ -1,76 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: metadatum.cpp
- Version: $Rev: 538 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- Brad Schick (brad) <brad@robotbattle.com>
- History: 26-Jan-04, ahu: created
- 31-Jul-04, brad: isolated as a component
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: metadatum.cpp 538 2005-03-12 16:43:06Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "metadatum.hpp"
-
-// + standard includes
-#include <iostream>
-#include <iomanip>
-
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- Key::AutoPtr Key::clone() const
- {
- return AutoPtr(clone_());
- }
-
- std::ostream& operator<<(std::ostream& os, const Metadatum& md)
- {
- os << "0x" << std::setw(4) << std::setfill('0') << std::right
- << std::hex << md.tag() << " "
- << std::setw(40) << std::setfill(' ') << std::left
- << md.key() << " "
- << std::setw(9) << std::setfill(' ') << std::left
- << md.typeName() << " "
- << std::dec << md.value()
- << "\n";
- return os;
- }
-
- bool cmpMetadataByTag(const Metadatum& lhs, const Metadatum& rhs)
- {
- return lhs.tag() < rhs.tag();
- }
-
-
- bool cmpMetadataByKey(const Metadatum& lhs, const Metadatum& rhs)
- {
- return lhs.key() < rhs.key();
- }
-
-} // namespace Exiv2
-
diff --git a/src/plugins/exiv2/metadatum.hpp b/src/plugins/exiv2/metadatum.hpp
@@ -1,294 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file metadatum.hpp
- @brief Provides abstract base classes Metadatum and Key
- @version $Rev: 560 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @author Brad Schick (brad)
- <a href="mailto:brad@robotbattle.com">brad@robotbattle.com</a>
- @date 09-Jan-04, ahu: created<BR>
- 31-Jul-04, brad: isolated as a component<BR>
- 23-Aug-04, ahu: added Key
- */
-#ifndef METADATUM_HPP_
-#define METADATUM_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "value.hpp"
-
-// + standard includes
-#include <string>
-#include <memory>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class definitions
-
- /*!
- @brief Abstract base class defining the %Key of a metadatum.
- Keys are used to identify and group metadata.
- */
- class Key {
- public:
- //! Shortcut for a %Key auto pointer.
- typedef std::auto_ptr<Key> AutoPtr;
-
- //! @name Creators
- //@{
- //! Destructor
- virtual ~Key() {}
- //@}
-
- //! @name Accessors
- //@{
- /*!
- @brief Return the key of the metadatum as a string. The key is of the
- form 'familyName.groupName.tagName'. Note however that the
- key is not necessarily unique, e.g., an ExifData may contain
- multiple metadata with the same key.
- */
- virtual std::string key() const =0;
- //! Return an identifier for the type of metadata (the first part of the key)
- virtual const char* familyName() const =0;
- //! Return the name of the group (the second part of the key)
- virtual std::string groupName() const =0;
- //! Return the name of the tag (which is also the third part of the key)
- virtual std::string tagName() const =0;
- //! Return the tag number
- virtual uint16_t tag() const =0;
- /*!
- @brief Return an auto-pointer to a copy of itself (deep copy).
- The caller owns this copy and the auto-pointer ensures that it
- will be deleted.
- */
- AutoPtr clone() const;
- /*!
- @brief Write the key to an output stream. You do not usually have
- to use this function; it is used for the implementation of
- the output operator for %Key,
- operator<<(std::ostream &os, const Key &key).
- */
- std::ostream& write(std::ostream& os) const { return os << key(); }
- //@}
-
- protected:
- //! @name Manipulators
- //@{
- /*!
- @brief Assignment operator. Protected so that it can only be used
- by subclasses but not directly.
- */
- Key& operator=(const Key& rhs) { return *this; }
- //@}
-
- private:
- //! Internal virtual copy constructor.
- virtual Key* clone_() const =0;
-
- }; // class Key
-
- //! Output operator for Key types
- inline std::ostream& operator<<(std::ostream& os, const Key& key)
- {
- return key.write(os);
- }
-
- /*!
- @brief Abstract base class defining the interface to access information
- related to one metadata tag.
- */
- class Metadatum {
- public:
- //! @name Creators
- //@{
- //! Default Constructor
- Metadatum() {}
- //! Copy constructor
- Metadatum(const Metadatum& rhs) {}
- //! Destructor
- virtual ~Metadatum() {}
- //@}
-
- //! @name Manipulators
- //@{
- /*!
- @brief Set the value. This method copies (clones) the value pointed
- to by pValue.
- */
- virtual void setValue(const Value* pValue) =0;
- /*!
- @brief Set the value to the string buf.
- Uses Value::read(const std::string& buf). If the metadatum does
- not have a value yet, then an AsciiValue is created.
- */
- virtual void setValue(const std::string& buf) =0;
- //@}
-
- //! @name Accessors
- //@{
- /*!
- @brief Write value to a data buffer and return the number
- of bytes written.
-
- The user must ensure that the buffer has enough memory. Otherwise
- the call results in undefined behaviour.
-
- @param buf Data buffer to write to.
- @param byteOrder Applicable byte order (little or big endian).
- @return Number of characters written.
- */
- virtual long copy(byte* buf, ByteOrder byteOrder) const =0;
- /*!
- @brief Return the key of the metadatum. The key is of the form
- 'familyName.ifdItem.tagName'. Note however that the key
- is not necessarily unique, i.e., an ExifData may contain
- multiple metadata with the same key.
- */
- virtual std::string key() const =0;
- //! Return the name of the tag (which is also the third part of the key)
- virtual std::string tagName() const =0;
- //! Return the tag
- virtual uint16_t tag() const =0;
- //! Return the type id of the value
- virtual TypeId typeId() const =0;
- //! Return the name of the type
- virtual const char* typeName() const =0;
- //! Return the size in bytes of one component of this type
- virtual long typeSize() const =0;
- //! Return the number of components in the value
- virtual long count() const =0;
- //! Return the size of the value in bytes
- virtual long size() const =0;
- //! Return the value as a string.
- virtual std::string toString() const =0;
- /*!
- @brief Return the n-th component of the value converted to long. The
- return value is -1 if the value of the Metadatum is not set and
- the behaviour of the method is undefined if there is no n-th
- component.
- */
- virtual long toLong(long n =0) const =0;
- /*!
- @brief Return the n-th component of the value converted to float. The
- return value is -1 if the value of the Metadatum is not set and
- the behaviour of the method is undefined if there is no n-th
- component.
- */
- virtual float toFloat(long n =0) const =0;
- /*!
- @brief Return the n-th component of the value converted to
- Rational. The return value is -1/1 if the value of the
- Metadatum is not set and the behaviour of the method is
- undefined if there is no n-th component.
- */
- virtual Rational toRational(long n =0) const =0;
- /*!
- @brief Return an auto-pointer to a copy (clone) of the value. The
- caller owns this copy and the auto-poiner ensures that it will
- be deleted.
-
- This method is provided for users who need full control over the
- value. A caller may, e.g., downcast the pointer to the appropriate
- subclass of Value to make use of the interface of the subclass to set
- or modify its contents.
-
- @return An auto-pointer containing a pointer to a copy (clone) of the
- value, 0 if the value is not set.
- */
- virtual Value::AutoPtr getValue() const =0;
- /*!
- @brief Return a constant reference to the value.
-
- This method is provided mostly for convenient and versatile output of
- the value which can (to some extent) be formatted through standard
- stream manipulators. Do not attempt to write to the value through
- this reference.
-
- <b>Example:</b> <br>
- @code
- ExifData::const_iterator i = exifData.findKey(key);
- if (i != exifData.end()) {
- std::cout << i->key() << " " << std::hex << i->value() << "\n";
- }
- @endcode
-
- @return A constant reference to the value.
- @throw Error if the value is not set.
- */
- virtual const Value& value() const =0;
- //@}
-
- protected:
- //! @name Manipulators
- //@{
- /*!
- @brief Assignment operator. Protected so that it can only be used
- by subclasses but not directly.
- */
- Metadatum& operator=(const Metadatum& rhs) { return *this; }
- //@}
-
- }; // class Metadatum
-
- //! Unary predicate that matches a Exifdatum with a given key
- class FindMetadatumByKey {
- public:
- //! Constructor, initializes the object with the tag to look for
- FindMetadatumByKey(const std::string& key) : key_(key) {}
- /*!
- @brief Returns true if the key of the argument metadatum is equal
- to that of the object.
- */
- bool operator()(const Metadatum& metadatum) const
- { return key_ == metadatum.key(); }
-
- private:
- std::string key_;
-
- }; // class FindMetadatumByTag
-
-
- /*!
- @brief Output operator for Metadatum types, printing the interpreted
- tag value.
- */
- std::ostream& operator<<(std::ostream& os, const Metadatum& md);
- /*!
- @brief Compare two metadata by tag. Return true if the tag of metadatum
- lhs is less than that of rhs.
- */
- bool cmpMetadataByTag(const Metadatum& lhs, const Metadatum& rhs);
- /*!
- @brief Compare two metadata by key. Return true if the key of metadatum
- lhs is less than that of rhs.
- */
- bool cmpMetadataByKey(const Metadatum& lhs, const Metadatum& rhs);
-
-} // namespace Exiv2
-
-#endif // #ifndef METADATUM_HPP_
diff --git a/src/plugins/exiv2/mn.hpp b/src/plugins/exiv2/mn.hpp
@@ -1,43 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file mn.hpp
- @brief Include all makernote header files. Makes sure that the static
- variable used to register makernotes is instantiated.
- @version $Rev: 581 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 28-May-05, ahu: created
- */
-#ifndef MN_HPP_
-#define MN_HPP_
-
-// *****************************************************************************
-// included header files
-#include "canonmn.hpp"
-#include "fujimn.hpp"
-#include "nikonmn.hpp"
-#include "olympusmn.hpp"
-#include "panasonicmn.hpp"
-#include "sigmamn.hpp"
-#include "sonymn.hpp"
-
-#endif // #ifndef MN_HPP_
diff --git a/src/plugins/exiv2/nikonmn.cpp b/src/plugins/exiv2/nikonmn.cpp
@@ -1,870 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * Lens database to decode Exif.Nikon3.LensData
- * Copyright (C) 2005 Robert Rottmerhusen <email@rottmerhusen.com>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: nikonmn.cpp
- Version: $Rev: 588 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 17-May-04, ahu: created
- 25-May-04, ahu: combined all Nikon formats in one component
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: nikonmn.cpp 588 2005-06-14 13:57:39Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "nikonmn.hpp"
-#include "makernote.hpp"
-#include "value.hpp"
-#include "image.hpp"
-#include "tags.hpp"
-#include "error.hpp"
-
-// + standard includes
-#include <string>
-#include <sstream>
-#include <iomanip>
-#include <cassert>
-#include <cstring>
-
-#define EXV_HAVE_LENSDATA
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- //! @cond IGNORE
- Nikon1MakerNote::RegisterMn::RegisterMn()
- {
- MakerNoteFactory::registerMakerNote("NIKON*", "*", createNikonMakerNote);
- MakerNoteFactory::registerMakerNote(
- nikon1IfdId, MakerNote::AutoPtr(new Nikon1MakerNote));
-
- ExifTags::registerMakerTagInfo(nikon1IfdId, tagInfo_);
- }
- //! @endcond
-
- // Nikon1 MakerNote Tag Info
- const TagInfo Nikon1MakerNote::tagInfo_[] = {
- TagInfo(0x0001, "Version", "Nikon Makernote version", nikon1IfdId, makerTags, undefined, printValue),
- TagInfo(0x0002, "ISOSpeed", "ISO speed setting", nikon1IfdId, makerTags, unsignedShort, print0x0002),
- TagInfo(0x0003, "ColorMode", "Color mode", nikon1IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0004, "Quality", "Image quality setting", nikon1IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0005, "WhiteBalance", "White balance", nikon1IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0006, "Sharpening", "Image sharpening setting", nikon1IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0007, "Focus", "Focus mode", nikon1IfdId, makerTags, asciiString, print0x0007),
- TagInfo(0x0008, "Flash", "Flash mode", nikon1IfdId, makerTags, asciiString, printValue),
- TagInfo(0x000a, "0x000a", "Unknown", nikon1IfdId, makerTags, unsignedRational, printValue),
- TagInfo(0x000f, "ISOSelection", "ISO selection", nikon1IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0010, "DataDump", "Data dump", nikon1IfdId, makerTags, undefined, printValue),
- TagInfo(0x0080, "ImageAdjustment", "Image adjustment setting", nikon1IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0082, "Adapter", "Adapter used", nikon1IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0085, "FocusDistance", "Manual focus distance", nikon1IfdId, makerTags, unsignedRational, print0x0085),
- TagInfo(0x0086, "DigitalZoom", "Digital zoom setting", nikon1IfdId, makerTags, unsignedRational, print0x0086),
- TagInfo(0x0088, "AFFocusPos", "AF focus position", nikon1IfdId, makerTags, undefined, print0x0088),
- // End of list marker
- TagInfo(0xffff, "(UnknownNikon1MnTag)", "Unknown Nikon1MakerNote tag", nikon1IfdId, makerTags, invalidTypeId, printValue)
- };
-
- Nikon1MakerNote::Nikon1MakerNote(bool alloc)
- : IfdMakerNote(nikon1IfdId, alloc)
- {
- }
-
- Nikon1MakerNote::Nikon1MakerNote(const Nikon1MakerNote& rhs)
- : IfdMakerNote(rhs)
- {
- }
-
- Nikon1MakerNote::AutoPtr Nikon1MakerNote::create(bool alloc) const
- {
- return AutoPtr(create_(alloc));
- }
-
- Nikon1MakerNote* Nikon1MakerNote::create_(bool alloc) const
- {
- return new Nikon1MakerNote(alloc);
- }
-
- Nikon1MakerNote::AutoPtr Nikon1MakerNote::clone() const
- {
- return AutoPtr(clone_());
- }
-
- Nikon1MakerNote* Nikon1MakerNote::clone_() const
- {
- return new Nikon1MakerNote(*this);
- }
-
- std::ostream& Nikon1MakerNote::print0x0002(std::ostream& os,
- const Value& value)
- {
- if (value.count() > 1) {
- os << value.toLong(1);
- }
- else {
- os << "(" << value << ")";
- }
- return os;
- }
-
- std::ostream& Nikon1MakerNote::print0x0007(std::ostream& os,
- const Value& value)
- {
- std::string focus = value.toString();
- if (focus == "AF-C ") os << "Continuous autofocus";
- else if (focus == "AF-S ") os << "Single autofocus";
- else os << "(" << value << ")";
- return os;
- }
-
- std::ostream& Nikon1MakerNote::print0x0085(std::ostream& os,
- const Value& value)
- {
- Rational distance = value.toRational();
- if (distance.first == 0) {
- os << "Unknown";
- }
- else if (distance.second != 0) {
- std::ostringstream oss;
- oss.copyfmt(os);
- os << std::fixed << std::setprecision(2)
- << (float)distance.first / distance.second
- << " m";
- os.copyfmt(oss);
- }
- else {
- os << "(" << value << ")";
- }
- return os;
- }
-
- std::ostream& Nikon1MakerNote::print0x0086(std::ostream& os,
- const Value& value)
- {
- Rational zoom = value.toRational();
- if (zoom.first == 0) {
- os << "Not used";
- }
- else if (zoom.second != 0) {
- std::ostringstream oss;
- oss.copyfmt(os);
- os << std::fixed << std::setprecision(1)
- << (float)zoom.first / zoom.second
- << "x";
- os.copyfmt(oss);
- }
- else {
- os << "(" << value << ")";
- }
- return os;
- }
-
- std::ostream& Nikon1MakerNote::print0x0088(std::ostream& os,
- const Value& value)
- {
- if (value.count() > 1) {
- switch (value.toLong(1)) {
- case 0: os << "Center"; break;
- case 1: os << "Top"; break;
- case 2: os << "Bottom"; break;
- case 3: os << "Left"; break;
- case 4: os << "Right"; break;
- default: os << "(" << value << ")"; break;
- }
- }
- else {
- os << "(" << value << ")";
- }
- return os;
- }
-
- //! @cond IGNORE
- Nikon2MakerNote::RegisterMn::RegisterMn()
- {
- MakerNoteFactory::registerMakerNote(
- nikon2IfdId, MakerNote::AutoPtr(new Nikon2MakerNote));
-
- ExifTags::registerMakerTagInfo(nikon2IfdId, tagInfo_);
- }
- //! @endcond
-
- // Nikon2 MakerNote Tag Info
- const TagInfo Nikon2MakerNote::tagInfo_[] = {
- TagInfo(0x0002, "0x0002", "Unknown", nikon2IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0003, "Quality", "Image quality setting", nikon2IfdId, makerTags, unsignedShort, print0x0003),
- TagInfo(0x0004, "ColorMode", "Color mode", nikon2IfdId, makerTags, unsignedShort, print0x0004),
- TagInfo(0x0005, "ImageAdjustment", "Image adjustment setting", nikon2IfdId, makerTags, unsignedShort, print0x0005),
- TagInfo(0x0006, "ISOSpeed", "ISO speed setting", nikon2IfdId, makerTags, unsignedShort, print0x0006),
- TagInfo(0x0007, "WhiteBalance", "White balance", nikon2IfdId, makerTags, unsignedShort, print0x0007),
- TagInfo(0x0008, "Focus", "Focus mode", nikon2IfdId, makerTags, unsignedRational, printValue),
- TagInfo(0x0009, "0x0009", "Unknown", nikon2IfdId, makerTags, asciiString, printValue),
- TagInfo(0x000a, "DigitalZoom", "Digital zoom setting", nikon2IfdId, makerTags, unsignedRational, print0x000a),
- TagInfo(0x000b, "Adapter", "Adapter used", nikon2IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0f00, "0x0f00", "Unknown", nikon2IfdId, makerTags, unsignedLong, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownNikon2MnTag)", "Unknown Nikon2MakerNote tag", nikon2IfdId, makerTags, invalidTypeId, printValue)
- };
-
- Nikon2MakerNote::Nikon2MakerNote(bool alloc)
- : IfdMakerNote(nikon2IfdId, alloc)
- {
- byte buf[] = {
- 'N', 'i', 'k', 'o', 'n', '\0', 0x00, 0x01
- };
- readHeader(buf, 8, byteOrder_);
- }
-
- Nikon2MakerNote::Nikon2MakerNote(const Nikon2MakerNote& rhs)
- : IfdMakerNote(rhs)
- {
- }
-
- int Nikon2MakerNote::readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder)
- {
- if (len < 8) return 1;
-
- header_.alloc(8);
- memcpy(header_.pData_, buf, header_.size_);
- adjOffset_ = 8;
- return 0;
- }
-
- int Nikon2MakerNote::checkHeader() const
- {
- int rc = 0;
- // Check the Nikon prefix
- if ( header_.size_ < 8
- || std::string(reinterpret_cast<char*>(header_.pData_), 6)
- != std::string("Nikon\0", 6)) {
- rc = 2;
- }
- return rc;
- }
-
- Nikon2MakerNote::AutoPtr Nikon2MakerNote::create(bool alloc) const
- {
- return AutoPtr(create_(alloc));
- }
-
- Nikon2MakerNote* Nikon2MakerNote::create_(bool alloc) const
- {
- AutoPtr makerNote(new Nikon2MakerNote(alloc));
- assert(makerNote.get() != 0);
- makerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
- return makerNote.release();
- }
-
- Nikon2MakerNote::AutoPtr Nikon2MakerNote::clone() const
- {
- return AutoPtr(clone_());
- }
-
- Nikon2MakerNote* Nikon2MakerNote::clone_() const
- {
- return new Nikon2MakerNote(*this);
- }
-
- std::ostream& Nikon2MakerNote::print0x0003(std::ostream& os,
- const Value& value)
- {
- long quality = value.toLong();
- switch (quality) {
- case 1: os << "VGA Basic"; break;
- case 2: os << "VGA Normal"; break;
- case 3: os << "VGA Fine"; break;
- case 4: os << "SXGA Basic"; break;
- case 5: os << "SXGA Normal"; break;
- case 6: os << "SXGA Fine"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& Nikon2MakerNote::print0x0004(std::ostream& os,
- const Value& value)
- {
- long color = value.toLong();
- switch (color) {
- case 1: os << "Color"; break;
- case 2: os << "Monochrome"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& Nikon2MakerNote::print0x0005(std::ostream& os,
- const Value& value)
- {
- long adjustment = value.toLong();
- switch (adjustment) {
- case 0: os << "Normal"; break;
- case 1: os << "Bright+"; break;
- case 2: os << "Bright-"; break;
- case 3: os << "Contrast+"; break;
- case 4: os << "Contrast-"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& Nikon2MakerNote::print0x0006(std::ostream& os,
- const Value& value)
- {
- long iso = value.toLong();
- switch (iso) {
- case 0: os << "80"; break;
- case 2: os << "160"; break;
- case 4: os << "320"; break;
- case 5: os << "100"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& Nikon2MakerNote::print0x0007(std::ostream& os,
- const Value& value)
- {
- long wb = value.toLong();
- switch (wb) {
- case 0: os << "Auto"; break;
- case 1: os << "Preset"; break;
- case 2: os << "Daylight"; break;
- case 3: os << "Incandescent"; break;
- case 4: os << "Fluorescent"; break;
- case 5: os << "Cloudy"; break;
- case 6: os << "Speedlight"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& Nikon2MakerNote::print0x000a(std::ostream& os,
- const Value& value)
- {
- Rational zoom = value.toRational();
- if (zoom.first == 0) {
- os << "Not used";
- }
- else if (zoom.second != 0) {
- std::ostringstream oss;
- oss.copyfmt(os);
- os << std::fixed << std::setprecision(1)
- << (float)zoom.first / zoom.second
- << "x";
- os.copyfmt(oss);
- }
- else {
- os << "(" << value << ")";
- }
- return os;
- }
-
- //! @cond IGNORE
- Nikon3MakerNote::RegisterMn::RegisterMn()
- {
- MakerNoteFactory::registerMakerNote(
- nikon3IfdId, MakerNote::AutoPtr(new Nikon3MakerNote));
-
- ExifTags::registerMakerTagInfo(nikon3IfdId, tagInfo_);
- }
- //! @endcond
-
- // Nikon3 MakerNote Tag Info
- const TagInfo Nikon3MakerNote::tagInfo_[] = {
- TagInfo(0x0001, "Version", "Nikon Makernote version", nikon3IfdId, makerTags, undefined, printValue),
- TagInfo(0x0002, "ISOSpeed", "ISO speed used", nikon3IfdId, makerTags, unsignedShort, print0x0002),
- TagInfo(0x0003, "ColorMode", "Color mode", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0004, "Quality", "Image quality setting", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0005, "WhiteBalance", "White balance", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0006, "Sharpening", "Image sharpening setting", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0007, "Focus", "Focus mode", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0008, "FlashSetting", "Flash setting", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0009, "FlashMode", "Flash mode", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x000b, "WhiteBalanceBias", "White balance bias", nikon3IfdId, makerTags, signedShort, printValue),
-// TagInfo(0x000c, "ColorBalance1", "Color balance 1", nikon3IfdId, makerTags, xxx, printValue),
- TagInfo(0x000d, "0x000d", "Unknown", nikon3IfdId, makerTags, undefined, printValue),
- TagInfo(0x000e, "ExposureDiff", "Exposure difference", nikon3IfdId, makerTags, undefined, printValue),
- TagInfo(0x000f, "ISOSelection", "ISO selection", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0010, "DataDump", "Data dump", nikon3IfdId, makerTags, undefined, printValue),
- TagInfo(0x0011, "ThumbOffset", "Thumbnail IFD offset", nikon3IfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x0012, "FlashComp", "Flash compensation setting", nikon3IfdId, makerTags, undefined, print0x0012),
- TagInfo(0x0013, "ISOSetting", "ISO speed setting", nikon3IfdId, makerTags, unsignedShort, print0x0002), // use 0x0002 print fct
- TagInfo(0x0016, "ImageBoundry", "Image boundry", nikon3IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0017, "0x0017", "Unknown", nikon3IfdId, makerTags, undefined, printValue),
- TagInfo(0x0018, "FlashBracketComp", "Flash bracket compensation applied", nikon3IfdId, makerTags, undefined, print0x0012), // use 0x0012 print fct
- TagInfo(0x0019, "ExposureBracketComp", "AE bracket compensation applied", nikon3IfdId, makerTags, signedRational, printValue),
- TagInfo(0x0080, "ImageAdjustment", "Image adjustment setting", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0081, "ToneComp", "Tone compensation setting (contrast)", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0082, "AuxiliaryLens", "Auxiliary lens (adapter)", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0083, "LensType", "Lens type", nikon3IfdId, makerTags, unsignedByte, printValue),
- TagInfo(0x0084, "Lens", "Lens", nikon3IfdId, makerTags, unsignedRational, print0x0084),
- TagInfo(0x0085, "FocusDistance", "Manual focus distance", nikon3IfdId, makerTags, unsignedRational, printValue),
- TagInfo(0x0086, "DigitalZoom", "Digital zoom setting", nikon3IfdId, makerTags, unsignedRational, printValue),
- TagInfo(0x0087, "FlashType", "Type of flash used", nikon3IfdId, makerTags, unsignedByte, print0x0087),
- TagInfo(0x0088, "AFFocusPos", "AF focus position", nikon3IfdId, makerTags, undefined, print0x0088),
- TagInfo(0x0089, "Bracketing", "Bracketing", nikon3IfdId, makerTags, unsignedShort, print0x0089),
- TagInfo(0x008a, "0x008a", "Unknown", nikon3IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x008b, "LensFStops", "Number of lens stops", nikon3IfdId, makerTags, undefined, print0x008b),
-// TagInfo(0x008c, "NEFCurve1", "NEF curve 1", nikon3IfdId, makerTags, xxx, printValue),
- TagInfo(0x008d, "ColorMode", "Color mode", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x008f, "SceneMode", "Scene mode", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0090, "LightingType", "Lighting type", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x0091, "0x0091", "Unknown", nikon3IfdId, makerTags, undefined, printValue),
- TagInfo(0x0092, "HueAdjustment", "Hue adjustment", nikon3IfdId, makerTags, signedShort, printValue),
- TagInfo(0x0094, "Saturation", "Saturation adjustment", nikon3IfdId, makerTags, signedShort, printValue),
- TagInfo(0x0095, "NoiseReduction", "Noise reduction", nikon3IfdId, makerTags, asciiString, printValue),
-// TagInfo(0x0096, "NEFCurve2", "NEF curve 2", nikon3IfdId, makerTags, xxx, printValue),
- TagInfo(0x0097, "ColorBalance2", "Color balance 2", nikon3IfdId, makerTags, undefined, printValue),
- TagInfo(0x0098, "LensData", "Lens data", nikon3IfdId, makerTags, undefined, print0x0098),
- TagInfo(0x0099, "NEFThumbnailSize", "NEF thumbnail size", nikon3IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x009a, "0x009a", "Unknown", nikon3IfdId, makerTags, unsignedRational, printValue),
- TagInfo(0x009b, "0x009b", "Unknown", nikon3IfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x009f, "0x009f", "Unknown", nikon3IfdId, makerTags, signedShort, printValue),
- TagInfo(0x00a0, "SerialNumber", "Camera serial number", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x00a2, "0x00a2", "Unknown", nikon3IfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x00a3, "0x00a3", "Unknown", nikon3IfdId, makerTags, unsignedByte, printValue),
- TagInfo(0x00a5, "0x00a5", "Unknown", nikon3IfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x00a6, "0x00a6", "Unknown", nikon3IfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x00a7, "ShutterCount", "Number of shots taken by camera", nikon3IfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x00a8, "0x00a8", "Unknown", nikon3IfdId, makerTags, undefined, printValue),
- TagInfo(0x00a9, "ImageOptimization", "Image optimization", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x00aa, "Saturation", "Saturation", nikon3IfdId, makerTags, asciiString, printValue),
- TagInfo(0x00ab, "VariProgram", "Vari program", nikon3IfdId, makerTags, asciiString, printValue),
-// TagInfo(0x0e00, "PrintIM", "Print image matching", nikon3IfdId, makerTags, xxx, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownNikon3MnTag)", "Unknown Nikon3MakerNote tag", nikon3IfdId, makerTags, invalidTypeId, printValue)
- };
-
- Nikon3MakerNote::Nikon3MakerNote(bool alloc)
- : IfdMakerNote(nikon3IfdId, alloc)
- {
- absOffset_ = false;
- byte buf[] = {
- 'N', 'i', 'k', 'o', 'n', '\0',
- 0x02, 0x10, 0x00, 0x00, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08
- };
- readHeader(buf, 18, byteOrder_);
- }
-
- Nikon3MakerNote::Nikon3MakerNote(const Nikon3MakerNote& rhs)
- : IfdMakerNote(rhs)
- {
- }
-
- int Nikon3MakerNote::readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder)
- {
- if (len < 18) return 1;
-
- header_.alloc(18);
- memcpy(header_.pData_, buf, header_.size_);
- TiffHeader tiffHeader;
- tiffHeader.read(header_.pData_ + 10);
- byteOrder_ = tiffHeader.byteOrder();
- adjOffset_ = tiffHeader.offset();
- return 0;
- }
-
- int Nikon3MakerNote::checkHeader() const
- {
- int rc = 0;
- // Check the Nikon prefix
- if ( header_.size_ < 18
- || std::string(reinterpret_cast<char*>(header_.pData_), 6)
- != std::string("Nikon\0", 6)) {
- rc = 2;
- }
- return rc;
- }
-
- Nikon3MakerNote::AutoPtr Nikon3MakerNote::create(bool alloc) const
- {
- return AutoPtr(create_(alloc));
- }
-
- Nikon3MakerNote* Nikon3MakerNote::create_(bool alloc) const
- {
- AutoPtr makerNote(new Nikon3MakerNote(alloc));
- assert(makerNote.get() != 0);
- makerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
- return makerNote.release();
- }
-
- Nikon3MakerNote::AutoPtr Nikon3MakerNote::clone() const
- {
- return AutoPtr(clone_());
- }
-
- Nikon3MakerNote* Nikon3MakerNote::clone_() const
- {
- return new Nikon3MakerNote(*this);
- }
-
- std::ostream& Nikon3MakerNote::print0x0002(std::ostream& os,
- const Value& value)
- {
- if (value.count() > 1) {
- os << value.toLong(1);
- }
- else {
- os << "(" << value << ")";
- }
- return os;
- }
-
- std::ostream& Nikon3MakerNote::print0x0012(std::ostream& os,
- const Value& value)
- {
- // From the PHP JPEG Metadata Toolkit
- long fec = value.toLong();
- switch (fec) {
- case 0x06: os << "+1.0 EV"; break;
- case 0x04: os << "+0.7 EV"; break;
- case 0x03: os << "+0.5 EV"; break;
- case 0x02: os << "+0.3 EV"; break;
- case 0x00: os << "0.0 EV"; break;
- case 0xfe: os << "-0.3 EV"; break;
- case 0xfd: os << "-0.5 EV"; break;
- case 0xfc: os << "-0.7 EV"; break;
- case 0xfa: os << "-1.0 EV"; break;
- case 0xf8: os << "-1.3 EV"; break;
- case 0xf7: os << "-1.5 EV"; break;
- case 0xf6: os << "-1.7 EV"; break;
- case 0xf4: os << "-2.0 EV"; break;
- case 0xf2: os << "-2.3 EV"; break;
- case 0xf1: os << "-2.5 EV"; break;
- case 0xf0: os << "-2.7 EV"; break;
- case 0xee: os << "-3.0 EV"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& Nikon3MakerNote::print0x0084(std::ostream& os,
- const Value& value)
- {
- if (value.count() == 4) {
- long len1 = value.toLong(0);
- long len2 = value.toLong(1);
- Rational fno1 = value.toRational(2);
- Rational fno2 = value.toRational(3);
- os << len1;
- if (len2 != len1) {
- os << "-" << len2;
- }
- os << "mm "
- << "F" << (float)fno1.first / fno1.second;
- if (fno2 != fno1) {
- os << "-" << (float)fno2.first / fno2.second;
- }
- }
- else {
- os << "(" << value << ")";
- }
- return os;
- }
-
- std::ostream& Nikon3MakerNote::print0x0087(std::ostream& os,
- const Value& value)
- {
- // From Exiftool
- long flash = value.toLong();
- switch (flash) {
- case 0: os << "Not used"; break;
- case 8: os << "Fired, commander mode"; break;
- case 9: os << "Fired, TTL mode"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& Nikon3MakerNote::print0x0088(std::ostream& os,
- const Value& value)
- {
- // Mappings taken from Exiftool
- long afpos = value.toLong();
- switch (afpos) {
- case 0x0000: os << "Center"; break;
- case 0x0100: os << "Top"; break;
- case 0x0200: os << "Bottom"; break;
- case 0x0300: os << "Left"; break;
- case 0x0400: os << "Right"; break;
-
- // D70
- case 0x00001: os << "Single area, center"; break;
- case 0x10002: os << "Single area, top"; break;
- case 0x20004: os << "Single area, bottom"; break;
- case 0x30008: os << "Single area, left"; break;
- case 0x40010: os << "Single area, right"; break;
-
- case 0x1000001: os << "Dynamic area, center"; break;
- case 0x1010002: os << "Dynamic area, top"; break;
- case 0x1020004: os << "Dynamic area, bottom"; break;
- case 0x1030008: os << "Dynamic area, left"; break;
- case 0x1040010: os << "Dynamic area, right"; break;
-
- case 0x2000001: os << "Closest subject, center"; break;
- case 0x2010002: os << "Closest subject, top"; break;
- case 0x2020004: os << "Closest subject, bottom"; break;
- case 0x2030008: os << "Closest subject, left"; break;
- case 0x2040010: os << "Closest subject, right"; break;
-
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& Nikon3MakerNote::print0x0089(std::ostream& os,
- const Value& value)
- {
- // From Exiftool
- long b = value.toLong();
- switch (b) {
- case 0x00: os << "Single"; break;
- case 0x01: os << "Continuous"; break;
- case 0x02: os << "Delay"; break;
- case 0x03: os << "Remote with delay"; break;
- case 0x04: os << "Remote"; break;
- case 0x16: os << "Exposure bracketing"; break;
- case 0x64: os << "White balance bracketing"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& Nikon3MakerNote::print0x008b(std::ostream& os,
- const Value& value)
- {
- // Decoded by Robert Rottmerhusen <email@rottmerhusen.com>
- if (value.size() != 4) return os << "(" << value << ")";
- float a = value.toFloat(0);
- long b = value.toLong(1);
- long c = value.toLong(2);
- if (c == 0) return os << "(" << value << ")";
- return os << a * b / c;
- }
-
- std::ostream& Nikon3MakerNote::print0x0098(std::ostream& os,
- const Value& value)
- {
-#ifdef EXV_HAVE_LENSDATA
- //# List of AF F-Mount lenses - version 1.12
- //#-----------------------------------------
- //# created by Robert Rottmerhusen 2005
- //# for use in non-commercial, GPL or open source software only!
- //# please contact me for adding lenses or use in commercial software.
- //#
- //#"data from TAG 0x98" "ltyp""manuf" "lens name from manuf";
- //#
- struct {unsigned char lid,stps,focs,focl,aps,apl,lfw, ltype; const char *manuf, *lensname;}
- fmountlens[] = {
- {0x01,0x58,0x50,0x50,0x14,0x14,0x02,0x00, "Nikon", "AF Nikkor 50mm f/1.8"},
- {0x02,0x42,0x44,0x5C,0x2A,0x34,0x08,0x00, "Nikon", "AF Zoom-Nikkor 35-70mm f/3.3-4.5"},
- {0x04,0x48,0x3C,0x3C,0x24,0x24,0x03,0x00, "Nikon", "AF Nikkor 28mm f/2.8"},
- {0x05,0x54,0x50,0x50,0x0C,0x0C,0x04,0x00, "Nikon", "AF Nikkor 50mm f/1.4"},
- {0x07,0x40,0x3C,0x62,0x2C,0x34,0x03,0x00, "Nikon", "AF Zoom-Nikkor 28-85mm f/3.5-4.5"},
- {0x08,0x40,0x44,0x6A,0x2C,0x34,0x04,0x00, "Nikon", "AF Zoom-Nikkor 35-105mm f/3.5-4.5"},
- {0x09,0x48,0x37,0x37,0x24,0x24,0x04,0x00, "Nikon", "AF Nikkor 24mm f/2.8"},
- {0x0A,0x48,0x8E,0x8E,0x24,0x24,0x03,0x00, "Nikon", "AF Nikkor 300mm f/2.8 IF-ED"},
- {0x0B,0x48,0x7C,0x7C,0x24,0x24,0x05,0x00, "Nikon", "AF Nikkor 180mm f/2.8 IF-ED"},
- {0x0E,0x48,0x5C,0x81,0x30,0x30,0x05,0x00, "Nikon", "AF Zoom-Nikkor 70-210mm f/4"},
- {0x0F,0x58,0x50,0x50,0x14,0x14,0x05,0x00, "Nikon", "AF Nikkor 50mm f/1.8 N"},
- {0x10,0x48,0x8E,0x8E,0x30,0x30,0x08,0x00, "Nikon", "AF Nikkor 300mm f/4 IF-ED"},
- {0x12,0x48,0x5C,0x81,0x30,0x3C,0x09,0x00, "Nikon", "AF Nikkor 70-210mm f/4-5.6"},
- {0x13,0x42,0x37,0x50,0x2A,0x34,0x0B,0x00, "Nikon", "AF Zoom-Nikkor 24-50mm f/3.3-4.5"},
- {0x14,0x48,0x60,0x80,0x24,0x24,0x0B,0x00, "Nikon", "AF Zoom-Nikkor 80-200mm f/2.8 ED"},
- {0x15,0x4C,0x62,0x62,0x14,0x14,0x0C,0x00, "Nikon", "AF Nikkor 85mm f/1.8"},
- {0x1B,0x44,0x5E,0x8E,0x34,0x3C,0x10,0x00, "Nikon", "AF Zoom-Nikkor 75-300mm f/4.5-5.6"},
- {0x1C,0x48,0x30,0x30,0x24,0x24,0x12,0x00, "Nikon", "AF Nikkor 20mm f/2.8"},
- {0x1D,0x42,0x44,0x5C,0x2A,0x34,0x12,0x00, "Nikon", "AF Zoom-Nikkor 35-70mm f/3.3-4.5 N"},
- {0x1E,0x54,0x56,0x56,0x24,0x24,0x13,0x00, "Nikon", "AF Micro-Nikkor 60mm f/2.8"},
- {0x25,0x48,0x44,0x5c,0x24,0x24,0x1B,0x02, "Nikon", "AF Zoom-Nikkor 35-70mm f/2.8D"},
- {0x25,0x48,0x44,0x5c,0x24,0x24,0x52,0x02, "Nikon", "AF Zoom-Nikkor 35-70mm f/2.8D N"},
- {0x27,0x48,0x8E,0x8E,0x24,0x24,0xF2,0x02, "Nikon", "AF-I Nikkor 300mm f/2.8D IF-ED"},
- {0x2A,0x54,0x3C,0x3C,0x0C,0x0C,0x26,0x02, "Nikon", "AF Nikkor 28mm f/1.4D"},
- {0x2C,0x48,0x6A,0x6A,0x18,0x18,0x27,0x02, "Nikon", "AF DC-Nikkor 105mm f/2D"},
- {0x2D,0x48,0x80,0x80,0x30,0x30,0x21,0x02, "Nikon", "AF Micro-Nikkor 200mm f/4D IF-ED"},
- {0x31,0x54,0x56,0x56,0x24,0x24,0x25,0x02, "Nikon", "AF Micro-Nikkor 60mm f/2.8D"},
- {0x32,0x54,0x6A,0x6A,0x24,0x24,0x35,0x02, "Nikon", "AF Micro-Nikkor 105mm f/2.8D"},
- {0x33,0x48,0x2D,0x2D,0x24,0x24,0x31,0x02, "Nikon", "AF Nikkor 18mm f/2.8D"},
- {0x36,0x48,0x37,0x37,0x24,0x24,0x34,0x02, "Nikon", "AF Nikkor 24mm f/2.8D"},
- {0x37,0x48,0x30,0x30,0x24,0x24,0x36,0x02, "Nikon", "AF Nikkor 20mm f/2.8D"},
- {0x38,0x4C,0x62,0x62,0x14,0x14,0x37,0x02, "Nikon", "AF Nikkor 85mm f/1.8D"},
- {0x3B,0x48,0x44,0x5C,0x24,0x24,0x3A,0x02, "Nikon", "AF Zoom-Nikkor 35-70mm f/2.8D N"},
- {0x3E,0x48,0x3C,0x3C,0x24,0x24,0x3D,0x02, "Nikon", "AF Nikkor 28mm f/2.8D"},
- {0x41,0x48,0x7c,0x7c,0x24,0x24,0x43,0x02, "Nikon", "AF Nikkor 180mm f/2.8D IF-ED"},
- {0x42,0x54,0x44,0x44,0x18,0x18,0x44,0x02, "Nikon", "AF Nikkor 35mm f/2D"},
- {0x43,0x54,0x50,0x50,0x0C,0x0C,0x46,0x02, "Nikon", "AF Nikkor 50mm f/1.4D"},
- {0x46,0x3C,0x44,0x60,0x30,0x3C,0x49,0x02, "Nikon", "AF Zoom-Nikkor 35-80mm f/4-5.6D"},
- {0x48,0x48,0x8E,0x8E,0x24,0x24,0x4B,0x02, "Nikon", "AF-S Nikkor 300mm f/2.8D IF-ED"},
- {0x4A,0x54,0x62,0x62,0x0C,0x0C,0x4D,0x02, "Nikon", "AF Nikkor 85mm f/1.4D IF"},
- {0x4C,0x40,0x37,0x6E,0x2C,0x3C,0x4F,0x02, "Nikon", "AF Zoom-Nikkor 24-120mm f/3.5-5.6D IF"},
- {0x4D,0x40,0x3C,0x80,0x2C,0x3C,0x62,0x02, "Nikon", "AF Zoom-Nikkor 28-200mm f/3.5-5.6D IF"},
- {0x4E,0x48,0x72,0x72,0x18,0x18,0x51,0x02, "Nikon", "AF DC-Nikkor 135mm f/2D"},
- {0x53,0x48,0x60,0x80,0x24,0x24,0x60,0x02, "Nikon", "AF Zoom-Nikkor 80-200mm f/2.8D ED"},
- {0x54,0x44,0x5C,0x7C,0x34,0x3C,0x58,0x02, "Nikon", "AF Zoom-Micro Nikkor 70-180mm f/4.5-5.6D ED"},
- {0x56,0x48,0x5C,0x8E,0x30,0x3C,0x5A,0x02, "Nikon", "AF Zoom-Nikkor 70-300mm f/4-5.6D ED"},
- {0x59,0x48,0x98,0x98,0x24,0x24,0x5D,0x02, "Nikon", "AF-S Nikkor 400mm f/2.8D IF-ED"},
- {0x5A,0x3C,0x3E,0x56,0x30,0x3C,0x5E,0x06, "Nikon", "IX-Nikkor 30-60mm f/4-5.6"},
- {0x5D,0x48,0x3C,0x5C,0x24,0x24,0x63,0x02, "Nikon", "AF-S Zoom-Nikkor 28-70mm f/2.8D IF-ED"},
- {0x5E,0x48,0x60,0x80,0x24,0x24,0x64,0x02, "Nikon", "AF-S Zoom-Nikkor 80-200mm f/2.8D IF-ED"},
- {0x5F,0x40,0x3C,0x6A,0x2C,0x34,0x65,0x02, "Nikon", "AF Zoom-Nikkor 28-105mm f/3.5-4.5D IF"},
- {0x63,0x48,0x2B,0x44,0x24,0x24,0x68,0x02, "Nikon", "AF-S Nikkor 17-35mm f/2.8D IF-ED"},
- {0x64,0x00,0x62,0x62,0x24,0x24,0x6A,0x02, "Nikon", "PC Micro-Nikkor 85mm f/2.8D"},
- {0x65,0x44,0x60,0x98,0x34,0x3C,0x6B,0x0A, "Nikon", "AF VR Zoom-Nikkor 80-400mm f/4.5-5.6D ED"},
- {0x66,0x40,0x2D,0x44,0x2C,0x34,0x6C,0x02, "Nikon", "AF Zoom-Nikkor 18-35mm f/3.5-4.5D IF-ED"},
- {0x67,0x48,0x37,0x62,0x24,0x30,0x6D,0x02, "Nikon", "AF Zoom-Nikkor 24-85mm f/2.8-4D IF"},
- {0x68,0x42,0x3C,0x60,0x2A,0x3C,0x6E,0x06, "Nikon", "AF Zoom-Nikkor 28-80mm f/3.3-5.6G"},
- {0x69,0x48,0x5C,0x8E,0x30,0x3C,0x6F,0x06, "Nikon", "AF Zoom-Nikkor 70-300mm f/4-5.6G"},
- {0x6A,0x48,0x8E,0x8E,0x30,0x30,0x70,0x02, "Nikon", "AF-S Nikkor 300mm f/4D IF-ED"},
- {0x6D,0x48,0x8E,0x8E,0x24,0x24,0x73,0x02, "Nikon", "AF-S Nikkor 300mm f/2.8D IF-ED II"},
- {0x6E,0x48,0x98,0x98,0x24,0x24,0x74,0x02, "Nikon", "AF-S Nikkor 400mm f/2.8D IF-ED II"},
- {0x70,0x3C,0xA6,0xA6,0x30,0x30,0x76,0x02, "Nikon", "AF-S Nikkor 600mm f/4D IF-ED"},
- {0x72,0x48,0x4C,0x4C,0x24,0x24,0x77,0x00, "Nikon", "Nikkor 45mm f/2.8 P"},
- {0x74,0x40,0x37,0x62,0x2C,0x34,0x78,0x06, "Nikon", "AF-S Zoom-Nikkor 24-85mm f/3.5-4.5G IF-ED"},
- {0x75,0x40,0x3C,0x68,0x2C,0x3C,0x79,0x06, "Nikon", "AF Zoom-Nikkor 28-100mm f/3.5-5.6G"},
- {0x76,0x58,0x50,0x50,0x14,0x14,0x7A,0x02, "Nikon", "AF Nikkor 50mm f/1.8D"},
- {0x77,0x48,0x5C,0x80,0x24,0x24,0x7B,0x0E, "Nikon", "AF-S VR Zoom-Nikkor 70-200mm f/2.8G IF-ED"},
- {0x78,0x40,0x37,0x6E,0x2C,0x3C,0x7C,0x0E, "Nikon", "AF-S VR Zoom-Nikkor 24-120mm f/3.5-5.6G IF-ED"},
- {0x79,0x40,0x3C,0x80,0x2C,0x3C,0x7F,0x06, "Nikon", "AF Zoom-Nikkor 28-200mm f/3.5-5.6G IF-ED"},
- {0x7A,0x3C,0x1F,0x37,0x30,0x30,0x7E,0x06, "Nikon", "AF-S DX Zoom-Nikkor 12-24mm f/4G IF-ED"},
- {0x7B,0x48,0x80,0x98,0x30,0x30,0x80,0x0E, "Nikon", "AF-S VR Zoom-Nikkor 200-400mm f/4G IF-ED"},
- {0x7D,0x48,0x2B,0x53,0x24,0x24,0x82,0x06, "Nikon", "AF-S DX Zoom-Nikkor 17-55mm f/2.8G IF-ED"},
- {0x7F,0x40,0x2D,0x5C,0x2C,0x34,0x84,0x06, "Nikon", "AF-S DX Zoom-Nikkor 18-70mm f/3.5-4.5G IF-ED"},
- {0x80,0x48,0x1A,0x1A,0x24,0x24,0x85,0x06, "Nikon", "AF DX Fisheye-Nikkor 10.5mm f/2.8G ED"},
- {0x81,0x54,0x80,0x80,0x18,0x18,0x86,0x0E, "Nikon", "AF-S VR Nikkor 200mm f/2G IF-ED"},
- {0x82,0x48,0x8E,0x8E,0x24,0x24,0x87,0x0E, "Nikon", "AF-S VR Nikkor 300mm f/2.8G IF-ED"},
- {0x89,0x3C,0x53,0x80,0x30,0x3C,0x8B,0x06, "Nikon", "AF-S DX Zoom-Nikkor 55-200mm f/4-5.6G ED"},
- {0x8C,0x40,0x2D,0x53,0x2C,0x3C,0x8E,0x06, "Nikon", "AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED"},
- {0x06,0x3F,0x68,0x68,0x2C,0x2C,0x06,0x00, "Cosina", "100mm F/3.5 Macro"},
- {0x02,0x3F,0x24,0x24,0x2C,0x2C,0x02,0x00, "Sigma", "14mm F3.5"},
- {0x02,0x46,0x37,0x37,0x25,0x25,0x02,0x00, "Sigma", "24mm F2.8 Macro"},
- {0x02,0x3F,0x3C,0x5C,0x2D,0x35,0x02,0x00, "Sigma", "28-70mm F3.5-4.5 UC"},
- {0x02,0x40,0x44,0x73,0x2B,0x36,0x02,0x00, "Sigma", "35-135mm F3.5-4.5 a"},
- {0x02,0x37,0x5E,0x8E,0x35,0x3D,0x02,0x00, "Sigma", "75-300mm F4.5-5.6 APO"},
- {0x02,0x48,0x65,0x65,0x24,0x24,0x02,0x00, "Sigma", "90mm F2.8 Macro"},
- {0x02,0x2F,0x98,0x98,0x3D,0x3D,0x02,0x00, "Sigma", "400mm F5.6 APO"},
- {0x26,0x40,0x3C,0x8E,0x2C,0x40,0x1C,0x02, "Sigma", "28-300mm F3.5-6.3 Macro D"},
- {0x26,0x40,0x3C,0x80,0x2B,0x3C,0x1C,0x02, "Sigma", "28-200mm F3.5-5.6 Compact Aspherical Hyperzoom Macro D"},
- {0x26,0x40,0x3C,0x60,0x2C,0x3C,0x1C,0x02, "Sigma", "28-80mm F3.5-5.6 Mini Zoom Macro II Aspherical D"},
- {0x26,0x54,0x37,0x5C,0x24,0x24,0x1C,0x02, "Sigma", "24-70mm F2.8 EX DG Macro D"},
- {0x26,0x40,0x2D,0x70,0x2B,0x3C,0x1C,0x06, "Sigma", "18-125mm F3.5-5.6 DC G"},
- {0x26,0x48,0x2D,0x50,0x24,0x24,0x1C,0x06, "Sigma", "18-50mm F2.8 EX DC G"},
- {0x26,0x40,0x2D,0x50,0x2C,0x3C,0x1C,0x06, "Sigma", "18-50mm F3.5-5.6 DC G"},
- {0x48,0x38,0x1F,0x37,0x34,0x3C,0x4B,0x06, "Sigma", "12-24mm F4.5-5.6 EX Aspherical DG HSM G"},
- {0x48,0x48,0x2B,0x44,0x24,0x30,0x4B,0x06, "Sigma", "17-35mm F2.8-4 EX DG Aspherical HSM G"},
- {0x48,0x3C,0x50,0xA0,0x30,0x40,0x4B,0x02, "Sigma", "50-500mmF4-6.3 EX APO RF HSM D"},
- {0x48,0x54,0x5C,0x80,0x24,0x24,0x4B,0x02, "Sigma", "70-200mm F2.8 EX APO IF HSM D"},
- {0x48,0x48,0x68,0x8E,0x30,0x30,0x4B,0x02, "Sigma", "100-300mm F4 EX IF HSM D"},
- {0x48,0x48,0x76,0x76,0x24,0x24,0x4B,0x06, "Sigma", "150mm F2.8 EX DG APO Macro HSM G"},
- {0x77,0x44,0x61,0x98,0x34,0x3C,0x7B,0x0E, "Sigma", "80-400mm f4.5-5.6 EX OS G"},
- {0x03,0x43,0x5C,0x81,0x35,0x35,0x02,0x00, "Soligor", "AF C/D ZOOM UMCS 70-210mm 1:4.5"},
- {0x00,0x3C,0x1F,0x37,0x30,0x30,0x00,0x06, "Tokina", "AT-X 124 AF PRO DX - AF 12-24mm f/4"},
- {0x00,0x40,0x2B,0x2B,0x2C,0x2C,0x00,0x02, "Tokina", "AT-X 17 AF PRO - AF 17mm f/3.5"},
- {0x00,0x54,0x68,0x68,0x24,0x24,0x00,0x02, "Tokina", "AT-X M100 PRO D - 100mm F2.8"},
- {0x4D,0x41,0x3C,0x8E,0x2B,0x40,0x62,0x02, "Tamron", "AF28-300mm F/3.5-6.3 XR Di LD Aspherical (IF)"},
- {0x00,0x3F,0x2D,0x80,0x2B,0x40,0x00,0x06, "Tamron", "AF18-200mm F/3.5-6.3 XR Di II LD Aspherical (IF)"},
- {0x32,0x53,0x64,0x64,0x24,0x24,0x35,0x02, "Tamron", "SP AF90mm F/2.8 Di 1:1 Macro"},
- {0x00,0x48,0x3C,0x6A,0x24,0x24,0x00,0x02, "Unknown", "28-105mm F/2.8D"},
- {0x00,0x49,0x30,0x48,0x22,0x2B,0x00,0x02, "Unknown", "20-40mm F/2.7-3.3D"},
- {0x07,0x46,0x2B,0x44,0x24,0x30,0x03,0x02, "Unknown", "AF17-35mm D"},
- {0x1E,0x5D,0x64,0x64,0x20,0x20,0x13,0x00, "Unknown", "90mm F/2.5"},
- {0x20,0x3C,0x80,0x98,0x3D,0x3D,0x1E,0x02, "Unknown", "200-400mm F/5.6D"},
- {0x2F,0x40,0x30,0x44,0x2C,0x34,0x29,0x02, "Unknown", "20-35mm F/3.5-4.5D"},
- {0,0,0,0,0,0,0,0, NULL, NULL}
- };
-
- if (value.typeId() != undefined) return os << value;
-
- DataBuf lens(value.size());
- // ByteOrder is only to satisfy the interface
- value.copy(lens.pData_, invalidByteOrder);
-
- int idx = 0;
- if (0 == memcmp(lens.pData_, "0100", 4)) {
- idx = 6;
- }
- else if (0 == memcmp(lens.pData_, "0101", 4)) {
- idx = 11;
- }
- else if (0 == memcmp(lens.pData_, "0201", 4)) {
- // Here we should decrypt(lens.pData_ + 4, lens.size_ - 4);
- // however, the decrypt algorithm requires access to serial number
- // and shutter count tags but print functions are static...
- idx = 11;
- }
- if (idx == 0 || lens.size_ < idx + 7) {
- // Unknown version or not enough data
- return os << value;
- }
- for (int i = 0; fmountlens[i].lensname != NULL; ++i) {
- if ( lens.pData_[idx] == fmountlens[i].lid
- && lens.pData_[idx+1] == fmountlens[i].stps
- && lens.pData_[idx+2] == fmountlens[i].focs
- && lens.pData_[idx+3] == fmountlens[i].focl
- && lens.pData_[idx+4] == fmountlens[i].aps
- && lens.pData_[idx+5] == fmountlens[i].apl
- && lens.pData_[idx+6] == fmountlens[i].lfw) {
- // Lens found in database
- return os << fmountlens[i].manuf << " " << fmountlens[i].lensname;
- }
- }
- // Lens not found in database
- return os << value;
-#else
- return os << value;
-#endif // EXV_HAVE_LENSDATA
- }
-
-// *****************************************************************************
-// free functions
-
- MakerNote::AutoPtr createNikonMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset)
- {
- // If there is no "Nikon" string it must be Nikon1 format
- if (len < 6 || std::string(reinterpret_cast<const char*>(buf), 6)
- != std::string("Nikon\0", 6)) {
- return MakerNote::AutoPtr(new Nikon1MakerNote(alloc));
- }
- // If the "Nikon" string is not followed by a TIFF header, we assume
- // Nikon2 format
- TiffHeader tiffHeader;
- if ( len < 18
- || tiffHeader.read(buf + 10) != 0 || tiffHeader.tag() != 0x002a) {
- return MakerNote::AutoPtr(new Nikon2MakerNote(alloc));
- }
- // Else we have a Nikon3 makernote
- return MakerNote::AutoPtr(new Nikon3MakerNote(alloc));
- }
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/nikonmn.hpp b/src/plugins/exiv2/nikonmn.hpp
@@ -1,309 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file nikonmn.hpp
- @brief Nikon MakerNote formats.
-
- The Nikon MakerNote formats are implemented according to the following references<BR>
- Format 1:
- <ul>
- <li><a href="http://www.tawbaware.com/990exif.htm">MakerNote EXIF Tag of the Nikon 990</a> by Max Lyons</li></ul>
- Format 2:
- <ul><li>"Appendix 2: Makernote of Nikon" of the document
- <a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html">
- Exif file format</a> by TsuruZoh Tachibanaya</li></ul>
- Format 3:
- <ul><li>"EXIFutils Field Reference Guide"</li>
- <li><a href="http://www.ozhiker.com/electronics/pjmt/jpeg_info/nikon_mn.html#Nikon_Type_3_Tags">Nikon Type 3 Makernote Tags Definition</a>
- of the PHP JPEG Metadata Toolkit by Evan Hunter</li>
- <li>Nikon tag information from <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/">ExifTool</a> by Phil Harvey</li>
- <li>Email communication with Robert Rottmerhusen</li>
- </ul>
-
- @version $Rev: 588 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 17-May-04, ahu: created<BR>
- 25-May-04, ahu: combined all Nikon formats in one component
- */
-#ifndef NIKONMN_HPP_
-#define NIKONMN_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "makernote.hpp"
-#include "tags.hpp"
-
-// + standard includes
-#include <string>
-#include <iosfwd>
-#include <memory>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class declarations
- class Value;
-
-// *****************************************************************************
-// free functions
-
- /*!
- @brief Return an auto-pointer to a newly created empty MakerNote
- initialized to operate in the memory management model indicated.
- The caller owns this copy and the auto-pointer ensures that it
- will be deleted.
-
- @param alloc Memory management model for the new MakerNote. Determines if
- memory required to store data should be allocated and deallocated
- (true) or not (false). If false, only pointers to the buffer
- provided to read() will be kept. See Ifd for more background on
- this concept.
- @param buf Pointer to the makernote character buffer (not used).
- @param len Length of the makernote character buffer (not used).
- @param byteOrder Byte order in which the Exif data (and possibly the
- makernote) is encoded (not used).
- @param offset Offset from the start of the TIFF header of the makernote
- buffer (not used).
-
- @return An auto-pointer to a newly created empty MakerNote. The caller
- owns this copy and the auto-pointer ensures that it will be
- deleted.
- */
- MakerNote::AutoPtr createNikonMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset);
-
-// *****************************************************************************
-// class definitions
-
- //! A MakerNote format used by Nikon cameras, such as the E990 and D1.
- class Nikon1MakerNote : public IfdMakerNote {
- public:
- //! Shortcut for a %Nikon1MakerNote auto pointer.
- typedef std::auto_ptr<Nikon1MakerNote> AutoPtr;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor. Allows to choose whether or not memory management
- is required for the makernote entries.
- */
- Nikon1MakerNote(bool alloc =true);
- //! Copy constructor
- Nikon1MakerNote(const Nikon1MakerNote& rhs);
- //! Virtual destructor
- virtual ~Nikon1MakerNote() {}
- //@}
-
- //! @name Accessors
- //@{
- AutoPtr create(bool alloc =true) const;
- AutoPtr clone() const;
- //@}
-
- //! @name Print functions for Nikon1 %MakerNote tags
- //@{
- //! Print ISO setting
- static std::ostream& print0x0002(std::ostream& os, const Value& value);
- //! Print autofocus mode
- static std::ostream& print0x0007(std::ostream& os, const Value& value);
- //! Print manual focus distance
- static std::ostream& print0x0085(std::ostream& os, const Value& value);
- //! Print digital zoom setting
- static std::ostream& print0x0086(std::ostream& os, const Value& value);
- //! Print AF focus position
- static std::ostream& print0x0088(std::ostream& os, const Value& value);
- //@}
-
- //! @cond IGNORE
- // Public only so that we can create a static instance
- struct RegisterMn {
- RegisterMn();
- };
- //! @endcond
-
- private:
- //! Internal virtual create function.
- Nikon1MakerNote* create_(bool alloc =true) const;
- //! Internal virtual copy constructor.
- Nikon1MakerNote* clone_() const;
-
- //! Tag information
- static const TagInfo tagInfo_[];
-
- }; // class Nikon1MakerNote
-
- static Nikon1MakerNote::RegisterMn registerNikon1MakerNote;
-
- /*!
- @brief A second MakerNote format used by Nikon cameras, including the
- E700, E800, E900, E900S, E910, E950
- */
- class Nikon2MakerNote : public IfdMakerNote {
- public:
- //! Shortcut for a %Nikon2MakerNote auto pointer.
- typedef std::auto_ptr<Nikon2MakerNote> AutoPtr;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor. Allows to choose whether or not memory management
- is required for the makernote entries.
- */
- Nikon2MakerNote(bool alloc =true);
- //! Copy constructor
- Nikon2MakerNote(const Nikon2MakerNote& rhs);
- //! Virtual destructor
- virtual ~Nikon2MakerNote() {}
- //@}
-
- //! @name Manipulators
- //@{
- int readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder);
- //@}
-
- //! @name Accessors
- //@{
- int checkHeader() const;
- AutoPtr create(bool alloc =true) const;
- AutoPtr clone() const;
- //@}
-
- //! @name Print functions for Nikon2 %MakerNote tags
- //@{
- //! Print quality setting
- static std::ostream& print0x0003(std::ostream& os, const Value& value);
- //! Print color mode setting
- static std::ostream& print0x0004(std::ostream& os, const Value& value);
- //! Print image adjustment setting
- static std::ostream& print0x0005(std::ostream& os, const Value& value);
- //! Print ISO speed setting
- static std::ostream& print0x0006(std::ostream& os, const Value& value);
- //! Print white balance setting
- static std::ostream& print0x0007(std::ostream& os, const Value& value);
- //! Print digital zoom setting
- static std::ostream& print0x000a(std::ostream& os, const Value& value);
- //@}
-
- //! @cond IGNORE
- // Public only so that we can create a static instance
- struct RegisterMn {
- RegisterMn();
- };
- //! @endcond
-
- private:
- //! Internal virtual create function.
- Nikon2MakerNote* create_(bool alloc =true) const;
- //! Internal virtual copy constructor.
- Nikon2MakerNote* clone_() const;
-
- //! Tag information
- static const TagInfo tagInfo_[];
-
- }; // class Nikon2MakerNote
-
- static Nikon2MakerNote::RegisterMn registerNikon2MakerNote;
-
- //! A third MakerNote format used by Nikon cameras, e.g., E5400, SQ, D2H, D70
- class Nikon3MakerNote : public IfdMakerNote {
- public:
- //! Shortcut for a %Nikon3MakerNote auto pointer.
- typedef std::auto_ptr<Nikon3MakerNote> AutoPtr;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor. Allows to choose whether or not memory management
- is required for the makernote entries.
- */
- Nikon3MakerNote(bool alloc =true);
- //! Copy constructor
- Nikon3MakerNote(const Nikon3MakerNote& rhs);
- //! Virtual destructor
- virtual ~Nikon3MakerNote() {}
- //@}
-
- //! @name Manipulators
- //@{
- int readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder);
- //@}
-
- //! @name Accessors
- //@{
- int checkHeader() const;
- AutoPtr create(bool alloc =true) const;
- AutoPtr clone() const;
- //@}
-
- //! @name Print functions for Nikon3 %MakerNote tags
- //@{
- //! Print ISO setting
- static std::ostream& print0x0002(std::ostream& os, const Value& value);
- //! Print flash compensation
- static std::ostream& print0x0012(std::ostream& os, const Value& value);
- //! Print lens information
- static std::ostream& print0x0084(std::ostream& os, const Value& value);
- //! Print flash used information
- static std::ostream& print0x0087(std::ostream& os, const Value& value);
- //! Print AF point
- static std::ostream& print0x0088(std::ostream& os, const Value& value);
- //! Print bracketing information
- static std::ostream& print0x0089(std::ostream& os, const Value& value);
- //! Print number of lens stops
- static std::ostream& print0x008b(std::ostream& os, const Value& value);
- //! Print number of lens data
- static std::ostream& print0x0098(std::ostream& os, const Value& value);
- //@}
-
- //! @cond IGNORE
- // Public only so that we can create a static instance
- struct RegisterMn {
- RegisterMn();
- };
- //! @endcond
-
- private:
- //! Internal virtual create function.
- Nikon3MakerNote* create_(bool alloc =true) const;
- //! Internal virtual copy constructor.
- Nikon3MakerNote* clone_() const;
-
- //! Tag information
- static const TagInfo tagInfo_[];
-
- }; // class Nikon3MakerNote
-
- static Nikon3MakerNote::RegisterMn registerNikon3MakerNote;
-
-} // namespace Exiv2
-
-#endif // #ifndef NIKONMN_HPP_
diff --git a/src/plugins/exiv2/olympusmn.cpp b/src/plugins/exiv2/olympusmn.cpp
@@ -1,315 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: olympusmn.cpp
- Version: $Rev: 600 $
- Author(s): Will Stokes (wuz) <wstokes@gmail.com>
- Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 10-Mar-05, wuz: created
- Credits: See header file.
- */
-
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: olympusmn.cpp 600 2005-07-09 10:38:09Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "olympusmn.hpp"
-#include "makernote.hpp"
-#include "value.hpp"
-
-// + standard includes
-#include <string>
-#include <sstream>
-#include <iomanip>
-#include <cassert>
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- //! @cond IGNORE
- OlympusMakerNote::RegisterMn::RegisterMn()
- {
- MakerNoteFactory::registerMakerNote(
- "OLYMPUS*", "*", createOlympusMakerNote);
- MakerNoteFactory::registerMakerNote(
- olympusIfdId, MakerNote::AutoPtr(new OlympusMakerNote));
-
- ExifTags::registerMakerTagInfo(olympusIfdId, tagInfo_);
- }
- //! @endcond
-
- // Olympus Tag Info
- const TagInfo OlympusMakerNote::tagInfo_[] = {
- TagInfo(0x0200, "SpecialMode", "Picture taking mode", olympusIfdId, makerTags, unsignedLong, print0x0200),
- TagInfo(0x0201, "Quality", "Image quality setting", olympusIfdId, makerTags, unsignedShort, print0x0201),
- TagInfo(0x0202, "Macro", "Macro mode", olympusIfdId, makerTags, unsignedShort, print0x0202),
- TagInfo(0x0203, "BWMode", "Black and White Mode", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0204, "DigitalZoom", "Digital zoom ratio", olympusIfdId, makerTags, unsignedRational, print0x0204),
- TagInfo(0x0205, "FocalPlaneDiagonal", "Focal plane diagonal", olympusIfdId, makerTags, unsignedRational, printValue),
- TagInfo(0x0206, "0x0206", "Unknown", olympusIfdId, makerTags, signedShort, printValue),
- TagInfo(0x0207, "FirmwareVersion", "Software firmware version", olympusIfdId, makerTags, asciiString, printValue),
- TagInfo(0x0208, "PictureInfo", "ASCII format data such as [PictureInfo]", olympusIfdId, makerTags, asciiString, printValue),
- TagInfo(0x0209, "CameraID", "CameraID data", olympusIfdId, makerTags, undefined, printValue),
- TagInfo(0x0300, "PreCaptureFrames", "Pre-capture frames", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0301, "0x0301", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0302, "OneTouchWB", "OneTouchWB", olympusIfdId, makerTags, unsignedShort, print0x0302),
- TagInfo(0x0303, "0x0303", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0304, "0x0304", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0f00, "DataDump", "Various camera settings", olympusIfdId, makerTags, undefined, printValue),
- TagInfo(0x1000, "0x1000", "Unknown", olympusIfdId, makerTags, signedRational, printValue),
- TagInfo(0x1001, "0x1001", "Unknown", olympusIfdId, makerTags, signedRational, printValue),
- TagInfo(0x1002, "0x1002", "Unknown", olympusIfdId, makerTags, signedRational, printValue),
- TagInfo(0x1003, "0x1003", "Unknown", olympusIfdId, makerTags, signedRational, printValue),
- TagInfo(0x1004, "FlashMode", "Flash mode", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1005, "FlashDevice", "Flash device", olympusIfdId, makerTags, unsignedShort, print0x1005),
- TagInfo(0x1006, "Bracket", "Bracket", olympusIfdId, makerTags, signedRational, printValue),
- TagInfo(0x1007, "0x1007", "Unknown", olympusIfdId, makerTags, signedShort, printValue),
- TagInfo(0x1008, "0x1008", "Unknown", olympusIfdId, makerTags, signedShort, printValue),
- TagInfo(0x1009, "0x1009", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x100a, "0x100a", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x100b, "FocusMode", "Focus mode", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x100c, "FocusDistance", "Focus distance", olympusIfdId, makerTags, unsignedRational, printValue),
- TagInfo(0x100d, "Zoom", "Zoom", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x100e, "MacroFocus", "Macro focus", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x100f, "SharpnessFactor", "Sharpness factor", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1010, "0x1010", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1011, "ColorMatrix", "Color matrix", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1012, "BlackLevel", "Black level", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1013, "0x1013", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1014, "0x1014", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1015, "WhiteBalance", "White balance", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1016, "0x1016", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1017, "RedBalance", "Red balance", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1018, "BlueBalance", "Blue balance", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1019, "0x1019", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x101a, "SerialNumber", "Serial number", olympusIfdId, makerTags, asciiString, printValue),
- TagInfo(0x101b, "0x101b", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x101c, "0x101c", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x101d, "0x101d", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x101e, "0x101e", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x101f, "0x101f", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x1020, "0x1020", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x1021, "0x1021", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x1022, "0x1022", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x1023, "FlashBias", "Flash bias", olympusIfdId, makerTags, signedRational, printValue),
- TagInfo(0x1024, "0x1024", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1025, "0x1025", "Unknown", olympusIfdId, makerTags, signedRational, printValue),
- TagInfo(0x1026, "0x1026", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1027, "0x1027", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1028, "0x1028", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1029, "Contrast", "Contrast setting", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x102a, "SharpnessFactor", "Sharpness factor", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x102b, "ColorControl", "Color control", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x102c, "ValidBits", "Valid bits", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x102d, "Coring Filter", "Coring filter", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x102e, "ImageWidth", "Image width", olympusIfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x102f, "ImageHeight", "Image height", olympusIfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x1030, "0x1030", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1031, "0x1031", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x1032, "0x1032", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x1033, "0x1033", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownOlympusMakerNoteTag)", "Unknown OlympusMakerNote tag", olympusIfdId, makerTags, invalidTypeId, printValue)
- };
-
- OlympusMakerNote::OlympusMakerNote(bool alloc)
- : IfdMakerNote(olympusIfdId, alloc)
- {
- byte buf[] = {
- 'O', 'L', 'Y', 'M', 'P', 0x00, 0x01, 0x00
- };
- readHeader(buf, 8, byteOrder_);
- }
-
- OlympusMakerNote::OlympusMakerNote(const OlympusMakerNote& rhs)
- : IfdMakerNote(rhs)
- {
- }
-
- int OlympusMakerNote::readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder)
- {
- if (len < 8) return 1;
-
- // Copy the header
- header_.alloc(8);
- memcpy(header_.pData_, buf, header_.size_);
- // Adjust the offset of the IFD for the prefix
- adjOffset_ = 8;
-
- return 0;
- }
-
- int OlympusMakerNote::checkHeader() const
- {
- int rc = 0;
- // Check the OLYMPUS prefix
- if ( header_.size_ < 8
- || std::string(reinterpret_cast<char*>(header_.pData_), 5)
- != std::string("OLYMP", 5)) {
- rc = 2;
- }
- return rc;
- }
-
- OlympusMakerNote::AutoPtr OlympusMakerNote::create(bool alloc) const
- {
- return AutoPtr(create_(alloc));
- }
-
- OlympusMakerNote* OlympusMakerNote::create_(bool alloc) const
- {
- AutoPtr makerNote = AutoPtr(new OlympusMakerNote(alloc));
- assert(makerNote.get() != 0);
- makerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
- return makerNote.release();
- }
-
- OlympusMakerNote::AutoPtr OlympusMakerNote::clone() const
- {
- return AutoPtr(clone_());
- }
-
- OlympusMakerNote* OlympusMakerNote::clone_() const
- {
- return new OlympusMakerNote(*this);
- }
-
- std::ostream& OlympusMakerNote::print0x0200(std::ostream& os,
- const Value& value)
- {
- if (value.count() != 3 || value.typeId() != unsignedLong) {
- return os << value;
- }
- long l0 = value.toLong(0);
- switch (l0) {
- case 0: os << "Normal"; break;
- case 2: os << "Fast"; break;
- case 3: os << "Panorama"; break;
- default: os << "(" << l0 << ")"; break;
- }
- if (l0 != 0) {
- os << ", ";
- long l1 = value.toLong(1);
- os << "Sequence number " << l1;
- }
- if (l0 != 0 && l0 != 2) {
- os << ", ";
- long l2 = value.toLong(2);
- switch (l2) {
- case 1: os << "Left to Right"; break;
- case 2: os << "Right to Left"; break;
- case 3: os << "Bottom to Top"; break;
- case 4: os << "Top to Bottom"; break;
- default: os << "(" << l2 << ")"; break;
- }
- }
- return os;
- } // OlympusMakerNote::print0x0200
-
- //! Quality
- const TagDetails quality[] = {
- { 0, "(start)" },
- { 1, "Standard Quality (SQ)" },
- { 2, "High Quality (HQ)" },
- { 3, "Super High Quality (SHQ)" },
- { 6, "Raw" },
- { 0, "(end)" }
- };
-
- std::ostream& OlympusMakerNote::print0x0201(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(quality).print(os, value);
- } // OlympusMakerNote::print0x0201
-
- //! Macro
- const TagDetails macro[] = {
- { -1, "(start)" },
- { 0, "Off" },
- { 1, "On" },
- { 2, "Super Macro" },
- { -1, "(end)" }
- };
-
- std::ostream& OlympusMakerNote::print0x0202(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(macro).print(os, value);
- } // OlympusMakerNote::print0x0202
-
- std::ostream& OlympusMakerNote::print0x0204(std::ostream& os,
- const Value& value)
- {
- float f = value.toFloat();
- if (f == 0.0 || f == 1.0) return os << "None";
- return os << std::fixed << std::setprecision(1) << f << "x";
- } // OlympusMakerNote::print0x0204
-
- //! OneTouchWB
- const TagDetails oneTouchWb[] = {
- { -1, "(start)" },
- { 0, "Off" },
- { 1, "On" },
- { 2, "On (Preset)" },
- { -1, "(end)" }
- };
-
- std::ostream& OlympusMakerNote::print0x0302(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(oneTouchWb).print(os, value);
- } // OlympusMakerNote::print0x0302
-
- //! FlashDevice
- const TagDetails flashDevice[] = {
- { -1, "(start)" },
- { 0, "None" },
- { 1, "Internal" },
- { 4, "External" },
- { 4, "Internal + External" },
- { -1, "(end)" }
- };
-
- std::ostream& OlympusMakerNote::print0x1005(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(flashDevice).print(os, value);
- } // OlympusMakerNote::print0x1005
-
-// *****************************************************************************
-// free functions
-
- MakerNote::AutoPtr createOlympusMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset)
- {
- return MakerNote::AutoPtr(new OlympusMakerNote(alloc));
- }
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/olympusmn.hpp b/src/plugins/exiv2/olympusmn.hpp
@@ -1,161 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file olympusmn.hpp
- @brief Olympus MakerNote implemented using the following references:
- <a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html#APP1">Exif file format, Appendix 1: MakerNote of Olympus Digicams</a> by TsuruZoh Tachibanaya,
- Olympus.pm of <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/">ExifTool</a> by Phil Harvey,
- <a href="http://www.ozhiker.com/electronics/pjmt/jpeg_info/olympus_mn.html">Olympus Makernote Format Specification</a> by Evan Hunter,
- email communication with <a href="mailto:wstokes@gmail.com">Will Stokes</a>
- @version $Rev: 580 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @author Will Stokes (wuz)
- <a href="mailto:wstokes@gmail.com">wstokes@gmail.com</a>
- @date 10-Mar-05, wuz: created
- */
-#ifndef OLYMPUSMN_HPP_
-#define OLYMPUSMN_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "makernote.hpp"
-#include "tags.hpp"
-
-// + standard includes
-#include <string>
-#include <iosfwd>
-#include <memory>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class declarations
- class Value;
-
-// *****************************************************************************
-// free functions
-
- /*!
- @brief Return an auto-pointer to a newly created empty MakerNote
- initialized to operate in the memory management model indicated.
- The caller owns this copy and the auto-pointer ensures that it
- will be deleted.
-
- @param alloc Memory management model for the new MakerNote. Determines if
- memory required to store data should be allocated and deallocated
- (true) or not (false). If false, only pointers to the buffer
- provided to read() will be kept. See Ifd for more background on
- this concept.
- @param buf Pointer to the makernote character buffer (not used).
- @param len Length of the makernote character buffer (not used).
- @param byteOrder Byte order in which the Exif data (and possibly the
- makernote) is encoded (not used).
- @param offset Offset from the start of the TIFF header of the makernote
- buffer (not used).
-
- @return An auto-pointer to a newly created empty MakerNote. The caller
- owns this copy and the auto-pointer ensures that it will be
- deleted.
- */
- MakerNote::AutoPtr createOlympusMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset);
-
-// *****************************************************************************
-// class definitions
-
- //! MakerNote for Olympus cameras
- class OlympusMakerNote : public IfdMakerNote {
- public:
- //! Shortcut for a %OlympusMakerNote auto pointer.
- typedef std::auto_ptr<OlympusMakerNote> AutoPtr;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor. Allows to choose whether or not memory management
- is required for the makernote entries.
- */
- OlympusMakerNote(bool alloc =true);
- //! Copy constructor
- OlympusMakerNote(const OlympusMakerNote& rhs);
- //! Virtual destructor
- virtual ~OlympusMakerNote() {}
- //@}
-
- //! @name Manipulators
- //@{
- int readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder);
- //@}
-
- //! @name Accessors
- //@{
- int checkHeader() const;
- AutoPtr create(bool alloc =true) const;
- AutoPtr clone() const;
- //@}
-
- //! @name Print functions for Olympus %MakerNote tags
- //@{
- //! Print 'Special Mode'
- static std::ostream& print0x0200(std::ostream& os, const Value& value);
- //! Print Jpeg quality
- static std::ostream& print0x0201(std::ostream& os, const Value& value);
- //! Print Macro mode
- static std::ostream& print0x0202(std::ostream& os, const Value& value);
- //! Print Digital Zoom Factor
- static std::ostream& print0x0204(std::ostream& os, const Value& value);
- //! Print OneTouchWB
- static std::ostream& print0x0302(std::ostream& os, const Value& value);
- //! Print FlashDevice
- static std::ostream& print0x1005(std::ostream& os, const Value& value);
- //@}
-
- //! @cond IGNORE
- // Public only so that we can create a static instance
- struct RegisterMn {
- RegisterMn();
- };
- //! @endcond
-
- private:
- //! Internal virtual create function.
- OlympusMakerNote* create_(bool alloc =true) const;
- //! Internal virtual copy constructor.
- OlympusMakerNote* clone_() const;
-
- //! Tag information
- static const TagInfo tagInfo_[];
-
- }; // class OlympusMakerNote
-
- static OlympusMakerNote::RegisterMn registerOlympusMakerNote;
-} // namespace Exiv2
-
-#endif // #ifndef OLYMPUSMN_HPP_
diff --git a/src/plugins/exiv2/panasonicmn.cpp b/src/plugins/exiv2/panasonicmn.cpp
@@ -1,358 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: panasonicmn.cpp
- Version: $Rev: 600 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 11-Jun-04, ahu: created
- Credits: See header file
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: panasonicmn.cpp 600 2005-07-09 10:38:09Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "panasonicmn.hpp"
-#include "makernote.hpp"
-#include "value.hpp"
-
-// + standard includes
-#include <string>
-#include <sstream>
-#include <iomanip>
-#include <cassert>
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- //! @cond IGNORE
- PanasonicMakerNote::RegisterMn::RegisterMn()
- {
- MakerNoteFactory::registerMakerNote("Panasonic", "*", createPanasonicMakerNote);
- MakerNoteFactory::registerMakerNote(
- panasonicIfdId, MakerNote::AutoPtr(new PanasonicMakerNote));
-
- ExifTags::registerMakerTagInfo(panasonicIfdId, tagInfo_);
- }
- //! @endcond
-
- // Panasonic MakerNote Tag Info
- const TagInfo PanasonicMakerNote::tagInfo_[] = {
- TagInfo(0x0001, "Quality", "Image Quality", panasonicIfdId, makerTags, unsignedShort, print0x0001),
- TagInfo(0x0002, "FirmwareVersion", "Firmware version", panasonicIfdId, makerTags, undefined, printValue),
- TagInfo(0x0003, "WhiteBalance", "White balance setting", panasonicIfdId, makerTags, unsignedShort, print0x0003),
- TagInfo(0x0004, "0x0004", "Unknown", panasonicIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0007, "FocusMode", "Focus mode", panasonicIfdId, makerTags, unsignedShort, print0x0007),
- TagInfo(0x000f, "SpotMode", "Spot mode", panasonicIfdId, makerTags, unsignedByte, print0x000f),
- TagInfo(0x001a, "ImageStabilizer", "Image stabilizer", panasonicIfdId, makerTags, unsignedShort, print0x001a),
- TagInfo(0x001c, "Macro", "Macro mode", panasonicIfdId, makerTags, unsignedShort, print0x001c),
- TagInfo(0x001f, "ShootingMode", "Shooting mode", panasonicIfdId, makerTags, unsignedShort, print0x001f),
- TagInfo(0x0020, "Audio", "Audio", panasonicIfdId, makerTags, unsignedShort, print0x0020),
- TagInfo(0x0021, "DataDump", "Data dump", panasonicIfdId, makerTags, undefined, printValue),
- TagInfo(0x0022, "0x0022", "Unknown", panasonicIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0023, "WhiteBalanceBias", "White balance adjustment", panasonicIfdId, makerTags, unsignedShort, print0x0023),
- TagInfo(0x0024, "FlashBias", "Flash bias", panasonicIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0025, "SerialNumber", "Serial number", panasonicIfdId, makerTags, undefined, printValue),
- TagInfo(0x0026, "0x0026", "Unknown", panasonicIfdId, makerTags, undefined, printValue),
- TagInfo(0x0027, "0x0027", "Unknown", panasonicIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0028, "ColorEffect", "Color effect", panasonicIfdId, makerTags, unsignedShort, print0x0028),
- TagInfo(0x0029, "0x0029", "Unknown", panasonicIfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x002a, "0x002a", "Unknown", panasonicIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x002b, "0x002b", "Unknown", panasonicIfdId, makerTags, unsignedLong, printValue),
- TagInfo(0x002c, "Contrast", "Contrast setting", panasonicIfdId, makerTags, unsignedShort, print0x002c),
- TagInfo(0x002d, "NoiseReduction", "Noise reduction", panasonicIfdId, makerTags, unsignedShort, print0x002d),
- TagInfo(0x002e, "0x002e", "Unknown", panasonicIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x002f, "0x002f", "Unknown", panasonicIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0030, "0x0030", "Unknown", panasonicIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0031, "0x0031", "Unknown", panasonicIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x0032, "0x0032", "Unknown", panasonicIfdId, makerTags, unsignedShort, printValue),
- TagInfo(0x4449, "0x4449", "Unknown", panasonicIfdId, makerTags, undefined, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownPanasonicMakerNoteTag)", "Unknown PanasonicMakerNote tag", panasonicIfdId, makerTags, invalidTypeId, printValue)
- };
-
- PanasonicMakerNote::PanasonicMakerNote(bool alloc)
- : IfdMakerNote(panasonicIfdId, alloc, false)
- {
- byte buf[] = {
- 'P', 'a', 'n', 'a', 's', 'o', 'n', 'i', 'c', 0x00, 0x00, 0x00
- };
- readHeader(buf, 12, byteOrder_);
- }
-
- PanasonicMakerNote::PanasonicMakerNote(const PanasonicMakerNote& rhs)
- : IfdMakerNote(rhs)
- {
- }
-
- int PanasonicMakerNote::readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder)
- {
- if (len < 12) return 1;
-
- header_.alloc(12);
- memcpy(header_.pData_, buf, header_.size_);
- // Adjust the offset of the IFD for the prefix
- adjOffset_ = 12;
- return 0;
- }
-
- int PanasonicMakerNote::checkHeader() const
- {
- int rc = 0;
- // Check the Panasonic prefix
- if ( header_.size_ < 12
- || std::string(reinterpret_cast<char*>(header_.pData_), 9)
- != std::string("Panasonic", 9)) {
- rc = 2;
- }
- return rc;
- }
-
- PanasonicMakerNote::AutoPtr PanasonicMakerNote::create(bool alloc) const
- {
- return AutoPtr(create_(alloc));
- }
-
- PanasonicMakerNote* PanasonicMakerNote::create_(bool alloc) const
- {
- AutoPtr makerNote = AutoPtr(new PanasonicMakerNote(alloc));
- assert(makerNote.get() != 0);
- makerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
- return makerNote.release();
- }
-
- PanasonicMakerNote::AutoPtr PanasonicMakerNote::clone() const
- {
- return AutoPtr(clone_());
- }
-
- PanasonicMakerNote* PanasonicMakerNote::clone_() const
- {
- return new PanasonicMakerNote(*this);
- }
-
- //! Quality
- const TagDetails quality[] = {
- { 0, "(start)" },
- { 2, "High" },
- { 3, "Standard" },
- { 6, "Very High" },
- { 7, "Raw" },
- { 0, "(end)" }
- };
-
- std::ostream& PanasonicMakerNote::print0x0001(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(quality).print(os, value);
- } // PanasonicMakerNote::print0x0001
-
- //! WhiteBalance
- const TagDetails whiteBalance[] = {
- { 0, "(start)" },
- { 1, "Auto" },
- { 2, "Daylight" },
- { 3, "Cloudy" },
- { 4, "Halogen" },
- { 5, "Manual" },
- { 8, "Flash" },
- { 10, "Black and White" },
- { 0, "(end)" }
- };
-
- std::ostream& PanasonicMakerNote::print0x0003(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(whiteBalance).print(os, value);
- } // PanasonicMakerNote::print0x0003
-
- //! FocusMode
- const TagDetails focusMode[] = {
- { 0, "(start)" },
- { 1, "Auto" },
- { 2, "Manual" },
- { 0, "(end)" }
- };
-
- std::ostream& PanasonicMakerNote::print0x0007(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(focusMode).print(os, value);
- } // PanasonicMakerNote::print0x0007
-
- std::ostream& PanasonicMakerNote::print0x000f(std::ostream& os,
- const Value& value)
- {
- if (value.count() < 2 || value.typeId() != unsignedByte) {
- return os << value;
- }
- long l0 = value.toLong(0);
- if (l0 == 1) os << "On";
- else if (l0 == 16) os << "Off";
- else os << value;
- return os;
- } // PanasonicMakerNote::print0x000f
-
- //! ImageStabilizer
- const TagDetails imageStabilizer[] = {
- { 0, "(start)" },
- { 2, "On, Mode 1" },
- { 3, "Off" },
- { 4, "On, Mode 2" },
- { 0, "(end)" }
- };
-
- std::ostream& PanasonicMakerNote::print0x001a(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(imageStabilizer).print(os, value);
- } // PanasonicMakerNote::print0x001a
-
- //! Macro
- const TagDetails macro[] = {
- { 0, "(start)" },
- { 1, "On" },
- { 2, "Off" },
- { 0, "(end)" }
- };
-
- std::ostream& PanasonicMakerNote::print0x001c(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(macro).print(os, value);
- } // PanasonicMakerNote::print0x001c
-
- //! ShootingMode
- const TagDetails shootingMode[] = {
- { 0, "(start)" },
- { 1, "Normal" },
- { 2, "Portrait" },
- { 3, "Scenery" },
- { 4, "Sports" },
- { 5, "Night Portrait" },
- { 6, "Program" },
- { 7, "Aperture Priority" },
- { 8, "Shutter Priority" },
- { 9, "Macro" },
- { 11, "Manual" },
- { 13, "Panning" },
- { 18, "Fireworks" },
- { 19, "Party" },
- { 20, "Snow" },
- { 21, "Night Scenery" },
- { 0, "(end)" }
- };
-
- std::ostream& PanasonicMakerNote::print0x001f(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(shootingMode).print(os, value);
- } // PanasonicMakerNote::print0x001f
-
- //! Audio
- const TagDetails Audio[] = {
- { 0, "(start)" },
- { 1, "Yes" },
- { 2, "No" },
- { 0, "(end)" }
- };
-
- std::ostream& PanasonicMakerNote::print0x0020(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(Audio).print(os, value);
- } // PanasonicMakerNote::print0x0020
-
- std::ostream& PanasonicMakerNote::print0x0023(std::ostream& os,
- const Value& value)
- {
- return os << std::fixed << std::setprecision(1)
- << value.toLong() / 3 << " EV";
- } // PanasonicMakerNote::print0x0023
-
- //! ColorEffect
- const TagDetails colorEffect[] = {
- { 0, "(start)" },
- { 1, "Off" },
- { 2, "Warm" },
- { 3, "Cool" },
- { 4, "Black and White" },
- { 5, "Sepia" },
- { 0, "(end)" }
- };
-
- std::ostream& PanasonicMakerNote::print0x0028(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(colorEffect).print(os, value);
- } // PanasonicMakerNote::print0x0028
-
- //! Contrast
- const TagDetails contrast[] = {
- { -1, "(start)" },
- { 0, "Standard" },
- { 1, "Low" },
- { 2, "High" },
- { 0x100, "Low" },
- { 0x110, "Standard" },
- { 0x120, "High" },
- { -1, "(end)" }
- };
-
- std::ostream& PanasonicMakerNote::print0x002c(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(contrast).print(os, value);
- } // PanasonicMakerNote::print0x002c
-
- //! NoiseReduction
- const TagDetails noiseReduction[] = {
- { -1, "(start)" },
- { 0, "Standard" },
- { 1, "Low" },
- { 2, "High" },
- { -1, "(end)" }
- };
-
- std::ostream& PanasonicMakerNote::print0x002d(std::ostream& os,
- const Value& value)
- {
- return TagTranslator(noiseReduction).print(os, value);
- } // PanasonicMakerNote::print0x002d
-
-// *****************************************************************************
-// free functions
-
- MakerNote::AutoPtr createPanasonicMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset)
- {
- return MakerNote::AutoPtr(new PanasonicMakerNote(alloc));
- }
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/panasonicmn.hpp b/src/plugins/exiv2/panasonicmn.hpp
@@ -1,170 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file panasonicmn.hpp
- @brief Panasonic MakerNote implemented using the following references:
- <a href="http://www.compton.nu/panasonic.html">Panasonic MakerNote Information</a> by Tom Hughes,
- Panasonic.pm of <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/">ExifTool</a> by Phil Harvey,
- <a href="http://www.ozhiker.com/electronics/pjmt/jpeg_info/panasonic_mn.html">Panasonic Makernote Format Specification</a> by Evan Hunter.
- @version $Rev: 581 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 11-Jun-05, ahu: created
- */
-#ifndef PANASONICMN_HPP_
-#define PANASONICMN_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "makernote.hpp"
-#include "tags.hpp"
-
-// + standard includes
-#include <string>
-#include <iosfwd>
-#include <memory>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class declarations
- class Value;
-
-// *****************************************************************************
-// free functions
-
- /*!
- @brief Return an auto-pointer to a newly created empty MakerNote
- initialized to operate in the memory management model indicated.
- The caller owns this copy and the auto-pointer ensures that it
- will be deleted.
-
- @param alloc Memory management model for the new MakerNote. Determines if
- memory required to store data should be allocated and deallocated
- (true) or not (false). If false, only pointers to the buffer
- provided to read() will be kept. See Ifd for more background on
- this concept.
- @param buf Pointer to the makernote character buffer (not used).
- @param len Length of the makernote character buffer (not used).
- @param byteOrder Byte order in which the Exif data (and possibly the
- makernote) is encoded (not used).
- @param offset Offset from the start of the TIFF header of the makernote
- buffer (not used).
-
- @return An auto-pointer to a newly created empty MakerNote. The caller
- owns this copy and the auto-pointer ensures that it will be
- deleted.
- */
- MakerNote::AutoPtr createPanasonicMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset);
-
-// *****************************************************************************
-// class definitions
-
- //! MakerNote for Panasonic cameras
- class PanasonicMakerNote : public IfdMakerNote {
- public:
- //! Shortcut for a %PanasonicMakerNote auto pointer.
- typedef std::auto_ptr<PanasonicMakerNote> AutoPtr;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor. Allows to choose whether or not memory management
- is required for the makernote entries.
- */
- PanasonicMakerNote(bool alloc =true);
- //! Copy constructor
- PanasonicMakerNote(const PanasonicMakerNote& rhs);
- //! Virtual destructor
- virtual ~PanasonicMakerNote() {}
- //@}
-
- //! @name Manipulators
- //@{
- int readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder);
- //@}
-
- //! @name Accessors
- //@{
- int checkHeader() const;
- AutoPtr create(bool alloc =true) const;
- AutoPtr clone() const;
- //@}
-
- //! @name Print functions for Panasonic %MakerNote tags
- //@{
- //! Print Quality
- static std::ostream& print0x0001(std::ostream& os, const Value& value);
- //! Print WhiteBalance
- static std::ostream& print0x0003(std::ostream& os, const Value& value);
- //! Print FocusMode
- static std::ostream& print0x0007(std::ostream& os, const Value& value);
- //! Print SpotMode
- static std::ostream& print0x000f(std::ostream& os, const Value& value);
- //! Print ImageStabilizer
- static std::ostream& print0x001a(std::ostream& os, const Value& value);
- //! Print Macro
- static std::ostream& print0x001c(std::ostream& os, const Value& value);
- //! Print ShootingMode
- static std::ostream& print0x001f(std::ostream& os, const Value& value);
- //! Print Audio
- static std::ostream& print0x0020(std::ostream& os, const Value& value);
- //! Print WhiteBalanceBias
- static std::ostream& print0x0023(std::ostream& os, const Value& value);
- //! Print ColorEffect
- static std::ostream& print0x0028(std::ostream& os, const Value& value);
- //! Print Contrast
- static std::ostream& print0x002c(std::ostream& os, const Value& value);
- //! Print NoiseReduction
- static std::ostream& print0x002d(std::ostream& os, const Value& value);
- //@}
-
- //! @cond IGNORE
- // Public only so that we can create a static instance
- struct RegisterMn {
- RegisterMn();
- };
- //! @endcond
-
- private:
- //! Internal virtual create function.
- PanasonicMakerNote* create_(bool alloc =true) const;
- //! Internal virtual copy constructor.
- PanasonicMakerNote* clone_() const;
-
- //! Tag information
- static const TagInfo tagInfo_[];
-
- }; // class PanasonicMakerNote
-
- static PanasonicMakerNote::RegisterMn registerPanasonicMakerNote;
-} // namespace Exiv2
-
-#endif // #ifndef PANASONICMN_HPP_
diff --git a/src/plugins/exiv2/rcsid.hpp b/src/plugins/exiv2/rcsid.hpp
@@ -1,62 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file rcsid.hpp
- @brief Define an RCS id string in every object file compiled from a source
- file that includes rcsid.hpp.
-
- This is a simplified version of the ACE_RCSID macro that is used in the
- <a href="http://www.cs.wustl.edu/~schmidt/ACE.html">ACE(TM)</a> distribution.
-
- @version $Rev: 538 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 02-Feb-04, ahu: created
- */
-#ifndef RCSID_HPP_
-#define RCSID_HPP_
-
-#if !defined (EXIV2_RCSID)
-/*!
- @brief Macro to store version information in each object file.
-
- Use this macro by including the following two lines at the beginning of
- each *.cpp file. See the ident(1) manual pages for more information.
-
- @code
- #include "rcsid.hpp"
- EXIV2_RCSID("@(#) $Id$");
- @endcode
-
- The macro hack itself has the following purposes:
- -# To define the RCS id string variable in the local namespace, so
- that there won't be any duplicate extern symbols at link time.
- -# To avoid warnings of the type "variable declared and never used".
-
- */
-#define EXIV2_RCSID(id) \
- namespace { \
- inline const char* getRcsId(const char*) { return id ; } \
- const char* rcsId = getRcsId(rcsId); \
- }
-
-#endif // #if !defined (EXIV2_RCSID)
-#endif // #ifndef RCSID_HPP_
diff --git a/src/plugins/exiv2/sigmamn.cpp b/src/plugins/exiv2/sigmamn.cpp
@@ -1,208 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: sigmamn.cpp
- Version: $Rev: 600 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 02-Apr-04, ahu: created
- Credits: Sigma and Foveon MakerNote implemented according to the specification
- in "SIGMA and FOVEON EXIF MakerNote Documentation" by Foveon.
- <http://www.x3f.info/technotes/FileDocs/MakerNoteDoc.html>
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: sigmamn.cpp 600 2005-07-09 10:38:09Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "sigmamn.hpp"
-#include "makernote.hpp"
-#include "value.hpp"
-
-// + standard includes
-#include <string>
-#include <sstream>
-#include <iomanip>
-#include <cassert>
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- //! @cond IGNORE
- SigmaMakerNote::RegisterMn::RegisterMn()
- {
- MakerNoteFactory::registerMakerNote("SIGMA", "*", createSigmaMakerNote);
- MakerNoteFactory::registerMakerNote("FOVEON", "*", createSigmaMakerNote);
- MakerNoteFactory::registerMakerNote(
- sigmaIfdId, MakerNote::AutoPtr(new SigmaMakerNote));
-
- ExifTags::registerMakerTagInfo(sigmaIfdId, tagInfo_);
- }
- //! @endcond
-
- // Sigma (Foveon) MakerNote Tag Info
- const TagInfo SigmaMakerNote::tagInfo_[] = {
- TagInfo(0x0002, "SerialNumber", "Camera serial number", sigmaIfdId, makerTags, asciiString, printValue),
- TagInfo(0x0003, "DriveMode", "Drive Mode", sigmaIfdId, makerTags, asciiString, printValue),
- TagInfo(0x0004, "ResolutionMode", "Resolution Mode", sigmaIfdId, makerTags, asciiString, printValue),
- TagInfo(0x0005, "AutofocusMode", "Autofocus mode", sigmaIfdId, makerTags, asciiString, printValue),
- TagInfo(0x0006, "FocusSetting", "Focus setting", sigmaIfdId, makerTags, asciiString, printValue),
- TagInfo(0x0007, "WhiteBalance", "White balance", sigmaIfdId, makerTags, asciiString, printValue),
- TagInfo(0x0008, "ExposureMode", "Exposure mode", sigmaIfdId, makerTags, asciiString, print0x0008),
- TagInfo(0x0009, "MeteringMode", "Metering mode", sigmaIfdId, makerTags, asciiString, print0x0009),
- TagInfo(0x000a, "LensRange", "Lens focal length range", sigmaIfdId, makerTags, asciiString, printValue),
- TagInfo(0x000b, "ColorSpace", "Color space", sigmaIfdId, makerTags, asciiString, printValue),
- TagInfo(0x000c, "Exposure", "Exposure", sigmaIfdId, makerTags, asciiString, printStripLabel),
- TagInfo(0x000d, "Contrast", "Contrast", sigmaIfdId, makerTags, asciiString, printStripLabel),
- TagInfo(0x000e, "Shadow", "Shadow", sigmaIfdId, makerTags, asciiString, printStripLabel),
- TagInfo(0x000f, "Highlight", "Highlight", sigmaIfdId, makerTags, asciiString, printStripLabel),
- TagInfo(0x0010, "Saturation", "Saturation", sigmaIfdId, makerTags, asciiString, printStripLabel),
- TagInfo(0x0011, "Sharpness", "Sharpness", sigmaIfdId, makerTags, asciiString, printStripLabel),
- TagInfo(0x0012, "FillLight", "X3 Fill light", sigmaIfdId, makerTags, asciiString, printStripLabel),
- TagInfo(0x0014, "ColorAdjustment", "Color adjustment", sigmaIfdId, makerTags, asciiString, printStripLabel),
- TagInfo(0x0015, "AdjustmentMode", "Adjustment mode", sigmaIfdId, makerTags, asciiString, printValue),
- TagInfo(0x0016, "Quality", "Quality", sigmaIfdId, makerTags, asciiString, printStripLabel),
- TagInfo(0x0017, "Firmware", "Firmware", sigmaIfdId, makerTags, asciiString, printValue),
- TagInfo(0x0018, "Software", "Software", sigmaIfdId, makerTags, asciiString, printValue),
- TagInfo(0x0019, "AutoBracket", "Auto bracket", sigmaIfdId, makerTags, asciiString, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownSigmaMakerNoteTag)", "Unknown SigmaMakerNote tag", sigmaIfdId, makerTags, invalidTypeId, printValue)
- };
-
- SigmaMakerNote::SigmaMakerNote(bool alloc)
- : IfdMakerNote(sigmaIfdId, alloc)
- {
- byte buf[] = {
- 'S', 'I', 'G', 'M', 'A', '\0', '\0', '\0', 0x01, 0x00
- };
- readHeader(buf, 10, byteOrder_);
- }
-
- SigmaMakerNote::SigmaMakerNote(const SigmaMakerNote& rhs)
- : IfdMakerNote(rhs)
- {
- }
-
- int SigmaMakerNote::readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder)
- {
- if (len < 10) return 1;
-
- // Copy the header. My one and only Sigma sample has two undocumented
- // extra bytes (0x01, 0x00) between the ID string and the start of the
- // Makernote IFD. So we copy 10 bytes into the header.
- header_.alloc(10);
- memcpy(header_.pData_, buf, header_.size_);
- // Adjust the offset of the IFD for the prefix
- adjOffset_ = 10;
- return 0;
- }
-
- int SigmaMakerNote::checkHeader() const
- {
- int rc = 0;
- // Check the SIGMA or FOVEON prefix
- if ( header_.size_ < 10
- || std::string(reinterpret_cast<char*>(header_.pData_), 8)
- != std::string("SIGMA\0\0\0", 8)
- && std::string(reinterpret_cast<char*>(header_.pData_), 8)
- != std::string("FOVEON\0\0", 8)) {
- rc = 2;
- }
- return rc;
- }
-
- SigmaMakerNote::AutoPtr SigmaMakerNote::create(bool alloc) const
- {
- return AutoPtr(create_(alloc));
- }
-
- SigmaMakerNote* SigmaMakerNote::create_(bool alloc) const
- {
- AutoPtr makerNote = AutoPtr(new SigmaMakerNote(alloc));
- assert(makerNote.get() != 0);
- makerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
- return makerNote.release();
- }
-
- SigmaMakerNote::AutoPtr SigmaMakerNote::clone() const
- {
- return AutoPtr(clone_());
- }
-
- SigmaMakerNote* SigmaMakerNote::clone_() const
- {
- return new SigmaMakerNote(*this);
- }
-
- std::ostream& SigmaMakerNote::printStripLabel(std::ostream& os,
- const Value& value)
- {
- std::string v = value.toString();
- std::string::size_type pos = v.find(':');
- if (pos != std::string::npos) {
- if (v[pos + 1] == ' ') ++pos;
- v = v.substr(pos + 1);
- }
- return os << v;
- }
-
- std::ostream& SigmaMakerNote::print0x0008(std::ostream& os,
- const Value& value)
- {
- switch (value.toString()[0]) {
- case 'P': os << "Program"; break;
- case 'A': os << "Aperture priority"; break;
- case 'S': os << "Shutter priority"; break;
- case 'M': os << "Manual"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
- std::ostream& SigmaMakerNote::print0x0009(std::ostream& os,
- const Value& value)
- {
- switch (value.toString()[0]) {
- case 'A': os << "Average"; break;
- case 'C': os << "Center"; break;
- case '8': os << "8-Segment"; break;
- default: os << "(" << value << ")"; break;
- }
- return os;
- }
-
-// *****************************************************************************
-// free functions
-
- MakerNote::AutoPtr createSigmaMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset)
- {
- return MakerNote::AutoPtr(new SigmaMakerNote(alloc));
- }
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/sigmamn.hpp b/src/plugins/exiv2/sigmamn.hpp
@@ -1,151 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file sigmamn.hpp
- @brief Sigma and Foveon MakerNote implemented according to the specification
- <a href="http://www.x3f.info/technotes/FileDocs/MakerNoteDoc.html">
- SIGMA and FOVEON EXIF MakerNote Documentation</a> by Foveon.
- @version $Rev: 569 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 02-Apr-04, ahu: created
- */
-#ifndef SIGMAMN_HPP_
-#define SIGMAMN_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "makernote.hpp"
-#include "tags.hpp"
-
-// + standard includes
-#include <string>
-#include <iosfwd>
-#include <memory>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class declarations
- class Value;
-
-// *****************************************************************************
-// free functions
-
- /*!
- @brief Return an auto-pointer to a newly created empty MakerNote
- initialized to operate in the memory management model indicated.
- The caller owns this copy and the auto-pointer ensures that it
- will be deleted.
-
- @param alloc Memory management model for the new MakerNote. Determines if
- memory required to store data should be allocated and deallocated
- (true) or not (false). If false, only pointers to the buffer
- provided to read() will be kept. See Ifd for more background on
- this concept.
- @param buf Pointer to the makernote character buffer (not used).
- @param len Length of the makernote character buffer (not used).
- @param byteOrder Byte order in which the Exif data (and possibly the
- makernote) is encoded (not used).
- @param offset Offset from the start of the TIFF header of the makernote
- buffer (not used).
-
- @return An auto-pointer to a newly created empty MakerNote. The caller
- owns this copy and the auto-pointer ensures that it will be
- deleted.
- */
- MakerNote::AutoPtr createSigmaMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset);
-
-// *****************************************************************************
-// class definitions
-
- //! MakerNote for Sigma (Foveon) cameras
- class SigmaMakerNote : public IfdMakerNote {
- public:
- //! Shortcut for a %SigmaMakerNote auto pointer.
- typedef std::auto_ptr<SigmaMakerNote> AutoPtr;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor. Allows to choose whether or not memory management
- is required for the makernote entries.
- */
- SigmaMakerNote(bool alloc =true);
- //! Copy constructor
- SigmaMakerNote(const SigmaMakerNote& rhs);
- //! Virtual destructor
- virtual ~SigmaMakerNote() {}
- //@}
-
- //! @name Manipulators
- //@{
- int readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder);
- //@}
-
- //! @name Accessors
- //@{
- int checkHeader() const;
- AutoPtr create(bool alloc =true) const;
- AutoPtr clone() const;
- //@}
-
- //! @name Print functions for Sigma (Foveon) %MakerNote tags
- //@{
- //! Strip the label from the value and print the remainder
- static std::ostream& printStripLabel(std::ostream& os, const Value& value);
- //! Print exposure mode
- static std::ostream& print0x0008(std::ostream& os, const Value& value);
- //! Print metering mode
- static std::ostream& print0x0009(std::ostream& os, const Value& value);
- //@}
-
- //! @cond IGNORE
- // Public only so that we can create a static instance
- struct RegisterMn {
- RegisterMn();
- };
- //! @endcond
-
- private:
- //! Internal virtual create function.
- SigmaMakerNote* create_(bool alloc =true) const;
- //! Internal virtual copy constructor.
- SigmaMakerNote* clone_() const;
-
- //! Tag information
- static const TagInfo tagInfo_[];
-
- }; // class SigmaMakerNote
-
- static SigmaMakerNote::RegisterMn registerSigmaMakerNote;
-} // namespace Exiv2
-
-#endif // #ifndef SIGMAMN_HPP_
diff --git a/src/plugins/exiv2/sonymn.cpp b/src/plugins/exiv2/sonymn.cpp
@@ -1,147 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: sonymn.cpp
- Version: $Rev: 600 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 18-Apr-05, ahu: created
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: sonymn.cpp 600 2005-07-09 10:38:09Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "sonymn.hpp"
-#include "makernote.hpp"
-#include "value.hpp"
-
-// + standard includes
-#include <string>
-#include <sstream>
-#include <iomanip>
-#include <cassert>
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- //! @cond IGNORE
- SonyMakerNote::RegisterMn::RegisterMn()
- {
- MakerNoteFactory::registerMakerNote("SONY", "*", createSonyMakerNote);
- MakerNoteFactory::registerMakerNote(
- sonyIfdId, MakerNote::AutoPtr(new SonyMakerNote));
-
- ExifTags::registerMakerTagInfo(sonyIfdId, tagInfo_);
- }
- //! @endcond
-
- // Sony MakerNote Tag Info
- const TagInfo SonyMakerNote::tagInfo_[] = {
- TagInfo(0x2000, "0x2000", "Unknown", sonyIfdId, makerTags, undefined, printValue),
- TagInfo(0x9001, "0x9001", "Unknown", sonyIfdId, makerTags, undefined, printValue),
- TagInfo(0x9002, "0x9002", "Unknown", sonyIfdId, makerTags, undefined, printValue),
- TagInfo(0x9003, "0x9003", "Unknown", sonyIfdId, makerTags, undefined, printValue),
- TagInfo(0x9004, "0x9004", "Unknown", sonyIfdId, makerTags, undefined, printValue),
- TagInfo(0x9005, "0x9005", "Unknown", sonyIfdId, makerTags, undefined, printValue),
- TagInfo(0x9006, "0x9006", "Unknown", sonyIfdId, makerTags, undefined, printValue),
- TagInfo(0x9007, "0x9007", "Unknown", sonyIfdId, makerTags, undefined, printValue),
- TagInfo(0x9008, "0x9008", "Unknown", sonyIfdId, makerTags, undefined, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownSonyMakerNoteTag)", "Unknown SonyMakerNote tag", sonyIfdId, makerTags, invalidTypeId, printValue)
- };
-
- SonyMakerNote::SonyMakerNote(bool alloc)
- : IfdMakerNote(sonyIfdId, alloc, false)
- {
- byte buf[] = {
- 'S', 'O', 'N', 'Y', ' ', 'D', 'S', 'C', ' ', '\0', '\0', '\0'
- };
- readHeader(buf, 12, byteOrder_);
- }
-
- SonyMakerNote::SonyMakerNote(const SonyMakerNote& rhs)
- : IfdMakerNote(rhs)
- {
- }
-
- int SonyMakerNote::readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder)
- {
- if (len < 12) return 1;
- header_.alloc(12);
- memcpy(header_.pData_, buf, header_.size_);
- // Adjust the offset of the IFD for the prefix
- adjOffset_ = 12;
- return 0;
- }
-
- int SonyMakerNote::checkHeader() const
- {
- int rc = 0;
- // Check the SONY prefix
- if ( header_.size_ < 12
- || std::string(reinterpret_cast<char*>(header_.pData_), 12)
- != std::string("SONY DSC \0\0\0", 12)) {
- rc = 2;
- }
- return rc;
- }
-
- SonyMakerNote::AutoPtr SonyMakerNote::create(bool alloc) const
- {
- return AutoPtr(create_(alloc));
- }
-
- SonyMakerNote* SonyMakerNote::create_(bool alloc) const
- {
- AutoPtr makerNote = AutoPtr(new SonyMakerNote(alloc));
- assert(makerNote.get() != 0);
- makerNote->readHeader(header_.pData_, header_.size_, byteOrder_);
- return makerNote.release();
- }
-
- SonyMakerNote::AutoPtr SonyMakerNote::clone() const
- {
- return AutoPtr(clone_());
- }
-
- SonyMakerNote* SonyMakerNote::clone_() const
- {
- return new SonyMakerNote(*this);
- }
-
-// *****************************************************************************
-// free functions
-
- MakerNote::AutoPtr createSonyMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset)
- {
- return MakerNote::AutoPtr(new SonyMakerNote(alloc));
- }
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/sonymn.hpp b/src/plugins/exiv2/sonymn.hpp
@@ -1,139 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file sonymn.hpp
- @brief Basic Sony MakerNote implementation
- @version $Rev: 569 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 18-Apr-05, ahu: created
- */
-#ifndef SONYMN_HPP_
-#define SONYMN_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-#include "makernote.hpp"
-#include "tags.hpp"
-
-// + standard includes
-#include <string>
-#include <iosfwd>
-#include <memory>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class declarations
- class Value;
-
-// *****************************************************************************
-// free functions
-
- /*!
- @brief Return an auto-pointer to a newly created empty MakerNote
- initialized to operate in the memory management model indicated.
- The caller owns this copy and the auto-pointer ensures that it
- will be deleted.
-
- @param alloc Memory management model for the new MakerNote. Determines if
- memory required to store data should be allocated and deallocated
- (true) or not (false). If false, only pointers to the buffer
- provided to read() will be kept. See Ifd for more background on
- this concept.
- @param buf Pointer to the makernote character buffer (not used).
- @param len Length of the makernote character buffer (not used).
- @param byteOrder Byte order in which the Exif data (and possibly the
- makernote) is encoded (not used).
- @param offset Offset from the start of the TIFF header of the makernote
- buffer (not used).
-
- @return An auto-pointer to a newly created empty MakerNote. The caller
- owns this copy and the auto-pointer ensures that it will be
- deleted.
- */
- MakerNote::AutoPtr createSonyMakerNote(bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset);
-
-// *****************************************************************************
-// class definitions
-
- //! MakerNote for Sony cameras
- class SonyMakerNote : public IfdMakerNote {
- public:
- //! Shortcut for a %SonyMakerNote auto pointer.
- typedef std::auto_ptr<SonyMakerNote> AutoPtr;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor. Allows to choose whether or not memory management
- is required for the makernote entries.
- */
- SonyMakerNote(bool alloc =true);
- //! Copy constructor
- SonyMakerNote(const SonyMakerNote& rhs);
- //! Virtual destructor
- virtual ~SonyMakerNote() {}
- //@}
-
- //! @name Manipulators
- //@{
- int readHeader(const byte* buf,
- long len,
- ByteOrder byteOrder);
- //@}
-
- //! @name Accessors
- //@{
- int checkHeader() const;
- AutoPtr create(bool alloc =true) const;
- AutoPtr clone() const;
- //@}
-
- //! @cond IGNORE
- // Public only so that we can create a static instance
- struct RegisterMn {
- RegisterMn();
- };
- //! @endcond
-
- private:
- //! Internal virtual create function.
- SonyMakerNote* create_(bool alloc =true) const;
- //! Internal virtual copy constructor.
- SonyMakerNote* clone_() const;
-
- //! Tag information
- static const TagInfo tagInfo_[];
-
- }; // class SonyMakerNote
-
- static SonyMakerNote::RegisterMn registerSonyMakerNote;
-} // namespace Exiv2
-
-#endif // #ifndef SONYMN_HPP_
diff --git a/src/plugins/exiv2/tags.cpp b/src/plugins/exiv2/tags.cpp
@@ -1,1233 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: tags.cpp
- Version: $Rev: 596 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 15-Jan-04, ahu: created
- 21-Jan-05, ahu: added MakerNote TagInfo registry and related code
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: tags.cpp 596 2005-06-26 11:04:27Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "tags.hpp"
-#include "error.hpp"
-#include "types.hpp"
-#include "ifd.hpp"
-#include "value.hpp"
-#include "makernote.hpp"
-#include "mn.hpp" // To ensure that all makernotes are registered
-
-#include <iostream>
-#include <iomanip>
-#include <sstream>
-#include <utility>
-#include <cstdlib>
-#include <cassert>
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- IfdInfo::IfdInfo(IfdId ifdId, const char* name, const char* item)
- : ifdId_(ifdId), name_(name), item_(item)
- {
- }
-
- // Todo: Allow to register new IfdInfo entries from elsewhere (the makernotes)
- // Important: IFD item must be unique!
- const IfdInfo ExifTags::ifdInfo_[] = {
- IfdInfo(ifdIdNotSet, "(Unknown IFD)", "(Unknown item)"),
- IfdInfo(ifd0Id, "IFD0", "Image"),
- IfdInfo(exifIfdId, "Exif", "Photo"), // just to avoid 'Exif.Exif.*' keys
- IfdInfo(gpsIfdId, "GPSInfo", "GPSInfo"),
- IfdInfo(iopIfdId, "Iop", "Iop"),
- IfdInfo(ifd1Id, "IFD1", "Thumbnail"),
- IfdInfo(canonIfdId, "Makernote", "Canon"),
- IfdInfo(canonCs1IfdId, "Makernote", "CanonCs1"),
- IfdInfo(canonCs2IfdId, "Makernote", "CanonCs2"),
- IfdInfo(canonCfIfdId, "Makernote", "CanonCf"),
- IfdInfo(fujiIfdId, "Makernote", "Fujifilm"),
- IfdInfo(nikon1IfdId, "Makernote", "Nikon1"),
- IfdInfo(nikon2IfdId, "Makernote", "Nikon2"),
- IfdInfo(nikon3IfdId, "Makernote", "Nikon3"),
- IfdInfo(olympusIfdId, "Makernote", "Olympus"),
- IfdInfo(panasonicIfdId, "Makernote", "Panasonic"),
- IfdInfo(sigmaIfdId, "Makernote", "Sigma"),
- IfdInfo(sonyIfdId, "Makernote", "Sony"),
- IfdInfo(lastIfdId, "(Last IFD info)", "(Last IFD item)")
- };
-
- SectionInfo::SectionInfo(
- SectionId sectionId,
- const char* name,
- const char* desc
- )
- : sectionId_(sectionId), name_(name), desc_(desc)
- {
- }
-
- const SectionInfo ExifTags::sectionInfo_[] = {
- SectionInfo(sectionIdNotSet, "(UnknownSection)", "Unknown section"),
- SectionInfo(imgStruct, "ImageStructure", "Image data structure"),
- SectionInfo(recOffset, "RecordingOffset", "Recording offset"),
- SectionInfo(imgCharacter, "ImageCharacteristics", "Image data characteristics"),
- SectionInfo(otherTags, "OtherTags", "Other data"),
- SectionInfo(exifFormat, "ExifFormat", "Exif data structure"),
- SectionInfo(exifVersion, "ExifVersion", "Exif Version"),
- SectionInfo(imgConfig, "ImageConfig", "Image configuration"),
- SectionInfo(userInfo, "UserInfo", "User information"),
- SectionInfo(relatedFile, "RelatedFile", "Related file"),
- SectionInfo(dateTime, "DateTime", "Date and time"),
- SectionInfo(captureCond, "CaptureConditions", "Picture taking conditions"),
- SectionInfo(gpsTags, "GPS", "GPS information"),
- SectionInfo(iopTags, "Interoperability", "Interoperability information"),
- SectionInfo(makerTags, "Makernote", "Vendor specific information"),
- SectionInfo(lastSectionId, "(LastSection)", "Last section")
- };
-
- TagInfo::TagInfo(
- uint16_t tag,
- const char* name,
- const char* desc,
- IfdId ifdId,
- SectionId sectionId,
- TypeId typeId,
- PrintFct printFct
- )
- : tag_(tag), name_(name), desc_(desc), ifdId_(ifdId),
- sectionId_(sectionId), typeId_(typeId), printFct_(printFct)
- {
- }
-
- // Base IFD Tags (IFD0 and IFD1)
- static const TagInfo ifdTagInfo[] = {
- TagInfo(0x0100, "ImageWidth", "Image width", ifd0Id, imgStruct, unsignedLong, printValue),
- TagInfo(0x0101, "ImageLength", "Image height", ifd0Id, imgStruct, unsignedLong, printValue),
- TagInfo(0x0102, "BitsPerSample", "Number of bits per component", ifd0Id, imgStruct, unsignedShort, printValue),
- TagInfo(0x0103, "Compression", "Compression scheme", ifd0Id, imgStruct, unsignedShort, print0x0103),
- TagInfo(0x0106, "PhotometricInterpretation", "Pixel composition", ifd0Id, imgStruct, unsignedShort, print0x0106),
- TagInfo(0x010e, "ImageDescription", "Image title", ifd0Id, otherTags, asciiString, printValue),
- TagInfo(0x010f, "Make", "Manufacturer of image input equipment", ifd0Id, otherTags, asciiString, printValue),
- TagInfo(0x0110, "Model", "Model of image input equipment", ifd0Id, otherTags, asciiString, printValue),
- TagInfo(0x0111, "StripOffsets", "Image data location", ifd0Id, recOffset, unsignedLong, printValue),
- TagInfo(0x0112, "Orientation", "Orientation of image", ifd0Id, imgStruct, unsignedShort, print0x0112),
- TagInfo(0x0115, "SamplesPerPixel", "Number of components", ifd0Id, imgStruct, unsignedShort, printValue),
- TagInfo(0x0116, "RowsPerStrip", "Number of rows per strip", ifd0Id, recOffset, unsignedLong, printValue),
- TagInfo(0x0117, "StripByteCounts", "Bytes per compressed strip", ifd0Id, recOffset, unsignedLong, printValue),
- TagInfo(0x011a, "XResolution", "Image resolution in width direction", ifd0Id, imgStruct, unsignedRational, printLong),
- TagInfo(0x011b, "YResolution", "Image resolution in height direction", ifd0Id, imgStruct, unsignedRational, printLong),
- TagInfo(0x011c, "PlanarConfiguration", "Image data arrangement", ifd0Id, imgStruct, unsignedShort, printValue),
- TagInfo(0x0128, "ResolutionUnit", "Unit of X and Y resolution", ifd0Id, imgStruct, unsignedShort, printUnit),
- TagInfo(0x012d, "TransferFunction", "Transfer function", ifd0Id, imgCharacter, unsignedShort, printValue),
- TagInfo(0x0131, "Software", "Software used", ifd0Id, otherTags, asciiString, printValue),
- TagInfo(0x0132, "DateTime", "File change date and time", ifd0Id, otherTags, asciiString, printValue),
- TagInfo(0x013b, "Artist", "Person who created the image", ifd0Id, otherTags, asciiString, printValue),
- TagInfo(0x013e, "WhitePoint", "White point chromaticity", ifd0Id, imgCharacter, unsignedRational, printValue),
- TagInfo(0x013f, "PrimaryChromaticities", "Chromaticities of primaries", ifd0Id, imgCharacter, unsignedRational, printValue),
- TagInfo(0x0201, "JPEGInterchangeFormat", "Offset to JPEG SOI", ifd0Id, recOffset, unsignedLong, printValue),
- TagInfo(0x0202, "JPEGInterchangeFormatLength", "Bytes of JPEG data", ifd0Id, recOffset, unsignedLong, printValue),
- TagInfo(0x0211, "YCbCrCoefficients", "Color space transformation matrix coefficients", ifd0Id, imgCharacter, unsignedRational, printValue),
- TagInfo(0x0212, "YCbCrSubSampling", "Subsampling ratio of Y to C", ifd0Id, imgStruct, unsignedShort, printValue),
- TagInfo(0x0213, "YCbCrPositioning", "Y and C positioning", ifd0Id, imgStruct, unsignedShort, print0x0213),
- TagInfo(0x0214, "ReferenceBlackWhite", "Pair of black and white reference values", ifd0Id, imgCharacter, unsignedRational, printValue),
- TagInfo(0x8298, "Copyright", "Copyright holder", ifd0Id, otherTags, asciiString, print0x8298),
- TagInfo(0x8769, "ExifTag", "Exif IFD Pointer", ifd0Id, exifFormat, unsignedLong, printValue),
- TagInfo(0x8825, "GPSTag", "GPSInfo IFD Pointer", ifd0Id, exifFormat, unsignedLong, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownIfdTag)", "Unknown IFD tag", ifdIdNotSet, sectionIdNotSet, invalidTypeId, printValue)
- };
-
- // Exif IFD Tags
- static const TagInfo exifTagInfo[] = {
- TagInfo(0x829a, "ExposureTime", "Exposure time", exifIfdId, captureCond, unsignedRational, print0x829a),
- TagInfo(0x829d, "FNumber", "F number", exifIfdId, captureCond, unsignedRational, print0x829d),
- TagInfo(0x8822, "ExposureProgram", "Exposure program", exifIfdId, captureCond, unsignedShort, print0x8822),
- TagInfo(0x8824, "SpectralSensitivity", "Spectral sensitivity", exifIfdId, captureCond, asciiString, printValue),
- TagInfo(0x8827, "ISOSpeedRatings", "ISO speed ratings", exifIfdId, captureCond, unsignedShort, print0x8827),
- TagInfo(0x8828, "OECF", "Optoelectric coefficient", exifIfdId, captureCond, undefined, printValue),
- TagInfo(0x9000, "ExifVersion", "Exif Version", exifIfdId, exifVersion, undefined, printValue),
- TagInfo(0x9003, "DateTimeOriginal", "Date and time original image was generated", exifIfdId, dateTime, asciiString, printValue),
- TagInfo(0x9004, "DateTimeDigitized", "Date and time image was made digital data", exifIfdId, dateTime, asciiString, printValue),
- TagInfo(0x9101, "ComponentsConfiguration", "Meaning of each component", exifIfdId, imgConfig, undefined, print0x9101),
- TagInfo(0x9102, "CompressedBitsPerPixel", "Image compression mode", exifIfdId, imgConfig, unsignedRational, printFloat),
- TagInfo(0x9201, "ShutterSpeedValue", "Shutter speed", exifIfdId, captureCond, signedRational, printFloat),
- TagInfo(0x9202, "ApertureValue", "Aperture", exifIfdId, captureCond, unsignedRational, printFloat),
- TagInfo(0x9203, "BrightnessValue", "Brightness", exifIfdId, captureCond, signedRational, printFloat),
- TagInfo(0x9204, "ExposureBiasValue", "Exposure bias", exifIfdId, captureCond, signedRational, print0x9204),
- TagInfo(0x9205, "MaxApertureValue", "Maximum lens aperture", exifIfdId, captureCond, unsignedRational, printFloat),
- TagInfo(0x9206, "SubjectDistance", "Subject distance", exifIfdId, captureCond, unsignedRational, print0x9206),
- TagInfo(0x9207, "MeteringMode", "Metering mode", exifIfdId, captureCond, unsignedShort, print0x9207),
- TagInfo(0x9208, "LightSource", "Light source", exifIfdId, captureCond, unsignedShort, print0x9208),
- TagInfo(0x9209, "Flash", "Flash", exifIfdId, captureCond, unsignedShort, print0x9209),
- TagInfo(0x920a, "FocalLength", "Lens focal length", exifIfdId, captureCond, unsignedRational, print0x920a),
- TagInfo(0x9214, "SubjectArea", "Subject area", exifIfdId, captureCond, unsignedShort, printValue),
- TagInfo(0x927c, "MakerNote", "Manufacturer notes", exifIfdId, userInfo, undefined, printValue),
- TagInfo(0x9286, "UserComment", "User comments", exifIfdId, userInfo, comment, print0x9286),
- TagInfo(0x9290, "SubSecTime", "DateTime subseconds", exifIfdId, dateTime, asciiString, printValue),
- TagInfo(0x9291, "SubSecTimeOriginal", "DateTimeOriginal subseconds", exifIfdId, dateTime, asciiString, printValue),
- TagInfo(0x9292, "SubSecTimeDigitized", "DateTimeDigitized subseconds", exifIfdId, dateTime, asciiString, printValue),
- TagInfo(0xa000, "FlashpixVersion", "Supported Flashpix version", exifIfdId, exifVersion, undefined, printValue),
- TagInfo(0xa001, "ColorSpace", "Color space information", exifIfdId, imgCharacter, unsignedShort, print0xa001),
- TagInfo(0xa002, "PixelXDimension", "Valid image width", exifIfdId, imgConfig, unsignedLong, printValue),
- TagInfo(0xa003, "PixelYDimension", "Valid image height", exifIfdId, imgConfig, unsignedLong, printValue),
- TagInfo(0xa004, "RelatedSoundFile", "Related audio file", exifIfdId, relatedFile, asciiString, printValue),
- TagInfo(0xa005, "InteroperabilityTag", "Interoperability IFD Pointer", exifIfdId, exifFormat, unsignedLong, printValue),
- TagInfo(0xa20b, "FlashEnergy", "Flash energy", exifIfdId, captureCond, unsignedRational, printValue),
- TagInfo(0xa20c, "SpatialFrequencyResponse", "Spatial frequency response", exifIfdId, captureCond, undefined, printValue),
- TagInfo(0xa20e, "FocalPlaneXResolution", "Focal plane X resolution", exifIfdId, captureCond, unsignedRational, printFloat),
- TagInfo(0xa20f, "FocalPlaneYResolution", "Focal plane Y resolution", exifIfdId, captureCond, unsignedRational, printFloat),
- TagInfo(0xa210, "FocalPlaneResolutionUnit", "Focal plane resolution unit", exifIfdId, captureCond, unsignedShort, printUnit),
- TagInfo(0xa214, "SubjectLocation", "Subject location", exifIfdId, captureCond, unsignedShort, printValue),
- TagInfo(0xa215, "ExposureIndex", "Exposure index", exifIfdId, captureCond, unsignedRational, printValue),
- TagInfo(0xa217, "SensingMethod", "Sensing method", exifIfdId, captureCond, unsignedShort, print0xa217),
- TagInfo(0xa300, "FileSource", "File source", exifIfdId, captureCond, undefined, print0xa300),
- TagInfo(0xa301, "SceneType", "Scene type", exifIfdId, captureCond, undefined, print0xa301),
- TagInfo(0xa302, "CFAPattern", "CFA pattern", exifIfdId, captureCond, undefined, printValue),
- TagInfo(0xa401, "CustomRendered", "Custom image processing", exifIfdId, captureCond, unsignedShort, printValue),
- TagInfo(0xa402, "ExposureMode", "Exposure mode", exifIfdId, captureCond, unsignedShort, print0xa402),
- TagInfo(0xa403, "WhiteBalance", "White balance", exifIfdId, captureCond, unsignedShort, print0xa403),
- TagInfo(0xa404, "DigitalZoomRatio", "Digital zoom ratio", exifIfdId, captureCond, unsignedRational, print0xa404),
- TagInfo(0xa405, "FocalLengthIn35mmFilm", "Focal length in 35 mm film", exifIfdId, captureCond, unsignedShort, print0xa405),
- TagInfo(0xa406, "SceneCaptureType", "Scene capture type", exifIfdId, captureCond, unsignedShort, print0xa406),
- TagInfo(0xa407, "GainControl", "Gain control", exifIfdId, captureCond, unsignedRational, print0xa407),
- TagInfo(0xa408, "Contrast", "Contrast", exifIfdId, captureCond, unsignedShort, print0xa408),
- TagInfo(0xa409, "Saturation", "Saturation", exifIfdId, captureCond, unsignedShort, print0xa409),
- TagInfo(0xa40a, "Sharpness", "Sharpness", exifIfdId, captureCond, unsignedShort, print0xa40a),
- TagInfo(0xa40b, "DeviceSettingDescription", "Device settings description", exifIfdId, captureCond, undefined, printValue),
- TagInfo(0xa40c, "SubjectDistanceRange", "Subject distance range", exifIfdId, captureCond, unsignedShort, print0xa40c),
- TagInfo(0xa420, "ImageUniqueID", "Unique image ID", exifIfdId, otherTags, asciiString, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownExifTag)", "Unknown Exif tag", ifdIdNotSet, sectionIdNotSet, invalidTypeId, printValue)
- };
-
- // GPS Info Tags
- static const TagInfo gpsTagInfo[] = {
- TagInfo(0x0000, "GPSVersionID", "GPS tag version", gpsIfdId, gpsTags, unsignedByte, printValue),
- TagInfo(0x0001, "GPSLatitudeRef", "North or South Latitude", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x0002, "GPSLatitude", "Latitude", gpsIfdId, gpsTags, unsignedRational, printValue),
- TagInfo(0x0003, "GPSLongitudeRef", "East or West Longitude", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x0004, "GPSLongitude", "Longitude", gpsIfdId, gpsTags, unsignedRational, printValue),
- TagInfo(0x0005, "GPSAltitudeRef", "Altitude reference", gpsIfdId, gpsTags, unsignedByte, printValue),
- TagInfo(0x0006, "GPSAltitude", "Altitude", gpsIfdId, gpsTags, unsignedRational, printValue),
- TagInfo(0x0007, "GPSTimeStamp", "GPS time (atomic clock)", gpsIfdId, gpsTags, unsignedRational, printValue),
- TagInfo(0x0008, "GPSSatellites", "GPS satellites used for measurement", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x0009, "GPSStatus", "GPS receiver status", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x000a, "GPSMeasureMode", "GPS measurement mode", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x000b, "GPSDOP", "Measurement precision", gpsIfdId, gpsTags, unsignedRational, printValue),
- TagInfo(0x000c, "GPSSpeedRef", "Speed unit", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x000d, "GPSSpeed", "Speed of GPS receiver", gpsIfdId, gpsTags, unsignedRational, printValue),
- TagInfo(0x000e, "GPSTrackRef", "Reference for direction of movement", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x000f, "GPSTrack", "Direction of movement", gpsIfdId, gpsTags, unsignedRational, printValue),
- TagInfo(0x0010, "GPSImgDirectionRef", "Reference for direction of image", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x0011, "GPSImgDirection", "Direction of image", gpsIfdId, gpsTags, unsignedRational, printValue),
- TagInfo(0x0012, "GPSMapDatum", "Geodetic survey data used", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x0013, "GPSDestLatitudeRef", "Reference for latitude of destination", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x0014, "GPSDestLatitude", "Latitude of destination", gpsIfdId, gpsTags, unsignedRational, printValue),
- TagInfo(0x0015, "GPSDestLongitudeRef", "Reference for longitude of destination", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x0016, "GPSDestLongitude", "Longitude of destination", gpsIfdId, gpsTags, unsignedRational, printValue),
- TagInfo(0x0017, "GPSDestBearingRef", "Reference for bearing of destination", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x0018, "GPSDestBearing", "Bearing of destination", gpsIfdId, gpsTags, unsignedRational, printValue),
- TagInfo(0x0019, "GPSDestDistanceRef", "Reference for distance to destination", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x001a, "GPSDestDistance", "Distance to destination", gpsIfdId, gpsTags, unsignedRational, printValue),
- TagInfo(0x001b, "GPSProcessingMethod", "Name of GPS processing method", gpsIfdId, gpsTags, undefined, printValue),
- TagInfo(0x001c, "GPSAreaInformation", "Name of GPS area", gpsIfdId, gpsTags, undefined, printValue),
- TagInfo(0x001d, "GPSDateStamp", "GPS date", gpsIfdId, gpsTags, asciiString, printValue),
- TagInfo(0x001e, "GPSDifferential", "GPS differential correction", gpsIfdId, gpsTags, unsignedShort, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownGpsTag)", "Unknown GPSInfo tag", ifdIdNotSet, sectionIdNotSet, invalidTypeId, printValue)
- };
-
- // Exif Interoperability IFD Tags
- static const TagInfo iopTagInfo[] = {
- TagInfo(0x0001, "InteroperabilityIndex", "Interoperability Identification", iopIfdId, iopTags, asciiString, printValue),
- TagInfo(0x0002, "InteroperabilityVersion", "Interoperability version", iopIfdId, iopTags, undefined, printValue),
- TagInfo(0x1000, "RelatedImageFileFormat", "File format of image file", iopIfdId, iopTags, asciiString, printValue),
- TagInfo(0x1001, "RelatedImageWidth", "Image width", iopIfdId, iopTags, unsignedLong, printValue),
- TagInfo(0x1002, "RelatedImageLength", "Image height", iopIfdId, iopTags, unsignedLong, printValue),
- // End of list marker
- TagInfo(0xffff, "(UnknownIopTag)", "Unknown Exif Interoperability tag", ifdIdNotSet, sectionIdNotSet, invalidTypeId, printValue)
- };
-
- // Unknown Tag
- static const TagInfo unknownTag(0xffff, "Unknown tag", "Unknown tag", ifdIdNotSet, sectionIdNotSet, asciiString, printValue);
-
- std::ostream& TagTranslator::print(std::ostream& os, const Value& value) const
- {
- if (!pTagDetails_) return os << value;
-
- long l = value.toLong();
-
- long e = pTagDetails_[0].val_;
- int i = 1;
- for (; pTagDetails_[i].val_ != l && pTagDetails_[i].val_ != e; ++i) {}
- if (pTagDetails_[i].val_ == l) {
- os << pTagDetails_[i].label_;
- }
- else {
- os << "(" << l << ")";
- }
- return os;
- } // TagTranslator::print
-
- // Tag lookup lists with tag names, desc and where they (preferably) belong to;
- // this is an array with pointers to one list per IFD. The IfdId is used as the
- // index into the array.
- const TagInfo* ExifTags::tagInfos_[] = {
- 0,
- ifdTagInfo, exifTagInfo, gpsTagInfo, iopTagInfo, ifdTagInfo,
- 0
- };
-
- // Lookup list for registered makernote tag info tables
- const TagInfo* ExifTags::makerTagInfos_[];
-
- // All makernote ifd ids, in the same order as the tag infos in makerTagInfos_
- IfdId ExifTags::makerIfdIds_[];
-
- void ExifTags::registerBaseTagInfo(IfdId ifdId)
- {
- registerMakerTagInfo(ifdId, ifdTagInfo);
- }
-
- void ExifTags::registerMakerTagInfo(IfdId ifdId, const TagInfo* tagInfo)
- {
- int i = 0;
- for (; i < MAX_MAKER_TAG_INFOS; ++i) {
- if (makerIfdIds_[i] == 0) {
- makerIfdIds_[i] = ifdId;
- makerTagInfos_[i] = tagInfo;
- break;
- }
- }
- if (i == MAX_MAKER_TAG_INFOS) throw Error(16);
- } // ExifTags::registerMakerTagInfo
-
- int ExifTags::tagInfoIdx(uint16_t tag, IfdId ifdId)
- {
- const TagInfo* tagInfo = tagInfos_[ifdId];
- if (tagInfo == 0) return -1;
- int idx;
- for (idx = 0; tagInfo[idx].tag_ != 0xffff; ++idx) {
- if (tagInfo[idx].tag_ == tag) return idx;
- }
- return -1;
- } // ExifTags::tagInfoIdx
-
- const TagInfo* ExifTags::makerTagInfo(uint16_t tag, IfdId ifdId)
- {
- int i = 0;
- for (; i < MAX_MAKER_TAG_INFOS && makerIfdIds_[i] != ifdId; ++i);
- if (i == MAX_MAKER_TAG_INFOS) return 0;
-
- for (int k = 0; makerTagInfos_[i][k].tag_ != 0xffff; ++k) {
- if (makerTagInfos_[i][k].tag_ == tag) return &makerTagInfos_[i][k];
- }
-
- return 0;
- } // ExifTags::makerTagInfo
-
- const TagInfo* ExifTags::makerTagInfo(const std::string& tagName,
- IfdId ifdId)
- {
- int i = 0;
- for (; i < MAX_MAKER_TAG_INFOS && makerIfdIds_[i] != ifdId; ++i);
- if (i == MAX_MAKER_TAG_INFOS) return 0;
-
- for (int k = 0; makerTagInfos_[i][k].tag_ != 0xffff; ++k) {
- if (makerTagInfos_[i][k].name_ == tagName) {
- return &makerTagInfos_[i][k];
- }
- }
-
- return 0;
- } // ExifTags::makerTagInfo
-
- bool ExifTags::isMakerIfd(IfdId ifdId)
- {
- int i = 0;
- for (; i < MAX_MAKER_TAG_INFOS && makerIfdIds_[i] != ifdId; ++i);
- return i != MAX_MAKER_TAG_INFOS && makerIfdIds_[i] != IfdId(0);
- }
-
- std::string ExifTags::tagName(uint16_t tag, IfdId ifdId)
- {
- if (isExifIfd(ifdId)) {
- int idx = tagInfoIdx(tag, ifdId);
- if (idx != -1) return tagInfos_[ifdId][idx].name_;
- }
- if (isMakerIfd(ifdId)) {
- const TagInfo* tagInfo = makerTagInfo(tag, ifdId);
- if (tagInfo != 0) return tagInfo->name_;
- }
- std::ostringstream os;
- os << "0x" << std::setw(4) << std::setfill('0') << std::right
- << std::hex << tag;
- return os.str();
- } // ExifTags::tagName
-
- const char* ExifTags::tagDesc(uint16_t tag, IfdId ifdId)
- {
- if (isExifIfd(ifdId)) {
- int idx = tagInfoIdx(tag, ifdId);
- if (idx == -1) return unknownTag.desc_;
- return tagInfos_[ifdId][idx].desc_;
- }
- if (isMakerIfd(ifdId)) {
- const TagInfo* tagInfo = makerTagInfo(tag, ifdId);
- if (tagInfo != 0) return tagInfo->desc_;
- }
- return "";
- } // ExifTags::tagDesc
-
- const char* ExifTags::sectionName(uint16_t tag, IfdId ifdId)
- {
- if (isExifIfd(ifdId)) {
- int idx = tagInfoIdx(tag, ifdId);
- if (idx == -1) return sectionInfo_[unknownTag.sectionId_].name_;
- const TagInfo* tagInfo = tagInfos_[ifdId];
- return sectionInfo_[tagInfo[idx].sectionId_].name_;
- }
- if (isMakerIfd(ifdId)) {
- const TagInfo* tagInfo = makerTagInfo(tag, ifdId);
- if (tagInfo != 0) return sectionInfo_[tagInfo->sectionId_].name_;
- }
- return "";
- } // ExifTags::sectionName
-
- const char* ExifTags::sectionDesc(uint16_t tag, IfdId ifdId)
- {
- if (isExifIfd(ifdId)) {
- int idx = tagInfoIdx(tag, ifdId);
- if (idx == -1) return sectionInfo_[unknownTag.sectionId_].desc_;
- const TagInfo* tagInfo = tagInfos_[ifdId];
- return sectionInfo_[tagInfo[idx].sectionId_].desc_;
- }
- if (isMakerIfd(ifdId)) {
- const TagInfo* tagInfo = makerTagInfo(tag, ifdId);
- if (tagInfo != 0) return sectionInfo_[tagInfo->sectionId_].desc_;
- }
- return "";
- } // ExifTags::sectionDesc
-
- uint16_t ExifTags::tag(const std::string& tagName, IfdId ifdId)
- {
- uint16_t tag = 0xffff;
- if (isExifIfd(ifdId)) {
- const TagInfo* tagInfo = tagInfos_[ifdId];
- if (tagInfo) {
- int idx;
- for (idx = 0; tagInfo[idx].tag_ != 0xffff; ++idx) {
- if (tagInfo[idx].name_ == tagName) break;
- }
- tag = tagInfo[idx].tag_;
- }
- }
- if (isMakerIfd(ifdId)) {
- const TagInfo* tagInfo = makerTagInfo(tagName, ifdId);
- if (tagInfo != 0) tag = tagInfo->tag_;
- }
- if (tag == 0xffff) {
- if (!isHex(tagName, 4, "0x")) throw Error(7, tagName, ifdId);
- std::istringstream is(tagName);
- is >> std::hex >> tag;
- }
- return tag;
- } // ExifTags::tag
-
- IfdId ExifTags::ifdIdByIfdItem(const std::string& ifdItem)
- {
- int i;
- for (i = int(lastIfdId) - 1; i > 0; --i) {
- if (ifdInfo_[i].item_ == ifdItem) break;
- }
- return IfdId(i);
- }
-
- const char* ExifTags::ifdName(IfdId ifdId)
- {
- return ifdInfo_[ifdId].name_;
- }
-
- const char* ExifTags::ifdItem(IfdId ifdId)
- {
- return ifdInfo_[ifdId].item_;
- }
-
- const char* ExifTags::sectionName(SectionId sectionId)
- {
- return sectionInfo_[sectionId].name_;
- }
-
- SectionId ExifTags::sectionId(const std::string& sectionName)
- {
- int i;
- for (i = int(lastSectionId) - 1; i > 0; --i) {
- if (sectionInfo_[i].name_ == sectionName) break;
- }
- return SectionId(i);
- }
-
- TypeId ExifTags::tagType(uint16_t tag, IfdId ifdId)
- {
- if (isExifIfd(ifdId)) {
- int idx = tagInfoIdx(tag, ifdId);
- if (idx != -1) return tagInfos_[ifdId][idx].typeId_;
- }
- if (isMakerIfd(ifdId)) {
- const TagInfo* tagInfo = makerTagInfo(tag, ifdId);
- if (tagInfo != 0) return tagInfo->typeId_;
- }
- return unknownTag.typeId_;
- }
-
- std::ostream& ExifTags::printTag(std::ostream& os,
- uint16_t tag,
- IfdId ifdId,
- const Value& value)
- {
- if (value.count() == 0) return os;
- PrintFct fct = printValue;
- if (isExifIfd(ifdId)) {
- int idx = tagInfoIdx(tag, ifdId);
- if (idx != -1) {
- fct = tagInfos_[ifdId][idx].printFct_;
- }
- }
- if (isMakerIfd(ifdId)) {
- const TagInfo* tagInfo = makerTagInfo(tag, ifdId);
- if (tagInfo != 0) fct = tagInfo->printFct_;
- }
- return fct(os, value);
- } // ExifTags::printTag
-
- void ExifTags::taglist(std::ostream& os)
- {
- for (int i=0; ifdTagInfo[i].tag_ != 0xffff; ++i) {
- os << ifdTagInfo[i] << "\n";
- }
- for (int i=0; exifTagInfo[i].tag_ != 0xffff; ++i) {
- os << exifTagInfo[i] << "\n";
- }
- for (int i=0; iopTagInfo[i].tag_ != 0xffff; ++i) {
- os << iopTagInfo[i] << "\n";
- }
- for (int i=0; gpsTagInfo[i].tag_ != 0xffff; ++i) {
- os << gpsTagInfo[i] << "\n";
- }
- } // ExifTags::taglist
-
- void ExifTags::makerTaglist(std::ostream& os, IfdId ifdId)
- {
- int i = 0;
- for (; i < MAX_MAKER_TAG_INFOS && makerIfdIds_[i] != ifdId; ++i);
- if (i != MAX_MAKER_TAG_INFOS) {
- const TagInfo* mnTagInfo = makerTagInfos_[i];
- for (int k=0; mnTagInfo[k].tag_ != 0xffff; ++k) {
- os << mnTagInfo[k] << "\n";
- }
- }
- } // ExifTags::makerTaglist
-
- const char* ExifKey::familyName_ = "Exif";
-
- ExifKey::ExifKey(const std::string& key)
- : tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""),
- idx_(0), key_(key)
- {
- decomposeKey();
- }
-
- ExifKey::ExifKey(uint16_t tag, const std::string& ifdItem)
- : tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""),
- idx_(0), key_("")
- {
- IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem);
- if (ExifTags::isMakerIfd(ifdId)) {
- MakerNote::AutoPtr makerNote = MakerNoteFactory::create(ifdId);
- if (makerNote.get() == 0) throw Error(23, ifdId);
- }
- tag_ = tag;
- ifdId_ = ifdId;
- ifdItem_ = ifdItem;
- makeKey();
- }
-
- ExifKey::ExifKey(const Entry& e)
- : tag_(e.tag()), ifdId_(e.ifdId()),
- ifdItem_(ExifTags::ifdItem(e.ifdId())),
- idx_(e.idx()), key_("")
- {
- makeKey();
- }
-
- ExifKey::ExifKey(const ExifKey& rhs)
- : tag_(rhs.tag_), ifdId_(rhs.ifdId_), ifdItem_(rhs.ifdItem_),
- idx_(rhs.idx_), key_(rhs.key_)
- {
- }
-
- ExifKey::~ExifKey()
- {
- }
-
- ExifKey& ExifKey::operator=(const ExifKey& rhs)
- {
- if (this == &rhs) return *this;
- Key::operator=(rhs);
- tag_ = rhs.tag_;
- ifdId_ = rhs.ifdId_;
- ifdItem_ = rhs.ifdItem_;
- idx_ = rhs.idx_;
- key_ = rhs.key_;
- return *this;
- }
-
- std::string ExifKey::tagName() const
- {
- return ExifTags::tagName(tag_, ifdId_);
- }
-
- ExifKey::AutoPtr ExifKey::clone() const
- {
- return AutoPtr(clone_());
- }
-
- ExifKey* ExifKey::clone_() const
- {
- return new ExifKey(*this);
- }
-
- std::string ExifKey::sectionName() const
- {
- return ExifTags::sectionName(tag(), ifdId());
- }
-
- void ExifKey::decomposeKey()
- {
- // Get the family name, IFD name and tag name parts of the key
- std::string::size_type pos1 = key_.find('.');
- if (pos1 == std::string::npos) throw Error(6, key_);
- std::string familyName = key_.substr(0, pos1);
- if (familyName != std::string(familyName_)) {
- throw Error(6, key_);
- }
- std::string::size_type pos0 = pos1 + 1;
- pos1 = key_.find('.', pos0);
- if (pos1 == std::string::npos) throw Error(6, key_);
- std::string ifdItem = key_.substr(pos0, pos1 - pos0);
- if (ifdItem == "") throw Error(6, key_);
- std::string tagName = key_.substr(pos1 + 1);
- if (tagName == "") throw Error(6, key_);
-
- // Find IfdId
- IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem);
- if (ifdId == ifdIdNotSet) throw Error(6, key_);
- if (ExifTags::isMakerIfd(ifdId)) {
- MakerNote::AutoPtr makerNote = MakerNoteFactory::create(ifdId);
- if (makerNote.get() == 0) throw Error(6, key_);
- }
- // Convert tag
- uint16_t tag = ExifTags::tag(tagName, ifdId);
-
- // Translate hex tag name (0xabcd) to a real tag name if there is one
- tagName = ExifTags::tagName(tag, ifdId);
-
- tag_ = tag;
- ifdId_ = ifdId;
- ifdItem_ = ifdItem;
- key_ = familyName + "." + ifdItem + "." + tagName;
- }
-
- void ExifKey::makeKey()
- {
- key_ = std::string(familyName_)
- + "." + ifdItem_
- + "." + ExifTags::tagName(tag_, ifdId_);
- }
-
- // *************************************************************************
- // free functions
-
- bool isExifIfd(IfdId ifdId)
- {
- bool rc;
- switch (ifdId) {
- case ifd0Id: rc = true; break;
- case exifIfdId: rc = true; break;
- case gpsIfdId: rc = true; break;
- case iopIfdId: rc = true; break;
- case ifd1Id: rc = true; break;
- default: rc = false; break;
- }
- return rc;
- } // isExifIfd
-
- std::ostream& operator<<(std::ostream& os, const TagInfo& ti)
- {
- ExifKey exifKey(ti.tag_, ExifTags::ifdItem(ti.ifdId_));
- return os << ExifTags::tagName(ti.tag_, ti.ifdId_) << ", "
- << std::dec << ti.tag_ << ", "
- << "0x" << std::setw(4) << std::setfill('0')
- << std::right << std::hex << ti.tag_ << ", "
- << ExifTags::ifdName(ti.ifdId_) << ", "
- << exifKey.key() << ", "
- << TypeInfo::typeName(
- ExifTags::tagType(ti.tag_, ti.ifdId_)) << ", "
- << ExifTags::tagDesc(ti.tag_, ti.ifdId_);
- }
-
- std::ostream& operator<<(std::ostream& os, const Rational& r)
- {
- return os << r.first << "/" << r.second;
- }
-
- std::istream& operator>>(std::istream& is, Rational& r)
- {
- int32_t nominator;
- int32_t denominator;
- char c;
- is >> nominator >> c >> denominator;
- if (is && c == '/') r = std::make_pair(nominator, denominator);
- return is;
- }
-
- std::ostream& operator<<(std::ostream& os, const URational& r)
- {
- return os << r.first << "/" << r.second;
- }
-
- std::istream& operator>>(std::istream& is, URational& r)
- {
- uint32_t nominator;
- uint32_t denominator;
- char c;
- is >> nominator >> c >> denominator;
- if (is && c == '/') r = std::make_pair(nominator, denominator);
- return is;
- }
-
- std::ostream& printValue(std::ostream& os, const Value& value)
- {
- return os << value;
- }
-
- std::ostream& printLong(std::ostream& os, const Value& value)
- {
- Rational r = value.toRational();
- if (r.second != 0) return os << static_cast<long>(r.first) / r.second;
- return os << "(" << value << ")";
- } // printLong
-
- std::ostream& printFloat(std::ostream& os, const Value& value)
- {
- Rational r = value.toRational();
- if (r.second != 0) return os << static_cast<float>(r.first) / r.second;
- return os << "(" << value << ")";
- } // printFloat
-
- std::ostream& printUnit(std::ostream& os, const Value& value)
- {
- long unit = value.toLong();
- switch (unit) {
- case 2: os << "inch"; break;
- case 3: os << "cm"; break;
- default: os << "(" << unit << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0x0103(std::ostream& os, const Value& value)
- {
- long compression = value.toLong();
- switch (compression) {
- case 1: os << "TIFF"; break;
- case 6: os << "JPEG"; break;
- default: os << "(" << compression << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0x0106(std::ostream& os, const Value& value)
- {
- long photo = value.toLong();
- switch (photo) {
- case 2: os << "RGB"; break;
- case 6: os << "YCbCr"; break;
- default: os << "(" << photo << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0x0112(std::ostream& os, const Value& value)
- {
- long orientation = value.toLong();
- switch (orientation) {
- case 1: os << "top, left"; break;
- case 2: os << "top, right"; break;
- case 3: os << "bottom, right"; break;
- case 4: os << "bottom, left"; break;
- case 5: os << "left, top"; break;
- case 6: os << "right, top"; break;
- case 7: os << "right, bottom"; break;
- case 8: os << "left, bottom"; break;
- default: os << "(" << orientation << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0x0213(std::ostream& os, const Value& value)
- {
- long position = value.toLong();
- switch (position) {
- case 1: os << "Centered"; break;
- case 2: os << "Co-sited"; break;
- default: os << "(" << position << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0x8298(std::ostream& os, const Value& value)
- {
- // Print the copyright information in the format Photographer, Editor
- std::string val = value.toString();
- std::string::size_type pos = val.find('\0');
- if (pos != std::string::npos) {
- std::string photographer(val, 0, pos);
- if (photographer != " ") os << photographer;
- std::string editor(val, pos + 1);
- if (editor != "") {
- if (photographer != " ") os << ", ";
- os << editor;
- }
- }
- else {
- os << val;
- }
- return os;
- }
-
- std::ostream& print0x829a(std::ostream& os, const Value& value)
- {
- Rational t = value.toRational();
- if (t.first > 1 && t.second > 1 && t.second >= t.first) {
- t.second = static_cast<uint32_t>(
- static_cast<float>(t.second) / t.first + 0.5);
- t.first = 1;
- }
- if (t.second > 1 && t.second < t.first) {
- t.first = static_cast<uint32_t>(
- static_cast<float>(t.first) / t.second + 0.5);
- t.second = 1;
- }
- if (t.second == 1) {
- os << t.first << " s";
- }
- else {
- os << t.first << "/" << t.second << " s";
- }
- return os;
- }
-
- std::ostream& print0x829d(std::ostream& os, const Value& value)
- {
- Rational fnumber = value.toRational();
- if (fnumber.second != 0) {
- os << "F" << (float)fnumber.first / fnumber.second;
- }
- else {
- os << "(" << value << ")";
- }
- return os;
- }
-
- std::ostream& print0x8822(std::ostream& os, const Value& value)
- {
- long program = value.toLong();
- switch (program) {
- case 0: os << "Not defined"; break;
- case 1: os << "Manual"; break;
- case 2: os << "Auto"; break;
- case 3: os << "Aperture priority"; break;
- case 4: os << "Shutter priority"; break;
- case 5: os << "Creative program"; break;
- case 6: os << "Action program"; break;
- case 7: os << "Portrait mode"; break;
- case 8: os << "Landscape mode"; break;
- default: os << "(" << program << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0x8827(std::ostream& os, const Value& value)
- {
- return os << value.toLong();
- }
-
- std::ostream& print0x9101(std::ostream& os, const Value& value)
- {
- for (long i = 0; i < value.count(); ++i) {
- long l = value.toLong(i);
- switch (l) {
- case 0: break;
- case 1: os << "Y"; break;
- case 2: os << "Cb"; break;
- case 3: os << "Cr"; break;
- case 4: os << "R"; break;
- case 5: os << "G"; break;
- case 6: os << "B"; break;
- default: os << "(" << l << ")"; break;
- }
- }
- return os;
- }
-
- std::ostream& print0x9204(std::ostream& os, const Value& value)
- {
- Rational bias = value.toRational();
- if (bias.second <= 0) {
- os << "(" << bias.first << "/" << bias.second << ")";
- }
- else if (bias.first == 0) {
- os << "0";
- }
- else {
- long d = lgcd(labs(bias.first), bias.second);
- long num = labs(bias.first) / d;
- long den = bias.second / d;
- os << (bias.first < 0 ? "-" : "+") << num;
- if (den != 1) {
- os << "/" << den;
- }
- }
- return os;
- }
-
- std::ostream& print0x9206(std::ostream& os, const Value& value)
- {
- Rational distance = value.toRational();
- if (distance.first == 0) {
- os << "Unknown";
- }
- else if (static_cast<uint32_t>(distance.first) == 0xffffffff) {
- os << "Infinity";
- }
- else if (distance.second != 0) {
- std::ostringstream oss;
- oss.copyfmt(os);
- os << std::fixed << std::setprecision(2)
- << (float)distance.first / distance.second
- << " m";
- os.copyfmt(oss);
- }
- else {
- os << "(" << value << ")";
- }
- return os;
- }
-
- std::ostream& print0x9207(std::ostream& os, const Value& value)
- {
- long mode = value.toLong();
- switch (mode) {
- case 0: os << "Unknown"; break;
- case 1: os << "Average"; break;
- case 2: os << "Center weighted"; break;
- case 3: os << "Spot"; break;
- case 4: os << "Multispot"; break;
- case 5: os << "Matrix"; break;
- case 6: os << "Partial"; break;
- default: os << "(" << mode << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0x9208(std::ostream& os, const Value& value)
- {
- long source = value.toLong();
- switch (source) {
- case 0: os << "Unknown"; break;
- case 1: os << "Daylight"; break;
- case 2: os << "Fluorescent"; break;
- case 3: os << "Tungsten (incandescent light)"; break;
- case 4: os << "Flash"; break;
- case 9: os << "Fine weather"; break;
- case 10: os << "Cloudy weather"; break;
- case 11: os << "Shade"; break;
- case 12: os << "Daylight fluorescent (D 5700 - 7100K)"; break;
- case 13: os << "Day white fluorescent (N 4600 - 5400K)"; break;
- case 14: os << "Cool white fluorescent (W 3900 - 4500K)"; break;
- case 15: os << "White fluorescent (WW 3200 - 3700K)"; break;
- case 17: os << "Standard light A"; break;
- case 18: os << "Standard light B"; break;
- case 19: os << "Standard light C"; break;
- case 20: os << "D55"; break;
- case 21: os << "D65"; break;
- case 22: os << "D75"; break;
- case 23: os << "D50"; break;
- case 24: os << "ISO studio tungsten"; break;
- case 255: os << "other light source"; break;
- default: os << "(" << source << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0x9209(std::ostream& os, const Value& value)
- {
- long flash = value.toLong();
- switch (flash) {
- case 0x00: os << "No"; break;
- case 0x01: os << "Yes"; break;
- case 0x05: os << "Strobe return light not detected"; break;
- case 0x07: os << "Strobe return light detected"; break;
- case 0x09: os << "Yes, compulsory"; break;
- case 0x0d: os << "Yes, compulsory, return light not detected"; break;
- case 0x0f: os << "Yes, compulsory, return light detected"; break;
- case 0x10: os << "No, compulsory"; break;
- case 0x18: os << "No, auto"; break;
- case 0x19: os << "Yes, auto"; break;
- case 0x1d: os << "Yes, auto, return light not detected"; break;
- case 0x1f: os << "Yes, auto, return light detected"; break;
- case 0x20: os << "No flash function"; break;
- case 0x41: os << "Yes, red-eye reduction"; break;
- case 0x45: os << "Yes, red-eye reduction, return light not detected"; break;
- case 0x47: os << "Yes, red-eye reduction, return light detected"; break;
- case 0x49: os << "Yes, compulsory, red-eye reduction"; break;
- case 0x4d: os << "Yes, compulsory, red-eye reduction, return light not detected"; break;
- case 0x4f: os << "Yes, compulsory, red-eye reduction, return light detected"; break;
- case 0x59: os << "Yes, auto, red-eye reduction"; break;
- case 0x5d: os << "Yes, auto, red-eye reduction, return light not detected"; break;
- case 0x5f: os << "Yes, auto, red-eye reduction, return light detected"; break;
- default: os << "(" << flash << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0x920a(std::ostream& os, const Value& value)
- {
- Rational length = value.toRational();
- if (length.second != 0) {
- std::ostringstream oss;
- oss.copyfmt(os);
- os << std::fixed << std::setprecision(1)
- << (float)length.first / length.second
- << " mm";
- os.copyfmt(oss);
- }
- else {
- os << "(" << value << ")";
- }
- return os;
- }
-
- // Todo: Implement this properly
- std::ostream& print0x9286(std::ostream& os, const Value& value)
- {
- if (value.size() > 8) {
- DataBuf buf(value.size());
- value.copy(buf.pData_, bigEndian);
- // Hack: Skip the leading 8-Byte character code, truncate
- // trailing '\0's and let the stream take care of the remainder
- std::string userComment(reinterpret_cast<char*>(buf.pData_) + 8, buf.size_ - 8);
- std::string::size_type pos = userComment.find_last_not_of('\0');
- os << userComment.substr(0, pos + 1);
- }
- return os;
- }
-
- std::ostream& print0xa001(std::ostream& os, const Value& value)
- {
- long space = value.toLong();
- switch (space) {
- case 1: os << "sRGB"; break;
- case 0xffff: os << "Uncalibrated"; break;
- default: os << "(" << space << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0xa217(std::ostream& os, const Value& value)
- {
- long method = value.toLong();
- switch (method) {
- case 1: os << "Not defined"; break;
- case 2: os << "One-chip color area"; break;
- case 3: os << "Two-chip color area"; break;
- case 4: os << "Three-chip color area"; break;
- case 5: os << "Color sequential area"; break;
- case 7: os << "Trilinear sensor"; break;
- case 8: os << "Color sequential linear"; break;
- default: os << "(" << method << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0xa300(std::ostream& os, const Value& value)
- {
- long source = value.toLong();
- switch (source) {
- case 3: os << "Digital still camera"; break;
- default: os << "(" << source << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0xa301(std::ostream& os, const Value& value)
- {
- long scene = value.toLong();
- switch (scene) {
- case 1: os << "Directly photographed"; break;
- default: os << "(" << scene << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0xa402(std::ostream& os, const Value& value)
- {
- long mode = value.toLong();
- switch (mode) {
- case 0: os << "Auto"; break;
- case 1: os << "Manual"; break;
- case 2: os << "Auto bracket"; break;
- default: os << "(" << mode << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0xa403(std::ostream& os, const Value& value)
- {
- long wb = value.toLong();
- switch (wb) {
- case 0: os << "Auto"; break;
- case 1: os << "Manual"; break;
- default: os << "(" << wb << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0xa404(std::ostream& os, const Value& value)
- {
- Rational zoom = value.toRational();
- if (zoom.second == 0) {
- os << "Digital zoom not used";
- }
- else {
- std::ostringstream oss;
- oss.copyfmt(os);
- os << std::fixed << std::setprecision(1)
- << (float)zoom.first / zoom.second;
- os.copyfmt(oss);
- }
- return os;
- }
-
- std::ostream& print0xa405(std::ostream& os, const Value& value)
- {
- long length = value.toLong();
- if (length == 0) {
- os << "Unknown";
- }
- else {
- os << length << ".0 mm";
- }
- return os;
- }
-
- std::ostream& print0xa406(std::ostream& os, const Value& value)
- {
- long scene = value.toLong();
- switch (scene) {
- case 0: os << "Standard"; break;
- case 1: os << "Landscape"; break;
- case 2: os << "Portrait"; break;
- case 3: os << "Night scene"; break;
- default: os << "(" << scene << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0xa407(std::ostream& os, const Value& value)
- {
- long gain = value.toLong();
- switch (gain) {
- case 0: os << "None"; break;
- case 1: os << "Low gain up"; break;
- case 2: os << "High gain up"; break;
- case 3: os << "Low gain down"; break;
- case 4: os << "High gain down"; break;
- default: os << "(" << gain << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0xa408(std::ostream& os, const Value& value)
- {
- long contrast = value.toLong();
- switch (contrast) {
- case 0: os << "Normal"; break;
- case 1: os << "Soft"; break;
- case 2: os << "Hard"; break;
- default: os << "(" << contrast << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0xa409(std::ostream& os, const Value& value)
- {
- long saturation = value.toLong();
- switch (saturation) {
- case 0: os << "Normal"; break;
- case 1: os << "Low"; break;
- case 2: os << "High"; break;
- default: os << "(" << saturation << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0xa40a(std::ostream& os, const Value& value)
- {
- long sharpness = value.toLong();
- switch (sharpness) {
- case 0: os << "Normal"; break;
- case 1: os << "Soft"; break;
- case 2: os << "Hard"; break;
- default: os << "(" << sharpness << ")"; break;
- }
- return os;
- }
-
- std::ostream& print0xa40c(std::ostream& os, const Value& value)
- {
- long distance = value.toLong();
- switch (distance) {
- case 0: os << "Unknown"; break;
- case 1: os << "Macro"; break;
- case 2: os << "Close view"; break;
- case 3: os << "Distant view"; break;
- default: os << "(" << distance << ")"; break;
- }
- return os;
- }
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/tags.hpp b/src/plugins/exiv2/tags.hpp
@@ -1,444 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file tags.hpp
- @brief Exif tag and type information
- @version $Rev: 580 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 15-Jan-04, ahu: created<BR>
- 11-Feb-04, ahu: isolated as a component
- */
-#ifndef TAGS_HPP_
-#define TAGS_HPP_
-
-// *****************************************************************************
-// included header files
-#include "metadatum.hpp"
-#include "types.hpp"
-
-// + standard includes
-#include <string>
-#include <utility> // for std::pair
-#include <iosfwd>
-#include <memory>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class declarations
- class Value;
- class Entry;
-
-// *****************************************************************************
-// type definitions
-
- //! Type for a function pointer for functions interpreting the tag value
- typedef std::ostream& (*PrintFct)(std::ostream&, const Value&);
-
- /*!
- @brief Section identifiers to logically group tags. A section consists
- of nothing more than a name, based on the Exif standard.
- */
- enum SectionId { sectionIdNotSet,
- imgStruct, recOffset, imgCharacter, otherTags, exifFormat,
- exifVersion, imgConfig, userInfo, relatedFile, dateTime,
- captureCond, gpsTags, iopTags, makerTags,
- lastSectionId };
-
-// *****************************************************************************
-// class definitions
-
- //! Contains information pertaining to one IFD
- struct IfdInfo {
- //! Constructor
- IfdInfo(IfdId ifdId, const char* name, const char* item);
- IfdId ifdId_; //!< IFD id
- const char* name_; //!< IFD name
- //! Related IFD item. This is also an IFD name, unique for each IFD.
- const char* item_;
- };
-
- //! Contains information pertaining to one section
- struct SectionInfo {
- //! Constructor
- SectionInfo(SectionId sectionId, const char* name, const char* desc);
- SectionId sectionId_; //!< Section id
- const char* name_; //!< Section name (one word)
- const char* desc_; //!< Section description
- };
-
- //! Tag information
- struct TagInfo {
- //! Constructor
- TagInfo(
- uint16_t tag,
- const char* name,
- const char* desc,
- IfdId ifdId,
- SectionId sectionId,
- TypeId typeId,
- PrintFct printFct
- );
- uint16_t tag_; //!< Tag
- const char* name_; //!< One word tag label
- const char* desc_; //!< Short tag description
- IfdId ifdId_; //!< Link to the (prefered) IFD
- SectionId sectionId_; //!< Section id
- TypeId typeId_; //!< Type id
- PrintFct printFct_; //!< Pointer to tag print function
- }; // struct TagInfo
-
- /*!
- @brief Helper structure for lookup tables for translations of numeric
- tag values to human readable labels.
- */
- struct TagDetails {
- long val_; //!< Tag value
- const char* label_; //!< Translation of the tag value
- }; // struct TagDetails
-
- /*!
- @brief Translation from numeric values from a lookup list to human
- readable labels
- */
- class TagTranslator {
- public:
- //! @name Creators
- //@{
- //! Default constructor.
- explicit TagTranslator(const TagDetails* pTagDetails)
- : pTagDetails_(pTagDetails) {}
- // No d'tor: Do not delete the list.
- //@}
-
- //! @name Accessors
- //@{
- //! Translate the tag value and write it out to the provided stream
- std::ostream& print(std::ostream& os, const Value& value) const;
- //@}
- private:
- const TagDetails* pTagDetails_;
- }; // class TagTranslator
-
- //! Container for Exif tag information. Implemented as a static class.
- class ExifTags {
- //! Prevent construction: not implemented.
- ExifTags() {}
- //! Prevent copy-construction: not implemented.
- ExifTags(const ExifTags& rhs);
- //! Prevent assignment: not implemented.
- ExifTags& operator=(const ExifTags& rhs);
-
- public:
- /*!
- @brief Return the name of the tag or a string with the hexadecimal
- value of the tag in the form "0x01ff", if the tag is not
- a known Exif tag.
-
- @param tag The tag
- @param ifdId IFD id
- @return The name of the tag or a string containing the hexadecimal
- value of the tag in the form "0x01ff", if this is an unknown
- tag.
- */
- static std::string tagName(uint16_t tag, IfdId ifdId);
- /*!
- @brief Return the description of the tag.
- @param tag The tag
- @param ifdId IFD id
- @return The description of the tag or a string indicating that
- the tag is unknown.
- */
- static const char* tagDesc(uint16_t tag, IfdId ifdId);
- /*!
- @brief Return the tag for one combination of IFD id and tagName.
- If the tagName is not known, it expects tag names in the
- form "0x01ff" and converts them to unsigned integer.
-
- @throw Error if the tagname or ifdId is invalid
- */
- static uint16_t tag(const std::string& tagName, IfdId ifdId);
- //! Return the IFD id for an IFD item
- static IfdId ifdIdByIfdItem(const std::string& ifdItem);
- //! Return the name of the IFD
- static const char* ifdName(IfdId ifdId);
- //! Return the related image item (image or thumbnail)
- static const char* ifdItem(IfdId ifdId);
- //! Return the name of the section
- static const char* sectionName(SectionId sectionId);
- /*!
- @brief Return the name of the section for a combination of
- tag and IFD id.
- @param tag The tag
- @param ifdId IFD id
- @return The name of the section or a string indicating that the
- section or the tag is unknown.
- */
- static const char* sectionName(uint16_t tag, IfdId ifdId);
- /*!
- @brief Return the description of the section for a combination of
- tag and IFD id.
- @param tag The tag
- @param ifdId IFD id
- @return The description of the section or a string indicating that
- the section or the tag is unknown.
- */
- static const char* sectionDesc(uint16_t tag, IfdId ifdId);
- //! Return the section id for a section name
- static SectionId sectionId(const std::string& sectionName);
- //! Return the type for tag and IFD id
- static TypeId tagType(uint16_t tag, IfdId ifdId);
- //! Interpret and print the value of an Exif tag
- static std::ostream& printTag(std::ostream& os,
- uint16_t tag,
- IfdId ifdId,
- const Value& value);
- //! Print a list of all standard Exif tags to output stream
- static void taglist(std::ostream& os);
- //! Print a list of all tags related to one makernote %IfdId
- static void makerTaglist(std::ostream& os, IfdId ifdId);
- //! Register an %IfdId with the base IFD %TagInfo list for a makernote
- static void registerBaseTagInfo(IfdId ifdId);
- /*!
- @brief Register an %IfdId and %TagInfo list for a makernote
-
- @throw Error if the MakerTagInfo registry is full
- */
- static void registerMakerTagInfo(IfdId ifdId, const TagInfo* tagInfo);
- /*!
- @brief Return true if \em ifdId is an %Ifd Id which is registered
- as a makernote %Ifd id. Note: Calling this function with
- makerIfd returns false.
- */
- static bool isMakerIfd(IfdId ifdId);
-
- private:
- static int tagInfoIdx(uint16_t tag, IfdId ifdId);
- static const TagInfo* makerTagInfo(uint16_t tag, IfdId ifdId);
- static const TagInfo* makerTagInfo(const std::string& tagName,
- IfdId ifdId);
-
- static const IfdInfo ifdInfo_[];
- static const SectionInfo sectionInfo_[];
-
- static const TagInfo* tagInfos_[];
-
- static const int MAX_MAKER_TAG_INFOS = 64;
- static const TagInfo* makerTagInfos_[MAX_MAKER_TAG_INFOS];
- static IfdId makerIfdIds_[MAX_MAKER_TAG_INFOS];
-
- }; // class ExifTags
-
- /*!
- @brief Concrete keys for Exif metadata.
- */
- class ExifKey : public Key {
- public:
- //! Shortcut for an %ExifKey auto pointer.
- typedef std::auto_ptr<ExifKey> AutoPtr;
-
- //! @name Creators
- //@{
- /*!
- @brief Constructor to create an Exif key from a key string.
-
- @param key The key string.
- @throw Error if the first part of the key is not '<b>Exif</b>' or
- the remainin parts of the key cannot be parsed and
- converted to an ifd-item and tag name.
- */
- explicit ExifKey(const std::string& key);
- /*!
- @brief Constructor to create an Exif key from a tag and IFD item
- string.
- @param tag The tag value
- @param ifdItem The IFD string. For MakerNote tags, this must be the
- IFD item of the specific MakerNote. "MakerNote" is not allowed.
- @throw Error if the key cannot be constructed from the tag and IFD
- item parameters.
- */
- ExifKey(uint16_t tag, const std::string& ifdItem);
- //! Constructor to build an ExifKey from an IFD entry.
- explicit ExifKey(const Entry& e);
- //! Copy constructor
- ExifKey(const ExifKey& rhs);
- virtual ~ExifKey();
- //@}
-
- //! @name Manipulators
- //@{
- /*!
- @brief Assignment operator.
- */
- ExifKey& operator=(const ExifKey& rhs);
- //@}
-
- //! @name Accessors
- //@{
- virtual std::string key() const { return key_; }
- virtual const char* familyName() const { return familyName_; }
- /*!
- @brief Return the name of the group (the second part of the key).
- For Exif keys, the group name is the IFD item.
- */
- virtual std::string groupName() const { return ifdItem(); }
- virtual std::string tagName() const;
- virtual uint16_t tag() const { return tag_; }
-
- AutoPtr clone() const;
- //! Return the IFD id
- IfdId ifdId() const { return ifdId_; }
- //! Return the name of the IFD
- const char* ifdName() const { return ExifTags::ifdName(ifdId()); }
- //! Return the related image item
- std::string ifdItem() const { return ifdItem_; }
- //! Return the name of the Exif section (deprecated)
- std::string sectionName() const;
- //! Return the index (unique id of this key within the original IFD)
- int idx() const { return idx_; }
- //@}
-
- protected:
- //! @name Manipulators
- //@{
- /*!
- @brief Set the key corresponding to the tag and IFD id.
- The key is of the form '<b>Exif</b>.ifdItem.tagName'.
- */
- void makeKey();
- /*!
- @brief Parse and convert the key string into tag and IFD Id.
- Updates data members if the string can be decomposed,
- or throws \em Error .
-
- @throw Error if the key cannot be decomposed.
- */
- void decomposeKey();
- //@}
-
- private:
- //! Internal virtual copy constructor.
- virtual ExifKey* clone_() const;
-
- // DATA
- static const char* familyName_;
-
- uint16_t tag_; //!< Tag value
- IfdId ifdId_; //!< The IFD associated with this tag
- std::string ifdItem_; //!< The IFD item
- int idx_; //!< Unique id of an entry within one IFD
- std::string key_; //!< Key
- }; // class ExifKey
-
-// *****************************************************************************
-// free functions
-
- /*!
- @brief Return true if \em ifdId is an Exif %Ifd Id, i.e., one of
- ifd0Id, exifIfdId, gpsIfdId, iopIfdId or ifd1Id, else false.
- This is used to differentiate between standard Exif %Ifds
- and %Ifds associated with the makernote.
- */
- bool isExifIfd(IfdId ifdId);
-
- //! Output operator for TagInfo
- std::ostream& operator<<(std::ostream& os, const TagInfo& ti);
-
- //! @name Functions printing interpreted tag values
- //@{
- //! Default print function, using the Value output operator
- std::ostream& printValue(std::ostream& os, const Value& value);
- //! Print the value converted to a long
- std::ostream& printLong(std::ostream& os, const Value& value);
- //! Print a Rational or URational value in floating point format
- std::ostream& printFloat(std::ostream& os, const Value& value);
- //! Print the unit for measuring X and Y resolution
- std::ostream& printUnit(std::ostream& os, const Value& value);
-
- //! Print the compression scheme used for the image data
- std::ostream& print0x0103(std::ostream& os, const Value& value);
- //! Print the pixel composition
- std::ostream& print0x0106(std::ostream& os, const Value& value);
- //! Print the orientation
- std::ostream& print0x0112(std::ostream& os, const Value& value);
- //! Print the YCbCrPositioning
- std::ostream& print0x0213(std::ostream& os, const Value& value);
- //! Print the Copyright
- std::ostream& print0x8298(std::ostream& os, const Value& value);
- //! Print the Exposure time
- std::ostream& print0x829a(std::ostream& os, const Value& value);
- //! Print the F number
- std::ostream& print0x829d(std::ostream& os, const Value& value);
- //! Print the Exposure mode
- std::ostream& print0x8822(std::ostream& os, const Value& value);
- //! Print ISO speed ratings
- std::ostream& print0x8827(std::ostream& os, const Value& value);
- //! Print components configuration specific to compressed data
- std::ostream& print0x9101(std::ostream& os, const Value& value);
- //! Print the exposure bias value
- std::ostream& print0x9204(std::ostream& os, const Value& value);
- //! Print the subject distance
- std::ostream& print0x9206(std::ostream& os, const Value& value);
- //! Print the metering mode
- std::ostream& print0x9207(std::ostream& os, const Value& value);
- //! Print the light source
- std::ostream& print0x9208(std::ostream& os, const Value& value);
- //! Print the flash status
- std::ostream& print0x9209(std::ostream& os, const Value& value);
- //! Print the actual focal length of the lens
- std::ostream& print0x920a(std::ostream& os, const Value& value);
- //! Print the user comment
- std::ostream& print0x9286(std::ostream& os, const Value& value);
- //! Print color space information
- std::ostream& print0xa001(std::ostream& os, const Value& value);
- //! Print info on image sensor type on the camera or input device
- std::ostream& print0xa217(std::ostream& os, const Value& value);
- //! Print file source
- std::ostream& print0xa300(std::ostream& os, const Value& value);
- //! Print scene type
- std::ostream& print0xa301(std::ostream& os, const Value& value);
- //! Print the exposure mode
- std::ostream& print0xa402(std::ostream& os, const Value& value);
- //! Print white balance information
- std::ostream& print0xa403(std::ostream& os, const Value& value);
- //! Print digital zoom ratio
- std::ostream& print0xa404(std::ostream& os, const Value& value);
- //! Print 35mm equivalent focal length
- std::ostream& print0xa405(std::ostream& os, const Value& value);
- //! Print scene capture type
- std::ostream& print0xa406(std::ostream& os, const Value& value);
- //! Print overall image gain adjustment
- std::ostream& print0xa407(std::ostream& os, const Value& value);
- //! Print contract adjustment
- std::ostream& print0xa408(std::ostream& os, const Value& value);
- //! Print saturation adjustment
- std::ostream& print0xa409(std::ostream& os, const Value& value);
- //! Print sharpness adjustment
- std::ostream& print0xa40a(std::ostream& os, const Value& value);
- //! Print subject distance range
- std::ostream& print0xa40c(std::ostream& os, const Value& value);
- //@}
-} // namespace Exiv2
-
-#endif // #ifndef TAGS_HPP_
diff --git a/src/plugins/exiv2/types.cpp b/src/plugins/exiv2/types.cpp
@@ -1,344 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: types.cpp
- Version: $Rev: 578 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 26-Jan-04, ahu: created
- 11-Feb-04, ahu: isolated as a component
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: types.cpp 578 2005-06-07 15:01:11Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-
-// + standard includes
-#include <string>
-#include <iostream>
-#include <iomanip>
-#include <sstream>
-#include <utility>
-#include <cctype>
-#include <string.h>
-
-// *****************************************************************************
-// 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(invalid6, "Invalid(6)", 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),
- // End of list marker
- TypeInfoTable(lastTypeId, "(Unknown)", 0)
- };
-
- const char* TypeInfo::typeName(TypeId typeId)
- {
- return typeInfoTable_[ typeId < lastTypeId ? typeId : 0 ].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_;
- }
-
- long TypeInfo::typeSize(TypeId typeId)
- {
- return typeInfoTable_[ typeId < lastTypeId ? typeId : 0 ].size_;
- }
-
- DataBuf::DataBuf(DataBuf& rhs)
- : pData_(rhs.pData_), size_(rhs.size_)
- {
- rhs.release();
- }
-
- DataBuf::DataBuf(byte* pData, long size)
- : pData_(0), size_(0)
- {
- if (size > 0) {
- pData_ = new byte[size];
- memcpy(pData_, pData, size);
- size_ = size;
- }
- }
-
- DataBuf& DataBuf::operator=(DataBuf& rhs)
- {
- if (this == &rhs) return *this;
- reset(rhs.release());
- return *this;
- }
-
- void DataBuf::alloc(long size)
- {
- if (size > size_) {
- delete[] pData_;
- size_ = size;
- pData_ = new byte[size];
- }
- }
-
- std::pair<byte*, long> DataBuf::release()
- {
- std::pair<byte*, long> p = std::make_pair(pData_, size_);
- pData_ = 0;
- size_ = 0;
- return p;
- }
-
- void DataBuf::reset(std::pair<byte*, long> p)
- {
- if (pData_ != p.first) {
- delete[] pData_;
- pData_ = p.first;
- }
- size_ = p.second;
- }
-
- // *************************************************************************
- // free functions
-
- uint16_t getUShort(const byte* buf, ByteOrder byteOrder)
- {
- if (byteOrder == littleEndian) {
- return (byte)buf[1] << 8 | (byte)buf[0];
- }
- else {
- return (byte)buf[0] << 8 | (byte)buf[1];
- }
- }
-
- uint32_t getULong(const byte* buf, ByteOrder byteOrder)
- {
- if (byteOrder == littleEndian) {
- return (byte)buf[3] << 24 | (byte)buf[2] << 16
- | (byte)buf[1] << 8 | (byte)buf[0];
- }
- else {
- return (byte)buf[0] << 24 | (byte)buf[1] << 16
- | (byte)buf[2] << 8 | (byte)buf[3];
- }
- }
-
- URational getURational(const byte* buf, ByteOrder byteOrder)
- {
- uint32_t nominator = getULong(buf, byteOrder);
- uint32_t denominator = getULong(buf + 4, byteOrder);
- return std::make_pair(nominator, denominator);
- }
-
- int16_t getShort(const byte* buf, ByteOrder byteOrder)
- {
- if (byteOrder == littleEndian) {
- return (byte)buf[1] << 8 | (byte)buf[0];
- }
- else {
- return (byte)buf[0] << 8 | (byte)buf[1];
- }
- }
-
- int32_t getLong(const byte* buf, ByteOrder byteOrder)
- {
- if (byteOrder == littleEndian) {
- return (byte)buf[3] << 24 | (byte)buf[2] << 16
- | (byte)buf[1] << 8 | (byte)buf[0];
- }
- else {
- return (byte)buf[0] << 24 | (byte)buf[1] << 16
- | (byte)buf[2] << 8 | (byte)buf[3];
- }
- }
-
- Rational getRational(const byte* buf, ByteOrder byteOrder)
- {
- int32_t nominator = getLong(buf, byteOrder);
- int32_t denominator = getLong(buf + 4, byteOrder);
- return std::make_pair(nominator, denominator);
- }
-
- long us2Data(byte* buf, uint16_t s, ByteOrder byteOrder)
- {
- if (byteOrder == littleEndian) {
- buf[0] = (byte)(s & 0x00ff);
- buf[1] = (byte)((s & 0xff00) >> 8);
- }
- else {
- buf[0] = (byte)((s & 0xff00) >> 8);
- buf[1] = (byte)(s & 0x00ff);
- }
- return 2;
- }
-
- long ul2Data(byte* buf, uint32_t l, ByteOrder byteOrder)
- {
- if (byteOrder == littleEndian) {
- buf[0] = (byte)(l & 0x000000ff);
- buf[1] = (byte)((l & 0x0000ff00) >> 8);
- buf[2] = (byte)((l & 0x00ff0000) >> 16);
- buf[3] = (byte)((l & 0xff000000) >> 24);
- }
- else {
- buf[0] = (byte)((l & 0xff000000) >> 24);
- buf[1] = (byte)((l & 0x00ff0000) >> 16);
- buf[2] = (byte)((l & 0x0000ff00) >> 8);
- buf[3] = (byte)(l & 0x000000ff);
- }
- return 4;
- }
-
- long ur2Data(byte* buf, URational l, ByteOrder byteOrder)
- {
- long o = ul2Data(buf, l.first, byteOrder);
- o += ul2Data(buf+o, l.second, byteOrder);
- return o;
- }
-
- long s2Data(byte* buf, int16_t s, ByteOrder byteOrder)
- {
- if (byteOrder == littleEndian) {
- buf[0] = (byte)(s & 0x00ff);
- buf[1] = (byte)((s & 0xff00) >> 8);
- }
- else {
- buf[0] = (byte)((s & 0xff00) >> 8);
- buf[1] = (byte)(s & 0x00ff);
- }
- return 2;
- }
-
- long l2Data(byte* buf, int32_t l, ByteOrder byteOrder)
- {
- if (byteOrder == littleEndian) {
- buf[0] = (byte)(l & 0x000000ff);
- buf[1] = (byte)((l & 0x0000ff00) >> 8);
- buf[2] = (byte)((l & 0x00ff0000) >> 16);
- buf[3] = (byte)((l & 0xff000000) >> 24);
- }
- else {
- buf[0] = (byte)((l & 0xff000000) >> 24);
- buf[1] = (byte)((l & 0x00ff0000) >> 16);
- buf[2] = (byte)((l & 0x0000ff00) >> 8);
- buf[3] = (byte)(l & 0x000000ff);
- }
- return 4;
- }
-
- long r2Data(byte* buf, Rational l, ByteOrder byteOrder)
- {
- long o = l2Data(buf, l.first, byteOrder);
- o += l2Data(buf+o, l.second, byteOrder);
- return o;
- }
-
- void hexdump(std::ostream& os, const byte* buf, long len, long offset)
- {
- const std::string::size_type pos = 8 + 16 * 3 + 2;
- const std::string align(pos, ' ');
-
- long i = 0;
- while (i < len) {
- os << " "
- << std::setw(4) << std::setfill('0') << std::hex
- << i + offset << " ";
- std::ostringstream ss;
- do {
- byte c = buf[i];
- os << std::setw(2) << std::setfill('0') << std::right
- << std::hex << (int)c << " ";
- ss << ((int)c >= 31 && (int)c < 127 ? char(buf[i]) : '.');
- } while (++i < len && i%16 != 0);
- std::string::size_type width = 9 + ((i-1)%16 + 1) * 3;
- os << (width > pos ? "" : align.substr(width)) << ss.str() << "\n";
- }
- os << std::dec << std::setfill(' ');
- } // hexdump
-
- int gcd(int a, int b)
- {
- int temp;
- if (a < b) {
- temp = a;
- a = b;
- b = temp;
- }
- while ((temp = a % b) != 0) {
- a = b;
- b = temp;
- }
- return b;
- } // gcd
-
- long lgcd(long a, long b)
- {
- long temp;
- if (a < b) {
- temp = a;
- a = b;
- b = temp;
- }
- while ((temp = a % b) != 0) {
- a = b;
- b = temp;
- }
- return b;
- } // lgcd
-
- bool isHex(const std::string& str, size_t size, const std::string& prefix)
- {
- if ( str.size() <= prefix.size()
- || str.substr(0, prefix.size()) != prefix) return false;
- if ( size > 0
- && str.size() != size + prefix.size()) return false;
-
- for (size_t i = prefix.size(); i < str.size(); ++i) {
- if (!isxdigit(str[i])) return false;
- }
- return true;
- } // isHex
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/types.hpp b/src/plugins/exiv2/types.hpp
@@ -1,307 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file types.hpp
- @brief Type definitions for %Exiv2 and related functionality
- @version $Rev: 581 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 09-Jan-04, ahu: created<BR>
- 11-Feb-04, ahu: isolated as a component
- 31-Jul-04, brad: added Time, Data and String values
- */
-#ifndef TYPES_HPP_
-#define TYPES_HPP_
-
-// *****************************************************************************
-// included header files
-#if _MSC_VER
-# include "exv_msvc.h"
-#else
-# include "exv_conf.h"
-#endif
-
-// + standard includes
-#include <string>
-#include <iosfwd>
-#include <utility>
-#include <sstream>
-#include <cstdio>
-#if EXV_HAVE_STDINT_H
-# include <stdint.h>
-#endif
-
-// MSVC doesn't provide C99 types, but it has MS specific variants
-#if _MSC_VER
-typedef unsigned __int8 uint8_t;
-typedef unsigned __int16 uint16_t;
-typedef unsigned __int32 uint32_t;
-typedef __int16 int16_t;
-typedef __int32 int32_t;
-#endif
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// type definitions
-
- //! 1 byte unsigned integer type.
- typedef uint8_t byte;
-
- //! 8 byte unsigned rational type.
- typedef std::pair<uint32_t, uint32_t> URational;
- //! 8 byte signed rational type.
- typedef std::pair<int32_t, int32_t> Rational;
-
- //! Type to express the byte order (little or big endian)
- enum ByteOrder { invalidByteOrder, littleEndian, bigEndian };
-
- //! Type identifiers for IFD format types
- enum TypeId { invalidTypeId, unsignedByte, asciiString, unsignedShort,
- unsignedLong, unsignedRational, invalid6, undefined,
- signedShort, signedLong, signedRational,
- string, date, time,
- comment,
- lastTypeId };
-
- // Todo: decentralize IfdId, so that new ids can be defined elsewhere
- //! Type to specify the IFD to which a metadata belongs
- enum IfdId { ifdIdNotSet,
- ifd0Id, exifIfdId, gpsIfdId, iopIfdId, ifd1Id,
- canonIfdId, canonCs1IfdId, canonCs2IfdId, canonCfIfdId,
- fujiIfdId, nikon1IfdId, nikon2IfdId, nikon3IfdId,
- olympusIfdId, panasonicIfdId, sigmaIfdId, sonyIfdId,
- lastIfdId };
-
-// *****************************************************************************
-// class definitions
-
- //! Information pertaining to the defined types
- 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
- }; // struct TypeInfoTable
-
- //! Type information lookup functions. Implemented as a static class.
- class TypeInfo {
- //! Prevent construction: not implemented.
- TypeInfo() {}
- //! Prevent copy-construction: not implemented.
- TypeInfo(const TypeInfo& rhs);
- //! Prevent assignment: not implemented.
- TypeInfo& operator=(const TypeInfo& rhs);
-
- public:
- //! Return the name of the type
- static const char* typeName(TypeId typeId);
- //! Return the type id for a type name
- static TypeId typeId(const std::string& typeName);
- //! Return the size in bytes of one element of this type
- static long typeSize(TypeId typeId);
-
- private:
- static const TypeInfoTable typeInfoTable_[];
- };
-
- /*!
- @brief Auxiliary type to enable copies and assignments, similar to
- std::auto_ptr_ref. See http://www.josuttis.com/libbook/auto_ptr.html
- for a discussion.
- */
- struct DataBufRef {
- //! Constructor
- DataBufRef(std::pair<byte*, long> rhs) : p(rhs) {}
- //! Pointer to a byte array and its size
- std::pair<byte*, long> p;
- };
-
- /*!
- @brief Utility class containing a character array. All it does is to take
- care of memory allocation and deletion. Its primary use is meant to
- be as a stack variable in functions that need a temporary data
- buffer. Todo: this should be some sort of smart pointer,
- essentially an std::auto_ptr for a character array. But it isn't...
- */
- class DataBuf {
- public:
- //! @name Creators
- //@{
- //! Default constructor
- DataBuf() : pData_(0), size_(0) {}
- //! Constructor with an initial buffer size
- explicit DataBuf(long size) : pData_(new byte[size]), size_(size) {}
- //! Constructor, copies an existing buffer
- DataBuf(byte* pData, long size);
- /*!
- @brief Copy constructor. Transfers the buffer to the newly created
- object similar to std::auto_ptr, i.e., the original object is
- modified.
- */
- DataBuf(DataBuf& rhs);
- //! Destructor, deletes the allocated buffer
- ~DataBuf() { delete[] pData_; }
- //@}
-
- //! @name Manipulators
- //@{
- /*!
- @brief Assignment operator. Transfers the buffer and releases the
- buffer at the original object similar to std::auto_ptr, i.e.,
- the original object is modified.
- */
- DataBuf& operator=(DataBuf& rhs);
- //! Allocate a data buffer of the given size
- void alloc(long size);
- /*!
- @brief Release ownership of the buffer to the caller. Returns the
- buffer as a data pointer and size pair, resets the internal
- buffer.
- */
- std::pair<byte*, long> release();
- //! Reset value
- void reset(std::pair<byte*, long> =std::make_pair(0,0));
- //@}
-
- /*!
- @name Conversions
-
- Special conversions with auxiliary type to enable copies
- and assignments, similar to those used for std::auto_ptr.
- See http://www.josuttis.com/libbook/auto_ptr.html for a discussion.
- */
- //@{
- DataBuf(DataBufRef rhs) : pData_(rhs.p.first), size_(rhs.p.second) {}
- DataBuf& operator=(DataBufRef rhs) { reset(rhs.p); return *this; }
- operator DataBufRef() { return DataBufRef(release()); }
- //@}
-
- // DATA
- //! Pointer to the buffer, 0 if none has been allocated
- byte* pData_;
- //! The current size of the buffer
- long size_;
- }; // class DataBuf
-
-
-// *****************************************************************************
-// free functions
-
- //! Read a 2 byte unsigned short value from the data buffer
- uint16_t getUShort(const byte* buf, ByteOrder byteOrder);
- //! Read a 4 byte unsigned long value from the data buffer
- uint32_t getULong(const byte* buf, ByteOrder byteOrder);
- //! Read an 8 byte unsigned rational value from the data buffer
- URational getURational(const byte* buf, ByteOrder byteOrder);
- //! Read a 2 byte signed short value from the data buffer
- int16_t getShort(const byte* buf, ByteOrder byteOrder);
- //! Read a 4 byte signed long value from the data buffer
- int32_t getLong(const byte* buf, ByteOrder byteOrder);
- //! Read an 8 byte signed rational value from the data buffer
- Rational getRational(const byte* buf, ByteOrder byteOrder);
-
- //! Output operator for our fake rational
- std::ostream& operator<<(std::ostream& os, const Rational& r);
- //! Input operator for our fake rational
- std::istream& operator>>(std::istream& is, Rational& r);
- //! Output operator for our fake unsigned rational
- std::ostream& operator<<(std::ostream& os, const URational& r);
- //! Input operator for our fake unsigned rational
- std::istream& operator>>(std::istream& is, URational& r);
-
- /*!
- @brief Convert an unsigned short to data, write the data to the buffer,
- return number of bytes written.
- */
- long us2Data(byte* buf, uint16_t s, ByteOrder byteOrder);
- /*!
- @brief Convert an unsigned long to data, write the data to the buffer,
- return number of bytes written.
- */
- long ul2Data(byte* buf, uint32_t l, ByteOrder byteOrder);
- /*!
- @brief Convert an unsigned rational to data, write the data to the buffer,
- return number of bytes written.
- */
- long ur2Data(byte* buf, URational l, ByteOrder byteOrder);
- /*!
- @brief Convert a signed short to data, write the data to the buffer,
- return number of bytes written.
- */
- long s2Data(byte* buf, int16_t s, ByteOrder byteOrder);
- /*!
- @brief Convert a signed long to data, write the data to the buffer,
- return number of bytes written.
- */
- long l2Data(byte* buf, int32_t l, ByteOrder byteOrder);
- /*!
- @brief Convert a signed rational to data, write the data to the buffer,
- return number of bytes written.
- */
- long r2Data(byte* buf, Rational l, ByteOrder byteOrder);
-
- /*!
- @brief Print len bytes from buf in hex and ASCII format to the given
- stream, prefixed with the position in the buffer adjusted by
- offset.
- */
- void hexdump(std::ostream& os, const byte* buf, long len, long offset =0);
-
- /*!
- @brief Return the greatest common denominator of integers a and b.
- Both parameters must be greater than 0.
- */
- int gcd(int a, int b);
-
- /*!
- @brief Return the greatest common denominator of long values a and b.
- Both parameters must be greater than 0.
- */
- long lgcd(long a, long b);
-
- /*!
- @brief Return true if str is a hex number starting with prefix followed
- by size hex digits, false otherwise. If size is 0, any number of
- digits is allowed and all are checked.
- */
- bool isHex(const std::string& str,
- size_t size =0,
- const std::string& prefix ="");
-
-// *****************************************************************************
-// template and inline definitions
-
- //! Utility function to convert the argument of any type to a string
- template<typename T>
- std::string toString(const T& arg)
- {
- std::ostringstream os;
- os << arg;
- return os.str();
- }
-
-} // namespace Exiv2
-
-#endif // #ifndef TYPES_HPP_
diff --git a/src/plugins/exiv2/value.cpp b/src/plugins/exiv2/value.cpp
@@ -1,559 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*
- File: value.cpp
- Version: $Rev: 560 $
- Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
- History: 26-Jan-04, ahu: created
- 11-Feb-04, ahu: isolated as a component
- 31-Jul-04, brad: added Time, Date and String values
- */
-// *****************************************************************************
-#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Id: value.cpp 560 2005-04-17 11:51:32Z ahuggel $");
-
-// *****************************************************************************
-// included header files
-#include "value.hpp"
-#include "types.hpp"
-#include "error.hpp"
-
-// + standard includes
-#include <cstdlib>
-#include <iostream>
-#include <iomanip>
-#include <sstream>
-#include <cassert>
-#include <ctime>
-#include <stdlib.h>
-
-// *****************************************************************************
-// class member definitions
-namespace Exiv2 {
-
- Value& Value::operator=(const Value& rhs)
- {
- if (this == &rhs) return *this;
- type_ = rhs.type_;
- return *this;
- }
-
- Value::AutoPtr Value::create(TypeId typeId)
- {
- AutoPtr value;
- switch (typeId) {
- case invalidTypeId:
- value = AutoPtr(new DataValue(invalidTypeId));
- break;
- case unsignedByte:
- value = AutoPtr(new DataValue(unsignedByte));
- break;
- case asciiString:
- value = AutoPtr(new AsciiValue);
- break;
- case unsignedShort:
- value = AutoPtr(new ValueType<uint16_t>);
- break;
- case unsignedLong:
- value = AutoPtr(new ValueType<uint32_t>);
- break;
- case unsignedRational:
- value = AutoPtr(new ValueType<URational>);
- break;
- case invalid6:
- value = AutoPtr(new DataValue(invalid6));
- break;
- case undefined:
- value = AutoPtr(new DataValue);
- break;
- case signedShort:
- value = AutoPtr(new ValueType<int16_t>);
- break;
- case signedLong:
- value = AutoPtr(new ValueType<int32_t>);
- break;
- case signedRational:
- value = AutoPtr(new ValueType<Rational>);
- break;
- case string:
- value = AutoPtr(new StringValue);
- break;
- case date:
- value = AutoPtr(new DateValue);
- break;
- case time:
- value = AutoPtr(new TimeValue);
- break;
- case comment:
- value = AutoPtr(new CommentValue);
- break;
- default:
- value = AutoPtr(new DataValue(typeId));
- break;
- }
- return value;
- } // Value::create
-
- std::string Value::toString() const
- {
- std::ostringstream os;
- write(os);
- return os.str();
- }
-
- DataValue& DataValue::operator=(const DataValue& rhs)
- {
- if (this == &rhs) return *this;
- Value::operator=(rhs);
- value_ = rhs.value_;
- return *this;
- }
-
- void DataValue::read(const byte* buf, long len, ByteOrder byteOrder)
- {
- // byteOrder not needed
- value_.assign(buf, buf + len);
- }
-
- void DataValue::read(const std::string& buf)
- {
- std::istringstream is(buf);
- int tmp;
- value_.clear();
- while (is >> tmp) {
- value_.push_back(static_cast<byte>(tmp));
- }
- }
-
- long DataValue::copy(byte* buf, ByteOrder byteOrder) const
- {
- // byteOrder not needed
- return static_cast<long>(
- std::copy(value_.begin(), value_.end(), buf) - buf
- );
- }
-
- long DataValue::size() const
- {
- return static_cast<long>(value_.size());
- }
-
- DataValue* DataValue::clone_() const
- {
- return new DataValue(*this);
- }
-
- std::ostream& DataValue::write(std::ostream& os) const
- {
- std::vector<byte>::size_type end = value_.size();
- for (std::vector<byte>::size_type i = 0; i != end; ++i) {
- os << static_cast<int>(value_[i]) << " ";
- }
- return os;
- }
-
- StringValueBase& StringValueBase::operator=(const StringValueBase& rhs)
- {
- if (this == &rhs) return *this;
- Value::operator=(rhs);
- value_ = rhs.value_;
- return *this;
- }
-
- void StringValueBase::read(const std::string& buf)
- {
- value_ = buf;
- }
-
- void StringValueBase::read(const byte* buf, long len, ByteOrder byteOrder)
- {
- // byteOrder not needed
- value_ = std::string(reinterpret_cast<const char*>(buf), len);
- }
-
- long StringValueBase::copy(byte* buf, ByteOrder byteOrder) const
- {
- // byteOrder not needed
- return static_cast<long>(
- value_.copy(reinterpret_cast<char*>(buf), value_.size())
- );
- }
-
- long StringValueBase::size() const
- {
- return static_cast<long>(value_.size());
- }
-
- std::ostream& StringValueBase::write(std::ostream& os) const
- {
- return os << value_;
- }
-
- StringValue& StringValue::operator=(const StringValue& rhs)
- {
- if (this == &rhs) return *this;
- StringValueBase::operator=(rhs);
- return *this;
- }
-
- StringValue* StringValue::clone_() const
- {
- return new StringValue(*this);
- }
-
- AsciiValue& AsciiValue::operator=(const AsciiValue& rhs)
- {
- if (this == &rhs) return *this;
- StringValueBase::operator=(rhs);
- return *this;
- }
-
- void AsciiValue::read(const std::string& buf)
- {
- value_ = buf;
- if (value_[value_.size()-1] != '\0') value_ += '\0';
- }
-
- AsciiValue* AsciiValue::clone_() const
- {
- return new AsciiValue(*this);
- }
-
- std::ostream& AsciiValue::write(std::ostream& os) const
- {
- // Strip all trailing '\0's (if any)
- std::string::size_type pos = value_.find_last_not_of('\0');
- return os << value_.substr(0, pos + 1);
- }
-
- CommentValue::CharsetTable::CharsetTable(CharsetId charsetId,
- const char* name,
- const char* code)
- : charsetId_(charsetId), name_(name), code_(code)
- {
- }
-
- //! Lookup list of supported IFD type information
- const CommentValue::CharsetTable CommentValue::CharsetInfo::charsetTable_[] = {
- CharsetTable(ascii, "Ascii", "ASCII\0\0\0"),
- CharsetTable(jis, "Jis", "JIS\0\0\0\0\0"),
- CharsetTable(unicode, "Unicode", "UNICODE\0"),
- CharsetTable(undefined, "Undefined", "\0\0\0\0\0\0\0\0"),
- CharsetTable(invalidCharsetId, "InvalidCharsetId", "\0\0\0\0\0\0\0\0"),
- CharsetTable(lastCharsetId, "InvalidCharsetId", "\0\0\0\0\0\0\0\0")
- };
-
- const char* CommentValue::CharsetInfo::name(CharsetId charsetId)
- {
- return charsetTable_[ charsetId < lastCharsetId ? charsetId : undefined ].name_;
- }
-
- const char* CommentValue::CharsetInfo::code(CharsetId charsetId)
- {
- return charsetTable_[ charsetId < lastCharsetId ? charsetId : undefined ].code_;
- }
-
- CommentValue::CharsetId CommentValue::CharsetInfo::charsetIdByName(
- const std::string& name)
- {
- int i = 0;
- for (; charsetTable_[i].charsetId_ != lastCharsetId
- && charsetTable_[i].name_ != name; ++i) {}
- return charsetTable_[i].charsetId_ == lastCharsetId ?
- invalidCharsetId : charsetTable_[i].charsetId_;
- }
-
- CommentValue::CharsetId CommentValue::CharsetInfo::charsetIdByCode(
- const std::string& code)
- {
- int i = 0;
- for (; charsetTable_[i].charsetId_ != lastCharsetId
- && std::string(charsetTable_[i].code_, 8) != code; ++i) {}
- return charsetTable_[i].charsetId_ == lastCharsetId ?
- invalidCharsetId : charsetTable_[i].charsetId_;
- }
-
- CommentValue::CommentValue(const std::string& comment)
- : StringValueBase(Exiv2::undefined)
- {
- read(comment);
- }
-
- CommentValue& CommentValue::operator=(const CommentValue& rhs)
- {
- if (this == &rhs) return *this;
- StringValueBase::operator=(rhs);
- return *this;
- }
-
- void CommentValue::read(const std::string& comment)
- {
- std::string c = comment;
- CharsetId charsetId = undefined;
- if (comment.length() > 8 && comment.substr(0, 8) == "charset=") {
- std::string::size_type pos = comment.find_first_of(' ');
- std::string name = comment.substr(8, pos-8);
- // Strip quotes (so you can also to specify the charset without quotes)
- if (name[0] == '"') name = name.substr(1);
- if (name[name.length()-1] == '"') name = name.substr(0, name.length()-1);
- charsetId = CharsetInfo::charsetIdByName(name);
- if (charsetId == invalidCharsetId) throw Error(28, name);
- c.clear();
- if (pos != std::string::npos) c = comment.substr(pos+1);
- }
- const std::string code(CharsetInfo::code(charsetId), 8);
- StringValueBase::read(code + c);
- }
-
- std::ostream& CommentValue::write(std::ostream& os) const
- {
- CharsetId charsetId = this->charsetId();
- if (charsetId != undefined) {
- os << "charset=\"" << CharsetInfo::name(charsetId) << "\" ";
- }
- return os << comment();
- }
-
- std::string CommentValue::comment() const
- {
- if (value_.length() >= 8) return value_.substr(8);
- return "";
- }
-
- CommentValue::CharsetId CommentValue::charsetId() const
- {
- CharsetId charsetId = undefined;
- if (value_.length() >= 8) {
- const std::string code = value_.substr(0, 8);
- charsetId = CharsetInfo::charsetIdByCode(code);
- }
- return charsetId;
- }
-
- CommentValue* CommentValue::clone_() const
- {
- return new CommentValue(*this);
- }
-
- DateValue::DateValue(int year, int month, int day)
- : Value(date)
- {
- date_.year = year;
- date_.month = month;
- date_.day = day;
- }
-
- DateValue& DateValue::operator=(const DateValue& rhs)
- {
- if (this == &rhs) return *this;
- Value::operator=(rhs);
- date_.year = rhs.date_.year;
- date_.month = rhs.date_.month;
- date_.day = rhs.date_.day;
- return *this;
- }
-
- void DateValue::read(const byte* buf, long len, ByteOrder byteOrder)
- {
- // byteOrder not needed
- // Hard coded to read Iptc style dates
- if (len != 8) throw Error(29);
- int scanned = sscanf(reinterpret_cast<const char*>(buf),
- "%4d%2d%2d",
- &date_.year, &date_.month, &date_.day);
- if (scanned != 3) throw Error(29);
- }
-
- void DateValue::read(const std::string& buf)
- {
- // byteOrder not needed
- // Hard coded to read Iptc style dates
- if (buf.length() < 8) throw Error(29);
- int scanned = sscanf(buf.data(),
- "%4d-%d-%d",
- &date_.year, &date_.month, &date_.day);
- if (scanned != 3) throw Error(29);
- }
-
- void DateValue::setDate( const Date& src )
- {
- date_.year = src.year;
- date_.month = src.month;
- date_.day = src.day;
- }
-
- long DateValue::copy(byte* buf, ByteOrder byteOrder) const
- {
- // byteOrder not needed
- // sprintf wants to add the null terminator, so use oversized buffer
- char temp[9];
-
- int wrote = sprintf( temp, "%04d%02d%02d",
- date_.year, date_.month, date_.day);
- assert(wrote == 8);
- memcpy(buf, temp, 8);
- return 8;
- }
-
- long DateValue::size() const
- {
- return 8;
- }
-
- DateValue* DateValue::clone_() const
- {
- return new DateValue(*this);
- }
-
- std::ostream& DateValue::write(std::ostream& os) const
- {
- return os << date_.year << '-' << std::right
- << std::setw(2) << std::setfill('0') << date_.month << '-'
- << std::setw(2) << std::setfill('0') << date_.day;
- }
-
- long DateValue::toLong(long n) const
- {
- // Range of tm struct is limited to about 1970 to 2038
- // This will return -1 if outside that range
- std::tm tms;
- memset(&tms, 0, sizeof(tms));
- tms.tm_mday = date_.day;
- tms.tm_mon = date_.month - 1;
- tms.tm_year = date_.year - 1900;
- return static_cast<long>(std::mktime(&tms));
- }
-
- TimeValue::TimeValue(int hour, int minute,
- int second, int tzHour,
- int tzMinute)
- : Value(date)
- {
- time_.hour=hour;
- time_.minute=minute;
- time_.second=second;
- time_.tzHour=tzHour;
- time_.tzMinute=tzMinute;
- }
-
- TimeValue& TimeValue::operator=(const TimeValue& rhs)
- {
- if (this == &rhs) return *this;
- Value::operator=(rhs);
- memcpy(&time_, &rhs.time_, sizeof(time_));
- return *this;
- }
-
- void TimeValue::read(const byte* buf, long len, ByteOrder byteOrder)
- {
- // byteOrder not needed
- // Hard coded to read Iptc style times
- if (len != 11) throw Error(30);
- char plusMinus;
- int scanned = sscanf(reinterpret_cast<const char*>(buf),
- "%2d%2d%2d%1c%2d%2d",
- &time_.hour, &time_.minute, &time_.second,
- &plusMinus, &time_.tzHour, &time_.tzMinute );
-
- if (scanned != 6) throw Error(30);
- if (plusMinus == '-') {
- time_.tzHour *= -1;
- time_.tzMinute *= -1;
- }
- }
-
- void TimeValue::read(const std::string& buf)
- {
- // byteOrder not needed
- // Hard coded to read Iptc style times
- if (buf.length() < 9) throw Error(30);
- char plusMinus;
- int scanned = sscanf(buf.data(),
- "%d:%d:%d%1c%d:%d",
- &time_.hour, &time_.minute, &time_.second,
- &plusMinus, &time_.tzHour, &time_.tzMinute );
-
- if (scanned != 6) throw Error(30);
- if (plusMinus == '-') {
- time_.tzHour *= -1;
- time_.tzMinute *= -1;
- }
- }
-
- void TimeValue::setTime( const Time& src )
- {
- memcpy(&time_, &src, sizeof(time_));
- }
-
- long TimeValue::copy(byte* buf, ByteOrder byteOrder) const
- {
- // byteOrder not needed
- // sprintf wants to add the null terminator, so use oversized buffer
- char temp[12];
- char plusMinus = '+';
- if (time_.tzHour < 0 || time_.tzMinute < 0) plusMinus = '-';
-
- int wrote = sprintf(temp,
- "%02d%02d%02d%1c%02d%02d",
- time_.hour, time_.minute, time_.second,
- plusMinus, abs(time_.tzHour), abs(time_.tzMinute));
-
- assert(wrote == 11);
- memcpy(buf, temp, 11);
- return 11;
- }
-
- long TimeValue::size() const
- {
- return 11;
- }
-
- TimeValue* TimeValue::clone_() const
- {
- return new TimeValue(*this);
- }
-
- std::ostream& TimeValue::write(std::ostream& os) const
- {
- char plusMinus = '+';
- if (time_.tzHour < 0 || time_.tzMinute < 0) plusMinus = '-';
-
- return os << std::right
- << std::setw(2) << std::setfill('0') << time_.hour << ':'
- << std::setw(2) << std::setfill('0') << time_.minute << ':'
- << std::setw(2) << std::setfill('0') << time_.second << plusMinus
- << std::setw(2) << std::setfill('0') << abs(time_.tzHour) << ':'
- << std::setw(2) << std::setfill('0') << abs(time_.tzMinute);
- }
-
- long TimeValue::toLong(long n) const
- {
- // Returns number of seconds in the day in UTC.
- long result = (time_.hour - time_.tzHour) * 60 * 60;
- result += (time_.minute - time_.tzMinute) * 60;
- result += time_.second;
- if (result < 0) {
- result += 86400;
- }
- return result;
- }
-
-} // namespace Exiv2
diff --git a/src/plugins/exiv2/value.hpp b/src/plugins/exiv2/value.hpp
@@ -1,1226 +0,0 @@
-// ***************************************************************** -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
- *
- * This program is part of the Exiv2 distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/*!
- @file value.hpp
- @brief Value interface and concrete subclasses
- @version $Rev: 560 $
- @author Andreas Huggel (ahu)
- <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
- @date 09-Jan-04, ahu: created
- 11-Feb-04, ahu: isolated as a component
- 31-Jul-04, brad: added Time, Data and String values
- */
-#ifndef VALUE_HPP_
-#define VALUE_HPP_
-
-// *****************************************************************************
-// included header files
-#include "types.hpp"
-
-// + standard includes
-#include <string>
-#include <vector>
-#include <iostream>
-#include <sstream>
-#include <memory>
-#include <string.h>
-
-// *****************************************************************************
-// namespace extensions
-namespace Exiv2 {
-
-// *****************************************************************************
-// class definitions
-
- /*!
- @brief Common interface for all types of values used with metadata.
-
- The interface provides a uniform way to access values independent from
- their actual C++ type for simple tasks like reading the values from a
- string or data buffer. For other tasks, like modifying values you may
- need to downcast it to the actual subclass of %Value so that you can
- access the subclass specific interface.
- */
- class Value {
- public:
- //! Shortcut for a %Value auto pointer.
- typedef std::auto_ptr<Value> AutoPtr;
-
- //! @name Creators
- //@{
- //! Constructor, taking a type id to initialize the base class with
- explicit Value(TypeId typeId)
- : type_(typeId) {}
- //! Copy constructor
- Value(const Value& rhs)
- : type_(rhs.type_) {}
- //! Virtual destructor.
- virtual ~Value() {}
- //@}
-
- //! @name Manipulators
- //@{
- /*!
- @brief Read the value from a character buffer.
-
- @param buf Pointer to the data buffer to read from
- @param len Number of bytes in the data buffer
- @param byteOrder Applicable byte order (little or big endian).
- */
- virtual void read(const byte* buf, long len, ByteOrder byteOrder) =0;
- /*!
- @brief Set the value from a string buffer. The format of the string
- corresponds to that of the write() method, i.e., a string
- obtained through the write() method can be read by this
- function.
-
- @param buf The string to read from.
- */
- virtual void read(const std::string& buf) =0;
- /*!
- @brief Set the data area, if the value has one by copying (cloning)
- the buffer pointed to by buf.
-
- Values may have a data area, which can contain additional
- information besides the actual value. This method is used to set such
- a data area.
-
- @param buf Pointer to the source data area
- @param len Size of the data area
- @return Return -1 if the value has no data area, else 0.
- */
- virtual int setDataArea(const byte* buf, long len) { return -1; }
- //@}
-
- //! @name Accessors
- //@{
- //! Return the type identifier (Exif data format type).
- TypeId typeId() const { return type_; }
- /*!
- @brief Return the value as a string. Implemented in terms of
- write(std::ostream& os) const of the concrete class.
- */
- std::string toString() const;
- /*!
- @brief Return an auto-pointer to a copy of itself (deep copy).
- The caller owns this copy and the auto-pointer ensures that
- it will be deleted.
- */
- AutoPtr clone() const { return AutoPtr(clone_()); }
- /*!
- @brief Write value to a data buffer.
-
- The user must ensure that the buffer has enough memory. Otherwise
- the call results in undefined behaviour.
-
- @param buf Data buffer to write to.
- @param byteOrder Applicable byte order (little or big endian).
- @return Number of bytes written.
- */
- virtual long copy(byte* buf, ByteOrder byteOrder) const =0;
- //! Return the number of components of the value
- virtual long count() const =0;
- //! Return the size of the value in bytes
- virtual long size() const =0;
- /*!
- @brief Write the value to an output stream. You do not usually have
- to use this function; it is used for the implementation of
- the output operator for %Value,
- operator<<(std::ostream &os, const Value &value).
- */
- virtual std::ostream& write(std::ostream& os) const =0;
- /*!
- @brief Convert the n-th component of the value to a long. The
- behaviour of this method may be undefined if there is no
- n-th component.
-
- @return The converted value.
- */
- virtual long toLong(long n =0) const =0;
- /*!
- @brief Convert the n-th component of the value to a float. The
- behaviour of this method may be undefined if there is no
- n-th component.
-
- @return The converted value.
- */
- virtual float toFloat(long n =0) const =0;
- /*!
- @brief Convert the n-th component of the value to a Rational. The
- behaviour of this method may be undefined if there is no
- n-th component.
-
- @return The converted value.
- */
- virtual Rational toRational(long n =0) const =0;
- //! Return the size of the data area, 0 if there is none.
- virtual long sizeDataArea() const { return 0; }
- /*!
- @brief Return a copy of the data area if the value has one. The
- caller owns this copy and DataBuf ensures that it will be
- deleted.
-
- Values may have a data area, which can contain additional
- information besides the actual value. This method is used to access
- such a data area.
-
- @return A DataBuf containing a copy of the data area or an empty
- DataBuf if the value does not have a data area assigned.
- */
- virtual DataBuf dataArea() const { return DataBuf(0, 0); };
- //@}
-
- /*!
- @brief A (simple) factory to create a Value type.
-
- The following Value subclasses are created depending on typeId:<BR><BR>
- <TABLE>
- <TR><TD class="indexkey"><B>typeId</B></TD><TD class="indexvalue"><B>%Value subclass</B></TD></TR>
- <TR><TD class="indexkey">invalidTypeId</TD><TD class="indexvalue">%DataValue(invalidTypeId)</TD></TR>
- <TR><TD class="indexkey">unsignedByte</TD><TD class="indexvalue">%DataValue(unsignedByte)</TD></TR>
- <TR><TD class="indexkey">asciiString</TD><TD class="indexvalue">%AsciiValue</TD></TR>
- <TR><TD class="indexkey">string</TD><TD class="indexvalue">%StringValue</TD></TR>
- <TR><TD class="indexkey">unsignedShort</TD><TD class="indexvalue">%ValueType < uint16_t ></TD></TR>
- <TR><TD class="indexkey">unsignedLong</TD><TD class="indexvalue">%ValueType < uint32_t ></TD></TR>
- <TR><TD class="indexkey">unsignedRational</TD><TD class="indexvalue">%ValueType < URational ></TD></TR>
- <TR><TD class="indexkey">invalid6</TD><TD class="indexvalue">%DataValue(invalid6)</TD></TR>
- <TR><TD class="indexkey">undefined</TD><TD class="indexvalue">%DataValue</TD></TR>
- <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">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>
- <TR><TD class="indexkey"><EM>default:</EM></TD><TD class="indexvalue">%DataValue(typeId)</TD></TR>
- </TABLE>
-
- @param typeId Type of the value.
- @return Auto-pointer to the newly created Value. The caller owns this
- copy and the auto-pointer ensures that it will be deleted.
- */
- static AutoPtr create(TypeId typeId);
-
- protected:
- /*!
- @brief Assignment operator. Protected so that it can only be used
- by subclasses but not directly.
- */
- Value& operator=(const Value& rhs);
-
- private:
- //! Internal virtual copy constructor.
- virtual Value* clone_() const =0;
- // DATA
- TypeId type_; //!< Type of the data
-
- }; // class Value
-
- //! Output operator for Value types
- inline std::ostream& operator<<(std::ostream& os, const Value& value)
- {
- return value.write(os);
- }
-
- //! %Value for an undefined data type.
- class DataValue : public Value {
- public:
- //! Shortcut for a %DataValue auto pointer.
- typedef std::auto_ptr<DataValue> AutoPtr;
-
- //! @name Creators
- //@{
- //! Default constructor.
- DataValue(TypeId typeId =undefined) : Value(typeId) {}
- //! Constructor
- DataValue(const byte* buf,
- long len, ByteOrder byteOrder =invalidByteOrder,
- TypeId typeId =undefined)
- : Value(typeId) { read(buf, len, byteOrder); }
- //! Virtual destructor.
- virtual ~DataValue() {}
- //@}
-
- //! @name Manipulators
- //@{
- //! Assignment operator.
- DataValue& operator=(const DataValue& rhs);
- /*!
- @brief Read the value from a character buffer.
-
- @note The byte order is required by the interface but not
- used by this method, so just use the default.
-
- @param buf Pointer to the data buffer to read from
- @param len Number of bytes in the data buffer
- @param byteOrder Byte order. Not needed.
- */
- virtual void read(const byte* buf,
- long len,
- ByteOrder byteOrder =invalidByteOrder);
- //! Set the data from a string of integer values (e.g., "0 1 2 3")
- virtual void read(const std::string& buf);
- //@}
-
- //! @name Accessors
- //@{
- AutoPtr clone() const { return AutoPtr(clone_()); }
- /*!
- @brief Write value to a character data buffer.
-
- @note The byte order is required by the interface but not used by this
- method, so just use the default.
-
- The user must ensure that the buffer has enough memory. Otherwise
- the call results in undefined behaviour.
-
- @param buf Data buffer to write to.
- @param byteOrder Byte order. Not needed.
- @return Number of characters written.
- */
- virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
- virtual long count() const { return size(); }
- virtual long size() const;
- virtual std::ostream& write(std::ostream& os) const;
- virtual long toLong(long n =0) const { return value_[n]; }
- virtual float toFloat(long n =0) const { return value_[n]; }
- virtual Rational toRational(long n =0) const
- { return Rational(value_[n], 1); }
- //@}
-
- private:
- //! Internal virtual copy constructor.
- virtual DataValue* clone_() const;
- // DATA
- std::vector<byte> value_;
-
- }; // class DataValue
-
- /*!
- @brief Abstract base class for a string based %Value type.
-
- Uses a std::string to store the value and implements defaults for
- most operations.
- */
- class StringValueBase : public Value {
- public:
- //! Shortcut for a %StringValueBase auto pointer.
- typedef std::auto_ptr<StringValueBase> AutoPtr;
-
- //! @name Creators
- //@{
- //! Constructor for subclasses
- StringValueBase(TypeId typeId)
- : Value(typeId) {}
- //! Constructor for subclasses
- StringValueBase(TypeId typeId, const std::string& buf)
- : Value(typeId) { read(buf); }
- //! Copy constructor
- StringValueBase(const StringValueBase& rhs)
- : Value(rhs), value_(rhs.value_) {}
-
- //! Virtual destructor.
- virtual ~StringValueBase() {}
- //@}
-
- //! @name Manipulators
- //@{
- //! Assignment operator.
- StringValueBase& operator=(const StringValueBase& rhs);
- //! Read the value from buf. This default implementation uses buf as it is.
- virtual void read(const std::string& buf);
- /*!
- @brief Read the value from a character buffer.
-
- @note The byte order is required by the interface but not used by this
- method, so just use the default.
-
- @param buf Pointer to the data buffer to read from
- @param len Number of bytes in the data buffer
- @param byteOrder Byte order. Not needed.
- */
- virtual void read(const byte* buf,
- long len,
- ByteOrder byteOrder =invalidByteOrder);
- //@}
-
- //! @name Accessors
- //@{
- AutoPtr clone() const { return AutoPtr(clone_()); }
- /*!
- @brief Write value to a character data buffer.
-
- The user must ensure that the buffer has enough memory. Otherwise
- the call results in undefined behaviour.
-
- @note The byte order is required by the interface but not used by this
- method, so just use the default.
-
- @param buf Data buffer to write to.
- @param byteOrder Byte order. Not used.
- @return Number of characters written.
- */
- virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
- virtual long count() const { return size(); }
- virtual long size() const;
- virtual long toLong(long n =0) const { return value_[n]; }
- virtual float toFloat(long n =0) const { return value_[n]; }
- virtual Rational toRational(long n =0) const
- { return Rational(value_[n], 1); }
- virtual std::ostream& write(std::ostream& os) const;
- //@}
-
- protected:
- //! Internal virtual copy constructor.
- virtual StringValueBase* clone_() const =0;
- // DATA
- std::string value_; //!< Stores the string value.
-
- }; // class StringValueBase
-
- /*!
- @brief %Value for string type.
-
- This can be a plain Ascii string or a multipe byte encoded string. It is
- left to caller to decode and encode the string to and from readable
- text if that is required.
- */
- class StringValue : public StringValueBase {
- public:
- //! Shortcut for a %StringValue auto pointer.
- typedef std::auto_ptr<StringValue> AutoPtr;
-
- //! @name Creators
- //@{
- //! Default constructor.
- StringValue()
- : StringValueBase(string) {}
- //! Constructor
- StringValue(const std::string& buf)
- : StringValueBase(string, buf) {}
- //! Copy constructor
- StringValue(const StringValue& rhs)
- : StringValueBase(rhs) {}
- //! Virtual destructor.
- virtual ~StringValue() {}
- //@}
-
- //! @name Manipulators
- //@{
- StringValue& operator=(const StringValue& rhs);
- //@}
-
- //! @name Accessors
- //@{
- AutoPtr clone() const { return AutoPtr(clone_()); }
- //@}
-
- private:
- //! Internal virtual copy constructor.
- virtual StringValue* clone_() const;
-
- }; // class StringValue
-
- /*!
- @brief %Value for an Ascii string type.
-
- This class is for null terminated single byte Ascii strings.
- This class also ensures that the string is null terminated.
- */
- class AsciiValue : public StringValueBase {
- public:
- //! Shortcut for a %AsciiValue auto pointer.
- typedef std::auto_ptr<AsciiValue> AutoPtr;
-
- //! @name Creators
- //@{
- //! Default constructor.
- AsciiValue()
- : StringValueBase(asciiString) {}
- //! Constructor
- AsciiValue(const std::string &buf)
- : StringValueBase(asciiString, buf) {}
- //! Copy constructor
- AsciiValue(const AsciiValue& rhs)
- : StringValueBase(rhs) {}
- //! Virtual destructor.
- virtual ~AsciiValue() {}
- //@}
-
- //! @name Manipulators
- //@{
- //! Assignment operator
- AsciiValue& operator=(const AsciiValue& rhs);
- /*!
- @brief Set the value to that of the string buf. Overrides base class
- to append a terminating '\\0' character if buf doesn't end
- with '\\0'.
- */
- virtual void read(const std::string& buf);
- //@}
-
- //! @name Accessors
- //@{
- AutoPtr clone() const { return AutoPtr(clone_()); }
- /*!
- @brief Write the value to an output stream. Any trailing '\\0'
- characters of the ASCII value are stripped and not written to
- the output stream.
- */
- virtual std::ostream& write(std::ostream& os) const;
- //@}
-
- private:
- //! Internal virtual copy constructor.
- virtual AsciiValue* clone_() const;
-
- }; // class AsciiValue
-
- /*!
- @brief %Value for an Exif comment.
-
- This can be a plain Ascii string or a multipe byte encoded string. The
- comment is expected to be encoded in the character set indicated (default
- undefined), but this is not checked. It is left to caller to decode and
- encode the string to and from readable text if that is required.
- */
- class CommentValue : public StringValueBase {
- public:
- //! Character set identifiers for the character sets defined by %Exif
- enum CharsetId { ascii, jis, unicode, undefined,
- invalidCharsetId, lastCharsetId };
- //! Information pertaining to the defined character sets
- struct CharsetTable {
- //! Constructor
- CharsetTable(CharsetId charsetId,
- const char* name,
- const char* code);
- CharsetId charsetId_; //!< Charset id
- const char* name_; //!< Name of the charset
- const char* code_; //!< Code of the charset
- }; // struct CharsetTable
- //! Charset information lookup functions. Implemented as a static class.
- class CharsetInfo {
- //! Prevent construction: not implemented.
- CharsetInfo() {}
- //! Prevent copy-construction: not implemented.
- CharsetInfo(const CharsetInfo&);
- //! Prevent assignment: not implemented.
- CharsetInfo& operator=(const CharsetInfo&);
-
- public:
- //! Return the name for a charset id
- static const char* name(CharsetId charsetId);
- //! Return the code for a charset id
- static const char* code(CharsetId charsetId);
- //! Return the charset id for a name
- static CharsetId charsetIdByName(const std::string& name);
- //! Return the charset id for a code
- static CharsetId charsetIdByCode(const std::string& code);
-
- private:
- static const CharsetTable charsetTable_[];
- }; // class CharsetInfo
-
- //! Shortcut for a %CommentValue auto pointer.
- typedef std::auto_ptr<CommentValue> AutoPtr;
-
- //! @name Creators
- //@{
- //! Default constructor.
- CommentValue()
- : StringValueBase(Exiv2::undefined) {}
- //! Constructor, uses read(const std::string& comment)
- CommentValue(const std::string& comment);
- //! Copy constructor
- CommentValue(const CommentValue& rhs)
- : StringValueBase(rhs) {}
- //! Virtual destructor.
- virtual ~CommentValue() {}
- //@}
-
- //! @name Manipulators
- //@{
- //! Assignment operator.
- CommentValue& operator=(const CommentValue& rhs);
- /*!
- @brief Read the value from a comment
-
- The format of \em comment is:
- <BR>
- <CODE>[charset=["]Ascii|Jis|Unicode|Undefined["] ]comment</CODE>
- <BR>
- The default charset is Undefined.
-
- @throw Error if an invalid character set is encountered
- */
- void read(const std::string& comment);
- //@}
-
- //! @name Accessors
- //@{
- AutoPtr clone() const { return AutoPtr(clone_()); }
- /*!
- @brief Write the comment in a format which can be read by
- read(const std::string& comment).
- */
- std::ostream& write(std::ostream& os) const;
- //! Return the comment (without a charset="..." prefix)
- std::string comment() const;
- //! Return the charset id of the comment
- CharsetId charsetId() const;
- //@}
-
- private:
- //! Internal virtual copy constructor.
- virtual CommentValue* clone_() const;
-
- }; // class CommentValue
-
- /*!
- @brief %Value for simple ISO 8601 dates
-
- This class is limited to parsing simple date strings in the ISO 8601
- format CCYYMMDD (century, year, month, day).
- */
- class DateValue : public Value {
- public:
- //! Shortcut for a %DateValue auto pointer.
- typedef std::auto_ptr<DateValue> AutoPtr;
-
- //! @name Creators
- //@{
- //! Default constructor.
- DateValue() : Value(date) { memset(&date_, 0, sizeof(date_)); }
- //! Constructor
- DateValue(int year, int month, int day);
- //! Virtual destructor.
- virtual ~DateValue() {}
- //@}
-
- //! Simple Date helper structure
- struct Date
- {
- int year; //!< Year
- int month; //!< Month
- int day; //!< Day
- };
-
- //! @name Manipulators
- //@{
- //! Assignment operator.
- DateValue& operator=(const DateValue& rhs);
- /*!
- @brief Read the value from a character buffer.
-
- @note The byte order is required by the interface but not used by this
- method, so just use the default.
-
- @param buf Pointer to the data buffer to read from
- @param len Number of bytes in the data buffer
- @param byteOrder Byte order. Not needed.
-
- @throw Error in case of an unsupported date format
- */
- virtual void read(const byte* buf,
- long len,
- ByteOrder byteOrder =invalidByteOrder);
- /*!
- @brief Set the value to that of the string buf.
-
- @param buf String containing the date
-
- @throw Error in case of an unsupported date format
- */
- virtual void read(const std::string& buf);
- //! Set the date
- void setDate(const Date& src);
- //@}
-
- //! @name Accessors
- //@{
- AutoPtr clone() const { return AutoPtr(clone_()); }
- /*!
- @brief Write value to a character data buffer.
-
- The user must ensure that the buffer has enough memory. Otherwise
- the call results in undefined behaviour.
-
- @note The byte order is required by the interface but not used by this
- method, so just use the default.
-
- @param buf Data buffer to write to.
- @param byteOrder Byte order. Not used.
- @return Number of characters written.
- */
- virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
- //! Return date struct containing date information
- virtual const Date& getDate() const { return date_; }
- virtual long count() const { return size(); }
- virtual long size() const;
- /*!
- @brief Write the value to an output stream. .
- */
- virtual std::ostream& write(std::ostream& os) const;
- virtual long toLong(long n =0) const;
- virtual float toFloat(long n =0) const
- { return static_cast<float>(toLong(n)); }
- virtual Rational toRational(long n =0) const
- { return Rational(toLong(n), 1); }
- //@}
-
- private:
- //! Internal virtual copy constructor.
- virtual DateValue* clone_() const;
- // DATA
- Date date_;
-
- }; // class DateValue
-
- /*!
- @brief %Value for simple ISO 8601 times.
-
- This class is limited to handling simple time strings in the ISO 8601
- format HHMMSS±HHMM where HHMMSS refers to local hour, minute and
- seconds and ±HHMM refers to hours and minutes ahead or behind
- Universal Coordinated Time.
- */
- class TimeValue : public Value {
- public:
- //! Shortcut for a %TimeValue auto pointer.
- typedef std::auto_ptr<TimeValue> AutoPtr;
-
- //! @name Creators
- //@{
- //! Default constructor.
- TimeValue() : Value(time) { memset(&time_, 0, sizeof(time_)); }
- //! Constructor
- TimeValue(int hour, int minute, int second =0,
- int tzHour =0, int tzMinute =0);
-
- //! Virtual destructor.
- virtual ~TimeValue() {}
- //@}
-
- //! Simple Time helper structure
- struct Time
- {
- int hour; //!< Hour
- int minute; //!< Minute
- int second; //!< Second
- int tzHour; //!< Hours ahead or behind UTC
- int tzMinute; //!< Minutes ahead or behind UTC
- };
-
- //! @name Manipulators
- //@{
- //! Assignment operator.
- TimeValue& operator=(const TimeValue& rhs);
- /*!
- @brief Read the value from a character buffer.
-
- @note The byte order is required by the interface but not used by this
- method, so just use the default.
-
- @param buf Pointer to the data buffer to read from
- @param len Number of bytes in the data buffer
- @param byteOrder Byte order. Not needed.
-
- @throw Error in case of an unsupported time format
- */
- virtual void read(const byte* buf,
- long len,
- ByteOrder byteOrder =invalidByteOrder);
- /*!
- @brief Set the value to that of the string buf.
-
- @param buf String containing the time.
-
- @throw Error in case of an unsupported time format
- */
- virtual void read(const std::string& buf);
- //! Set the time
- void setTime(const Time& src);
- //@}
-
- //! @name Accessors
- //@{
- AutoPtr clone() const { return AutoPtr(clone_()); }
- /*!
- @brief Write value to a character data buffer.
-
- The user must ensure that the buffer has enough memory. Otherwise
- the call results in undefined behaviour.
-
- @note The byte order is required by the interface but not used by this
- method, so just use the default.
-
- @param buf Data buffer to write to.
- @param byteOrder Byte order. Not used.
- @return Number of characters written.
- */
- virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
- //! Return time struct containing time information
- virtual const Time& getTime() const { return time_; }
- virtual long count() const { return size(); }
- virtual long size() const;
- /*!
- @brief Write the value to an output stream. .
- */
- virtual std::ostream& write(std::ostream& os) const;
- virtual long toLong(long n =0) const;
- virtual float toFloat(long n =0) const
- { return static_cast<float>(toLong(n)); }
- virtual Rational toRational(long n =0) const
- { return Rational(toLong(n), 1); }
- //@}
-
- private:
- //! Internal virtual copy constructor.
- virtual TimeValue* clone_() const;
- // DATA
- Time time_;
-
- }; // class TimeValue
- //! Template to determine the TypeId for a type T
- template<typename T> TypeId getType();
-
- //! Specialization for an unsigned short
- template<> inline TypeId getType<uint16_t>() { return unsignedShort; }
- //! Specialization for an unsigned long
- template<> inline TypeId getType<uint32_t>() { return unsignedLong; }
- //! Specialization for an unsigned rational
- template<> inline TypeId getType<URational>() { return unsignedRational; }
- //! Specialization for a signed short
- template<> inline TypeId getType<int16_t>() { return signedShort; }
- //! Specialization for a signed long
- template<> inline TypeId getType<int32_t>() { return signedLong; }
- //! Specialization for a signed rational
- template<> inline TypeId getType<Rational>() { return signedRational; }
-
- // No default implementation: let the compiler/linker complain
-// template<typename T> inline TypeId getType() { return invalid; }
-
- /*!
- @brief Template for a %Value of a basic type. This is used for unsigned
- and signed short, long and rationals.
- */
- template<typename T>
- class ValueType : public Value {
- public:
- //! Shortcut for a %ValueType\<T\> auto pointer.
- typedef std::auto_ptr<ValueType<T> > AutoPtr;
-
- //! @name Creators
- //@{
- //! Default constructor.
- ValueType() : Value(getType<T>()), pDataArea_(0), sizeDataArea_(0) {}
- //! Constructor
- ValueType(const byte* buf, long len, ByteOrder byteOrder);
- //! Constructor
- ValueType(const T& val, ByteOrder byteOrder =littleEndian);
- //! Copy constructor
- ValueType(const ValueType<T>& rhs);
- //! Virtual destructor.
- virtual ~ValueType();
- //@}
-
- //! @name Manipulators
- //@{
- //! Assignment operator.
- ValueType<T>& operator=(const ValueType<T>& rhs);
- virtual void read(const byte* buf, long len, ByteOrder byteOrder);
- /*!
- @brief Set the data from a string of values of type T (e.g.,
- "0 1 2 3" or "1/2 1/3 1/4" depending on what T is).
- Generally, the accepted input format is the same as that
- produced by the write() method.
- */
- virtual void read(const std::string& buf);
- /*!
- @brief Set the data area. This method copies (clones) the buffer
- pointed to by buf.
- */
- virtual int setDataArea(const byte* buf, long len);
- //@}
-
- //! @name Accessors
- //@{
- AutoPtr clone() const { return AutoPtr(clone_()); }
- virtual long copy(byte* buf, ByteOrder byteOrder) const;
- virtual long count() const { return static_cast<long>(value_.size()); }
- virtual long size() const;
- virtual std::ostream& write(std::ostream& os) const;
- virtual long toLong(long n =0) const;
- virtual float toFloat(long n =0) const;
- virtual Rational toRational(long n =0) const;
- //! Return the size of the data area.
- virtual long sizeDataArea() const { return sizeDataArea_; }
- /*!
- @brief Return a copy of the data area in a DataBuf. The caller owns
- this copy and DataBuf ensures that it will be deleted.
- */
- virtual DataBuf dataArea() const;
- //@}
-
- //! Container for values
- typedef std::vector<T> ValueList;
- //! Iterator type defined for convenience.
- typedef typename std::vector<T>::iterator iterator;
- //! Const iterator type defined for convenience.
- typedef typename std::vector<T>::const_iterator const_iterator;
-
- // DATA
- /*!
- @brief The container for all values. In your application, if you know
- what subclass of Value you're dealing with (and possibly the T)
- then you can access this STL container through the usual
- standard library functions.
- */
- ValueList value_;
-
- private:
- //! Internal virtual copy constructor.
- virtual ValueType<T>* clone_() const;
-
- // DATA
- //! Pointer to the buffer, 0 if none has been allocated
- byte* pDataArea_;
- //! The current size of the buffer
- long sizeDataArea_;
- }; // class ValueType
-
- //! Unsigned short value type
- typedef ValueType<uint16_t> UShortValue;
- //! Unsigned long value type
- typedef ValueType<uint32_t> ULongValue;
- //! Unsigned rational value type
- typedef ValueType<URational> URationalValue;
- //! Signed short value type
- typedef ValueType<int16_t> ShortValue;
- //! Signed long value type
- typedef ValueType<int32_t> LongValue;
- //! Signed rational value type
- typedef ValueType<Rational> RationalValue;
-
-// *****************************************************************************
-// template and inline definitions
-
- /*!
- @brief Read a value of type T from the data buffer.
-
- We need this template function for the ValueType template classes.
- There are only specializations of this function available; no default
- implementation is provided.
-
- @param buf Pointer to the data buffer to read from.
- @param byteOrder Applicable byte order (little or big endian).
- @return A value of type T.
- */
- template<typename T> T getValue(const byte* buf, ByteOrder byteOrder);
- // Specialization for a 2 byte unsigned short value.
- template<>
- inline uint16_t getValue(const byte* buf, ByteOrder byteOrder)
- {
- return getUShort(buf, byteOrder);
- }
- // Specialization for a 4 byte unsigned long value.
- template<>
- inline uint32_t getValue(const byte* buf, ByteOrder byteOrder)
- {
- return getULong(buf, byteOrder);
- }
- // Specialization for an 8 byte unsigned rational value.
- template<>
- inline URational getValue(const byte* buf, ByteOrder byteOrder)
- {
- return getURational(buf, byteOrder);
- }
- // Specialization for a 2 byte signed short value.
- template<>
- inline int16_t getValue(const byte* buf, ByteOrder byteOrder)
- {
- return getShort(buf, byteOrder);
- }
- // Specialization for a 4 byte signed long value.
- template<>
- inline int32_t getValue(const byte* buf, ByteOrder byteOrder)
- {
- return getLong(buf, byteOrder);
- }
- // Specialization for an 8 byte signed rational value.
- template<>
- inline Rational getValue(const byte* buf, ByteOrder byteOrder)
- {
- return getRational(buf, byteOrder);
- }
-
- /*!
- @brief Convert a value of type T to data, write the data to the data buffer.
-
- We need this template function for the ValueType template classes.
- There are only specializations of this function available; no default
- implementation is provided.
-
- @param buf Pointer to the data buffer to write to.
- @param t Value to be converted.
- @param byteOrder Applicable byte order (little or big endian).
- @return The number of bytes written to the buffer.
- */
- template<typename T> long toData(byte* buf, T t, ByteOrder byteOrder);
- /*!
- @brief Specialization to write an unsigned short to the data buffer.
- Return the number of bytes written.
- */
- template<>
- inline long toData(byte* buf, uint16_t t, ByteOrder byteOrder)
- {
- return us2Data(buf, t, byteOrder);
- }
- /*!
- @brief Specialization to write an unsigned long to the data buffer.
- Return the number of bytes written.
- */
- template<>
- inline long toData(byte* buf, uint32_t t, ByteOrder byteOrder)
- {
- return ul2Data(buf, t, byteOrder);
- }
- /*!
- @brief Specialization to write an unsigned rational to the data buffer.
- Return the number of bytes written.
- */
- template<>
- inline long toData(byte* buf, URational t, ByteOrder byteOrder)
- {
- return ur2Data(buf, t, byteOrder);
- }
- /*!
- @brief Specialization to write a signed short to the data buffer.
- Return the number of bytes written.
- */
- template<>
- inline long toData(byte* buf, int16_t t, ByteOrder byteOrder)
- {
- return s2Data(buf, t, byteOrder);
- }
- /*!
- @brief Specialization to write a signed long to the data buffer.
- Return the number of bytes written.
- */
- template<>
- inline long toData(byte* buf, int32_t t, ByteOrder byteOrder)
- {
- return l2Data(buf, t, byteOrder);
- }
- /*!
- @brief Specialization to write a signed rational to the data buffer.
- Return the number of bytes written.
- */
- template<>
- inline long toData(byte* buf, Rational t, ByteOrder byteOrder)
- {
- return r2Data(buf, t, byteOrder);
- }
-
- template<typename T>
- ValueType<T>::ValueType(const byte* buf, long len, ByteOrder byteOrder)
- : Value(getType<T>()), pDataArea_(0), sizeDataArea_(0)
- {
- read(buf, len, byteOrder);
- }
-
- template<typename T>
- ValueType<T>::ValueType(const T& val, ByteOrder byteOrder)
- : Value(getType<T>()), pDataArea_(0), sizeDataArea_(0)
- {
- read(reinterpret_cast<const byte*>(&val),
- TypeInfo::typeSize(typeId()),
- byteOrder);
- }
-
- template<typename T>
- ValueType<T>::ValueType(const ValueType<T>& rhs)
- : Value(rhs), value_(rhs.value_), pDataArea_(0), sizeDataArea_(0)
- {
- if (rhs.sizeDataArea_ > 0) {
- pDataArea_ = new byte[rhs.sizeDataArea_];
- memcpy(pDataArea_, rhs.pDataArea_, rhs.sizeDataArea_);
- sizeDataArea_ = rhs.sizeDataArea_;
- }
- }
-
- template<typename T>
- ValueType<T>::~ValueType()
- {
- delete[] pDataArea_;
- }
-
- template<typename T>
- ValueType<T>& ValueType<T>::operator=(const ValueType<T>& rhs)
- {
- if (this == &rhs) return *this;
- Value::operator=(rhs);
- value_ = rhs.value_;
-
- byte* tmp = 0;
- if (rhs.sizeDataArea_ > 0) {
- tmp = new byte[rhs.sizeDataArea_];
- memcpy(tmp, rhs.pDataArea_, rhs.sizeDataArea_);
- }
- delete[] pDataArea_;
- pDataArea_ = tmp;
- sizeDataArea_ = rhs.sizeDataArea_;
-
- return *this;
- }
-
- template<typename T>
- void ValueType<T>::read(const byte* buf, long len, ByteOrder byteOrder)
- {
- value_.clear();
- for (long i = 0; i < len; i += TypeInfo::typeSize(typeId())) {
- value_.push_back(getValue<T>(buf + i, byteOrder));
- }
- }
-
- template<typename T>
- void ValueType<T>::read(const std::string& buf)
- {
- std::istringstream is(buf);
- T tmp;
- value_.clear();
- while (is >> tmp) {
- value_.push_back(tmp);
- }
- }
-
- template<typename T>
- long ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const
- {
- long offset = 0;
- typename ValueList::const_iterator end = value_.end();
- for (typename ValueList::const_iterator i = value_.begin(); i != end; ++i) {
- offset += toData(buf + offset, *i, byteOrder);
- }
- return offset;
- }
-
- template<typename T>
- long ValueType<T>::size() const
- {
- return static_cast<long>(TypeInfo::typeSize(typeId()) * value_.size());
- }
-
- template<typename T>
- ValueType<T>* ValueType<T>::clone_() const
- {
- return new ValueType<T>(*this);
- }
-
- template<typename T>
- std::ostream& ValueType<T>::write(std::ostream& os) const
- {
- typename ValueList::const_iterator end = value_.end();
- typename ValueList::const_iterator i = value_.begin();
- while (i != end) {
- os << *i;
- if (++i != end) os << " ";
- }
- return os;
- }
- // Default implementation
- template<typename T>
- inline long ValueType<T>::toLong(long n) const
- {
- return value_[n];
- }
- // Specialization for rational
- template<>
- inline long ValueType<Rational>::toLong(long n) const
- {
- return value_[n].first / value_[n].second;
- }
- // Specialization for unsigned rational
- template<>
- inline long ValueType<URational>::toLong(long n) const
- {
- return value_[n].first / value_[n].second;
- }
- // Default implementation
- template<typename T>
- inline float ValueType<T>::toFloat(long n) const
- {
- return static_cast<float>(value_[n]);
- }
- // Specialization for rational
- template<>
- inline float ValueType<Rational>::toFloat(long n) const
- {
- return static_cast<float>(value_[n].first) / value_[n].second;
- }
- // Specialization for unsigned rational
- template<>
- inline float ValueType<URational>::toFloat(long n) const
- {
- return static_cast<float>(value_[n].first) / value_[n].second;
- }
- // Default implementation
- template<typename T>
- inline Rational ValueType<T>::toRational(long n) const
- {
- return Rational(value_[n], 1);
- }
- // Specialization for rational
- template<>
- inline Rational ValueType<Rational>::toRational(long n) const
- {
- return Rational(value_[n].first, value_[n].second);
- }
- // Specialization for unsigned rational
- template<>
- inline Rational ValueType<URational>::toRational(long n) const
- {
- return Rational(value_[n].first, value_[n].second);
- }
-
- template<typename T>
- inline DataBuf ValueType<T>::dataArea() const
- {
- return DataBuf(pDataArea_, sizeDataArea_);
- }
-
- template<typename T>
- inline int ValueType<T>::setDataArea(const byte* buf, long len)
- {
- byte* tmp = 0;
- if (len > 0) {
- tmp = new byte[len];
- memcpy(tmp, buf, len);
- }
- delete[] pDataArea_;
- pDataArea_ = tmp;
- sizeDataArea_ = len;
- return 0;
- }
-
-} // namespace Exiv2
-
-#endif // #ifndef VALUE_HPP_