gnunet-svn
[Top][All Lists]
Advanced

[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 &lt; uint16_t &gt;</TD></TR>
-          <TR><TD class="indexkey">unsignedLong</TD><TD 
class="indexvalue">%ValueType &lt; uint32_t &gt;</TD></TR>
-          <TR><TD class="indexkey">unsignedRational</TD><TD 
class="indexvalue">%ValueType &lt; URational &gt;</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 &lt; int16_t &gt;</TD></TR>
-          <TR><TD class="indexkey">signedLong</TD><TD 
class="indexvalue">%ValueType &lt; int32_t &gt;</TD></TR>
-          <TR><TD class="indexkey">signedRational</TD><TD 
class="indexvalue">%ValueType &lt; Rational &gt;</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_





reply via email to

[Prev in Thread] Current Thread [Next in Thread]