diff --git a/src/actions.cpp b/src/actions.cpp index 2cf2f01c..75a0a845 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -113,12 +113,15 @@ namespace { @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); /*! @@ -1022,13 +1025,15 @@ namespace Action { rc = writeThumbnail(); } if (Params::instance().target_ & Params::ctXmpSidecar) { - rc = writeXmpSidecar(); + std::string xmpPath = newFilePath(path_, ".xmp"); + if (dontOverwrite(xmpPath)) return 0; + rc = metacopy(path_, xmpPath, Exiv2::ImageType::xmp, false); } if ( !(Params::instance().target_ & Params::ctXmpSidecar) && !(Params::instance().target_ & Params::ctThumb)) { std::string exvPath = newFilePath(path_, ".exv"); if (dontOverwrite(exvPath)) return 0; - rc = metacopy(path_, exvPath, false); + rc = metacopy(path_, exvPath, Exiv2::ImageType::exv, false); } return rc; } @@ -1039,43 +1044,6 @@ namespace Action { return 1; } // Extract::run - int Extract::writeXmpSidecar() 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(); - - std::string sidecarPath = newFilePath(path_, ".xmp"); - if (dontOverwrite(sidecarPath)) return 0; - - // Apply any modification commands to the source image on-the-fly - Action::Modify::applyCommands(image.get()); - - Exiv2::Image::AutoPtr xmpSidecar = - Exiv2::ImageFactory::create(Exiv2::ImageType::xmp, sidecarPath); - assert(xmpSidecar.get() != 0); - if (Params::instance().verbose_) { - std::cout << _("Writing XMP sidecar file ") << " " - << sidecarPath << std::endl; - } - if (Params::instance().target_ & Params::ctExif) { - xmpSidecar->setExifData(image->exifData()); - } - if (Params::instance().target_ & Params::ctIptc) { - xmpSidecar->setIptcData(image->iptcData()); - } - if (Params::instance().target_ & Params::ctXmp) { - xmpSidecar->setXmpData(image->xmpData()); - } - xmpSidecar->writeMetadata(); - return 0; - } // Extract::writeXmpSidecar - int Extract::writeThumbnail() const { if (!Exiv2::fileExists(path_, true)) { @@ -1148,8 +1116,9 @@ namespace Action { || 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, true); + rc = metacopy(exvPath, path, Exiv2::ImageType::none, true); } if (0 == rc && Params::instance().target_ & Params::ctXmpSidecar) { rc = insertXmpPacket(path); @@ -1751,6 +1720,7 @@ namespace { int metacopy(const std::string& source, const std::string& target, + int targetType, bool preserve) { if (!Exiv2::fileExists(source, true)) { @@ -1772,8 +1742,7 @@ namespace { if (preserve) targetImage->readMetadata(); } else { - targetImage - = Exiv2::ImageFactory::create(Exiv2::ImageType::exv, target); + targetImage = Exiv2::ImageFactory::create(targetType, target); assert(targetImage.get() != 0); } if ( Params::instance().target_ & Params::ctExif diff --git a/src/actions.hpp b/src/actions.hpp index c2e6e89c..747a2b49 100644 --- a/src/actions.hpp +++ b/src/actions.hpp @@ -278,8 +278,6 @@ namespace Action { on the format of the Exif thumbnail image. */ int writeThumbnail() const; - //! Write an XMP sidecar file. - int writeXmpSidecar() const; private: virtual Extract* clone_() const; diff --git a/src/exiv2.1 b/src/exiv2.1 index 0e7e1e4f..cb725ed4 100644 --- a/src/exiv2.1 +++ b/src/exiv2.1 @@ -3,7 +3,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH EXIV2 1 "December 23rd, 2007" +.TH EXIV2 1 "May 22nd, 2008" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -43,15 +43,16 @@ Print image metadata. This is the default action, i.e., the command \fIexiv2 image.jpg\fP will print a summary of the image Exif metadata. .TP .B ex | extract -Extract metadata to *.exv, *.xmp and thumbnail image files. +Extract metadata to *.exv, XMP sidecar (*.xmp) and thumbnail image files. Modification commands can be applied on-the-fly. .TP .B in | insert -Insert metadata from corresponding *.exv, *.xmp and thumbnail files. -Use option \fB\-S\fP \fI.suf\fP to change the suffix of the input -files. Since files of any supported format can be used as input files, -this command can be used to copy the metadata between files of -different formats. Modification commands can be applied on-the-fly. +Insert metadata from corresponding *.exv, XMP sidecar (*.xmp) and +thumbnail files. Use option \fB\-S\fP \fI.suf\fP to change the suffix +of the input files. Since files of any supported format can be used as +input files, this command can be used to copy the metadata between +files of different formats. Modification commands can be applied +on-the-fly. .TP .B rm | delete Delete image metadata from the files. @@ -195,18 +196,24 @@ c : JPEG comment .TP .B \-i \fItgt\fP Insert target(s) for the 'insert' action. Possible targets are the -same as those for the \fB\-d\fP option, plus: +same as those for the \fB\-d\fP option, plus a modifier: .br -X : Insert XMP packet from .xmp +X : Insert metadata from an XMP sidecar file .xmp. The remaining +insert targets determine what metadata to insert from the sidecar +file. Possible are Exif, IPTC and XMP and the default is all of +these. Note that the inserted XMP properties include those converted +to Exif and IPTC. .br Only JPEG thumbnails can be inserted (not TIFF thumbnails), they need to be named \fIfile\fP\-thumb.jpg. .TP .B \-e \fItgt\fP Extract target(s) for the 'extract' action. Possible targets are the same -as those for the \fB\-d\fP option, plus: +as those for the \fB\-d\fP option, plus a modifier: .br -X : Extract XMP packet to .xmp +X : Extract metadata to an XMP sidecar file .xmp. The remaining +extract targets determine what metadata to extract to the sidecar +file. Possible are Exif, IPTC and XMP and the default is all of these. .TP .B \-r \fIfmt\fP Filename format for the 'rename' action. The format string follows @@ -348,9 +355,6 @@ Renames img_1234.jpg (taken on 13\-Nov\-05 at 22:58:31) to 20051113_225831.jpg exiv2 -r':basename:_%Y%m' rename img_1234.jpg Renames img_1234.jpg to img_1234_200511.jpg .TP -exiv2 ex img1.jpg img2.jpg -Extracts metadata from the two files into files img1.exv and img2.exv. -.TP exiv2 \-et img1.jpg img2.jpg Extracts the Exif thumbnails from the two files into img1\-thumb.jpg and img2\-thumb.jpg. @@ -359,6 +363,17 @@ exiv2 \-it img1.jpg img2.jpg Inserts (copies) metadata from img1.exv to img1.jpg and from img2.exv to img2.jpg. .TP +exiv2 \-eiX image.jpg +Extracts IPTC datasets into an XMP sidecar file image.xmp and in the +process converts them to "IPTC Core" XMP schema. +.TP +exiv2 \-iixX image.jpg +Inserts IPTC and XMP metadata from an XMP sidecar file image.xmp into +image.jpg. The resulting IPTC datasets are converted from the "IPTC +Core" XMP schema properties in the sidecar file to the older IPTC IIM4 +format. The inserted XMP properties include those in the "IPTC Core" +XMP schema. +.TP .nf exiv2 \-M"set Exif.Photo.UserComment charset=Ascii New Exif comment" image.jpg .fi diff --git a/src/exiv2.cpp b/src/exiv2.cpp index 4d5895a6..7d64a8bb 100644 --- a/src/exiv2.cpp +++ b/src/exiv2.cpp @@ -277,13 +277,13 @@ void Params::help(std::ostream& os) const << _(" x : XMP packet\n") << _(" c : JPEG comment\n") << _(" -i tgt Insert target(s) for the 'insert' action. Possible targets are\n" - " the same as those for the -d option, plus:\n" - " X : Insert XMP packet from .xmp\n" + " the same as those for the -d option, plus a modifier:\n" + " X : Insert metadata from an XMP sidecar file .xmp\n" " Only JPEG thumbnails can be inserted, they need to be named\n" " -thumb.jpg\n") << _(" -e tgt Extract target(s) for the 'extract' action. Possible targets\n" - " are the same as those for the -i option, plus:\n" - " X : Extract XMP packet to .xmp\n") + " are the same as those for the -d option, plus a modifier:\n" + " X : Extract metadata to an XMP sidecar file .xmp\n") << _(" -r fmt Filename format for the 'rename' action. The format string\n" " follows strftime(3). The following keywords are supported:\n") << _(" :basename: - original filename without extension\n") @@ -842,11 +842,14 @@ namespace { case 'x': target |= Params::ctXmp; break; case 'c': target |= Params::ctComment; break; case 't': target |= Params::ctThumb; break; - case 'X': target |= Params::ctXmpSidecar; // fall-through case 'a': target |= Params::ctExif | Params::ctIptc | Params::ctComment | Params::ctXmp; break; + case 'X': + target |= Params::ctXmpSidecar; + if (optarg == "X") target |= Params::ctExif | Params::ctIptc | Params::ctXmp; + break; default: std::cerr << Params::instance().progname() << ": " << _("Unrecognized ") << action << " " << _("target") << " `" << optarg[i] << "'\n"; diff --git a/src/xmpsidecar.cpp b/src/xmpsidecar.cpp index 9848df13..f8a4ebd0 100644 --- a/src/xmpsidecar.cpp +++ b/src/xmpsidecar.cpp @@ -55,7 +55,7 @@ EXIV2_RCSID("@(#) $Id$") namespace Exiv2 { const char* XmpSidecar::xmlHeader_ = "\n"; - const long XmpSidecar::xmlHdrCnt_ = 39; + const long XmpSidecar::xmlHdrCnt_ = 39; // without the trailing 0-character XmpSidecar::XmpSidecar(BasicIo::AutoPtr io, bool create) : Image(ImageType::xmp, mdXmp, io) diff --git a/test/data/exiv2-test.out b/test/data/exiv2-test.out index 4a4dad2b..87455f3e 100644 --- a/test/data/exiv2-test.out +++ b/test/data/exiv2-test.out @@ -88,13 +88,13 @@ Options: x : XMP packet c : JPEG comment -i tgt Insert target(s) for the 'insert' action. Possible targets are - the same as those for the -d option, plus: - X : Insert XMP packet from .xmp + the same as those for the -d option, plus a modifier: + X : Insert metadata from an XMP sidecar file .xmp Only JPEG thumbnails can be inserted, they need to be named -thumb.jpg -e tgt Extract target(s) for the 'extract' action. Possible targets - are the same as those for the -i option, plus: - X : Extract XMP packet to .xmp + are the same as those for the -d option, plus a modifier: + X : Extract metadata to an XMP sidecar file .xmp -r fmt Filename format for the 'rename' action. The format string follows strftime(3). The following keywords are supported: :basename: - original filename without extension