From ceeff042fcdb91d39870e9aa8d7222522c13771c Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Tue, 29 Jan 2008 13:33:51 +0000 Subject: [PATCH] Further XMP print function updates (based on patch from webustany for GHOP 98). --- src/nikonmn.cpp | 2 +- src/properties.cpp | 103 ++++++++++++++++++++++++--------------------- src/tags.cpp | 86 +++++++++++++++++++++++++++---------- src/tags.hpp | 13 ++++-- src/xmp.cpp | 2 +- 5 files changed, 129 insertions(+), 77 deletions(-) diff --git a/src/nikonmn.cpp b/src/nikonmn.cpp index 355645b9..eafab48d 100644 --- a/src/nikonmn.cpp +++ b/src/nikonmn.cpp @@ -578,7 +578,7 @@ namespace Exiv2 { const TagInfo Nikon3MakerNote::tagInfo_[] = { TagInfo(0x0001, "Version", N_("Version"), N_("Nikon Makernote version"), - nikon3IfdId, makerTags, undefined, printVersion), + nikon3IfdId, makerTags, undefined, printExifVersion), TagInfo(0x0002, "ISOSpeed", N_("ISO Speed"), N_("ISO speed setting"), nikon3IfdId, makerTags, unsignedShort, print0x0002), diff --git a/src/properties.cpp b/src/properties.cpp index 28d1c5b2..e6555b0f 100644 --- a/src/properties.cpp +++ b/src/properties.cpp @@ -450,7 +450,7 @@ namespace Exiv2 { extern const TagDetails xmpExifColorSpace[] = { { 1, N_("sRGB") }, { 2, N_("Adobe RGB") }, // Not defined to Exif 2.2 spec. But used by a lot of cameras. - { 65535, N_("uncalibrated") } + { 65535, N_("Uncalibrated") } }; //! exif:ComponentsConfiguration @@ -483,8 +483,8 @@ namespace Exiv2 { { 1, N_("Average") }, { 2, N_("Center weighted average") }, { 3, N_("Spot") }, - { 4, N_("Multi spot") }, - { 5, N_("Pattern") }, + { 4, N_("Multi-spot") }, + { 5, N_("Multi-segment") }, { 6, N_("Partial") }, { 255, N_("other") } }; @@ -523,12 +523,12 @@ namespace Exiv2 { //! exif:SensingMethod extern const TagDetails xmpExifSensingMethod[] = { { 1, N_("Not defined") }, - { 2, N_("One-chip color area sensor") }, - { 3, N_("Two-chip color area sensor") }, - { 4, N_("Three-chip color area sensor") }, - { 5, N_("Color sequential area sensor") }, + { 2, N_("One-chip color area") }, + { 3, N_("Two-chip color area") }, + { 4, N_("Three-chip color area") }, + { 5, N_("Color sequential area") }, { 7, N_("Trilinear sensor") }, - { 8, N_("Color sequential linear sensor") } + { 8, N_("Color sequential linear") } }; //! exif:FileSource @@ -785,47 +785,52 @@ namespace Exiv2 { }; extern const XmpPrintInfo xmpPrintInfo[] = { - {"Xmp.crs.CropUnits", EXV_PRINT_TAG(xmpCrsCropUnits)}, - {"Xmp.exif.ColorSpace", EXV_PRINT_TAG(xmpExifColorSpace)}, - {"Xmp.exif.ComponentsConfiguration", EXV_PRINT_TAG(xmpExifComponentsConfiguration)}, - {"Xmp.exif.Contrast", EXV_PRINT_TAG(xmpExifNormalSoftHard)}, - {"Xmp.exif.CustomRendered", EXV_PRINT_TAG(xmpExifCustomRendered)}, - {"Xmp.exif.ExposureProgram", EXV_PRINT_TAG(xmpExifExposureProgram)}, - {"Xmp.exif.FileSource", EXV_PRINT_TAG(xmpExifFileSource)}, - {"Xmp.exif.FocalPlaneResolutionUnit", EXV_PRINT_TAG(xmpExifFocalPlaneResolutionUnit)}, - {"Xmp.exif.GainControl", EXV_PRINT_TAG(xmpExifGainControl)}, - {"Xmp.exif.LightSource", EXV_PRINT_TAG(xmpExifLightSource)}, - {"Xmp.exif.MeteringMode", EXV_PRINT_TAG(xmpExifMeteringMode)}, - {"Xmp.exif.Saturation", EXV_PRINT_TAG(xmpExifSaturation)}, - {"Xmp.exif.SceneCaptureType", EXV_PRINT_TAG(xmpExifSceneCaptureType)}, - {"Xmp.exif.SceneType", EXV_PRINT_TAG(xmpExifSceneType)}, - {"Xmp.exif.SensingMethod", EXV_PRINT_TAG(xmpExifSensingMethod)}, - {"Xmp.exif.Sharpness", EXV_PRINT_TAG(xmpExifNormalSoftHard)}, - {"Xmp.exif.SubjectDistanceRange", EXV_PRINT_TAG(xmpExifSubjectDistanceRange)}, - {"Xmp.exif.WhiteBalance", EXV_PRINT_TAG(xmpExifWhiteBalance)}, - {"Xmp.exif.GPSAltitudeRef", EXV_PRINT_TAG(xmpExifGPSAltitudeRef)}, - {"Xmp.exif.GPSDestBearingRef", EXV_PRINT_TAG(xmpExifGPSDirection)}, - {"Xmp.exif.GPSDestDistanceRef", EXV_PRINT_TAG(xmpExifGPSDestDistanceRef)}, - {"Xmp.exif.GPSDifferential", EXV_PRINT_TAG(xmpExifGPSDifferential)}, - {"Xmp.exif.GPSImgDirectionRef", EXV_PRINT_TAG(xmpExifGPSDirection)}, - {"Xmp.exif.GPSMeasureMode", EXV_PRINT_TAG(xmpExifGPSMeasureMode)}, - {"Xmp.exif.GPSSpeedRef", EXV_PRINT_TAG(xmpExifGPSSpeedRef)}, - {"Xmp.exif.GPSStatus", EXV_PRINT_TAG(xmpExifGPSStatus)}, - {"Xmp.exif.GPSTrackRef", EXV_PRINT_TAG(xmpExifGPSDirection)}, - {"Xmp.tiff.XResolution", printLong}, - {"Xmp.tiff.YResolution", printLong}, - {"Xmp.exif.DateTimeOriginal", printDate}, - {"Xmp.exif.GPSTimeStamp", printDate}, - {"Xmp.exif.CreateDate", printDate}, - {"Xmp.exif.ModifyDate", printDate}, - {"Xmp.exif.ApertureValue", print0x9202}, - {"Xmp.exif.FNumber", print0x9202}, - {"Xmp.exif.BrightnessValue", printLong}, - {"Xmp.exif.ExposureBiasValue", printLong}, - {"Xmp.exif.FocalLength", print0x920a}, - {"Xmp.exif.FocalPlaneXResolution", printFloat}, - {"Xmp.exif.FocalPlaneYResolution", printFloat}, - {"Xmp.exif.ShutterSpeedValue", print0x9201} + {"Xmp.crs.CropUnits", EXV_PRINT_TAG(xmpCrsCropUnits) }, + {"Xmp.exif.ApertureValue", print0x9202 }, + {"Xmp.exif.BrightnessValue", printFloat }, + {"Xmp.exif.ColorSpace", EXV_PRINT_TAG(xmpExifColorSpace) }, + {"Xmp.exif.ComponentsConfiguration", EXV_PRINT_TAG(xmpExifComponentsConfiguration) }, + {"Xmp.exif.Contrast", EXV_PRINT_TAG(xmpExifNormalSoftHard) }, + {"Xmp.exif.CreateDate", printXmpDate }, + {"Xmp.exif.CustomRendered", EXV_PRINT_TAG(xmpExifCustomRendered) }, + {"Xmp.exif.DateTimeOriginal", printXmpDate }, + {"Xmp.exif.ExifVersion", printXmpVersion }, + {"Xmp.exif.ExposureBiasValue", print0x9204 }, + {"Xmp.exif.ExposureProgram", EXV_PRINT_TAG(xmpExifExposureProgram) }, + {"Xmp.exif.FileSource", EXV_PRINT_TAG(xmpExifFileSource) }, + {"Xmp.exif.FlashpixVersion", printXmpVersion }, + {"Xmp.exif.FNumber", print0x829d }, + {"Xmp.exif.FocalLength", print0x920a }, + {"Xmp.exif.FocalPlaneResolutionUnit", EXV_PRINT_TAG(xmpExifFocalPlaneResolutionUnit) }, + {"Xmp.exif.FocalPlaneXResolution", printFloat }, + {"Xmp.exif.FocalPlaneYResolution", printFloat }, + {"Xmp.exif.GainControl", EXV_PRINT_TAG(xmpExifGainControl) }, + {"Xmp.exif.GPSAltitudeRef", EXV_PRINT_TAG(xmpExifGPSAltitudeRef) }, + {"Xmp.exif.GPSDestBearingRef", EXV_PRINT_TAG(xmpExifGPSDirection) }, + {"Xmp.exif.GPSDestDistanceRef", EXV_PRINT_TAG(xmpExifGPSDestDistanceRef) }, + {"Xmp.exif.GPSDifferential", EXV_PRINT_TAG(xmpExifGPSDifferential) }, + {"Xmp.exif.GPSImgDirectionRef", EXV_PRINT_TAG(xmpExifGPSDirection) }, + {"Xmp.exif.GPSMeasureMode", EXV_PRINT_TAG(xmpExifGPSMeasureMode) }, + {"Xmp.exif.GPSSpeedRef", EXV_PRINT_TAG(xmpExifGPSSpeedRef) }, + {"Xmp.exif.GPSStatus", EXV_PRINT_TAG(xmpExifGPSStatus) }, + {"Xmp.exif.GPSTimeStamp", printXmpDate }, + {"Xmp.exif.GPSTrackRef", EXV_PRINT_TAG(xmpExifGPSDirection) }, + {"Xmp.exif.LightSource", EXV_PRINT_TAG(xmpExifLightSource) }, + {"Xmp.exif.MeteringMode", EXV_PRINT_TAG(xmpExifMeteringMode) }, + {"Xmp.exif.ModifyDate", printXmpDate }, + {"Xmp.exif.Saturation", EXV_PRINT_TAG(xmpExifSaturation) }, + {"Xmp.exif.SceneCaptureType", EXV_PRINT_TAG(xmpExifSceneCaptureType) }, + {"Xmp.exif.SceneType", EXV_PRINT_TAG(xmpExifSceneType) }, + {"Xmp.exif.SensingMethod", EXV_PRINT_TAG(xmpExifSensingMethod) }, + {"Xmp.exif.Sharpness", EXV_PRINT_TAG(xmpExifNormalSoftHard) }, + {"Xmp.exif.ShutterSpeedValue", print0x9201 }, + {"Xmp.exif.SubjectDistanceRange", EXV_PRINT_TAG(xmpExifSubjectDistanceRange) }, + {"Xmp.exif.WhiteBalance", EXV_PRINT_TAG(xmpExifWhiteBalance) }, + {"Xmp.tiff.Orientation", print0x0112 }, + {"Xmp.tiff.ResolutionUnit", printExifUnit }, + {"Xmp.tiff.XResolution", printLong }, + {"Xmp.tiff.YCbCrPositioning", print0x0213 }, + {"Xmp.tiff.YResolution", printLong } }; XmpNsInfo::Ns::Ns(const std::string& ns) diff --git a/src/tags.cpp b/src/tags.cpp index 737f6358..3fd629ab 100644 --- a/src/tags.cpp +++ b/src/tags.cpp @@ -54,6 +54,13 @@ EXIV2_RCSID("@(#) $Id$") # include #endif +// ***************************************************************************** +// local declarations +namespace { + // Print version string from an intermediate string + std::ostream& printVersion(std::ostream& os, const std::string& str); +} + // ***************************************************************************** // class member definitions namespace Exiv2 { @@ -295,7 +302,7 @@ namespace Exiv2 { ifd0Id, recOffset, unsignedLong, printValue), TagInfo(0x0112, "Orientation", N_("Orientation"), N_("The image orientation viewed in terms of rows and columns."), - ifd0Id, imgStruct, unsignedShort, EXV_PRINT_TAG(exifOrientation)), + ifd0Id, imgStruct, unsignedShort, print0x0112), TagInfo(0x0115, "SamplesPerPixel", N_("Samples per Pixel"), N_("The number of components per pixel. Since this standard applies " "to RGB and YCbCr images, the value set for this tag is 3. " @@ -329,7 +336,7 @@ namespace Exiv2 { N_("The unit for measuring and . The same " "unit is used for both and . If " "the image resolution is unknown, 2 (inches) is designated."), - ifd0Id, imgStruct, unsignedShort, EXV_PRINT_TAG(exifUnit)), + ifd0Id, imgStruct, unsignedShort, printExifUnit), TagInfo(0x012d, "TransferFunction", N_("Transfer Function"), N_("A transfer function for the image, described in tabular style. " "Normally this tag is not necessary, since color space is " @@ -417,7 +424,7 @@ namespace Exiv2 { ", it shall follow the TIFF default regardless " "of the value in this field. It is preferable that readers " "be able to support both centered and co-sited positioning."), - ifd0Id, imgStruct, unsignedShort, EXV_PRINT_TAG(exifYCbCrPositioning)), + ifd0Id, imgStruct, unsignedShort, print0x0213), TagInfo(0x0214, "ReferenceBlackWhite", N_("Reference Black/White"), N_("The reference black point value and reference white point " "value. No defaults are given in TIFF, but the values " @@ -725,7 +732,7 @@ namespace Exiv2 { TagInfo(0x9000, "ExifVersion", N_("Exif Version"), N_("The version of this standard supported. Nonexistence of this " "field is taken to mean nonconformance to the standard."), - exifIfdId, exifVersion, undefined, printVersion), + exifIfdId, exifVersion, undefined, printExifVersion), TagInfo(0x9003, "DateTimeOriginal", N_("Date and Time (original)"), N_("The date and time when the original image data was generated. " "For a digital still camera the date and time the picture was taken are recorded."), @@ -807,7 +814,7 @@ namespace Exiv2 { exifIfdId, dateTime, asciiString, printValue), TagInfo(0xa000, "FlashpixVersion", N_("FlashPix Version"), N_("The FlashPix format version supported by a FPXR file."), - exifIfdId, exifVersion, undefined, printVersion), + exifIfdId, exifVersion, undefined, printExifVersion), TagInfo(0xa001, "ColorSpace", N_("Color Space"), N_("The color space information tag is always " "recorded as the color space specifier. Normally sRGB " @@ -868,7 +875,7 @@ namespace Exiv2 { TagInfo(0xa210, "FocalPlaneResolutionUnit", N_("Focal Plane Resolution Unit"), N_("Indicates the unit for measuring and " ". This value is the same as the ."), - exifIfdId, captureCond, unsignedShort, EXV_PRINT_TAG(exifUnit)), + exifIfdId, captureCond, unsignedShort, printExifUnit), TagInfo(0xa214, "SubjectLocation", N_("Subject Location"), N_("Indicates the location of the main subject in the scene. The " "value of this tag represents the pixel at the center of the " @@ -1165,7 +1172,7 @@ namespace Exiv2 { iopIfdId, iopTags, asciiString, printValue), TagInfo(0x0002, "InteroperabilityVersion", N_("Interoperability Version"), N_("Interoperability version"), - iopIfdId, iopTags, undefined, printVersion), + iopIfdId, iopTags, undefined, printExifVersion), TagInfo(0x1000, "RelatedImageFileFormat", N_("Related Image File Format"), N_("File format of image file"), iopIfdId, iopTags, asciiString, printValue), @@ -1760,6 +1767,11 @@ namespace Exiv2 { } // printUcs2 + std::ostream& printExifUnit(std::ostream& os, const Value& value) + { + return EXV_PRINT_TAG(exifUnit)(os, value); + } + std::ostream& print0x0000(std::ostream& os, const Value& value) { if (value.size() != 4 || value.typeId() != unsignedByte) { @@ -1816,6 +1828,16 @@ namespace Exiv2 { return os; } + std::ostream& print0x0112(std::ostream& os, const Value& value) + { + return EXV_PRINT_TAG(exifOrientation)(os, value); + } + + std::ostream& print0x0213(std::ostream& os, const Value& value) + { + return EXV_PRINT_TAG(exifYCbCrPositioning)(os, value); + } + std::ostream& print0x8298(std::ostream& os, const Value& value) { // Print the copyright information in the format Photographer, Editor @@ -1899,7 +1921,10 @@ namespace Exiv2 { std::ostream& print0x9201(std::ostream& os, const Value& value) { - URational ur = exposureTime(value.toFloat()); + Rational r = value.toRational(); + if (!value.ok() || r.second == 0) return os << "(" << value << ")"; + + URational ur = exposureTime(static_cast(r.first) / r.second); os << ur.first; if (ur.second > 1) { os << "/" << ur.second; @@ -2021,33 +2046,37 @@ namespace Exiv2 { return os; } - std::ostream& printVersion(std::ostream& os, const Value& value) + std::ostream& printExifVersion(std::ostream& os, const Value& value) { if (value.size() != 4 || value.typeId() != undefined) { return os << "(" << value << ")"; } - int i = 0; - /* Strip an eventual non significative digit */ - if (value.toLong(0) == '0') { - i++; + char s[5]; + for (int i = 0; i < 4; ++i) { + s[i] = value.toLong(i); } - for (; i < 4 ; ++i) { - os << static_cast(value.toLong(i)); - if (i == 1) { - os << '.'; - } - } - return os; + s[4] = '\0'; + + return printVersion(os, s); } - std::ostream& printDate(std::ostream& os, const Value& value) + std::ostream& printXmpVersion(std::ostream& os, const Value& value) + { + if (value.size() != 4 || value.typeId() != xmpText) { + return os << "(" << value << ")"; + } + + return printVersion(os, value.toString()); + } + + std::ostream& printXmpDate(std::ostream& os, const Value& value) { if (value.size() != 20 || value.typeId() != xmpText) { return os << "(" << value << ")"; } - - std::string stringValue = value.toString(); + + std::string stringValue = value.toString(); if (stringValue[19] == 'Z') { stringValue = stringValue.substr(0, 19); } @@ -2078,3 +2107,14 @@ namespace Exiv2 { } } // namespace Exiv2 + +namespace { + std::ostream& printVersion(std::ostream& os, const std::string& str) + { + if (str.size() != 4) { + return os << "(" << str << ")"; + } + if (str[0] != '0') os << str[0]; + return os << str[1] << "." << str[2] << str[3]; + } +} diff --git a/src/tags.hpp b/src/tags.hpp index a9a741e6..da17f291 100644 --- a/src/tags.hpp +++ b/src/tags.hpp @@ -444,13 +444,18 @@ namespace Exiv2 { std::ostream& printDegrees(std::ostream& os, const Value& value); //! Print function converting from UCS-2LE to UTF-8 std::ostream& printUcs2(std::ostream& os, const Value& value); - + //! Print function for Exif units (wrapper to be able to this also for XMP properties) + std::ostream& printExifUnit(std::ostream& os, const Value& value); //! Print GPS version std::ostream& print0x0000(std::ostream& os, const Value& value); //! Print GPS altitude std::ostream& print0x0006(std::ostream& os, const Value& value); //! Print GPS timestamp std::ostream& print0x0007(std::ostream& os, const Value& value); + //! Print orientation (wrapper to be able to this also for XMP properties) + std::ostream& print0x0112(std::ostream& os, const Value& value); + //! Print YCbCrPositioning (wrapper to be able to this also for XMP properties) + std::ostream& print0x0213(std::ostream& os, const Value& value); //! Print the copyright std::ostream& print0x8298(std::ostream& os, const Value& value); //! Print the exposure time @@ -478,9 +483,11 @@ namespace Exiv2 { //! Print 35mm equivalent focal length std::ostream& print0xa405(std::ostream& os, const Value& value); //! Print any version packed in 4 Bytes format : major major minor minor - std::ostream& printVersion(std::ostream& os, const Value& value); + std::ostream& printExifVersion(std::ostream& os, const Value& value); + //! Print any version encoded in the ASCII string majormajorminorminor + std::ostream& printXmpVersion(std::ostream& os, const Value& value); //! Print a date following the format YYYY-MM-DDTHH:MM:SSZ - std::ostream& printDate(std::ostream& os, const Value& value); + std::ostream& printXmpDate(std::ostream& os, const Value& value); //@} //! Calculate F number from an APEX aperture value diff --git a/src/xmp.cpp b/src/xmp.cpp index 3ea3e75a..6898d78b 100644 --- a/src/xmp.cpp +++ b/src/xmp.cpp @@ -397,7 +397,7 @@ namespace Exiv2 { #endif } // XmpParser::registerNs - void XmpParser::unregisterNs(const std::string& ns) + void XmpParser::unregisterNs(const std::string& /*ns*/) { #ifdef EXV_HAVE_XMP_TOOLKIT try {