From a297d2b69eca0277b5b0c795b278a1226e8f0cfd Mon Sep 17 00:00:00 2001 From: Robin Mills Date: Wed, 24 Jul 2013 05:05:52 +0000 Subject: [PATCH] Rollback 3089 - somehow it's broken the build! --- samples/addmoddel.cpp | 1 - samples/convert-test.cpp | 1 - samples/easyaccess-test.cpp | 1 - samples/exifprint.cpp | 1 - samples/geotag.cpp | 1 - samples/iotest.cpp | 225 ++++ samples/iptceasy.cpp | 1 - samples/iptcprint.cpp | 1 - samples/largeiptc-test.cpp | 1 - samples/metacopy.cpp | 2 +- samples/metacopy.hpp | 2 +- samples/mmap-test.cpp | 1 - samples/path-test.cpp | 1 - samples/prevtest.cpp | 1 - samples/stringto-test.cpp | 1 - samples/tiff-test.cpp | 1 - samples/tiffaddpath-test.cpp | 1 - samples/werror-test.cpp | 1 - samples/xmpparser-test.cpp | 1 - samples/xmpsample.cpp | 1 - src/actions.cpp | 2009 ++++++++++++++++++++++++++++++++++ src/actions.hpp | 2 +- src/asfvideo.cpp | 4 +- src/asfvideo.hpp | 2 +- src/basicio.cpp | 2 +- src/basicio.hpp | 2 +- src/bmpimage.cpp | 2 +- src/bmpimage.hpp | 2 +- src/canonmn.cpp | 2 +- src/canonmn_int.hpp | 2 +- src/convert.cpp | 2 +- src/convert.hpp | 2 +- src/cr2image.cpp | 2 +- src/cr2image.hpp | 2 +- src/cr2image_int.hpp | 2 +- src/crwimage.cpp | 2 +- src/crwimage.hpp | 2 +- src/crwimage_int.hpp | 2 +- src/datasets.cpp | 2 +- src/datasets.hpp | 2 +- src/easyaccess.cpp | 2 +- src/easyaccess.hpp | 2 +- src/epsimage.cpp | 2 +- src/epsimage.hpp | 2 +- src/error.cpp | 2 +- src/error.hpp | 2 +- src/exif.cpp | 2 +- src/exif.hpp | 2 +- src/exiv2.cpp | 4 +- src/exiv2.hpp | 2 +- src/exiv2app.hpp | 2 +- src/fujimn.cpp | 2 +- src/fujimn_int.hpp | 2 +- src/futils.cpp | 2 +- src/futils.hpp | 2 +- src/gifimage.cpp | 2 +- src/gifimage.hpp | 2 +- src/image.cpp | 2 +- src/image.hpp | 2 +- src/iptc.cpp | 2 +- src/iptc.hpp | 2 +- src/jp2image.cpp | 2 +- src/jp2image.hpp | 2 +- src/jpgimage.cpp | 2 +- src/jpgimage.hpp | 2 +- src/makernote.cpp | 2 +- src/makernote_int.hpp | 2 +- src/matroskavideo.cpp | 4 +- src/matroskavideo.hpp | 2 +- src/metadatum.cpp | 2 +- src/metadatum.hpp | 2 +- src/minoltamn.cpp | 2 +- src/minoltamn_int.hpp | 2 +- src/mrwimage.cpp | 2 +- src/mrwimage.hpp | 2 +- src/nikonmn.cpp | 2 +- src/nikonmn_int.hpp | 2 +- src/olympusmn.cpp | 2 +- src/olympusmn_int.hpp | 2 +- src/orfimage.cpp | 2 +- src/orfimage.hpp | 2 +- src/orfimage_int.hpp | 2 +- src/panasonicmn.cpp | 2 +- src/panasonicmn_int.hpp | 2 +- src/pentaxmn.cpp | 2 +- src/pentaxmn_int.hpp | 2 +- src/pgfimage.cpp | 2 +- src/pgfimage.hpp | 2 +- src/pngchunk.cpp | 2 +- src/pngchunk_int.hpp | 2 +- src/pngimage.cpp | 2 +- src/pngimage.hpp | 2 +- src/preview.cpp | 2 +- src/preview.hpp | 2 +- src/properties.cpp | 2 +- src/properties.hpp | 2 +- src/psdimage.cpp | 2 +- src/psdimage.hpp | 2 +- src/quicktimevideo.cpp | 4 +- src/quicktimevideo.hpp | 2 +- src/rafimage.cpp | 2 +- src/rafimage.hpp | 2 +- src/rcsid_int.hpp | 2 +- src/riffvideo.cpp | 4 +- src/riffvideo.hpp | 2 +- src/rw2image.cpp | 2 +- src/rw2image.hpp | 2 +- src/rw2image_int.hpp | 2 +- src/samsungmn.cpp | 2 +- src/samsungmn_int.hpp | 2 +- src/sigmamn.cpp | 2 +- src/sigmamn_int.hpp | 2 +- src/sonymn.cpp | 2 +- src/sonymn_int.hpp | 2 +- src/tags.cpp | 2 +- src/tags.hpp | 2 +- src/tags_int.hpp | 2 +- src/tgaimage.cpp | 2 +- src/tgaimage.hpp | 2 +- src/tiffcomposite.cpp | 2 +- src/tiffcomposite_int.hpp | 2 +- src/tifffwd_int.hpp | 2 +- src/tiffimage.cpp | 2 +- src/tiffimage.hpp | 2 +- src/tiffimage_int.hpp | 2 +- src/tiffvisitor.cpp | 2 +- src/tiffvisitor_int.hpp | 2 +- src/types.cpp | 2 +- src/types.hpp | 2 +- src/utils.cpp | 2 +- src/utils.hpp | 2 +- src/value.cpp | 2 +- src/value.hpp | 672 +++++++++++- src/version.cpp | 2 +- src/version.hpp | 2 +- src/xmp.cpp | 2 +- src/xmp.hpp | 2 +- src/xmpsidecar.cpp | 2 +- src/xmpsidecar.hpp | 2 +- 139 files changed, 3029 insertions(+), 142 deletions(-) diff --git a/samples/addmoddel.cpp b/samples/addmoddel.cpp index bffa8b33..6fb9702e 100644 --- a/samples/addmoddel.cpp +++ b/samples/addmoddel.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // addmoddel.cpp, $Rev$ // Sample program showing how to add, modify and delete Exif metadata. -// Copyright (C) 2004-2013 Andreas Huggel #include diff --git a/samples/convert-test.cpp b/samples/convert-test.cpp index 82aa8ff1..80e61f28 100644 --- a/samples/convert-test.cpp +++ b/samples/convert-test.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // convert-test.cpp, $Rev$ // Conversion test driver - make sure you have a copy of the input file around! -// Copyright (C) 2004-2013 Andreas Huggel #include diff --git a/samples/easyaccess-test.cpp b/samples/easyaccess-test.cpp index f14b5eea..065f44aa 100644 --- a/samples/easyaccess-test.cpp +++ b/samples/easyaccess-test.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // easyaccess-test.cpp, $Rev$ // Sample program using high-level metadata access functions -// Copyright (C) 2004-2013 Andreas Huggel // included header files #include diff --git a/samples/exifprint.cpp b/samples/exifprint.cpp index b05fd6e4..ea7fe3fb 100644 --- a/samples/exifprint.cpp +++ b/samples/exifprint.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // exifprint.cpp, $Rev$ // Sample program to print the Exif metadata of an image -// Copyright (C) 2004-2013 Andreas Huggel #include diff --git a/samples/geotag.cpp b/samples/geotag.cpp index d9da4777..4381fccf 100644 --- a/samples/geotag.cpp +++ b/samples/geotag.cpp @@ -2,7 +2,6 @@ // geotag.cpp, $Rev: 2286 $ // Sample program to read gpx files and update the images with GPS tags -// Copyright (C) 2004-2013 Andreas Huggel #include diff --git a/samples/iotest.cpp b/samples/iotest.cpp index e69de29b..04b1ad63 100644 --- a/samples/iotest.cpp +++ b/samples/iotest.cpp @@ -0,0 +1,225 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (C) 2004-2012 Andreas Huggel + * + * 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., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. + */ +/* + Abstract : Tester application for BasicIo functions. Tests MemIo primarily + since FileIo just sits atop of FILE* streams. + + File : iotest.cpp + Version : $Rev$ + Author(s): Brad Schick (brad) + History : 04-Dec-04, brad: created + */ +// ***************************************************************************** +// included header files +#include + +#include // for EOF +#include +#include + +using Exiv2::byte; +using Exiv2::BasicIo; +using Exiv2::MemIo; +using Exiv2::FileIo; +using Exiv2::IoCloser; +using Exiv2::Error; +using Exiv2::strError; + +int WriteReadSeek(BasicIo &io); + +// ***************************************************************************** +// Main +int main(int argc, char* const argv[]) +{ +try { + if (argc != 4) { + std::cout << "Usage: " << argv[0] << " filein fileout1 fileout2\n"; + std::cout << "fileouts are overwritten and should match filein exactly\n"; + return 1; + } + + FileIo fileIn(argv[1]); + if (fileIn.open() != 0) { + throw Error(9, fileIn.path(), strError()); + } + + FileIo fileOut1(argv[2]); + if (fileOut1.open("w+b") != 0) { + throw Error(10, argv[2], "w+b", strError()); + } + + MemIo memIo1; + + // Copy to output file through memIo + memIo1.write(fileIn); + memIo1.seek(0, BasicIo::beg); + fileOut1.write(memIo1); + + // Make sure they are all the same size + if(fileIn.size() != memIo1.size() || memIo1.size() != fileOut1.size()) { + std::cerr << argv[0] << + ": Sizes do not match\n"; + return 1; + } + + // Read writereadseek test on MemIo + MemIo memIo2; + int rc = WriteReadSeek(memIo2); + if (rc != 0) return rc; + + // Read writereadseek test on FileIo + // Create or overwrite the file, then close it + FileIo fileTest("iotest.txt"); + if (fileTest.open("w+b") != 0) { + throw Error(10, "iotest.txt", "w+b", strError()); + } + + fileTest.close(); + rc = WriteReadSeek(fileTest); + if (rc != 0) return rc; + + // Another test of reading and writing + fileOut1.seek(0, BasicIo::beg); + memIo2.seek(0, BasicIo::beg); + FileIo fileOut2(argv[3]); + if (fileOut2.open("w+b") != 0) { + throw Error(10, argv[3], "w+b", strError()); + } + + long readCount = 0; + byte buf[32]; + while ((readCount=fileOut1.read(buf, sizeof(buf)))) { + if (memIo2.write(buf, readCount) != readCount) { + std::cerr << argv[0] << + ": MemIo bad write 2\n"; + return 13; + } + if (fileOut2.write(buf, readCount) != readCount) { + std::cerr << argv[0] << + ": FileIo bad write 2\n"; + return 14; + } + } + + return 0; +} +catch (Exiv2::AnyError& e) { + std::cerr << "Caught Exiv2 exception '" << e << "'\n"; + return 20; +} +} + + +int WriteReadSeek(BasicIo &io) +{ + byte buf[4096]; + const char tester1[] = "this is a little test of MemIo"; + const char tester2[] = "Appending this on the end"; + const char expect[] = "this is a little teAppending this on the end"; + const long insert = 19; + const long len1 = (long)std::strlen(tester1) + 1; + const long len2 = (long)std::strlen(tester2) + 1; + + if (io.open() != 0) { + throw Error(9, io.path(), strError()); + } + IoCloser closer(io); + if (io.write((byte*)tester1, len1) != len1) { + std::cerr << ": WRS initial write failed\n"; + return 2; + } + + if (io.size() != len1) { + std::cerr << ": WRS size is not " << len1 << "\n"; + return 2; + } + + io.seek(-len1, BasicIo::cur); + + int c = EOF; + std::memset(buf, -1, sizeof(buf)); + for (int i = 0; (c=io.getb()) != EOF; ++i) { + buf[i] = (byte)c; + } + + // Make sure we got the null back + if(buf[len1-1] != 0) { + std::cerr << ": WRS missing null terminator 1\n"; + return 3; + } + + if (strcmp(tester1, (char*)buf) != 0 ) { + std::cerr << ": WRS strings don't match 1\n"; + return 4; + } + + io.seek(-2, BasicIo::end); + if (io.getb() != 'o') { + std::cerr << ": WRS bad getb o\n"; + return 5; + } + + io.seek(-2, BasicIo::cur); + if (io.getb() != 'I') { + std::cerr << ": WRS bad getb I\n"; + return 6; + } + + if (io.putb('O') != 'O') { + std::cerr << ": WRS bad putb\n"; + return 7; + } + + io.seek(-1, BasicIo::cur); + if (io.getb() != 'O') { + std::cerr << ": WRS bad getb O\n"; + return 8; + } + + io.seek(insert, BasicIo::beg); + if(io.write((byte*)tester2, len2) != len2) { + std::cerr << ": WRS bad write 1\n"; + return 9; + } + + // open should seek to beginning + if (io.open() != 0) { + throw Error(9, io.path(), strError()); + } + std::memset(buf, -1, sizeof(buf)); + if (io.read(buf, sizeof(buf)) != insert + len2) { + std::cerr << ": WRS something went wrong\n"; + return 10; + } + + // Make sure we got the null back + if(buf[insert + len2 - 1] != 0) { + std::cerr << ": WRS missing null terminator 2\n"; + return 11; + } + + if (std::strcmp(expect, (char*)buf) != 0 ) { + std::cerr << ": WRS strings don't match 2\n"; + return 12; + } + + return 0; +} diff --git a/samples/iptceasy.cpp b/samples/iptceasy.cpp index dad7b2b9..78f6e7bc 100644 --- a/samples/iptceasy.cpp +++ b/samples/iptceasy.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // iptceasy.cpp, $Rev$ // The quickest way to access, set or modify IPTC metadata. -// Copyright (C) 2004-2013 Andreas Huggel #include diff --git a/samples/iptcprint.cpp b/samples/iptcprint.cpp index 3e0b6e6e..f327c018 100644 --- a/samples/iptcprint.cpp +++ b/samples/iptcprint.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // iptcprint.cpp, $Rev$ // Sample program to print the IPTC metadata of an image -// Copyright (C) 2004-2013 Andreas Huggel #include diff --git a/samples/largeiptc-test.cpp b/samples/largeiptc-test.cpp index b40d6bf1..88ba80b8 100644 --- a/samples/largeiptc-test.cpp +++ b/samples/largeiptc-test.cpp @@ -1,6 +1,5 @@ // ***************************************************************** -*- C++ -*- // Test for large (>65535 bytes) IPTC buffer -// Copyright (C) 2004-2013 Andreas Huggel #include diff --git a/samples/metacopy.cpp b/samples/metacopy.cpp index 90c3c590..9f0ab52f 100644 --- a/samples/metacopy.cpp +++ b/samples/metacopy.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/samples/metacopy.hpp b/samples/metacopy.hpp index 4394839c..ba948b64 100644 --- a/samples/metacopy.hpp +++ b/samples/metacopy.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/samples/mmap-test.cpp b/samples/mmap-test.cpp index add95afa..e4f2980e 100644 --- a/samples/mmap-test.cpp +++ b/samples/mmap-test.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // mmap-test.cpp, $Rev$ // Simple mmap tests -// Copyright (C) 2004-2013 Andreas Huggel #include diff --git a/samples/path-test.cpp b/samples/path-test.cpp index ae6545d0..41dad6f9 100644 --- a/samples/path-test.cpp +++ b/samples/path-test.cpp @@ -1,6 +1,5 @@ // ***************************************************************** -*- C++ -*- // path-test.cpp, $Rev$ -// Copyright (C) 2004-2013 Andreas Huggel #include "utils.hpp" #include diff --git a/samples/prevtest.cpp b/samples/prevtest.cpp index 9dcc3f2c..a8048e7b 100644 --- a/samples/prevtest.cpp +++ b/samples/prevtest.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // prevtest.cpp, $Rev$ // Test access to preview images -// Copyright (C) 2004-2013 Andreas Huggel #include diff --git a/samples/stringto-test.cpp b/samples/stringto-test.cpp index 2343bb21..d970b3b1 100644 --- a/samples/stringto-test.cpp +++ b/samples/stringto-test.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // stringto-test.cpp, $Rev$ // Test conversions from string to long, float and Rational types. -// Copyright (C) 2004-2013 Andreas Huggel #include diff --git a/samples/tiff-test.cpp b/samples/tiff-test.cpp index 3a034af0..be3dd722 100644 --- a/samples/tiff-test.cpp +++ b/samples/tiff-test.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // tiff-test.cpp, $Rev$ // First and very simple TIFF write test. -// Copyright (C) 2004-2013 Andreas Huggel #include diff --git a/samples/tiffaddpath-test.cpp b/samples/tiffaddpath-test.cpp index 71942eef..548af041 100644 --- a/samples/tiffaddpath-test.cpp +++ b/samples/tiffaddpath-test.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // tiffaddpath-test.cpp, $Rev$ // Test driver to test adding new tags to a TIFF composite structure -// Copyright (C) 2004-2013 Andreas Huggel #include "tiffcomposite_int.hpp" #include "makernote2_int.hpp" diff --git a/samples/werror-test.cpp b/samples/werror-test.cpp index bc6a8c24..d282b875 100644 --- a/samples/werror-test.cpp +++ b/samples/werror-test.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // werror-test.cpp, $Rev$ // Simple tests for the wide-string error class WError -// Copyright (C) 2004-2013 Andreas Huggel #include #include diff --git a/samples/xmpparser-test.cpp b/samples/xmpparser-test.cpp index c35c00bf..1ab16776 100644 --- a/samples/xmpparser-test.cpp +++ b/samples/xmpparser-test.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // xmpparser-test.cpp, $Rev$ // Read an XMP packet from a file, parse and re-serialize it. -// Copyright (C) 2004-2013 Andreas Huggel #include diff --git a/samples/xmpsample.cpp b/samples/xmpsample.cpp index 40a904e8..b2e79eb4 100644 --- a/samples/xmpsample.cpp +++ b/samples/xmpsample.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- // xmpsample.cpp, $Rev$ // Sample/test for high level XMP classes. See also addmoddel.cpp -// Copyright (C) 2004-2013 Andreas Huggel #include diff --git a/src/actions.cpp b/src/actions.cpp index e69de29b..1e4c7ae2 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -0,0 +1,2009 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (C) 2004-2012 Andreas Huggel + * + * 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., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. + */ +/* + File: actions.cpp + Version: $Rev$ + Author(s): Andreas Huggel (ahu) + History: 08-Dec-03, ahu: created + 30-Apr-06, Roger Larsson: Print filename if processing multiple files + */ +// ***************************************************************************** +#include "rcsid_int.hpp" +EXIV2_RCSID("@(#) $Id$") + +// ***************************************************************************** +// included header files +#ifdef _MSC_VER +# include "exv_msvc.h" +#else +# include "exv_conf.h" +#endif + +#ifndef EXV_HAVE_TIMEGM +# include "timegm.h" +#endif +#include "actions.hpp" +#include "exiv2app.hpp" +#include "image.hpp" +#include "jpgimage.hpp" +#include "xmpsidecar.hpp" +#include "utils.hpp" +#include "types.hpp" +#include "exif.hpp" +#include "easyaccess.hpp" +#include "iptc.hpp" +#include "xmp.hpp" +#include "preview.hpp" +#include "futils.hpp" +#include "i18n.h" // NLS support. + +// + standard includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for stat() +#include // for stat() +#ifdef EXV_HAVE_UNISTD_H +# include // for stat() +#endif +#ifdef _MSC_VER +# include +#else +# include +#endif + +// ***************************************************************************** +// local declarations +namespace { + + //! Helper class to set the timestamp of a file to that of another file + class Timestamp { + public: + //! C'tor + Timestamp() : actime_(0), modtime_(0) {} + //! Read the timestamp of a file + int read(const std::string& path); + //! Read the timestamp from a broken-down time in buffer \em tm. + int read(struct tm* tm); + //! Set the timestamp of a file + int touch(const std::string& path); + + private: + time_t actime_; + time_t modtime_; + }; + + /*! + @brief Convert a string "YYYY:MM:DD HH:MI:SS" to a struct tm type, + returns 0 if successful + */ + int str2Tm(const std::string& timeStr, struct tm* tm); + + //! Convert a localtime to a string "YYYY:MM:DD HH:MI:SS", "" on error + std::string time2Str(time_t time); + + //! Convert a tm structure to a string "YYYY:MM:DD HH:MI:SS", "" on error + std::string tm2Str(const struct tm* tm); + + /*! + @brief Copy metadata from source to target according to Params::copyXyz + + @param source Source file path + @param target Target file path. An *.exv file is created if target doesn't + exist. + @param targetType Image type for the target image in case it needs to be + created. + @param preserve Indicates if existing metadata in the target file should + be kept. + @return 0 if successful, else an error code + */ + int metacopy(const std::string& source, + const std::string& target, + int targetType, + bool preserve); + + /*! + @brief Rename a file according to a timestamp value. + + @param path The original file path. Contains the new path on exit. + @param tm Pointer to a buffer with the broken-down time to rename + the file to. + @return 0 if successful, -1 if the file was skipped, 1 on error. + */ + int renameFile(std::string& path, const struct tm* tm); + + /*! + @brief Make a file path from the current file path, destination + directory (if any) and the filename extension passed in. + + @param path Path of the existing file + @param ext New filename extension (incl. the dot '.' if required) + @return 0 if successful, 1 if the new file exists and the user + chose not to overwrite it. + */ + std::string newFilePath(const std::string& path, const std::string& ext); + + /*! + @brief Check if file \em path exists and whether it should be + overwritten. Ask user if necessary. Return 1 if the file + exists and shouldn't be overwritten, else 0. + */ + int dontOverwrite(const std::string& path); +} + +// ***************************************************************************** +// class member definitions +namespace Action { + + Task::~Task() + { + } + + Task::AutoPtr Task::clone() const + { + return AutoPtr(clone_()); + } + + TaskFactory* TaskFactory::instance_ = 0; + + TaskFactory& TaskFactory::instance() + { + if (0 == instance_) { + instance_ = new TaskFactory; + } + return *instance_; + } // TaskFactory::instance + + void TaskFactory::cleanup() + { + if (instance_ != 0) { + Registry::iterator e = registry_.end(); + for (Registry::iterator i = registry_.begin(); i != e; ++i) { + delete i->second; + } + delete instance_; + instance_ = 0; + } + } //TaskFactory::cleanup + + void TaskFactory::registerTask(TaskType type, Task::AutoPtr task) + { + Registry::iterator i = registry_.find(type); + if (i != registry_.end()) { + delete i->second; + } + registry_[type] = task.release(); + } // TaskFactory::registerTask + + TaskFactory::TaskFactory() + { + // Register a prototype of each known task + registerTask(adjust, Task::AutoPtr(new Adjust)); + registerTask(print, Task::AutoPtr(new Print)); + registerTask(rename, Task::AutoPtr(new Rename)); + registerTask(erase, Task::AutoPtr(new Erase)); + registerTask(extract, Task::AutoPtr(new Extract)); + registerTask(insert, Task::AutoPtr(new Insert)); + registerTask(modify, Task::AutoPtr(new Modify)); + registerTask(fixiso, Task::AutoPtr(new FixIso)); + registerTask(fixcom, Task::AutoPtr(new FixCom)); + } // TaskFactory c'tor + + Task::AutoPtr TaskFactory::create(TaskType type) + { + Registry::const_iterator i = registry_.find(type); + if (i != registry_.end() && i->second != 0) { + Task* t = i->second; + return t->clone(); + } + return Task::AutoPtr(0); + } // TaskFactory::create + + Print::~Print() + { + } + + int Print::run(const std::string& path) + try { + path_ = path; + int rc = 0; + switch (Params::instance().printMode_) { + case Params::pmSummary: rc = printSummary(); break; + case Params::pmList: rc = printList(); break; + case Params::pmComment: rc = printComment(); break; + case Params::pmPreview: rc = printPreviewList(); break; + } + return rc; + } + catch(const Exiv2::AnyError& e) { + std::cerr << "Exiv2 exception in print action for file " + << path << ":\n" << e << "\n"; + return 1; + } // Print::run + + int Print::printSummary() + { + if (!Exiv2::fileExists(path_, true)) { + std::cerr << path_ << ": " + << _("Failed to open the file\n"); + return -1; + } + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path_); + assert(image.get() != 0); + image->readMetadata(); + Exiv2::ExifData& exifData = image->exifData(); + align_ = 16; + + // Filename + printLabel(_("File name")); + std::cout << path_ << std::endl; + + // Filesize + struct stat buf; + if (0 == stat(path_.c_str(), &buf)) { + printLabel(_("File size")); + std::cout << buf.st_size << " " << _("Bytes") << std::endl; + } + + // MIME type + printLabel(_("MIME type")); + std::cout << image->mimeType() << std::endl; + + // Image size + printLabel(_("Image size")); + std::cout << image->pixelWidth() << " x " << image->pixelHeight() << std::endl; + + if (exifData.empty()) { + std::cerr << path_ << ": " + << _("No Exif data found in the file\n"); + return -3; + } + + // Camera make + printTag(exifData, "Exif.Image.Make", _("Camera make")); + + // Camera model + printTag(exifData, "Exif.Image.Model", _("Camera model")); + + // Image Timestamp + printTag(exifData, "Exif.Photo.DateTimeOriginal", _("Image timestamp")); + + // Image number + // Todo: Image number for cameras other than Canon + printTag(exifData, "Exif.Canon.FileNumber", _("Image number")); + + // Exposure time + // From ExposureTime, failing that, try ShutterSpeedValue + bool done = false; + printLabel(_("Exposure time")); + if (!done) { + done = 0 != printTag(exifData, "Exif.Photo.ExposureTime"); + } + if (!done) { + done = 0 != printTag(exifData, "Exif.Photo.ShutterSpeedValue"); + } + std::cout << std::endl; + + // Aperture + // Get if from FNumber and, failing that, try ApertureValue + done = false; + printLabel(_("Aperture")); + if (!done) { + done = 0 != printTag(exifData, "Exif.Photo.FNumber"); + } + if (!done) { + done = 0 != printTag(exifData, "Exif.Photo.ApertureValue"); + } + std::cout << std::endl; + + // Exposure bias + printTag(exifData, "Exif.Photo.ExposureBiasValue", _("Exposure bias")); + + // Flash + printTag(exifData, "Exif.Photo.Flash", _("Flash")); + + // Flash bias + printTag(exifData, Exiv2::flashBias, _("Flash bias")); + + // Actual focal length and 35 mm equivalent + // Todo: Calculate 35 mm equivalent a la jhead + Exiv2::ExifData::const_iterator md; + printLabel(_("Focal length")); + if (1 == printTag(exifData, "Exif.Photo.FocalLength")) { + md = exifData.findKey( + Exiv2::ExifKey("Exif.Photo.FocalLengthIn35mmFilm")); + if (md != exifData.end()) { + std::cout << " ("<< _("35 mm equivalent") << ": " + << md->print(&exifData) << ")"; + } + } + else { + printTag(exifData, "Exif.Canon.FocalLength"); + } + std::cout << std::endl; + + // Subject distance + printLabel(_("Subject distance")); + done = false; + if (!done) { + done = 0 != printTag(exifData, "Exif.Photo.SubjectDistance"); + } + if (!done) { + done = 0 != printTag(exifData, "Exif.CanonSi.SubjectDistance"); + } + std::cout << std::endl; + + // ISO speed + printTag(exifData, Exiv2::isoSpeed, _("ISO speed")); + + // Exposure mode + printTag(exifData, Exiv2::exposureMode, _("Exposure mode")); + + // Metering mode + printTag(exifData, "Exif.Photo.MeteringMode", _("Metering mode")); + + // Macro mode + printTag(exifData, Exiv2::macroMode, _("Macro mode")); + + // Image quality setting (compression) + printTag(exifData, Exiv2::imageQuality, _("Image quality")); + + // Exif Resolution + printLabel(_("Exif Resolution")); + long xdim = 0; + long ydim = 0; + if (image->mimeType() == "image/tiff") { + xdim = image->pixelWidth(); + ydim = image->pixelHeight(); + } + else { + md = exifData.findKey(Exiv2::ExifKey("Exif.Image.ImageWidth")); + if (md == exifData.end()) { + md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension")); + } + if (md != exifData.end() && md->count() > 0) { + xdim = md->toLong(); + } + md = exifData.findKey(Exiv2::ExifKey("Exif.Image.ImageLength")); + if (md == exifData.end()) { + md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension")); + } + if (md != exifData.end() && md->count() > 0) { + ydim = md->toLong(); + } + } + if (xdim != 0 && ydim != 0) { + std::cout << xdim << " x " << ydim; + } + std::cout << std::endl; + + // White balance + printTag(exifData, Exiv2::whiteBalance, _("White balance")); + + // Thumbnail + printLabel(_("Thumbnail")); + Exiv2::ExifThumbC exifThumb(exifData); + std::string thumbExt = exifThumb.extension(); + if (thumbExt.empty()) { + std::cout << _("None"); + } + else { + Exiv2::DataBuf buf = exifThumb.copy(); + if (buf.size_ == 0) { + std::cout << _("None"); + } + else { + std::cout << exifThumb.mimeType() << ", " + << buf.size_ << " " << _("Bytes"); + } + } + std::cout << std::endl; + + // Copyright + printTag(exifData, "Exif.Image.Copyright", _("Copyright")); + + // Exif Comment + printTag(exifData, "Exif.Photo.UserComment", _("Exif comment")); + std::cout << std::endl; + + return 0; + } // Print::printSummary + + void Print::printLabel(const std::string& label) const + { + std::cout << std::setfill(' ') << std::left; + if (Params::instance().files_.size() > 1) { + std::cout << std::setw(20) << path_ << " "; + } + std::cout << std::setw(align_) + << label << ": "; + } + + int Print::printTag(const Exiv2::ExifData& exifData, + const std::string& key, + const std::string& label) const + { + int rc = 0; + if (!label.empty()) { + printLabel(label); + } + Exiv2::ExifKey ek(key); + Exiv2::ExifData::const_iterator md = exifData.findKey(ek); + if (md != exifData.end()) { + md->write(std::cout, &exifData); + rc = 1; + } + if (!label.empty()) std::cout << std::endl; + return rc; + } // Print::printTag + + int Print::printTag(const Exiv2::ExifData& exifData, + EasyAccessFct easyAccessFct, + const std::string& label) const + { + int rc = 0; + if (!label.empty()) { + printLabel(label); + } + Exiv2::ExifData::const_iterator md = easyAccessFct(exifData); + if (md != exifData.end()) { + md->write(std::cout, &exifData); + rc = 1; + } + if (!label.empty()) std::cout << std::endl; + return rc; + } // Print::printTag + + int Print::printList() + { + if (!Exiv2::fileExists(path_, true)) { + std::cerr << path_ + << ": " << _("Failed to open the file\n"); + return -1; + } + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path_); + assert(image.get() != 0); + image->readMetadata(); + // Set defaults for metadata types and data columns + if (Params::instance().printTags_ == Exiv2::mdNone) { + Params::instance().printTags_ = Exiv2::mdExif | Exiv2::mdIptc | Exiv2::mdXmp; + } + if (Params::instance().printItems_ == 0) { + Params::instance().printItems_ = Params::prKey | Params::prType | Params::prCount | Params::prTrans; + } + return printMetadata(image.get()); + } // Print::printList + + int Print::printMetadata(const Exiv2::Image* image) + { + int rc = 0; + if (Params::instance().printTags_ & Exiv2::mdExif) { + const Exiv2::ExifData& exifData = image->exifData(); + for (Exiv2::ExifData::const_iterator md = exifData.begin(); + md != exifData.end(); ++md) { + printMetadatum(*md, image); + } + if (exifData.empty()) { + if (Params::instance().verbose_) { + std::cerr << path_ << ": " << _("No Exif data found in the file\n"); + } + rc = -3; + } + } + if (Params::instance().printTags_ & Exiv2::mdIptc) { + const Exiv2::IptcData& iptcData = image->iptcData(); + for (Exiv2::IptcData::const_iterator md = iptcData.begin(); + md != iptcData.end(); ++md) { + printMetadatum(*md, image); + } + if (iptcData.empty()) { + if (Params::instance().verbose_) { + std::cerr << path_ << ": " << _("No IPTC data found in the file\n"); + } + rc = -3; + } + } + if (Params::instance().printTags_ & Exiv2::mdXmp) { + const Exiv2::XmpData& xmpData = image->xmpData(); + for (Exiv2::XmpData::const_iterator md = xmpData.begin(); + md != xmpData.end(); ++md) { + printMetadatum(*md, image); + } + if (xmpData.empty()) { + if (Params::instance().verbose_) { + std::cerr << path_ << ": " << _("No XMP data found in the file\n"); + } + rc = -3; + } + } + return rc; + } // Print::printMetadata + + bool Print::grepTag(const std::string& key) + { + bool result=Params::instance().keys_.empty(); + if (!result) + for (Params::Keys::const_iterator k = Params::instance().keys_.begin(); + !result && k != Params::instance().keys_.end(); ++k) { + result = key.find(*k) != std::string::npos; + } + return result ; + } + + void Print::printMetadatum(const Exiv2::Metadatum& md, const Exiv2::Image* pImage) + { + if (!grepTag(md.key())) return; + + if ( Params::instance().unknown_ + && md.tagName().substr(0, 2) == "0x") { + return; + } + bool const manyFiles = Params::instance().files_.size() > 1; + if (manyFiles) { + std::cout << std::setfill(' ') << std::left << std::setw(20) + << path_ << " "; + } + bool first = true; + if (Params::instance().printItems_ & Params::prTag) { + if (!first) std::cout << " "; + first = false; + std::cout << "0x" << std::setw(4) << std::setfill('0') + << std::right << std::hex + << md.tag(); + } + if (Params::instance().printItems_ & Params::prGroup) { + if (!first) std::cout << " "; + first = false; + std::cout << std::setw(12) << std::setfill(' ') << std::left + << md.groupName(); + } + if (Params::instance().printItems_ & Params::prKey) { + if (!first) std::cout << " "; + first = false; + std::cout << std::setfill(' ') << std::left << std::setw(44) + << md.key(); + } + if (Params::instance().printItems_ & Params::prName) { + if (!first) std::cout << " "; + first = false; + std::cout << std::setw(27) << std::setfill(' ') << std::left + << md.tagName(); + } + if (Params::instance().printItems_ & Params::prLabel) { + if (!first) std::cout << " "; + first = false; + std::cout << std::setw(30) << std::setfill(' ') << std::left + << md.tagLabel(); + } + if (Params::instance().printItems_ & Params::prType) { + if (!first) std::cout << " "; + first = false; + std::cout << std::setw(9) << std::setfill(' ') << std::left; + const char* tn = md.typeName(); + if (tn) { + std::cout << tn; + } + else { + std::ostringstream os; + os << "0x" << std::setw(4) << std::setfill('0') << std::hex << md.typeId(); + std::cout << os.str(); + } + } + if (Params::instance().printItems_ & Params::prCount) { + if (!first) std::cout << " "; + first = false; + std::cout << std::dec << std::setw(3) + << std::setfill(' ') << std::right + << md.count(); + } + if (Params::instance().printItems_ & Params::prSize) { + if (!first) std::cout << " "; + first = false; + std::cout << std::dec << std::setw(3) + << std::setfill(' ') << std::right + << md.size(); + } + if (Params::instance().printItems_ & Params::prValue) { + if (!first) std::cout << " "; + first = false; + if ( Params::instance().binary_ + && ( md.typeId() == Exiv2::undefined + || md.typeId() == Exiv2::unsignedByte + || md.typeId() == Exiv2::signedByte) + && md.size() > 128) { + std::cout << _("(Binary value suppressed)") << std::endl; + return; + } + bool done = false; + if (0 == strcmp(md.key().c_str(), "Exif.Photo.UserComment")) { + const Exiv2::CommentValue* pcv = dynamic_cast(&md.value()); + if (pcv) { + Exiv2::CommentValue::CharsetId csId = pcv->charsetId(); + if (csId != Exiv2::CommentValue::undefined) { + std::cout << "charset=\"" << Exiv2::CommentValue::CharsetInfo::name(csId) << "\" "; + } + std::cout << pcv->comment(Params::instance().charset_.c_str()); + done = true; + } + } + if (!done) std::cout << std::dec << md.value(); + } + if (Params::instance().printItems_ & Params::prTrans) { + if (!first) std::cout << " "; + first = false; + if ( Params::instance().binary_ + && ( md.typeId() == Exiv2::undefined + || md.typeId() == Exiv2::unsignedByte + || md.typeId() == Exiv2::signedByte) + && md.size() > 128) { + std::cout << _("(Binary value suppressed)") << std::endl; + return; + } + bool done = false; + if (0 == strcmp(md.key().c_str(), "Exif.Photo.UserComment")) { + const Exiv2::CommentValue* pcv = dynamic_cast(&md.value()); + if (pcv) { + std::cout << pcv->comment(Params::instance().charset_.c_str()); + done = true; + } + } + if (!done) std::cout << std::dec << md.print(&pImage->exifData()); + } + if (Params::instance().printItems_ & Params::prHex) { + if (!first) std::cout << std::endl; + first = false; + if ( Params::instance().binary_ + && ( md.typeId() == Exiv2::undefined + || md.typeId() == Exiv2::unsignedByte + || md.typeId() == Exiv2::signedByte) + && md.size() > 128) { + std::cout << _("(Binary value suppressed)") << std::endl; + return; + } + Exiv2::DataBuf buf(md.size()); + md.copy(buf.pData_, pImage->byteOrder()); + Exiv2::hexdump(std::cout, buf.pData_, buf.size_); + } + std::cout << std::endl; + } // Print::printMetadatum + + int Print::printComment() + { + if (!Exiv2::fileExists(path_, true)) { + std::cerr << path_ + << ": " << _("Failed to open the file\n"); + return -1; + } + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path_); + assert(image.get() != 0); + image->readMetadata(); + if (Params::instance().verbose_) { + std::cout << _("JPEG comment") << ": "; + } + std::cout << image->comment() << std::endl; + return 0; + } // Print::printComment + + int Print::printPreviewList() + { + if (!Exiv2::fileExists(path_, true)) { + std::cerr << path_ + << ": " << _("Failed to open the file\n"); + return -1; + } + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path_); + assert(image.get() != 0); + image->readMetadata(); + bool const manyFiles = Params::instance().files_.size() > 1; + int cnt = 0; + Exiv2::PreviewManager pm(*image); + Exiv2::PreviewPropertiesList list = pm.getPreviewProperties(); + for (Exiv2::PreviewPropertiesList::const_iterator pos = list.begin(); pos != list.end(); ++pos) { + if (manyFiles) { + std::cout << std::setfill(' ') << std::left << std::setw(20) + << path_ << " "; + } + std::cout << _("Preview") << " " << ++cnt << ": " + << pos->mimeType_ << ", "; + if (pos->width_ != 0 && pos->height_ != 0) { + std::cout << pos->width_ << "x" << pos->height_ << " " + << _("pixels") << ", "; + } + std::cout << pos->size_ << " " << _("bytes") << "\n"; + } + return 0; + } // Print::printPreviewList + + Print::AutoPtr Print::clone() const + { + return AutoPtr(clone_()); + } + + Print* Print::clone_() const + { + return new Print(*this); + } + + Rename::~Rename() + { + } + + int Rename::run(const std::string& path) + { + try { + if (!Exiv2::fileExists(path, true)) { + std::cerr << path + << ": " << _("Failed to open the file\n"); + return -1; + } + Timestamp ts; + if (Params::instance().preserve_) { + ts.read(path); + } + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path); + assert(image.get() != 0); + image->readMetadata(); + Exiv2::ExifData& exifData = image->exifData(); + if (exifData.empty()) { + std::cerr << path + << ": " << _("No Exif data found in the file\n"); + return -3; + } + Exiv2::ExifKey key("Exif.Photo.DateTimeOriginal"); + Exiv2::ExifData::iterator md = exifData.findKey(key); + if (md == exifData.end()) { + key = Exiv2::ExifKey("Exif.Image.DateTime"); + md = exifData.findKey(key); + } + if (md == exifData.end()) { + std::cerr << _("Neither tag") << " `Exif.Photo.DateTimeOriginal' " + << _("nor") << " `Exif.Image.DateTime' " + << _("found in the file") << " " << path << "\n"; + return 1; + } + std::string v = md->toString(); + if (v.length() == 0 || v[0] == ' ') { + std::cerr << _("Image file creation timestamp not set in the file") + << " " << path << "\n"; + return 1; + } + struct tm tm; + if (str2Tm(v, &tm) != 0) { + std::cerr << _("Failed to parse timestamp") << " `" << v + << "' " << _("in the file") << " " << path << "\n"; + return 1; + } + if ( Params::instance().timestamp_ + || Params::instance().timestampOnly_) { + ts.read(&tm); + } + int rc = 0; + std::string newPath = path; + if (Params::instance().timestampOnly_) { + if (Params::instance().verbose_) { + std::cout << _("Updating timestamp to") << " " << v << std::endl; + } + } + else { + rc = renameFile(newPath, &tm); + if (rc == -1) return 0; // skip + } + if ( 0 == rc + && ( Params::instance().preserve_ + || Params::instance().timestamp_ + || Params::instance().timestampOnly_)) { + ts.touch(newPath); + } + return rc; + } + catch(const Exiv2::AnyError& e) + { + std::cerr << "Exiv2 exception in rename action for file " << path + << ":\n" << e << "\n"; + return 1; + }} // Rename::run + + Rename::AutoPtr Rename::clone() const + { + return AutoPtr(clone_()); + } + + Rename* Rename::clone_() const + { + return new Rename(*this); + } + + Erase::~Erase() + { + } + + int Erase::run(const std::string& path) + try { + path_ = path; + + if (!Exiv2::fileExists(path_, true)) { + std::cerr << path_ + << ": " << _("Failed to open the file\n"); + return -1; + } + Timestamp ts; + if (Params::instance().preserve_) { + ts.read(path); + } + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path_); + assert(image.get() != 0); + image->readMetadata(); + // Thumbnail must be before Exif + int rc = 0; + if (Params::instance().target_ & Params::ctThumb) { + rc = eraseThumbnail(image.get()); + } + if (0 == rc && Params::instance().target_ & Params::ctExif) { + rc = eraseExifData(image.get()); + } + if (0 == rc && Params::instance().target_ & Params::ctIptc) { + rc = eraseIptcData(image.get()); + } + if (0 == rc && Params::instance().target_ & Params::ctComment) { + rc = eraseComment(image.get()); + } + if (0 == rc && Params::instance().target_ & Params::ctXmp) { + rc = eraseXmpData(image.get()); + } + if (0 == rc) { + image->writeMetadata(); + } + if (Params::instance().preserve_) { + ts.touch(path); + } + + return rc; + } + catch(const Exiv2::AnyError& e) + { + std::cerr << "Exiv2 exception in erase action for file " << path + << ":\n" << e << "\n"; + return 1; + } // Erase::run + + int Erase::eraseThumbnail(Exiv2::Image* image) const + { + Exiv2::ExifThumb exifThumb(image->exifData()); + std::string thumbExt = exifThumb.extension(); + if (thumbExt.empty()) { + return 0; + } + exifThumb.erase(); + if (Params::instance().verbose_) { + std::cout << _("Erasing thumbnail data") << std::endl; + } + return 0; + } + + int Erase::eraseExifData(Exiv2::Image* image) const + { + if (Params::instance().verbose_ && image->exifData().count() > 0) { + std::cout << _("Erasing Exif data from the file") << std::endl; + } + image->clearExifData(); + return 0; + } + + int Erase::eraseIptcData(Exiv2::Image* image) const + { + if (Params::instance().verbose_ && image->iptcData().count() > 0) { + std::cout << _("Erasing IPTC data from the file") << std::endl; + } + image->clearIptcData(); + return 0; + } + + int Erase::eraseComment(Exiv2::Image* image) const + { + if (Params::instance().verbose_ && image->comment().size() > 0) { + std::cout << _("Erasing JPEG comment from the file") << std::endl; + } + image->clearComment(); + return 0; + } + + int Erase::eraseXmpData(Exiv2::Image* image) const + { + if (Params::instance().verbose_ && image->xmpData().count() > 0) { + std::cout << _("Erasing XMP data from the file") << std::endl; + } + image->clearXmpData(); // Quick fix for bug #612 + image->clearXmpPacket(); + return 0; + } + + Erase::AutoPtr Erase::clone() const + { + return AutoPtr(clone_()); + } + + Erase* Erase::clone_() const + { + return new Erase(*this); + } + + Extract::~Extract() + { + } + + int Extract::run(const std::string& path) + try { + path_ = path; + int rc = 0; + if (Params::instance().target_ & Params::ctThumb) { + rc = writeThumbnail(); + } + if (Params::instance().target_ & Params::ctXmpSidecar) { + std::string xmpPath = newFilePath(path_, ".xmp"); + if (dontOverwrite(xmpPath)) return 0; + rc = metacopy(path_, xmpPath, Exiv2::ImageType::xmp, false); + } + if (Params::instance().target_ & Params::ctPreview) { + rc = writePreviews(); + } + if ( !(Params::instance().target_ & Params::ctXmpSidecar) + && !(Params::instance().target_ & Params::ctThumb) + && !(Params::instance().target_ & Params::ctPreview)) { + std::string exvPath = newFilePath(path_, ".exv"); + if (dontOverwrite(exvPath)) return 0; + rc = metacopy(path_, exvPath, Exiv2::ImageType::exv, false); + } + return rc; + } + catch(const Exiv2::AnyError& e) + { + std::cerr << "Exiv2 exception in extract action for file " << path + << ":\n" << e << "\n"; + return 1; + } // Extract::run + + int Extract::writeThumbnail() const + { + if (!Exiv2::fileExists(path_, true)) { + std::cerr << path_ + << ": " << _("Failed to open the file\n"); + return -1; + } + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path_); + assert(image.get() != 0); + image->readMetadata(); + Exiv2::ExifData& exifData = image->exifData(); + if (exifData.empty()) { + std::cerr << path_ + << ": " << _("No Exif data found in the file\n"); + return -3; + } + int rc = 0; + Exiv2::ExifThumb exifThumb(exifData); + std::string thumbExt = exifThumb.extension(); + if (thumbExt.empty()) { + std::cerr << path_ << ": " << _("Image does not contain an Exif thumbnail\n"); + } + else { + std::string thumb = newFilePath(path_, "-thumb"); + std::string thumbPath = thumb + thumbExt; + if (dontOverwrite(thumbPath)) return 0; + if (Params::instance().verbose_) { + Exiv2::DataBuf buf = exifThumb.copy(); + if (buf.size_ != 0) { + std::cout << _("Writing thumbnail") << " (" << exifThumb.mimeType() << ", " + << buf.size_ << " " << _("Bytes") << ") " << _("to file") << " " + << thumbPath << std::endl; + } + } + rc = exifThumb.writeFile(thumb); + if (rc == 0) { + std::cerr << path_ << ": " << _("Exif data doesn't contain a thumbnail\n"); + } + } + return rc; + } // Extract::writeThumbnail + + int Extract::writePreviews() const + { + if (!Exiv2::fileExists(path_, true)) { + std::cerr << path_ + << ": " << _("Failed to open the file\n"); + return -1; + } + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path_); + assert(image.get() != 0); + image->readMetadata(); + + Exiv2::PreviewManager pvMgr(*image); + Exiv2::PreviewPropertiesList pvList = pvMgr.getPreviewProperties(); + + const Params::PreviewNumbers& numbers = Params::instance().previewNumbers_; + for (Params::PreviewNumbers::const_iterator n = numbers.begin(); n != numbers.end(); ++n) { + if (*n == 0) { + // Write all previews + for (int num = 0; num < static_cast(pvList.size()); ++num) { + writePreviewFile(pvMgr.getPreviewImage(pvList[num]), num + 1); + } + break; + } + if (*n > static_cast(pvList.size())) { + std::cerr << path_ << ": " << _("Image does not have preview") + << " " << *n << "\n"; + continue; + } + writePreviewFile(pvMgr.getPreviewImage(pvList[*n - 1]), *n); + } + return 0; + } // Extract::writePreviews + + void Extract::writePreviewFile(const Exiv2::PreviewImage& pvImg, int num) const + { + std::string pvFile = newFilePath(path_, "-preview") + Exiv2::toString(num); + std::string pvPath = pvFile + pvImg.extension(); + if (dontOverwrite(pvPath)) return; + if (Params::instance().verbose_) { + std::cout << _("Writing preview") << " " << num << " (" + << pvImg.mimeType() << ", "; + if (pvImg.width() != 0 && pvImg.height() != 0) { + std::cout << pvImg.width() << "x" << pvImg.height() << " " + << _("pixels") << ", "; + } + std::cout << pvImg.size() << " " << _("bytes") << ") " + << _("to file") << " " << pvPath << std::endl; + } + long rc = pvImg.writeFile(pvFile); + if (rc == 0) { + std::cerr << path_ << ": " << _("Image does not have preview") + << " " << num << "\n"; + } + } // Extract::writePreviewFile + + Extract::AutoPtr Extract::clone() const + { + return AutoPtr(clone_()); + } + + Extract* Extract::clone_() const + { + return new Extract(*this); + } + + Insert::~Insert() + { + } + + int Insert::run(const std::string& path) + try { + if (!Exiv2::fileExists(path, true)) { + std::cerr << path + << ": " << _("Failed to open the file\n"); + return -1; + } + int rc = 0; + Timestamp ts; + if (Params::instance().preserve_) { + ts.read(path); + } + if (Params::instance().target_ & Params::ctThumb) { + rc = insertThumbnail(path); + } + if ( rc == 0 + && ( Params::instance().target_ & Params::ctExif + || Params::instance().target_ & Params::ctIptc + || Params::instance().target_ & Params::ctComment + || Params::instance().target_ & Params::ctXmp)) { + std::string suffix = Params::instance().suffix_; + if (suffix.empty()) suffix = ".exv"; + if (Params::instance().target_ & Params::ctXmpSidecar) suffix = ".xmp"; + std::string exvPath = newFilePath(path, suffix); + rc = metacopy(exvPath, path, Exiv2::ImageType::none, true); + } + if (0 == rc && Params::instance().target_ & Params::ctXmpSidecar) { + rc = insertXmpPacket(path); + } + if (Params::instance().preserve_) { + ts.touch(path); + } + return rc; + } + catch(const Exiv2::AnyError& e) + { + std::cerr << "Exiv2 exception in insert action for file " << path + << ":\n" << e << "\n"; + return 1; + } // Insert::run + + int Insert::insertXmpPacket(const std::string& path) const + { + std::string xmpPath = newFilePath(path, ".xmp"); + if (!Exiv2::fileExists(xmpPath, true)) { + std::cerr << xmpPath + << ": " << _("Failed to open the file\n"); + return -1; + } + if (!Exiv2::fileExists(path, true)) { + std::cerr << path + << ": " << _("Failed to open the file\n"); + return -1; + } + Exiv2::DataBuf buf = Exiv2::readFile(xmpPath); + std::string xmpPacket; + xmpPacket.assign(reinterpret_cast(buf.pData_), buf.size_); + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path); + assert(image.get() != 0); + image->readMetadata(); + image->setXmpPacket(xmpPacket); + image->writeMetadata(); + + return 0; + } + + int Insert::insertThumbnail(const std::string& path) const + { + std::string thumbPath = newFilePath(path, "-thumb.jpg"); + if (!Exiv2::fileExists(thumbPath, true)) { + std::cerr << thumbPath + << ": " << _("Failed to open the file\n"); + return -1; + } + if (!Exiv2::fileExists(path, true)) { + std::cerr << path + << ": " << _("Failed to open the file\n"); + return -1; + } + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path); + assert(image.get() != 0); + image->readMetadata(); + Exiv2::ExifThumb exifThumb(image->exifData()); + exifThumb.setJpegThumbnail(thumbPath); + image->writeMetadata(); + + return 0; + } // Insert::insertThumbnail + + Insert::AutoPtr Insert::clone() const + { + return AutoPtr(clone_()); + } + + Insert* Insert::clone_() const + { + return new Insert(*this); + } + + Modify::~Modify() + { + } + + int Modify::run(const std::string& path) + { + try { + if (!Exiv2::fileExists(path, true)) { + std::cerr << path + << ": " << _("Failed to open the file\n"); + return -1; + } + Timestamp ts; + if (Params::instance().preserve_) { + ts.read(path); + } + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path); + assert(image.get() != 0); + image->readMetadata(); + + int rc = applyCommands(image.get()); + + // Save both exif and iptc metadata + image->writeMetadata(); + + if (Params::instance().preserve_) { + ts.touch(path); + } + return rc; + } + catch(const Exiv2::AnyError& e) + { + std::cerr << "Exiv2 exception in modify action for file " << path + << ":\n" << e << "\n"; + return 1; + } + } // Modify::run + + int Modify::applyCommands(Exiv2::Image* pImage) + { + if (!Params::instance().jpegComment_.empty()) { + if (Params::instance().verbose_) { + std::cout << _("Setting JPEG comment") << " '" + << Params::instance().jpegComment_ + << "'" + << std::endl; + } + pImage->setComment(Params::instance().jpegComment_); + } + + // loop through command table and apply each command + ModifyCmds& modifyCmds = Params::instance().modifyCmds_; + ModifyCmds::const_iterator i = modifyCmds.begin(); + ModifyCmds::const_iterator end = modifyCmds.end(); + int rc = 0; + int ret = 0; + for (; i != end; ++i) { + switch (i->cmdId_) { + case add: + ret = addMetadatum(pImage, *i); + if (rc == 0) rc = ret; + break; + case set: + ret = setMetadatum(pImage, *i); + if (rc == 0) rc = ret; + break; + case del: + delMetadatum(pImage, *i); + break; + case reg: + regNamespace(*i); + break; + case invalidCmdId: + assert(invalidCmdId == i->cmdId_); + break; + } + } + return rc; + } // Modify::applyCommands + + int Modify::addMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) + { + if (Params::instance().verbose_) { + std::cout << _("Add") << " " << modifyCmd.key_ << " \"" + << modifyCmd.value_ << "\" (" + << Exiv2::TypeInfo::typeName(modifyCmd.typeId_) + << ")" << std::endl; + } + Exiv2::ExifData& exifData = pImage->exifData(); + Exiv2::IptcData& iptcData = pImage->iptcData(); + Exiv2::XmpData& xmpData = pImage->xmpData(); + Exiv2::Value::AutoPtr value = Exiv2::Value::create(modifyCmd.typeId_); + int rc = value->read(modifyCmd.value_); + if (0 == rc) { + if (modifyCmd.metadataId_ == exif) { + exifData.add(Exiv2::ExifKey(modifyCmd.key_), value.get()); + } + if (modifyCmd.metadataId_ == iptc) { + iptcData.add(Exiv2::IptcKey(modifyCmd.key_), value.get()); + } + if (modifyCmd.metadataId_ == xmp) { + xmpData.add(Exiv2::XmpKey(modifyCmd.key_), value.get()); + } + } + else { + std::cerr << _("Warning") << ": " << modifyCmd.key_ << ": " + << _("Failed to read") << " " + << Exiv2::TypeInfo::typeName(value->typeId()) + << " " << _("value") + << " \"" << modifyCmd.value_ << "\"\n"; + } + return rc; + } + + // This function looks rather complex because we try to avoid adding an + // empty metadatum if reading the value fails + int Modify::setMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) + { + if (Params::instance().verbose_) { + std::cout << _("Set") << " " << modifyCmd.key_ << " \"" + << modifyCmd.value_ << "\" (" + << Exiv2::TypeInfo::typeName(modifyCmd.typeId_) + << ")" << std::endl; + } + Exiv2::ExifData& exifData = pImage->exifData(); + Exiv2::IptcData& iptcData = pImage->iptcData(); + Exiv2::XmpData& xmpData = pImage->xmpData(); + Exiv2::Metadatum* metadatum = 0; + if (modifyCmd.metadataId_ == exif) { + Exiv2::ExifData::iterator pos = + exifData.findKey(Exiv2::ExifKey(modifyCmd.key_)); + if (pos != exifData.end()) { + metadatum = &(*pos); + } + } + if (modifyCmd.metadataId_ == iptc) { + Exiv2::IptcData::iterator pos = + iptcData.findKey(Exiv2::IptcKey(modifyCmd.key_)); + if (pos != iptcData.end()) { + metadatum = &(*pos); + } + } + if (modifyCmd.metadataId_ == xmp) { + Exiv2::XmpData::iterator pos = + xmpData.findKey(Exiv2::XmpKey(modifyCmd.key_)); + if (pos != xmpData.end()) { + metadatum = &(*pos); + } + } + // If a type was explicitly requested, use it; else + // use the current type of the metadatum, if any; + // or the default type + Exiv2::Value::AutoPtr value; + if (metadatum) { + value = metadatum->getValue(); + } + if ( value.get() == 0 + || ( modifyCmd.explicitType_ + && modifyCmd.typeId_ != value->typeId())) { + value = Exiv2::Value::create(modifyCmd.typeId_); + } + int rc = value->read(modifyCmd.value_); + if (0 == rc) { + if (metadatum) { + metadatum->setValue(value.get()); + } + else { + if (modifyCmd.metadataId_ == exif) { + exifData.add(Exiv2::ExifKey(modifyCmd.key_), value.get()); + } + if (modifyCmd.metadataId_ == iptc) { + iptcData.add(Exiv2::IptcKey(modifyCmd.key_), value.get()); + } + if (modifyCmd.metadataId_ == xmp) { + xmpData.add(Exiv2::XmpKey(modifyCmd.key_), value.get()); + } + } + } + else { + std::cerr << _("Warning") << ": " << modifyCmd.key_ << ": " + << _("Failed to read") << " " + << Exiv2::TypeInfo::typeName(value->typeId()) + << " " << _("value") + << " \"" << modifyCmd.value_ << "\"\n"; + } + return rc; + } + + void Modify::delMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) + { + if (Params::instance().verbose_) { + std::cout << _("Del") << " " << modifyCmd.key_ << std::endl; + } + + Exiv2::ExifData& exifData = pImage->exifData(); + Exiv2::IptcData& iptcData = pImage->iptcData(); + Exiv2::XmpData& xmpData = pImage->xmpData(); + if (modifyCmd.metadataId_ == exif) { + Exiv2::ExifData::iterator pos; + Exiv2::ExifKey exifKey = Exiv2::ExifKey(modifyCmd.key_); + while((pos = exifData.findKey(exifKey)) != exifData.end()) { + exifData.erase(pos); + } + } + if (modifyCmd.metadataId_ == iptc) { + Exiv2::IptcData::iterator pos; + Exiv2::IptcKey iptcKey = Exiv2::IptcKey(modifyCmd.key_); + while((pos = iptcData.findKey(iptcKey)) != iptcData.end()) { + iptcData.erase(pos); + } + } + if (modifyCmd.metadataId_ == xmp) { + Exiv2::XmpData::iterator pos; + Exiv2::XmpKey xmpKey = Exiv2::XmpKey(modifyCmd.key_); + while((pos = xmpData.findKey(xmpKey)) != xmpData.end()) { + xmpData.erase(pos); + } + } + } + + void Modify::regNamespace(const ModifyCmd& modifyCmd) + { + if (Params::instance().verbose_) { + std::cout << _("Reg ") << modifyCmd.key_ << "=\"" + << modifyCmd.value_ << "\"" << std::endl; + } + Exiv2::XmpProperties::registerNs(modifyCmd.value_, modifyCmd.key_); + } + + Modify::AutoPtr Modify::clone() const + { + return AutoPtr(clone_()); + } + + Modify* Modify::clone_() const + { + return new Modify(*this); + } + + Adjust::~Adjust() + { + } + + int Adjust::run(const std::string& path) + try { + adjustment_ = Params::instance().adjustment_; + yearAdjustment_ = Params::instance().yodAdjust_[Params::yodYear].adjustment_; + monthAdjustment_ = Params::instance().yodAdjust_[Params::yodMonth].adjustment_; + dayAdjustment_ = Params::instance().yodAdjust_[Params::yodDay].adjustment_; + + if (!Exiv2::fileExists(path, true)) { + std::cerr << path + << ": " << _("Failed to open the file\n"); + return -1; + } + Timestamp ts; + if (Params::instance().preserve_) { + ts.read(path); + } + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path); + assert(image.get() != 0); + image->readMetadata(); + Exiv2::ExifData& exifData = image->exifData(); + if (exifData.empty()) { + std::cerr << path + << ": " << _("No Exif data found in the file\n"); + return -3; + } + int rc = adjustDateTime(exifData, "Exif.Image.DateTime", path); + rc += adjustDateTime(exifData, "Exif.Photo.DateTimeOriginal", path); + rc += adjustDateTime(exifData, "Exif.Photo.DateTimeDigitized", path); + if (rc) return 1; + image->writeMetadata(); + if (Params::instance().preserve_) { + ts.touch(path); + } + return rc; + } + catch(const Exiv2::AnyError& e) + { + std::cerr << "Exiv2 exception in adjust action for file " << path + << ":\n" << e << "\n"; + return 1; + } // Adjust::run + + Adjust::AutoPtr Adjust::clone() const + { + return AutoPtr(clone_()); + } + + Adjust* Adjust::clone_() const + { + return new Adjust(*this); + } + + int Adjust::adjustDateTime(Exiv2::ExifData& exifData, + const std::string& key, + const std::string& path) const + { + Exiv2::ExifKey ek(key); + Exiv2::ExifData::iterator md = exifData.findKey(ek); + if (md == exifData.end()) { + // Key not found. That's ok, we do nothing. + return 0; + } + std::string timeStr = md->toString(); + if (timeStr == "" || timeStr[0] == ' ') { + std::cerr << path << ": " << _("Timestamp of metadatum with key") << " `" + << ek << "' " << _("not set\n"); + return 1; + } + if (Params::instance().verbose_) { + bool comma = false; + std::cout << _("Adjusting") << " `" << ek << "' " << _("by"); + if (yearAdjustment_ != 0) { + std::cout << (yearAdjustment_ < 0 ? " " : " +") << yearAdjustment_ << " "; + if (yearAdjustment_ < -1 || yearAdjustment_ > 1) { + std::cout << _("years"); + } + else { + std::cout << _("year"); + } + comma = true; + } + if (monthAdjustment_ != 0) { + if (comma) std::cout << ","; + std::cout << (monthAdjustment_ < 0 ? " " : " +") << monthAdjustment_ << " "; + if (monthAdjustment_ < -1 || monthAdjustment_ > 1) { + std::cout << _("months"); + } + else { + std::cout << _("month"); + } + comma = true; + } + if (dayAdjustment_ != 0) { + if (comma) std::cout << ","; + std::cout << (dayAdjustment_ < 0 ? " " : " +") << dayAdjustment_ << " "; + if (dayAdjustment_ < -1 || dayAdjustment_ > 1) { + std::cout << _("days"); + } + else { + std::cout << _("day"); + } + comma = true; + } + if (adjustment_ != 0) { + if (comma) std::cout << ","; + std::cout << " " << adjustment_ << _("s"); + } + } + struct tm tm; + if (str2Tm(timeStr, &tm) != 0) { + if (Params::instance().verbose_) std::cout << std::endl; + std::cerr << path << ": " << _("Failed to parse timestamp") << " `" + << timeStr << "'\n"; + return 1; + } + const long monOverflow = (tm.tm_mon + monthAdjustment_) / 12; + tm.tm_mon = (tm.tm_mon + monthAdjustment_) % 12; + tm.tm_year += yearAdjustment_ + monOverflow; + // Let's not create files with non-4-digit years, we can't read them. + if (tm.tm_year > 9999 - 1900 || tm.tm_year < 1000 - 1900) { + if (Params::instance().verbose_) std::cout << std::endl; + std::cerr << path << ": " << _("Can't adjust timestamp by") << " " + << yearAdjustment_ + monOverflow + << " " << _("years") << "\n"; + return 1; + } + time_t time = mktime(&tm); + time += adjustment_ + dayAdjustment_ * 86400; + timeStr = time2Str(time); + if (Params::instance().verbose_) { + std::cout << " " << _("to") << " " << timeStr << std::endl; + } + md->setValue(timeStr); + return 0; + } // Adjust::adjustDateTime + + FixIso::~FixIso() + { + } + + int FixIso::run(const std::string& path) + { + try { + if (!Exiv2::fileExists(path, true)) { + std::cerr << path + << ": " <<_("Failed to open the file\n"); + return -1; + } + Timestamp ts; + if (Params::instance().preserve_) { + ts.read(path); + } + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path); + assert(image.get() != 0); + image->readMetadata(); + Exiv2::ExifData& exifData = image->exifData(); + if (exifData.empty()) { + std::cerr << path + << ": " << _("No Exif data found in the file\n"); + return -3; + } + Exiv2::ExifData::const_iterator md = Exiv2::isoSpeed(exifData); + if (md != exifData.end()) { + if (strcmp(md->key().c_str(), "Exif.Photo.ISOSpeedRatings") == 0) { + if (Params::instance().verbose_) { + std::cout << _("Standard Exif ISO tag exists; not modified\n"); + } + return 0; + } + // Copy the proprietary tag to the standard place + std::ostringstream os; + md->write(os, &exifData); + if (Params::instance().verbose_) { + std::cout << _("Setting Exif ISO value to") << " " << os.str() << "\n"; + } + exifData["Exif.Photo.ISOSpeedRatings"] = os.str(); + } + image->writeMetadata(); + if (Params::instance().preserve_) { + ts.touch(path); + } + return 0; + } + catch(const Exiv2::AnyError& e) + { + std::cerr << "Exiv2 exception in fixiso action for file " << path + << ":\n" << e << "\n"; + return 1; + } + } // FixIso::run + + FixIso::AutoPtr FixIso::clone() const + { + return AutoPtr(clone_()); + } + + FixIso* FixIso::clone_() const + { + return new FixIso(*this); + } + + FixCom::~FixCom() + { + } + + int FixCom::run(const std::string& path) + { + try { + if (!Exiv2::fileExists(path, true)) { + std::cerr << path + << ": " <<_("Failed to open the file\n"); + return -1; + } + Timestamp ts; + if (Params::instance().preserve_) { + ts.read(path); + } + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path); + assert(image.get() != 0); + image->readMetadata(); + Exiv2::ExifData& exifData = image->exifData(); + if (exifData.empty()) { + std::cerr << path + << ": " << _("No Exif data found in the file\n"); + return -3; + } + Exiv2::ExifData::iterator pos = exifData.findKey(Exiv2::ExifKey("Exif.Photo.UserComment")); + if (pos == exifData.end()) { + if (Params::instance().verbose_) { + std::cout << _("No Exif user comment found") << "\n"; + } + return 0; + } + Exiv2::Value::AutoPtr v = pos->getValue(); + const Exiv2::CommentValue* pcv = dynamic_cast(v.get()); + if (!pcv) { + if (Params::instance().verbose_) { + std::cout << _("Found Exif user comment with unexpected value type") << "\n"; + } + return 0; + } + Exiv2::CommentValue::CharsetId csId = pcv->charsetId(); + if (csId != Exiv2::CommentValue::unicode) { + if (Params::instance().verbose_) { + std::cout << _("No Exif UNICODE user comment found") << "\n"; + } + return 0; + } + std::string comment = pcv->comment(Params::instance().charset_.c_str()); + if (Params::instance().verbose_) { + std::cout << _("Setting Exif UNICODE user comment to") << " \"" << comment << "\"\n"; + } + comment = std::string("charset=\"") + Exiv2::CommentValue::CharsetInfo::name(csId) + "\" " + comment; + // Remove BOM and convert value from source charset to UCS-2, but keep byte order + pos->setValue(comment); + image->writeMetadata(); + if (Params::instance().preserve_) { + ts.touch(path); + } + return 0; + } + catch(const Exiv2::AnyError& e) + { + std::cerr << "Exiv2 exception in fixcom action for file " << path + << ":\n" << e << "\n"; + return 1; + } + } // FixCom::run + + FixCom::AutoPtr FixCom::clone() const + { + return AutoPtr(clone_()); + } + + FixCom* FixCom::clone_() const + { + return new FixCom(*this); + } + +} // namespace Action + +// ***************************************************************************** +// local definitions +namespace { + + //! @cond IGNORE + int Timestamp::read(const std::string& path) + { + struct stat buf; + int rc = stat(path.c_str(), &buf); + if (0 == rc) { + actime_ = buf.st_atime; + modtime_ = buf.st_mtime; + } + return rc; + } + + int Timestamp::read(struct tm* tm) + { + int rc = 1; + time_t t = mktime(tm); // interpret tm according to current timezone settings + if (t != (time_t)-1) { + rc = 0; + actime_ = t; + modtime_ = t; + } + return rc; + } + + int Timestamp::touch(const std::string& path) + { + if (0 == actime_) return 1; + struct utimbuf buf; + buf.actime = actime_; + buf.modtime = modtime_; + return utime(path.c_str(), &buf); + } + //! @endcond + + int str2Tm(const std::string& timeStr, struct tm* tm) + { + if (timeStr.length() == 0 || timeStr[0] == ' ') return 1; + if (timeStr.length() < 19) return 2; + if ( timeStr[4] != ':' || timeStr[7] != ':' || timeStr[10] != ' ' + || timeStr[13] != ':' || timeStr[16] != ':') return 3; + if (0 == tm) return 4; + std::memset(tm, 0x0, sizeof(struct tm)); + tm->tm_isdst = -1; + + long tmp; + if (!Util::strtol(timeStr.substr(0,4).c_str(), tmp)) return 5; + tm->tm_year = tmp - 1900; + if (!Util::strtol(timeStr.substr(5,2).c_str(), tmp)) return 6; + tm->tm_mon = tmp - 1; + if (!Util::strtol(timeStr.substr(8,2).c_str(), tmp)) return 7; + tm->tm_mday = tmp; + if (!Util::strtol(timeStr.substr(11,2).c_str(), tmp)) return 8; + tm->tm_hour = tmp; + if (!Util::strtol(timeStr.substr(14,2).c_str(), tmp)) return 9; + tm->tm_min = tmp; + if (!Util::strtol(timeStr.substr(17,2).c_str(), tmp)) return 10; + tm->tm_sec = tmp; + + // Conversions to set remaining fields of the tm structure + if (mktime(tm) == (time_t)-1) return 11; + + return 0; + } // str2Tm + + std::string time2Str(time_t time) + { + struct tm* tm = localtime(&time); + return tm2Str(tm); + } // time2Str + + std::string tm2Str(const struct tm* tm) + { + if (0 == tm) return ""; + + std::ostringstream os; + os << std::setfill('0') + << tm->tm_year + 1900 << ":" + << std::setw(2) << tm->tm_mon + 1 << ":" + << std::setw(2) << tm->tm_mday << " " + << std::setw(2) << tm->tm_hour << ":" + << std::setw(2) << tm->tm_min << ":" + << std::setw(2) << tm->tm_sec; + + return os.str(); + } // tm2Str + + int metacopy(const std::string& source, + const std::string& target, + int targetType, + bool preserve) + { + if (!Exiv2::fileExists(source, true)) { + std::cerr << source + << ": " << _("Failed to open the file\n"); + return -1; + } + Exiv2::Image::AutoPtr sourceImage = Exiv2::ImageFactory::open(source); + assert(sourceImage.get() != 0); + sourceImage->readMetadata(); + + // Apply any modification commands to the source image on-the-fly + Action::Modify::applyCommands(sourceImage.get()); + + Exiv2::Image::AutoPtr targetImage; + if (Exiv2::fileExists(target)) { + targetImage = Exiv2::ImageFactory::open(target); + assert(targetImage.get() != 0); + if (preserve) targetImage->readMetadata(); + } + else { + targetImage = Exiv2::ImageFactory::create(targetType, target); + assert(targetImage.get() != 0); + } + if ( Params::instance().target_ & Params::ctExif + && !sourceImage->exifData().empty()) { + if (Params::instance().verbose_) { + std::cout << _("Writing Exif data from") << " " << source + << " " << _("to") << " " << target << std::endl; + } + targetImage->setExifData(sourceImage->exifData()); + } + if ( Params::instance().target_ & Params::ctIptc + && !sourceImage->iptcData().empty()) { + if (Params::instance().verbose_) { + std::cout << _("Writing IPTC data from") << " " << source + << " " << _("to") << " " << target << std::endl; + } + targetImage->setIptcData(sourceImage->iptcData()); + } + if ( Params::instance().target_ & Params::ctXmp + && !sourceImage->xmpData().empty()) { + if (Params::instance().verbose_) { + std::cout << _("Writing XMP data from") << " " << source + << " " << _("to") << " " << target << std::endl; + } + // Todo: Should use XMP packet if there are no XMP modification commands + targetImage->setXmpData(sourceImage->xmpData()); + } + if ( Params::instance().target_ & Params::ctComment + && !sourceImage->comment().empty()) { + if (Params::instance().verbose_) { + std::cout << _("Writing JPEG comment from") << " " << source + << " " << _("to") << " " << target << std::endl; + } + targetImage->setComment(sourceImage->comment()); + } + try { + targetImage->writeMetadata(); + } + catch (const Exiv2::AnyError& e) { + std::cerr << target << + ": " << _("Could not write metadata to file") << ": " << e << "\n"; + return 1; + } + + return 0; + } // metacopy + + // Defined outside of the function so that Exiv2::find() can see it + struct String { + const char* s_; + bool operator==(const char* s) const { + return 0 == strcmp(s_, s); + } + }; + + int renameFile(std::string& newPath, const struct tm* tm) + { + std::string path = newPath; + std::string format = Params::instance().format_; + Util::replace(format, ":basename:", Util::basename(path, true)); + Util::replace(format, ":dirname:", Util::basename(Util::dirname(path))); + Util::replace(format, ":parentname:", Util::basename(Util::dirname(Util::dirname(path)))); + + const size_t max = 1024; + char basename[max]; + std::memset(basename, 0x0, max); + if (strftime(basename, max, format.c_str(), tm) == 0) { + std::cerr << _("Filename format yields empty filename for the file") << " " + << path << "\n"; + return 1; + } + newPath = Util::dirname(path) + EXV_SEPERATOR_STR + + basename + Util::suffix(path); + if ( Util::dirname(newPath) == Util::dirname(path) + && Util::basename(newPath) == Util::basename(path)) { + if (Params::instance().verbose_) { + std::cout << _("This file already has the correct name") << std::endl; + } + return -1; + } + + bool go = true; + int seq = 1; + std::string s; + Params::FileExistsPolicy fileExistsPolicy + = Params::instance().fileExistsPolicy_; + while (go) { + if (Exiv2::fileExists(newPath)) { + switch (fileExistsPolicy) { + case Params::overwritePolicy: + go = false; + break; + case Params::renamePolicy: + newPath = Util::dirname(path) + + EXV_SEPERATOR_STR + basename + + "_" + Exiv2::toString(seq++) + + Util::suffix(path); + break; + case Params::askPolicy: + std::cout << Params::instance().progname() + << ": " << _("File") << " `" << newPath + << "' " << _("exists. [O]verwrite, [r]ename or [s]kip?") + << " "; + std::cin >> s; + switch (s[0]) { + case 'o': + case 'O': + go = false; + break; + case 'r': + case 'R': + fileExistsPolicy = Params::renamePolicy; + newPath = Util::dirname(path) + + EXV_SEPERATOR_STR + basename + + "_" + Exiv2::toString(seq++) + + Util::suffix(path); + break; + default: // skip + return -1; + break; + } + } + } + else { + go = false; + } + } + + if (Params::instance().verbose_) { + std::cout << _("Renaming file to") << " " << newPath; + if (Params::instance().timestamp_) { + std::cout << ", " << _("updating timestamp"); + } + std::cout << std::endl; + } + + // Workaround for MinGW rename which does not overwrite existing files + remove(newPath.c_str()); + if (std::rename(path.c_str(), newPath.c_str()) == -1) { + std::cerr << Params::instance().progname() + << ": " << _("Failed to rename") << " " + << path << " " << _("to") << " " << newPath << ": " + << Exiv2::strError() << "\n"; + return 1; + } + + return 0; + } // renameFile + + std::string newFilePath(const std::string& path, const std::string& ext) + { + std::string directory = Params::instance().directory_; + if (directory.empty()) directory = Util::dirname(path); + std::string newPath = directory + EXV_SEPERATOR_STR + + Util::basename(path, true) + ext; + return newPath; + } + + int dontOverwrite(const std::string& path) + { + if (!Params::instance().force_ && Exiv2::fileExists(path)) { + std::cout << Params::instance().progname() + << ": " << _("Overwrite") << " `" << path << "'? "; + std::string s; + std::cin >> s; + if (s[0] != 'y' && s[0] != 'Y') return 1; + } + return 0; + } + +} diff --git a/src/actions.hpp b/src/actions.hpp index bf0c8547..bc72a28f 100644 --- a/src/actions.hpp +++ b/src/actions.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/asfvideo.cpp b/src/asfvideo.cpp index 21db17df..6120d41f 100644 --- a/src/asfvideo.cpp +++ b/src/asfvideo.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * @@ -21,7 +21,7 @@ /* File: asfvideo.cpp Version: $Rev$ - Author(s): Abhinav Badola for GSoC 2013 (AB) + Author(s): Abhinav Badola for GSoC 2012 (AB) History: 08-Aug-12, AB: created Credits: See header file */ diff --git a/src/asfvideo.hpp b/src/asfvideo.hpp index 79515b9c..ee2fd95a 100644 --- a/src/asfvideo.hpp +++ b/src/asfvideo.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/basicio.cpp b/src/basicio.cpp index d2e42b67..0ddceeed 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/basicio.hpp b/src/basicio.hpp index d22f0de1..e3020238 100644 --- a/src/basicio.hpp +++ b/src/basicio.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/bmpimage.cpp b/src/bmpimage.cpp index 4b183780..fcff92f3 100644 --- a/src/bmpimage.cpp +++ b/src/bmpimage.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/bmpimage.hpp b/src/bmpimage.hpp index b6ce3933..f39e7aae 100644 --- a/src/bmpimage.hpp +++ b/src/bmpimage.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/canonmn.cpp b/src/canonmn.cpp index 6317301d..21f73d70 100644 --- a/src/canonmn.cpp +++ b/src/canonmn.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/canonmn_int.hpp b/src/canonmn_int.hpp index 95f6d5df..5e214a25 100644 --- a/src/canonmn_int.hpp +++ b/src/canonmn_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/convert.cpp b/src/convert.cpp index 269a573a..610620e1 100644 --- a/src/convert.cpp +++ b/src/convert.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/convert.hpp b/src/convert.hpp index 7806a04f..280c55bb 100644 --- a/src/convert.hpp +++ b/src/convert.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/cr2image.cpp b/src/cr2image.cpp index d77c55bd..23270db3 100644 --- a/src/cr2image.cpp +++ b/src/cr2image.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/cr2image.hpp b/src/cr2image.hpp index 6591042f..bf331ad2 100644 --- a/src/cr2image.hpp +++ b/src/cr2image.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/cr2image_int.hpp b/src/cr2image_int.hpp index 1f8e9c42..bad358f8 100644 --- a/src/cr2image_int.hpp +++ b/src/cr2image_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/crwimage.cpp b/src/crwimage.cpp index ee6af502..8d7d59b2 100644 --- a/src/crwimage.cpp +++ b/src/crwimage.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/crwimage.hpp b/src/crwimage.hpp index 78ac781d..62b98cc6 100644 --- a/src/crwimage.hpp +++ b/src/crwimage.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/crwimage_int.hpp b/src/crwimage_int.hpp index 346b4d53..f76e4a47 100644 --- a/src/crwimage_int.hpp +++ b/src/crwimage_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/datasets.cpp b/src/datasets.cpp index 2849f229..07232919 100644 --- a/src/datasets.cpp +++ b/src/datasets.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/datasets.hpp b/src/datasets.hpp index cbc329a7..bd52e4eb 100644 --- a/src/datasets.hpp +++ b/src/datasets.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/easyaccess.cpp b/src/easyaccess.cpp index 2a798043..a2ba138e 100644 --- a/src/easyaccess.cpp +++ b/src/easyaccess.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/easyaccess.hpp b/src/easyaccess.hpp index 1711368e..e571d71c 100644 --- a/src/easyaccess.hpp +++ b/src/easyaccess.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/epsimage.cpp b/src/epsimage.cpp index 8840f70d..4a0ca3aa 100644 --- a/src/epsimage.cpp +++ b/src/epsimage.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/epsimage.hpp b/src/epsimage.hpp index 920abc2e..ffa29c2d 100644 --- a/src/epsimage.hpp +++ b/src/epsimage.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/error.cpp b/src/error.cpp index d89fe22e..36e702d0 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/error.hpp b/src/error.hpp index b8df55d2..dbbf9d14 100644 --- a/src/error.hpp +++ b/src/error.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/exif.cpp b/src/exif.cpp index 99338ae6..dcd81f7a 100644 --- a/src/exif.cpp +++ b/src/exif.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/exif.hpp b/src/exif.hpp index afc55f31..f04aaf3d 100644 --- a/src/exif.hpp +++ b/src/exif.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/exiv2.cpp b/src/exiv2.cpp index 7ac6810a..b27c1762 100644 --- a/src/exiv2.cpp +++ b/src/exiv2.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * @@ -209,7 +209,7 @@ void Params::version(bool verbose,std::ostream& os) const bool b64 = sizeof(void*)==8; const char* sBuild = b64 ? "(64 bit build)" : "(32 bit build)" ; os << EXV_PACKAGE_STRING << " " << Exiv2::versionNumberHexString() << " " << sBuild << "\n" - << _("Copyright (C) 2004-2013 Andreas Huggel.\n") + << _("Copyright (C) 2004-2012 Andreas Huggel.\n") << "\n" << _("This program is free software; you can redistribute it and/or\n" "modify it under the terms of the GNU General Public License\n" diff --git a/src/exiv2.hpp b/src/exiv2.hpp index c41cb762..0b4d26af 100644 --- a/src/exiv2.hpp +++ b/src/exiv2.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/exiv2app.hpp b/src/exiv2app.hpp index 31ff6d55..b33c6760 100644 --- a/src/exiv2app.hpp +++ b/src/exiv2app.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/fujimn.cpp b/src/fujimn.cpp index 46cbbdff..fc0adc55 100644 --- a/src/fujimn.cpp +++ b/src/fujimn.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/fujimn_int.hpp b/src/fujimn_int.hpp index fdbad2d8..ad830af7 100644 --- a/src/fujimn_int.hpp +++ b/src/fujimn_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/futils.cpp b/src/futils.cpp index fbd718ea..03514260 100644 --- a/src/futils.cpp +++ b/src/futils.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/futils.hpp b/src/futils.hpp index 84ac9bd1..2b506a67 100644 --- a/src/futils.hpp +++ b/src/futils.hpp @@ -1,6 +1,6 @@ // ********************************************************* -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/gifimage.cpp b/src/gifimage.cpp index 3a165971..68f70aa4 100644 --- a/src/gifimage.cpp +++ b/src/gifimage.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/gifimage.hpp b/src/gifimage.hpp index dbb5f4e5..51aa0679 100644 --- a/src/gifimage.hpp +++ b/src/gifimage.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/image.cpp b/src/image.cpp index bedad72a..372d8d00 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/image.hpp b/src/image.hpp index 5f11cd73..e62f83ad 100644 --- a/src/image.hpp +++ b/src/image.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/iptc.cpp b/src/iptc.cpp index a6507ac9..8abf8c95 100644 --- a/src/iptc.cpp +++ b/src/iptc.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/iptc.hpp b/src/iptc.hpp index 131728aa..f4bc7126 100644 --- a/src/iptc.hpp +++ b/src/iptc.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/jp2image.cpp b/src/jp2image.cpp index c32e3e42..005eb716 100644 --- a/src/jp2image.cpp +++ b/src/jp2image.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/jp2image.hpp b/src/jp2image.hpp index 7f458c92..f3bf89cc 100644 --- a/src/jp2image.hpp +++ b/src/jp2image.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index e91aef63..dde0e71d 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/jpgimage.hpp b/src/jpgimage.hpp index 2e233e9f..41b6284d 100644 --- a/src/jpgimage.hpp +++ b/src/jpgimage.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/makernote.cpp b/src/makernote.cpp index 97efe36b..933d9642 100644 --- a/src/makernote.cpp +++ b/src/makernote.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/makernote_int.hpp b/src/makernote_int.hpp index ce9f2ee4..74420e32 100644 --- a/src/makernote_int.hpp +++ b/src/makernote_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/matroskavideo.cpp b/src/matroskavideo.cpp index 050c3abc..a1a69297 100644 --- a/src/matroskavideo.cpp +++ b/src/matroskavideo.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * @@ -21,7 +21,7 @@ /* File: matroskavideo.cpp Version: $Rev$ - Author(s): Abhinav Badola for GSoC 2013 (AB) + Author(s): Abhinav Badola for GSoC 2012 (AB) History: 18-Jun-12, AB: created Credits: See header file */ diff --git a/src/matroskavideo.hpp b/src/matroskavideo.hpp index a86fb0c5..1f8a4e7c 100644 --- a/src/matroskavideo.hpp +++ b/src/matroskavideo.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/metadatum.cpp b/src/metadatum.cpp index 9908621b..c30b2ba8 100644 --- a/src/metadatum.cpp +++ b/src/metadatum.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/metadatum.hpp b/src/metadatum.hpp index 255456a0..1fb90200 100644 --- a/src/metadatum.hpp +++ b/src/metadatum.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/minoltamn.cpp b/src/minoltamn.cpp index 052a38c1..ec774df1 100644 --- a/src/minoltamn.cpp +++ b/src/minoltamn.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/minoltamn_int.hpp b/src/minoltamn_int.hpp index 2cc9b517..4aba375c 100644 --- a/src/minoltamn_int.hpp +++ b/src/minoltamn_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/mrwimage.cpp b/src/mrwimage.cpp index 2d7b6067..d5166b3a 100644 --- a/src/mrwimage.cpp +++ b/src/mrwimage.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/mrwimage.hpp b/src/mrwimage.hpp index eee7599b..2fa88aca 100644 --- a/src/mrwimage.hpp +++ b/src/mrwimage.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/nikonmn.cpp b/src/nikonmn.cpp index 2f3dc974..31efeac7 100644 --- a/src/nikonmn.cpp +++ b/src/nikonmn.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * Lens database for the conversion of Nikon lens data to readable lens names * Copyright (C) 2005-2008 Robert Rottmerhusen diff --git a/src/nikonmn_int.hpp b/src/nikonmn_int.hpp index 4290fecb..f48bd8b7 100644 --- a/src/nikonmn_int.hpp +++ b/src/nikonmn_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/olympusmn.cpp b/src/olympusmn.cpp index 031dc5fd..3ed80f42 100644 --- a/src/olympusmn.cpp +++ b/src/olympusmn.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/olympusmn_int.hpp b/src/olympusmn_int.hpp index 860d4d54..568eb865 100644 --- a/src/olympusmn_int.hpp +++ b/src/olympusmn_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/orfimage.cpp b/src/orfimage.cpp index 346c30ff..41699439 100644 --- a/src/orfimage.cpp +++ b/src/orfimage.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/orfimage.hpp b/src/orfimage.hpp index 0415c434..30fe611f 100644 --- a/src/orfimage.hpp +++ b/src/orfimage.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/orfimage_int.hpp b/src/orfimage_int.hpp index 1423e725..1eb6080d 100644 --- a/src/orfimage_int.hpp +++ b/src/orfimage_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/panasonicmn.cpp b/src/panasonicmn.cpp index cbfe7bdf..50c0c5b5 100644 --- a/src/panasonicmn.cpp +++ b/src/panasonicmn.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/panasonicmn_int.hpp b/src/panasonicmn_int.hpp index 853292fb..9b9071ca 100644 --- a/src/panasonicmn_int.hpp +++ b/src/panasonicmn_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/pentaxmn.cpp b/src/pentaxmn.cpp index 0a1e67c3..b217b9f6 100644 --- a/src/pentaxmn.cpp +++ b/src/pentaxmn.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/pentaxmn_int.hpp b/src/pentaxmn_int.hpp index 2aba980a..978a6161 100644 --- a/src/pentaxmn_int.hpp +++ b/src/pentaxmn_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/pgfimage.cpp b/src/pgfimage.cpp index 47d31478..0f3053c0 100644 --- a/src/pgfimage.cpp +++ b/src/pgfimage.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/pgfimage.hpp b/src/pgfimage.hpp index 10e7335e..3ac980d8 100644 --- a/src/pgfimage.hpp +++ b/src/pgfimage.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/pngchunk.cpp b/src/pngchunk.cpp index c382f739..8e0cc55f 100644 --- a/src/pngchunk.cpp +++ b/src/pngchunk.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/pngchunk_int.hpp b/src/pngchunk_int.hpp index a7945e8c..c2d997f6 100644 --- a/src/pngchunk_int.hpp +++ b/src/pngchunk_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/pngimage.cpp b/src/pngimage.cpp index 3dc437e4..133d205b 100644 --- a/src/pngimage.cpp +++ b/src/pngimage.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/pngimage.hpp b/src/pngimage.hpp index 5100e39e..056debb8 100644 --- a/src/pngimage.hpp +++ b/src/pngimage.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/preview.cpp b/src/preview.cpp index 2bcba3ed..8664c1fa 100644 --- a/src/preview.cpp +++ b/src/preview.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/preview.hpp b/src/preview.hpp index 25140001..fa5148fb 100644 --- a/src/preview.hpp +++ b/src/preview.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/properties.cpp b/src/properties.cpp index 330467d5..b2a6e43a 100644 --- a/src/properties.cpp +++ b/src/properties.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/properties.hpp b/src/properties.hpp index b56a65dc..5aeb2674 100644 --- a/src/properties.hpp +++ b/src/properties.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/psdimage.cpp b/src/psdimage.cpp index d92d3869..4292db0c 100644 --- a/src/psdimage.cpp +++ b/src/psdimage.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/psdimage.hpp b/src/psdimage.hpp index b592af65..dcade461 100644 --- a/src/psdimage.hpp +++ b/src/psdimage.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/quicktimevideo.cpp b/src/quicktimevideo.cpp index 7c512876..866ca466 100644 --- a/src/quicktimevideo.cpp +++ b/src/quicktimevideo.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * @@ -21,7 +21,7 @@ /* File: quicktimevideo.cpp Version: $Rev$ - Author(s): Abhinav Badola for GSoC 2013 (AB) + Author(s): Abhinav Badola for GSoC 2012 (AB) History: 28-Jun-12, AB: created Credits: See header file */ diff --git a/src/quicktimevideo.hpp b/src/quicktimevideo.hpp index 9a8b1d47..ea89fa2e 100644 --- a/src/quicktimevideo.hpp +++ b/src/quicktimevideo.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/rafimage.cpp b/src/rafimage.cpp index 959d9624..e2e77d56 100644 --- a/src/rafimage.cpp +++ b/src/rafimage.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/rafimage.hpp b/src/rafimage.hpp index da100c28..94b57a5d 100644 --- a/src/rafimage.hpp +++ b/src/rafimage.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/rcsid_int.hpp b/src/rcsid_int.hpp index 12fff6df..973f3f5b 100644 --- a/src/rcsid_int.hpp +++ b/src/rcsid_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/riffvideo.cpp b/src/riffvideo.cpp index 722ecdb7..9c5aff90 100644 --- a/src/riffvideo.cpp +++ b/src/riffvideo.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * @@ -21,7 +21,7 @@ /* File: riffvideo.cpp Version: $Rev$ - Author(s): Abhinav Badola for GSoC 2013 (AB) + Author(s): Abhinav Badola for GSoC 2012 (AB) History: 18-Jun-12, AB: created Credits: See header file */ diff --git a/src/riffvideo.hpp b/src/riffvideo.hpp index 785d27ce..65f03e01 100644 --- a/src/riffvideo.hpp +++ b/src/riffvideo.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/rw2image.cpp b/src/rw2image.cpp index ccc4cacb..ee15a332 100644 --- a/src/rw2image.cpp +++ b/src/rw2image.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/rw2image.hpp b/src/rw2image.hpp index 790c98c5..565bb215 100644 --- a/src/rw2image.hpp +++ b/src/rw2image.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/rw2image_int.hpp b/src/rw2image_int.hpp index 62aa1a04..7e7d9c70 100644 --- a/src/rw2image_int.hpp +++ b/src/rw2image_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/samsungmn.cpp b/src/samsungmn.cpp index 4596ab4f..6ccef637 100644 --- a/src/samsungmn.cpp +++ b/src/samsungmn.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/samsungmn_int.hpp b/src/samsungmn_int.hpp index 882013d6..f79792b6 100644 --- a/src/samsungmn_int.hpp +++ b/src/samsungmn_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/sigmamn.cpp b/src/sigmamn.cpp index add07df8..00f0d746 100644 --- a/src/sigmamn.cpp +++ b/src/sigmamn.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/sigmamn_int.hpp b/src/sigmamn_int.hpp index d68121ed..1285deb3 100644 --- a/src/sigmamn_int.hpp +++ b/src/sigmamn_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/sonymn.cpp b/src/sonymn.cpp index 3d34f016..7e0ce7bc 100644 --- a/src/sonymn.cpp +++ b/src/sonymn.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/sonymn_int.hpp b/src/sonymn_int.hpp index be6d1270..082f4fa8 100644 --- a/src/sonymn_int.hpp +++ b/src/sonymn_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/tags.cpp b/src/tags.cpp index ebe4ffde..20de82c1 100644 --- a/src/tags.cpp +++ b/src/tags.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/tags.hpp b/src/tags.hpp index 61c9989e..8c2cb125 100644 --- a/src/tags.hpp +++ b/src/tags.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/tags_int.hpp b/src/tags_int.hpp index 5ac2db90..07d87d0d 100644 --- a/src/tags_int.hpp +++ b/src/tags_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/tgaimage.cpp b/src/tgaimage.cpp index 99108b00..6f395f37 100644 --- a/src/tgaimage.cpp +++ b/src/tgaimage.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/tgaimage.hpp b/src/tgaimage.hpp index 4b1b4faf..2c4482ed 100644 --- a/src/tgaimage.hpp +++ b/src/tgaimage.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/tiffcomposite.cpp b/src/tiffcomposite.cpp index 386bb219..9dceb576 100644 --- a/src/tiffcomposite.cpp +++ b/src/tiffcomposite.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/tiffcomposite_int.hpp b/src/tiffcomposite_int.hpp index 13fad975..68991783 100644 --- a/src/tiffcomposite_int.hpp +++ b/src/tiffcomposite_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/tifffwd_int.hpp b/src/tifffwd_int.hpp index 8d3f77db..a2cd899b 100644 --- a/src/tifffwd_int.hpp +++ b/src/tifffwd_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp index e712d598..52742621 100644 --- a/src/tiffimage.cpp +++ b/src/tiffimage.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/tiffimage.hpp b/src/tiffimage.hpp index fce0cea3..6df313ee 100644 --- a/src/tiffimage.hpp +++ b/src/tiffimage.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/tiffimage_int.hpp b/src/tiffimage_int.hpp index 7ddbc3eb..a3d477f8 100644 --- a/src/tiffimage_int.hpp +++ b/src/tiffimage_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/tiffvisitor.cpp b/src/tiffvisitor.cpp index a9e92612..ad20b5fc 100644 --- a/src/tiffvisitor.cpp +++ b/src/tiffvisitor.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/tiffvisitor_int.hpp b/src/tiffvisitor_int.hpp index bda1af67..360f8eed 100644 --- a/src/tiffvisitor_int.hpp +++ b/src/tiffvisitor_int.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/types.cpp b/src/types.cpp index 6b77e8f9..40c78296 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/types.hpp b/src/types.hpp index 55f03777..9a5abad7 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/utils.cpp b/src/utils.cpp index 7c8a87cb..b576f999 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/utils.hpp b/src/utils.hpp index 5b2765ef..3e0dd2ea 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -1,6 +1,6 @@ // ********************************************************* -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/value.cpp b/src/value.cpp index f4bf86d2..d75a528d 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/value.hpp b/src/value.hpp index 7314e8e3..edbbaeb0 100644 --- a/src/value.hpp +++ b/src/value.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * @@ -1062,3 +1062,673 @@ namespace Exiv2 { @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 EXIV2API TimeValue : public Value { + public: + //! Shortcut for a %TimeValue auto pointer. + typedef std::auto_ptr AutoPtr; + + //! @name Creators + //@{ + //! Default constructor. + TimeValue(); + //! 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 + { + Time() : hour(0), minute(0), second(0), tzHour(0), tzMinute(0) {} + + 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 + //@{ + /*! + @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. + + @return 0 if successful
+ 1 in case of an unsupported time format + */ + virtual int 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. + + @return 0 if successful
+ 1 in case of an unsupported time format + */ + virtual int 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; + virtual long count() const; + virtual long size() const; + virtual std::ostream& write(std::ostream& os) const; + //! Returns number of seconds in the day in UTC. + virtual long toLong(long n =0) const; + //! Returns number of seconds in the day in UTC converted to float. + virtual float toFloat(long n =0) const; + //! Returns number of seconds in the day in UTC converted to Rational. + virtual Rational toRational(long n =0) const; + //@} + + private: + //! @name Manipulators + //@{ + /*! + @brief Set time from \em buf if it conforms to \em format + (3 input items). + + This function only sets the hour, minute and second parts of time_. + + @param buf A 0 terminated C-string containing the time to parse. + @param format Format string for sscanf(). + @return 0 if successful, else 1. + */ + EXV_DLLLOCAL int scanTime3(const char* buf, const char* format); + /*! + @brief Set time from \em buf if it conforms to \em format + (6 input items). + + This function sets all parts of time_. + + @param buf A 0 terminated C-string containing the time to parse. + @param format Format string for sscanf(). + @return 0 if successful, else 1. + */ + EXV_DLLLOCAL int scanTime6(const char* buf, const char* format); + //@} + + //! @name Accessors + //@{ + //! Internal virtual copy constructor. + EXV_DLLLOCAL virtual TimeValue* clone_() const; + //@} + + // DATA + Time time_; + + }; // class TimeValue + + //! Template to determine the TypeId for a type T + template TypeId getType(); + + //! Specialization for an unsigned short + template<> inline TypeId getType() { return unsignedShort; } + //! Specialization for an unsigned long + template<> inline TypeId getType() { return unsignedLong; } + //! Specialization for an unsigned rational + template<> inline TypeId getType() { return unsignedRational; } + //! Specialization for a signed short + template<> inline TypeId getType() { return signedShort; } + //! Specialization for a signed long + template<> inline TypeId getType() { return signedLong; } + //! Specialization for a signed rational + template<> inline TypeId getType() { return signedRational; } + //! Specialization for a float + template<> inline TypeId getType() { return tiffFloat; } + //! Specialization for a double + template<> inline TypeId getType() { return tiffDouble; } + + // No default implementation: let the compiler/linker complain + // template 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 + class ValueType : public Value { + public: + //! Shortcut for a %ValueType\ auto pointer. + typedef std::auto_ptr > AutoPtr; + + //! @name Creators + //@{ + //! Default Constructor. + ValueType(); + //! Constructor. + // The default c'tor and this one can be combined, but that causes MSVC 7.1 to fall on its nose + explicit ValueType(TypeId typeId); + //! Constructor. + ValueType(const byte* buf, long len, ByteOrder byteOrder, TypeId typeId =getType()); + //! Constructor. + explicit ValueType(const T& val, TypeId typeId =getType()); + //! Copy constructor + ValueType(const ValueType& rhs); + //! Virtual destructor. + virtual ~ValueType(); + //@} + + //! @name Manipulators + //@{ + //! Assignment operator. + ValueType& operator=(const ValueType& rhs); + virtual int 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 int 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; + virtual long size() const; + virtual std::ostream& write(std::ostream& os) const; + /*! + @brief Return the n-th component of the value as a string. + The behaviour of this method may be undefined if there is no + n-th + component. + */ + virtual std::string toString(long n) 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; + /*! + @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 ValueList; + //! Iterator type defined for convenience. + typedef typename std::vector::iterator iterator; + //! Const iterator type defined for convenience. + typedef typename std::vector::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* 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 UShortValue; + //! Unsigned long value type + typedef ValueType ULongValue; + //! Unsigned rational value type + typedef ValueType URationalValue; + //! Signed short value type + typedef ValueType ShortValue; + //! Signed long value type + typedef ValueType LongValue; + //! Signed rational value type + typedef ValueType RationalValue; + //! Float value type + typedef ValueType FloatValue; + //! Double value type + typedef ValueType DoubleValue; + +// ***************************************************************************** +// free functions, 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 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); + } + // Specialization for a 4 byte float value. + template<> + inline float getValue(const byte* buf, ByteOrder byteOrder) + { + return getFloat(buf, byteOrder); + } + // Specialization for a 8 byte double value. + template<> + inline double getValue(const byte* buf, ByteOrder byteOrder) + { + return getDouble(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 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); + } + /*! + @brief Specialization to write a float to the data buffer. + Return the number of bytes written. + */ + template<> + inline long toData(byte* buf, float t, ByteOrder byteOrder) + { + return f2Data(buf, t, byteOrder); + } + /*! + @brief Specialization to write a double to the data buffer. + Return the number of bytes written. + */ + template<> + inline long toData(byte* buf, double t, ByteOrder byteOrder) + { + return d2Data(buf, t, byteOrder); + } + + template + ValueType::ValueType() + : Value(getType()), pDataArea_(0), sizeDataArea_(0) + { + } + + template + ValueType::ValueType(TypeId typeId) + : Value(typeId), pDataArea_(0), sizeDataArea_(0) + { + } + + template + ValueType::ValueType(const byte* buf, long len, ByteOrder byteOrder, TypeId typeId) + : Value(typeId), pDataArea_(0), sizeDataArea_(0) + { + read(buf, len, byteOrder); + } + + template + ValueType::ValueType(const T& val, TypeId typeId) + : Value(typeId), pDataArea_(0), sizeDataArea_(0) + { + value_.push_back(val); + } + + template + ValueType::ValueType(const ValueType& rhs) + : Value(rhs), value_(rhs.value_), pDataArea_(0), sizeDataArea_(0) + { + if (rhs.sizeDataArea_ > 0) { + pDataArea_ = new byte[rhs.sizeDataArea_]; + std::memcpy(pDataArea_, rhs.pDataArea_, rhs.sizeDataArea_); + sizeDataArea_ = rhs.sizeDataArea_; + } + } + + template + ValueType::~ValueType() + { + delete[] pDataArea_; + } + + template + ValueType& ValueType::operator=(const ValueType& rhs) + { + if (this == &rhs) return *this; + Value::operator=(rhs); + value_ = rhs.value_; + + byte* tmp = 0; + if (rhs.sizeDataArea_ > 0) { + tmp = new byte[rhs.sizeDataArea_]; + std::memcpy(tmp, rhs.pDataArea_, rhs.sizeDataArea_); + } + delete[] pDataArea_; + pDataArea_ = tmp; + sizeDataArea_ = rhs.sizeDataArea_; + + return *this; + } + + template + int ValueType::read(const byte* buf, long len, ByteOrder byteOrder) + { + value_.clear(); + long ts = TypeInfo::typeSize(typeId()); + if (len % ts != 0) len = (len / ts) * ts; + for (long i = 0; i < len; i += ts) { + value_.push_back(getValue(buf + i, byteOrder)); + } + return 0; + } + + template + int ValueType::read(const std::string& buf) + { + std::istringstream is(buf); + T tmp; + ValueList val; + while (!(is.eof())) { + is >> tmp; + if (is.fail()) return 1; + val.push_back(tmp); + } + value_.swap(val); + return 0; + } + + template + long ValueType::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 + long ValueType::count() const + { + return static_cast(value_.size()); + } + + template + long ValueType::size() const + { + return static_cast(TypeInfo::typeSize(typeId()) * value_.size()); + } + + template + ValueType* ValueType::clone_() const + { + return new ValueType(*this); + } + + template + std::ostream& ValueType::write(std::ostream& os) const + { + typename ValueList::const_iterator end = value_.end(); + typename ValueList::const_iterator i = value_.begin(); + while (i != end) { + os << std::setprecision(15) << *i; + if (++i != end) os << " "; + } + return os; + } + + template + std::string ValueType::toString(long n) const + { + ok_ = true; + return Exiv2::toString(value_[n]); + } + + // Default implementation + template + long ValueType::toLong(long n) const + { + ok_ = true; + return static_cast(value_[n]); + } + // Specialization for rational + template<> + inline long ValueType::toLong(long n) const + { + ok_ = (value_[n].second != 0); + if (!ok_) return 0; + return value_[n].first / value_[n].second; + } + // Specialization for unsigned rational + template<> + inline long ValueType::toLong(long n) const + { + ok_ = (value_[n].second != 0); + if (!ok_) return 0; + return value_[n].first / value_[n].second; + } + // Default implementation + template + float ValueType::toFloat(long n) const + { + ok_ = true; + return static_cast(value_[n]); + } + // Specialization for rational + template<> + inline float ValueType::toFloat(long n) const + { + ok_ = (value_[n].second != 0); + if (!ok_) return 0.0f; + return static_cast(value_[n].first) / value_[n].second; + } + // Specialization for unsigned rational + template<> + inline float ValueType::toFloat(long n) const + { + ok_ = (value_[n].second != 0); + if (!ok_) return 0.0f; + return static_cast(value_[n].first) / value_[n].second; + } + // Default implementation + template + Rational ValueType::toRational(long n) const + { + ok_ = true; + return Rational(value_[n], 1); + } + // Specialization for rational + template<> + inline Rational ValueType::toRational(long n) const + { + ok_ = true; + return Rational(value_[n].first, value_[n].second); + } + // Specialization for unsigned rational + template<> + inline Rational ValueType::toRational(long n) const + { + ok_ = true; + return Rational(value_[n].first, value_[n].second); + } + // Specialization for float. + template<> + inline Rational ValueType::toRational(long n) const + { + ok_ = true; + // Warning: This is a very simple conversion, see floatToRationalCast() + return floatToRationalCast(value_[n]); + } + // Specialization for double. + template<> + inline Rational ValueType::toRational(long n) const + { + ok_ = true; + // Warning: This is a very simple conversion, see floatToRationalCast() + return floatToRationalCast(static_cast(value_[n])); + } + + template + long ValueType::sizeDataArea() const + { + return sizeDataArea_; + } + + template + DataBuf ValueType::dataArea() const + { + return DataBuf(pDataArea_, sizeDataArea_); + } + + template + int ValueType::setDataArea(const byte* buf, long len) + { + byte* tmp = 0; + if (len > 0) { + tmp = new byte[len]; + std::memcpy(tmp, buf, len); + } + delete[] pDataArea_; + pDataArea_ = tmp; + sizeDataArea_ = len; + return 0; + } +} // namespace Exiv2 + +#endif // #ifndef VALUE_HPP_ diff --git a/src/version.cpp b/src/version.cpp index 88298900..6883b394 100644 --- a/src/version.cpp +++ b/src/version.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/version.hpp b/src/version.hpp index 06d15922..e2cbdbcd 100644 --- a/src/version.hpp +++ b/src/version.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/xmp.cpp b/src/xmp.cpp index 16b95312..cea47536 100644 --- a/src/xmp.cpp +++ b/src/xmp.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/xmp.hpp b/src/xmp.hpp index bb86b94e..782eb216 100644 --- a/src/xmp.hpp +++ b/src/xmp.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/xmpsidecar.cpp b/src/xmpsidecar.cpp index e51b82f4..b214a510 100644 --- a/src/xmpsidecar.cpp +++ b/src/xmpsidecar.cpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. * diff --git a/src/xmpsidecar.hpp b/src/xmpsidecar.hpp index b54c3a6f..539e825f 100644 --- a/src/xmpsidecar.hpp +++ b/src/xmpsidecar.hpp @@ -1,6 +1,6 @@ // ***************************************************************** -*- C++ -*- /* - * Copyright (C) 2004-2013 Andreas Huggel + * Copyright (C) 2004-2012 Andreas Huggel * * This program is part of the Exiv2 distribution. *