[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r1942 - bug905
From: |
grothoff |
Subject: |
[GNUnet-SVN] r1942 - bug905 |
Date: |
Fri, 26 Aug 2005 21:03:56 -0700 (PDT) |
Author: grothoff
Date: 2005-08-26 21:03:54 -0700 (Fri, 26 Aug 2005)
New Revision: 1942
Removed:
bug905/addmoddel.cpp
bug905/basicio.cpp
bug905/basicio.hpp
bug905/config.h
bug905/datasets.cpp
bug905/datasets.hpp
bug905/error.cpp
bug905/error.hpp
bug905/exif.cpp
bug905/exif.hpp
bug905/exifcomment.cpp
bug905/exv_conf.h
bug905/exv_msvc.h
bug905/futils.cpp
bug905/futils.hpp
bug905/ifd.cpp
bug905/ifd.hpp
bug905/image.cpp
bug905/image.hpp
bug905/iptc.cpp
bug905/iptc.hpp
bug905/jpgimage.cpp
bug905/jpgimage.hpp
bug905/makernote.cpp
bug905/makernote.hpp
bug905/metadatum.cpp
bug905/metadatum.hpp
bug905/rcsid.hpp
bug905/tags.cpp
bug905/tags.hpp
bug905/types.cpp
bug905/types.hpp
bug905/value.cpp
bug905/value.hpp
Modified:
bug905/Makefile
bug905/plug.cc
Log:
reduced
Modified: bug905/Makefile
===================================================================
--- bug905/Makefile 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/Makefile 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,19 +1,5 @@
all: main.c plug.cc
gcc -ldl -lpthread main.c -o main
g++ -shared -lstdc++ -lc -lm plug.cc \
-basicio.cpp \
-datasets.cpp \
-error.cpp \
-exif.cpp \
-futils.cpp \
-ifd.cpp \
-image.cpp \
-iptc.cpp \
-jpgimage.cpp \
-makernote.cpp \
-metadatum.cpp \
-tags.cpp \
-types.cpp \
-value.cpp \
-o plug.so
./main
\ No newline at end of file
Deleted: bug905/addmoddel.cpp
===================================================================
--- bug905/addmoddel.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/addmoddel.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,109 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-// addmoddel.cpp, $Rev: 560 $
-// Sample program showing how to add, modify and delete Exif metadata.
-
-#include "image.hpp"
-#include "exif.hpp"
-#include <iostream>
-#include <iomanip>
-#include <cassert>
-
-int main(int argc, char* const argv[])
-try {
- if (argc != 2) {
- std::cout << "Usage: " << argv[0] << " file\n";
- return 1;
- }
- std::string file(argv[1]);
-
- // Container for exif metadata. This is an example of creating
- // exif metadata from scratch. If you want to add, modify, delete
- // metadata that exists in an image, start with ImageFactory::open
- Exiv2::ExifData exifData;
-
- //
*************************************************************************
- // Add to the Exif data
-
- // This is the quickest way to add (simple) Exif data. If a metadatum for
- // a given key already exists, its value is overwritten. Otherwise a new
- // tag is added.
- exifData["Exif.Image.Model"] = "Test 1"; // AsciiValue
- exifData["Exif.Image.SamplesPerPixel"] = uint16_t(162); // UShortValue
- exifData["Exif.Image.XResolution"] = int32_t(-2); // LongValue
- exifData["Exif.Image.YResolution"] = Exiv2::Rational(-2, 3); //
RationalValue
- std::cout << "Added a few tags the quick way.\n";
-
- // Create a ASCII string value (note the use of create)
- Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::asciiString);
- // Set the value to a string
- v->read("1999:12:31 23:59:59");
- // Add the value together with its key to the Exif data container
- Exiv2::ExifKey key("Exif.Photo.DateTimeOriginal");
- exifData.add(key, v.get());
- std::cout << "Added key \"" << key << "\", value \"" << *v << "\"\n";
-
- // Now create a more interesting value (without using the create method)
- Exiv2::URationalValue::AutoPtr rv(new Exiv2::URationalValue);
- // Set two rational components from a string
- rv->read("1/2 1/3");
- // Add more elements through the extended interface of rational value
- rv->value_.push_back(std::make_pair(2,3));
- rv->value_.push_back(std::make_pair(3,4));
- // Add the key and value pair to the Exif data
- key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
- exifData.add(key, rv.get());
- std::cout << "Added key \"" << key << "\", value \"" << *rv << "\"\n";
-
- //
*************************************************************************
- // Modify Exif data
-
- // Since we know that the metadatum exists (or we don't mind creating a new
- // tag if it doesn't), we can simply do this:
- Exiv2::Exifdatum& tag = exifData["Exif.Photo.DateTimeOriginal"];
- std::string date = tag.toString();
- date.replace(0, 4, "2000");
- tag.setValue(date);
- std::cout << "Modified key \"" << key
- << "\", new value \"" << tag.value() << "\"\n";
-
- // Alternatively, we can use findKey()
- key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
- Exiv2::ExifData::iterator pos = exifData.findKey(key);
- if (pos == exifData.end()) throw Exiv2::Error(1, "Key not found");
- // Get a pointer to a copy of the value
- v = pos->getValue();
- // Downcast the Value pointer to its actual type
- Exiv2::URationalValue* prv =
dynamic_cast<Exiv2::URationalValue*>(v.release());
- if (prv == 0) throw Exiv2::Error(1, "Downcast failed");
- rv = Exiv2::URationalValue::AutoPtr(prv);
- // Modify the value directly through the interface of URationalValue
- rv->value_[2] = std::make_pair(88,77);
- // Copy the modified value back to the metadatum
- pos->setValue(rv.get());
- std::cout << "Modified key \"" << key
- << "\", new value \"" << pos->value() << "\"\n";
-
- //
*************************************************************************
- // Delete metadata from the Exif data container
-
- // Delete the metadatum at iterator position pos
- key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
- pos = exifData.findKey(key);
- if (pos == exifData.end()) throw Exiv2::Error(1, "Key not found");
- exifData.erase(pos);
- std::cout << "Deleted key \"" << key << "\"\n";
-
- //
*************************************************************************
- // Finally, write the remaining Exif data to the image file
- Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(file);
- assert(image.get() != 0);
-
- image->setExifData(exifData);
- image->writeMetadata();
-
- return 0;
-}
-catch (Exiv2::AnyError& e) {
- std::cout << "Caught Exiv2 exception '" << e << "'\n";
- return -1;
-}
Deleted: bug905/basicio.cpp
===================================================================
--- bug905/basicio.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/basicio.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,500 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- 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)
- {
- // If copying data is too slow it might be worth
- // creating a readonly MemIo variant
- data_.reserve(size);
- data_.assign(data, data+size);
- idx_ = 0;
- }
-
- BasicIo::AutoPtr MemIo::temporary() const
- {
- return BasicIo::AutoPtr(new MemIo);
- }
-
- void MemIo::checkSize(long wcount)
- {
- ByteVector::size_type need = wcount + idx_;
- if (need > data_.size()) {
- data_.resize(need);
- }
- }
-
- long MemIo::write(const byte* data, long wcount)
- {
- checkSize(wcount);
- // According to Josuttis 6.2.3 this is safe
- memcpy(&data_[idx_], data, wcount);
- idx_ += wcount;
- return wcount;
- }
-
- void MemIo::transfer(BasicIo& src)
- {
- MemIo *memIo = dynamic_cast<MemIo*>(&src);
- if (memIo) {
- // Optimization if this is another instance of MemIo
- data_.swap(memIo->data_);
- idx_ = 0;
- }
- else{
- // Generic reopen to reset position to start
- data_.clear();
- idx_ = 0;
- if (src.open() != 0) {
- throw Error(9, src.path(), strError());
- }
- write(src);
- src.close();
- }
- if (error() || src.error()) throw Error(19, strError());
- }
-
- long MemIo::write(BasicIo& src)
- {
- if (static_cast<BasicIo*>(this)==&src) return 0;
- if (!src.isopen()) return 0;
-
- byte buf[4096];
- long readCount = 0;
- long writeTotal = 0;
- while ((readCount = src.read(buf, sizeof(buf)))) {
- write(buf, readCount);
- writeTotal += readCount;
- }
-
- return writeTotal;
- }
-
- int MemIo::putb(byte data)
- {
- checkSize(1);
- data_[idx_++] = data;
- return data;
- }
-
- int MemIo::seek(long offset, Position pos)
- {
- ByteVector::size_type newIdx;
-
- if (pos == BasicIo::cur ) {
- newIdx = idx_ + offset;
- }
- else if (pos == BasicIo::beg) {
- newIdx = offset;
- }
- else {
- assert(pos == BasicIo::end);
- newIdx = data_.size() + offset;
- }
-
- if (newIdx < 0 || newIdx > data_.size()) return 1;
- idx_ = newIdx;
- return 0;
- }
-
- long MemIo::tell() const
- {
- return (long)idx_;
- }
-
- long MemIo::size() const
- {
- return (long)data_.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 = (long)(data_.size() - idx_);
- long allow = std::min(rcount, avail);
-
- // According to Josuttis 6.2.3 this is safe
- memcpy(buf, &data_[idx_], allow);
- idx_ += allow;
- return allow;
- }
-
- int MemIo::getb()
- {
- if (idx_ == data_.size())
- return EOF;
- return data_[idx_++];
- }
-
- int MemIo::error() const
- {
- return 0;
- }
-
- bool MemIo::eof() const
- {
- return idx_ == data_.size();
- }
-
- std::string MemIo::path() const
- {
- return "MemIo";
- }
-
-} // namespace Exiv2
Deleted: bug905/basicio.hpp
===================================================================
--- bug905/basicio.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/basicio.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,642 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</a>
- @date 04-Dec-04, brad: created
- */
-#ifndef BASICIO_HPP_
-#define BASICIO_HPP_
-
-//
*****************************************************************************
-// included header files
-#include "types.hpp"
-
-// + standard includes
-#include <string>
-#include <vector>
-#include <cstdio>
-
-//
*****************************************************************************
-// 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() { idx_ = 0; }
- /*!
- @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
- virtual ~MemIo() {}
- //@}
-
- //! @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);
- /*!
- @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);
- /*!
- @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);
- /*!
- @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);
-
- // Typedefs
- typedef std::vector<byte> ByteVector;
-
- // DATA
- ByteVector data_;
- ByteVector::size_type idx_;
-
- // METHODS
- void checkSize(long wcount);
- }; // class MemIo
-} // namespace Exiv2
-
-#endif // #ifndef BASICIO_HPP_
Deleted: bug905/config.h
===================================================================
--- bug905/config.h 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/config.h 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,409 +0,0 @@
-/* src/include/config.h. Generated by configure. */
-/* src/include/config.h.in. Generated from configure.ac by autoheader. */
-
-#define _GNU_SOURCE 1
-
-/* Defined if the host has big endian byte ordering */
-/* #undef BIG_ENDIAN_HOST */
-
-/* This is a CYGWIN system */
-/* #undef CYGWIN */
-
-/* This is a Darwin system */
-/* #undef DARWIN */
-
-/* Define to 1 if translation of program messages to the user's native
- language is requested. */
-#define ENABLE_NLS 1
-
-/* Define to 1 if you have the `argz_append' function. */
-#define HAVE_ARGZ_APPEND 1
-
-/* Define to 1 if you have the `argz_create_sep' function. */
-#define HAVE_ARGZ_CREATE_SEP 1
-
-/* Define to 1 if you have the <argz.h> header file. */
-#define HAVE_ARGZ_H 1
-
-/* Define to 1 if you have the `argz_insert' function. */
-#define HAVE_ARGZ_INSERT 1
-
-/* Define to 1 if you have the `argz_next' function. */
-#define HAVE_ARGZ_NEXT 1
-
-/* Define to 1 if you have the `argz_stringify' function. */
-#define HAVE_ARGZ_STRINGIFY 1
-
-/* Define to 1 if you have the <assert.h> header file. */
-#define HAVE_ASSERT_H 1
-
-/* Define to 1 if you have the `bcopy' function. */
-/* #undef HAVE_BCOPY */
-
-/* Define to 1 if you have the `closedir' function. */
-#define HAVE_CLOSEDIR 1
-
-/* Define to 1 if you have the <ctype.h> header file. */
-#define HAVE_CTYPE_H 1
-
-/* Define if the GNU dcgettext() function is already present or preinstalled.
- */
-#define HAVE_DCGETTEXT 1
-
-/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
- */
-#define HAVE_DIRENT_H 1
-
-/* Define if you have the GNU dld library. */
-/* #undef HAVE_DLD */
-
-/* Define to 1 if you have the <dld.h> header file. */
-/* #undef HAVE_DLD_H */
-
-/* Define to 1 if you have the `dlerror' function. */
-#define HAVE_DLERROR 1
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the <dl.h> header file. */
-/* #undef HAVE_DL_H */
-
-/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
-/* #undef HAVE_DOPRNT */
-
-/* Define if you have the _dyld_func_lookup function. */
-/* #undef HAVE_DYLD */
-
-/* Define to 1 if you have the <errno.h> header file. */
-#define HAVE_ERRNO_H 1
-
-/* Define to 1 if the system has the type `error_t'. */
-#define HAVE_ERROR_T 1
-
-/* We use EXIV2 */
-#define HAVE_EXIV2 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the `floor' function. */
-/* #undef HAVE_FLOOR */
-
-/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
-#define HAVE_FSEEKO 1
-
-/* Define to 1 if you have the `ftruncate' function. */
-#define HAVE_FTRUNCATE 1
-
-/* Define to 1 if you have the `getcwd' function. */
-#define HAVE_GETCWD 1
-
-/* Define to 1 if you have the `getpagesize' function. */
-#define HAVE_GETPAGESIZE 1
-
-/* Define if the GNU gettext() function is already present or preinstalled. */
-#define HAVE_GETTEXT 1
-
-/* Have glib */
-#define HAVE_GLIB 1
-
-/* We have GTK */
-#define HAVE_GTK 1
-
-/* Define if you have the iconv() function. */
-#define HAVE_ICONV 1
-
-/* Define to 1 if you have the <iconv.h> header file. */
-#define HAVE_ICONV_H 1
-
-/* Define to 1 if you have the `index' function. */
-/* #undef HAVE_INDEX */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <langinfo.h> header file. */
-#define HAVE_LANGINFO_H 1
-
-/* Define to 1 if you have the `c_r' library (-lc_r). */
-/* #undef HAVE_LIBC_R */
-
-/* Define to 1 if you have the `dl' library (-ldl). */
-#define HAVE_LIBDL 1
-
-/* Define to 1 if you have the `intl' library (-lintl). */
-/* #undef HAVE_LIBINTL */
-
-/* Define to 1 if you have the <libintl.h> header file. */
-#define HAVE_LIBINTL_H 1
-
-/* Define to 1 if you have the `plibc' library (-lplibc). */
-/* #undef HAVE_LIBPLIBC */
-
-/* Define to 1 if you have the `resolv' library (-lresolv). */
-/* #undef HAVE_LIBRESOLV */
-
-/* Define to 1 if you have the `stdc++' library (-lstdc++). */
-#define HAVE_LIBSTDC__ 1
-
-/* Define to 1 if you have the `ws2_32' library (-lws2_32). */
-/* #undef HAVE_LIBWS2_32 */
-
-/* Define to 1 if you have the <limits.h> header file. */
-#define HAVE_LIMITS_H 1
-
-/* Define to 1 if you have the <ltdl.h> header file. */
-#define HAVE_LTDL_H 1
-
-/* Define to 1 if you have the <mach-o/dyld.h> header file. */
-/* #undef HAVE_MACH_O_DYLD_H */
-
-/* Define to 1 if you have the <malloc.h> header file. */
-#define HAVE_MALLOC_H 1
-
-/* Define to 1 if you have the `memcpy' function. */
-#define HAVE_MEMCPY 1
-
-/* Define to 1 if you have the `memmove' function. */
-#define HAVE_MEMMOVE 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `memset' function. */
-#define HAVE_MEMSET 1
-
-/* Define to 1 if you have the `mkstemp' function. */
-#define HAVE_MKSTEMP 1
-
-/* Define to 1 if you have a working `mmap' system call. */
-#define HAVE_MMAP 1
-
-/* Define to 1 if you have the `munmap' function. */
-#define HAVE_MUNMAP 1
-
-/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
-/* #undef HAVE_NDIR_H */
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#define HAVE_NETINET_IN_H 1
-
-/* Define to 1 if you have the `opendir' function. */
-#define HAVE_OPENDIR 1
-
-/* Define to 1 if you have the `pow' function. */
-/* #undef HAVE_POW */
-
-/* Define if libtool can extract symbol lists from object files. */
-#define HAVE_PRELOADED_SYMBOLS 1
-
-/* Define to 1 if you have the `readdir' function. */
-#define HAVE_READDIR 1
-
-/* Define to 1 if you have the `rindex' function. */
-/* #undef HAVE_RINDEX */
-
-/* Define to 1 if you have the `setenv' function. */
-#define HAVE_SETENV 1
-
-/* Define if you have the shl_load function. */
-/* #undef HAVE_SHL_LOAD */
-
-/* Define to 1 if you have the `sqrt' function. */
-/* #undef HAVE_SQRT */
-
-/* Define to 1 if `stat' has the bug that it succeeds when given the
- zero-length file name argument. */
-/* #undef HAVE_STAT_EMPTY_STRING_BUG */
-
-/* Define to 1 if stdbool.h conforms to C99. */
-#define HAVE_STDBOOL_H 1
-
-/* Define to 1 if you have the <stddef.h> header file. */
-#define HAVE_STDDEF_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdio.h> header file. */
-#define HAVE_STDIO_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#define HAVE_STRCASECMP 1
-
-/* Define to 1 if you have the `strchr' function. */
-#define HAVE_STRCHR 1
-
-/* Define to 1 if you have the `strcmp' function. */
-#define HAVE_STRCMP 1
-
-/* Define to 1 if you have the `strcspn' function. */
-#define HAVE_STRCSPN 1
-
-/* Define to 1 if you have the `strdup' function. */
-#define HAVE_STRDUP 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strncasecmp' function. */
-#define HAVE_STRNCASECMP 1
-
-/* Define to 1 if you have the `strndup' function. */
-#define HAVE_STRNDUP 1
-
-/* Define to 1 if you have the `strnlen' function. */
-#define HAVE_STRNLEN 1
-
-/* Define to 1 if you have the `strrchr' function. */
-#define HAVE_STRRCHR 1
-
-/* Define to 1 if you have the `strtoul' function. */
-#define HAVE_STRTOUL 1
-
-/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
- */
-/* #undef HAVE_SYS_DIR_H */
-
-/* Define to 1 if you have the <sys/dl.h> header file. */
-/* #undef HAVE_SYS_DL_H */
-
-/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
- */
-/* #undef HAVE_SYS_NDIR_H */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Have vorbisfile */
-#define HAVE_VORBISFILE 1
-
-/* Define to 1 if you have the <vorbis/vorbisfile.h> header file. */
-#define HAVE_VORBIS_VORBISFILE_H 1
-
-/* Define to 1 if you have the `vprintf' function. */
-#define HAVE_VPRINTF 1
-
-/* Have zlib */
-#define HAVE_ZLIB 1
-
-/* Define to 1 if you have the <zlib.h> header file. */
-#define HAVE_ZLIB_H 1
-
-/* Define to 1 if the system has the type `_Bool'. */
-#define HAVE__BOOL 1
-
-/* Define as const if the declaration of iconv() needs const. */
-#define ICONV_CONST
-
-/* This is a Linux system */
-#define LINUX 1
-
-/* Defined if the host has little endian byte ordering */
-#define LITTLE_ENDIAN_HOST 1
-
-/* gettext catalogs */
-#define LOCALEDIR "/home/grothoff//share/locale"
-
-/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
- slash. */
-#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
-
-/* Define if the OS needs help to load dependent libraries for dlopen(). */
-/* #undef LTDL_DLOPEN_DEPLIBS */
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LTDL_OBJDIR ".libs/"
-
-/* Define to the name of the environment variable that determines the dynamic
- library search path. */
-#define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH"
-
-/* Define to the extension used for shared libraries, say, ".so". */
-#define LTDL_SHLIB_EXT ".so"
-
-/* Define to the system default library search path. */
-#define LTDL_SYSSEARCHPATH "/lib:/usr/lib:/usr/X11R6/lib"
-
-/* This is a MinGW system */
-/* #undef MINGW */
-
-/* Define if dlsym() requires a leading underscore in symbol names. */
-/* #undef NEED_USCORE */
-
-/* Some strange OS */
-/* #undef OTHEROS */
-
-/* Name of package */
-#define PACKAGE "libextractor"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "address@hidden"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "libextractor"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "libextractor 0.5.3"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "libextractor"
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "0.5.3"
-
-/* This is a Solaris system */
-/* #undef SOLARIS */
-
-/* This is a BSD system */
-/* #undef SOMEBSD */
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "0.5.3"
-
-/* This is a Windows system */
-/* #undef WINDOWS */
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-#define _FILE_OFFSET_BITS 64
-
-/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
-#define _LARGEFILE_SOURCE 1
-
-/* Define for large files, on AIX-style hosts. */
-/* #undef _LARGE_FILES */
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to a type to use for `error_t' if it is not otherwise available. */
-/* #undef error_t */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
- calls it, or to nothing if 'inline' is not supported under any name. */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef pid_t */
-
-/* Define to `unsigned' if <sys/types.h> does not define. */
-/* #undef size_t */
Deleted: bug905/datasets.cpp
===================================================================
--- bug905/datasets.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/datasets.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,392 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- 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
Deleted: bug905/datasets.hpp
===================================================================
--- bug905/datasets.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/datasets.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,358 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- @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_
Deleted: bug905/error.cpp
===================================================================
--- bug905/error.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/error.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,121 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- 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
Deleted: bug905/error.hpp
===================================================================
--- bug905/error.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/error.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,148 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</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_
Deleted: bug905/exif.cpp
===================================================================
--- bug905/exif.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/exif.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,1237 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- 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;
- }
-
-}
Deleted: bug905/exif.hpp
===================================================================
--- bug905/exif.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/exif.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,908 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</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_
Deleted: bug905/exifcomment.cpp
===================================================================
--- bug905/exifcomment.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/exifcomment.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -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) <address@hidden>
- 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;
-}
Deleted: bug905/exv_conf.h
===================================================================
--- bug905/exv_conf.h 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/exv_conf.h 2005-08-27 04:03:54 UTC (rev 1942)
@@ -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
Deleted: bug905/exv_msvc.h
===================================================================
--- bug905/exv_msvc.h 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/exv_msvc.h 2005-08-27 04:03:54 UTC (rev 1942)
@@ -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
Deleted: bug905/futils.cpp
===================================================================
--- bug905/futils.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/futils.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,78 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- 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
Deleted: bug905/futils.hpp
===================================================================
--- bug905/futils.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/futils.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,66 +0,0 @@
-// ********************************************************* -*- C++ -*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</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_
Deleted: bug905/ifd.cpp
===================================================================
--- bug905/ifd.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/ifd.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,723 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- 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
Deleted: bug905/ifd.hpp
===================================================================
--- bug905/ifd.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/ifd.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,601 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</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_
Deleted: bug905/image.cpp
===================================================================
--- bug905/image.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/image.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,236 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- Brad Schick (brad) <address@hidden>
- 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 byte* data, long size)
- {
- BasicIo::AutoPtr io(new MemIo(data, size));
- 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
Deleted: bug905/image.hpp
===================================================================
--- bug905/image.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/image.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,493 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</a>
- @author Brad Schick (brad)
- <a href="mailto:address@hidden">address@hidden</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_
Deleted: bug905/iptc.cpp
===================================================================
--- bug905/iptc.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/iptc.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,301 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- 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
Deleted: bug905/iptc.hpp
===================================================================
--- bug905/iptc.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/iptc.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,415 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</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_
Deleted: bug905/jpgimage.cpp
===================================================================
--- bug905/jpgimage.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/jpgimage.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,661 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- Brad Schick (brad) <address@hidden>
- 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
Deleted: bug905/jpgimage.hpp
===================================================================
--- bug905/jpgimage.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/jpgimage.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,405 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</a>
- @author Brad Schick (brad)
- <a href="mailto:address@hidden">address@hidden</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_
Deleted: bug905/makernote.cpp
===================================================================
--- bug905/makernote.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/makernote.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,462 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- 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
Deleted: bug905/makernote.hpp
===================================================================
--- bug905/makernote.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/makernote.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,507 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</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>
-
-//
*****************************************************************************
-// 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_
Deleted: bug905/metadatum.cpp
===================================================================
--- bug905/metadatum.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/metadatum.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,76 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- Brad Schick (brad) <address@hidden>
- 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
-
Deleted: bug905/metadatum.hpp
===================================================================
--- bug905/metadatum.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/metadatum.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,294 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</a>
- @author Brad Schick (brad)
- <a href="mailto:address@hidden">address@hidden</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_
Modified: bug905/plug.cc
===================================================================
--- bug905/plug.cc 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/plug.cc 2005-08-27 04:03:54 UTC (rev 1942)
@@ -3,12 +3,12 @@
#include <string>
#include <map>
+#if 0
#include "exif.hpp"
#include "image.hpp"
#include "types.hpp"
+#endif
-#if 0
-
namespace Exiv2 {
class Image {
@@ -61,15 +61,18 @@
virtual ~AnyError()
{
}
- virtual int code() const =0;
- virtual std::string what() const =0;
};
+
+ class Error : public AnyError {
+ public:
+ explicit Error(int code) {
+ }
+ };
}
namespace {
Exiv2::ImageFactory::Init imageFactoryInit;
}
-#endif
extern "C" {
@@ -79,10 +82,9 @@
try {
printf("In plug.\n");
- Exiv2::Image::AutoPtr image
- = Exiv2::ImageFactory::open((const byte*)"foo", 3);
+ if (1) throw Error(12);
- } catch (const Exiv2::AnyError& e) {
+ } catch (const Exiv2::Error& e) {
}
printf("Leaving plug.\n");
}
Deleted: bug905/rcsid.hpp
===================================================================
--- bug905/rcsid.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/rcsid.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,62 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</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_
Deleted: bug905/tags.cpp
===================================================================
--- bug905/tags.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/tags.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,1232 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- 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 <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
Deleted: bug905/tags.hpp
===================================================================
--- bug905/tags.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/tags.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,444 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</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
- 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_
Deleted: bug905/types.cpp
===================================================================
--- bug905/types.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/types.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,343 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- 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>
-
-//
*****************************************************************************
-// 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
Deleted: bug905/types.hpp
===================================================================
--- bug905/types.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/types.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,307 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</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
-#ifdef _MSC_VER
-# include "exv_msvc.h"
-#else
-# include "exv_conf.h"
-#endif
-
-// + standard includes
-#include <string>
-#include <iosfwd>
-#include <utility>
-#include <sstream>
-#include <cstdio>
-#ifdef EXV_HAVE_STDINT_H
-# include <stdint.h>
-#endif
-
-// MSVC doesn't provide C99 types, but it has MS specific variants
-#ifdef _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_
Deleted: bug905/value.cpp
===================================================================
--- bug905/value.cpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/value.cpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,557 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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) <address@hidden>
- 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 <iostream>
-#include <iomanip>
-#include <sstream>
-#include <cassert>
-#include <ctime>
-
-//
*****************************************************************************
-// 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
Deleted: bug905/value.hpp
===================================================================
--- bug905/value.hpp 2005-08-27 03:57:29 UTC (rev 1941)
+++ bug905/value.hpp 2005-08-27 04:03:54 UTC (rev 1942)
@@ -1,1225 +0,0 @@
-// ***************************************************************** -*- C++
-*-
-/*
- * Copyright (C) 2004, 2005 Andreas Huggel <address@hidden>
- *
- * 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:address@hidden">address@hidden</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>
-
-//
*****************************************************************************
-// 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_
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r1942 - bug905,
grothoff <=