You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
exiv2/src/properties.cpp

1007 lines
100 KiB
C++

// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2008 Andreas Huggel <ahuggel@gmx.net>
*
* 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: properties.cpp
Version: $Rev$
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
Gilles Caulier (cgilles) <caulier dot gilles at gmail dot com>
History: 13-July-07, ahu: created
*/
// *****************************************************************************
#include "rcsid.hpp"
EXIV2_RCSID("@(#) $Id$")
// *****************************************************************************
// included header files
#include "properties.hpp"
#include "tags.hpp"
#include "error.hpp"
#include "types.hpp"
#include "value.hpp"
#include "metadatum.hpp"
#include "i18n.h" // NLS support.
#include "xmp.hpp"
#include <iostream>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <cstdlib>
// *****************************************************************************
// class member definitions
namespace Exiv2 {
extern const XmpPropertyInfo xmpDcInfo[];
extern const XmpPropertyInfo xmpXmpInfo[];
extern const XmpPropertyInfo xmpXmpRightsInfo[];
extern const XmpPropertyInfo xmpXmpMMInfo[];
extern const XmpPropertyInfo xmpXmpBJInfo[];
extern const XmpPropertyInfo xmpXmpTPgInfo[];
extern const XmpPropertyInfo xmpXmpDMInfo[];
extern const XmpPropertyInfo xmpPdfInfo[];
extern const XmpPropertyInfo xmpPhotoshopInfo[];
extern const XmpPropertyInfo xmpCrsInfo[];
extern const XmpPropertyInfo xmpTiffInfo[];
extern const XmpPropertyInfo xmpExifInfo[];
extern const XmpPropertyInfo xmpAuxInfo[];
extern const XmpPropertyInfo xmpIptcInfo[];
extern const XmpNsInfo xmpNsInfo[] = {
// Schemas
{ "http://purl.org/dc/elements/1.1/", "dc", xmpDcInfo, N_("Dublin Core schema") },
{ "http://ns.adobe.com/xap/1.0/", "xmp", xmpXmpInfo, N_("XMP Basic schema") },
{ "http://ns.adobe.com/xap/1.0/rights/", "xmpRights", xmpXmpRightsInfo, N_("XMP Rights Management schema") },
{ "http://ns.adobe.com/xap/1.0/mm/", "xmpMM", xmpXmpMMInfo, N_("XMP Media Management schema") },
{ "http://ns.adobe.com/xap/1.0/bj/", "xmpBJ", xmpXmpBJInfo, N_("XMP Basic Job Ticket schema") },
{ "http://ns.adobe.com/xap/1.0/t/pg/", "xmpTPg", xmpXmpTPgInfo, N_("XMP Paged-Text schema") },
{ "http://ns.adobe.com/xmp/1.0/DynamicMedia/", "xmpDM", xmpXmpDMInfo, N_("XMP Dynamic Media schema") },
{ "http://ns.adobe.com/pdf/1.3/", "pdf", xmpPdfInfo, N_("Adobe PDF schema") },
{ "http://ns.adobe.com/photoshop/1.0/", "photoshop", xmpPhotoshopInfo, N_("Adobe photoshop schema") },
{ "http://ns.adobe.com/camera-raw-settings/1.0/", "crs", xmpCrsInfo, N_("Camera Raw schema") },
{ "http://ns.adobe.com/tiff/1.0/", "tiff", xmpTiffInfo, N_("Exif Schema for TIFF Properties") },
{ "http://ns.adobe.com/exif/1.0/", "exif", xmpExifInfo, N_("Exif schema for Exif-specific Properties") },
{ "http://ns.adobe.com/exif/1.0/aux/", "aux", xmpAuxInfo, N_("Exif schema for Additional Exif Properties")},
{ "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/", "iptc", xmpIptcInfo, N_("IPTC Core schema") },
// NOTE: 'Iptc4xmpCore' is just too long
// Structures
{ "http://ns.adobe.com/xap/1.0/g/", "xapG", 0, N_("Colorant structure") },
{ "http://ns.adobe.com/xap/1.0/sType/Dimensions#", "stDim", 0, N_("Dimensions structure") },
{ "http://ns.adobe.com/xap/1.0/sType/Font#", "stFnt", 0, N_("Font structure") },
{ "http://ns.adobe.com/xap/1.0/g/img/", "xapGImg", 0, N_("Thumbnail structure") },
{ "http://ns.adobe.com/xap/1.0/sType/ResourceEvent#", "stEvt", 0, N_("Resource Event structure") },
{ "http://ns.adobe.com/xap/1.0/sType/ResourceRef#", "stRef", 0, N_("ResourceRef structure") },
{ "http://ns.adobe.com/xap/1.0/sType/Version#", "stVer", 0, N_("Version structure") },
{ "http://ns.adobe.com/xap/1.0/sType/Job#", "stJob", 0, N_("Basic Job/Workflow structure") },
// Qualifiers
{ "http://ns.adobe.com/xmp/Identifier/qual/1.0/", "xmpidq", 0, N_("Qualifier for xmp:Identifier") }
};
extern const XmpPropertyInfo xmpDcInfo[] = {
{ "contributor", N_("Contributor"), "bag ProperName", xmpBag, xmpExternal, N_("Contributors to the resource (other than the authors).") },
{ "coverage", N_("Coverage"), "Text", xmpText, xmpExternal, N_("The spatial or temporal topic of the resource, the spatial applicability of the "
"resource, or the jurisdiction under which the resource is relevant.") },
{ "creator", N_("Creator"), "seq ProperName", xmpSeq, xmpExternal, N_("The authors of the resource (listed in order of precedence, if significant).") },
{ "date", N_("Date"), "seq Date", xmpSeq, xmpExternal, N_("Date(s) that something interesting happened to the resource.") },
{ "description", N_("Description"), "Lang Alt", langAlt, xmpExternal, N_("A textual description of the content of the resource. Multiple values may be "
"present for different languages.") },
{ "format", N_("Format"), "MIMEType", xmpText, xmpInternal, N_("The file format used when saving the resource. Tools and applications should set "
"this property to the save format of the data. It may include appropriate qualifiers.") },
{ "identifier", N_("Identifier"), "Text", xmpText, xmpExternal, N_("Unique identifier of the resource. Recommended best practice is to identify the "
"resource by means of a string conforming to a formal identification system.") },
{ "language", N_("Language"), "bag Locale", xmpBag, xmpInternal, N_("An unordered array specifying the languages used in the resource.") },
{ "publisher", N_("Publisher"), "bag ProperName", xmpBag, xmpExternal, N_("An entity responsible for making the resource available. Examples of a Publisher "
"include a person, an organization, or a service. Typically, the name of a Publisher "
"should be used to indicate the entity.") },
{ "relation", N_("Relation"), "bag Text", xmpBag, xmpInternal, N_("Relationships to other documents. Recommended best practice is to identify the "
"related resource by means of a string conforming to a formal identification system.") },
{ "rights", N_("Rights"), "Lang Alt", langAlt, xmpExternal, N_("Informal rights statement, selected by language. Typically, rights information "
"includes a statement about various property rights associated with the resource, "
"including intellectual property rights.") },
{ "source", N_("Source"), "Text", xmpText, xmpExternal, N_("Unique identifier of the work from which this resource was derived.") },
{ "subject", N_("Subject"), "bag Text", xmpBag, xmpExternal, N_("An unordered array of descriptive phrases or keywords that specify the topic of the "
"content of the resource.") },
{ "title", N_("Title"), "Lang Alt", langAlt, xmpExternal, N_("The title of the document, or the name given to the resource. Typically, it will be "
"a name by which the resource is formally known.") },
{ "type", N_("Type"), "bag open Choice", xmpBag, xmpExternal, N_("A document type; for example, novel, poem, or working paper.") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPropertyInfo xmpXmpInfo[] = {
{ "Advisory", N_("Advisory"), "bag XPath", xmpBag, xmpExternal, N_("An unordered array specifying properties that were edited outside the authoring "
"application. Each item should contain a single namespace and XPath separated by "
"one ASCII space (U+0020).") },
{ "BaseURL", N_("Base URL"), "URL", xmpText, xmpInternal, N_("The base URL for relative URLs in the document content. If this document contains "
"Internet links, and those links are relative, they are relative to this base URL. "
"This property provides a standard way for embedded relative URLs to be interpreted "
"by tools. Web authoring tools should set the value based on their notion of where "
"URLs will be interpreted.") },
{ "CreateDate", N_("Create Date"), "Date", xmpText, xmpInternal, N_("The date and time the resource was originally created.") },
{ "CreatorTool", N_("Creator Tool"), "AgentName", xmpText, xmpInternal, N_("The name of the first known tool used to create the resource. If history is "
"present in the metadata, this value should be equivalent to that of "
"xmpMM:History's softwareAgent property.") },
{ "Identifier", N_("Identifier"), "bag Text", xmpBag, xmpExternal, N_("An unordered array of text strings that unambiguously identify the resource within "
"a given context. An array item may be qualified with xmpidq:Scheme to denote the "
"formal identification system to which that identifier conforms. Note: The "
"dc:identifier property is not used because it lacks a defined scheme qualifier and "
"has been defined in the XMP Specification as a simple (single-valued) property.") },
{ "Label", N_("Label"), "Text", xmpText, xmpExternal, N_("A word or short phrase that identifies a document as a member of a user-defined "
"collection. Used to organize documents in a file browser.") },
{ "MetadataDate", N_("Metadata Date"), "Date", xmpText, xmpInternal, N_("The date and time that any metadata for this resource was last changed. It should "
"be the same as or more recent than xmp:ModifyDate.") },
{ "ModifyDate", N_("Modify Date"), "Date", xmpText, xmpInternal, N_("The date and time the resource was last modified. Note: The value of this property "
"is not necessarily the same as the file's system modification date because it is "
"set before the file is saved.") },
{ "Nickname", N_("Nickname"), "Text", xmpText, xmpExternal, N_("A short informal name for the resource.") },
{ "Rating", N_("Rating"), "Closed Choice of Integer", xmpText, xmpExternal, N_("A number that indicates a document's status relative to other documents, "
"used to organize documents in a file browser. Values are user-defined within an "
"application-defined range.") },
{ "Thumbnails", N_("Thumbnails"), "alt Thumbnail", undefined, xmpInternal, N_("An alternative array of thumbnail images for a file, which can differ in "
"characteristics such as size or image encoding.") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPropertyInfo xmpXmpRightsInfo[] = {
{ "Certificate", N_("Certificate"), "URL", xmpText, xmpExternal, N_("Online rights management certificate.") },
{ "Marked", N_("Marked"), "Boolean", xmpText, xmpExternal, N_("Indicates that this is a rights-managed resource.") },
{ "Owner", N_("Owner"), "bag ProperName", xmpBag, xmpExternal, N_("An unordered array specifying the legal owner(s) of a resource.") },
{ "UsageTerms", N_("Usage Terms"), "Lang Alt", langAlt, xmpExternal, N_("Text instructions on how a resource can be legally used.") },
{ "WebStatement", N_("Web Statement"), "URL", xmpText, xmpExternal, N_("The location of a web page describing the owner and/or rights statement for this resource.") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPropertyInfo xmpXmpMMInfo[] = {
{ "DerivedFrom", N_("Derived From"), "ResourceRef", xmpText, xmpInternal, N_("A reference to the original document from which this one is derived. It is a "
"minimal reference; missing components can be assumed to be unchanged. For example, "
"a new version might only need to specify the instance ID and version number of the "
"previous version, or a rendition might only need to specify the instance ID and "
"rendition class of the original.") },
{ "DocumentID", N_("Document ID"), "URI", xmpText, xmpInternal, N_("The common identifier for all versions and renditions of a document. It should be "
"based on a UUID; see Document and Instance IDs below.") },
{ "History", N_("History"), "seq ResourceEvent", xmpText, xmpInternal, N_("An ordered array of high-level user actions that resulted in this resource. It is "
"intended to give human readers a general indication of the steps taken to make the "
"changes from the previous version to this one. The list should be at an abstract "
"level; it is not intended to be an exhaustive keystroke or other detailed history.") },
{ "InstanceID", N_("Instance ID"), "URI", xmpText, xmpInternal, N_("An identifier for a specific incarnation of a document, updated each time a file "
"is saved. It should be based on a UUID; see Document and Instance IDs below.") },
{ "ManagedFrom", N_("Managed From"), "ResourceRef", xmpText, xmpInternal, N_("A reference to the document as it was prior to becoming managed. It is set when a "
"managed document is introduced to an asset management system that does not "
"currently own it. It may or may not include references to different management systems.") },
{ "Manager", N_("Manager"), "AgentName", xmpText, xmpInternal, N_("The name of the asset management system that manages this resource. Along with "
"xmpMM: ManagerVariant, it tells applications which asset management system to "
"contact concerning this document.") },
{ "ManageTo", N_("Manage To"), "URI", xmpText, xmpInternal, N_("A URI identifying the managed resource to the asset management system; the presence "
"of this property is the formal indication that this resource is managed. The form "
"and content of this URI is private to the asset management system.") },
{ "ManageUI", N_("Manage UI"), "URI", xmpText, xmpInternal, N_("A URI that can be used to access information about the managed resource through a "
"web browser. It might require a custom browser plug-in.") },
{ "ManagerVariant", N_("Manager Variant"), "Text", xmpText, xmpInternal, N_("Specifies a particular variant of the asset management system. The format of this "
"property is private to the specific asset management system.") },
{ "RenditionClass", N_("Rendition Class"), "RenditionClass", xmpText, xmpInternal, N_("The rendition class name for this resource. This property should be absent or set "
"to default for a document version that is not a derived rendition.") },
{ "RenditionParams", N_("Rendition Params"), "Text", xmpText, xmpInternal, N_("Can be used to provide additional rendition parameters that are too complex or "
"verbose to encode in xmpMM: RenditionClass.") },
{ "VersionID", N_("Version ID"), "Text", xmpText, xmpInternal, N_("The document version identifier for this resource. Each version of a document gets "
"a new identifier, usually simply by incrementing integers 1, 2, 3 . . . and so on. "
"Media management systems can have other conventions or support branching which "
"requires a more complex scheme.") },
{ "Versions", N_("Versions"), "seq Version", xmpText, xmpInternal, N_("The version history associated with this resource. Entry [1] is the oldest known "
"version for this document, entry [last()] is the most recent version. Typically, a "
"media management system would fill in the version information in the metadata on "
"check-in. It is not guaranteed that a complete history versions from the first to "
"this one will be present in the xmpMM:Versions property. Interior version information "
"can be compressed or eliminated and the version history can be truncated at some point.") },
{ "LastURL", N_("Last URL"), "URL", xmpText, xmpInternal, N_("Deprecated for privacy protection.") },
{ "RenditionOf", N_("Rendition Of"), "ResourceRef", xmpText, xmpInternal, N_("Deprecated in favor of xmpMM:DerivedFrom. A reference to the document of which this is "
"a rendition.") },
{ "SaveID", N_("Save ID"), "Integer", xmpText, xmpInternal, N_("Deprecated. Previously used only to support the xmpMM:LastURL property.") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPropertyInfo xmpXmpBJInfo[] = {
{ "JobRef", N_("Job Reference"), "bag Job", xmpText, xmpExternal, N_("References an external job management file for a job process in which the document is being used. Use of job "
"names is under user control. Typical use would be to identify all documents that are part of a particular job or contract. "
"There are multiple values because there can be more than one job using a particular document at any time, and it can "
"also be useful to keep historical information about what jobs a document was part of previously.") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPropertyInfo xmpXmpTPgInfo[] = {
{ "MaxPageSize", N_("Maximum Page Size"), "Dimensions", xmpText, xmpInternal, N_("The size of the largest page in the document (including any in contained documents).") },
{ "NPages", N_("Number of Pages"), "Integer", xmpText, xmpInternal, N_("The number of pages in the document (including any in contained documents).") },
{ "Fonts", N_("Fonts"), "bag Font", xmpText, xmpInternal, N_("An unordered array of fonts that are used in the document (including any in contained documents).") },
{ "Colorants", N_("Colorants"), "seq Colorant", xmpText, xmpInternal, N_("An ordered array of colorants (swatches) that are used in the document (including any in contained documents).") },
{ "PlateNames", N_("Plate Names"), "seq Text", xmpSeq, xmpInternal, N_("An ordered array of plate names that are needed to print the document (including any in contained documents).") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPropertyInfo xmpXmpDMInfo[] = {
{ "projectRef", N_("Project Reference"), "ProjectLink", xmpText, xmpInternal, N_("A reference to the project that created this file.") },
{ "videoFrameRate", N_("Video Frame Rate"), "open Choice of Text", xmpText, xmpInternal, N_("The video frame rate. One of: 24, NTSC, PAL.") },
{ "videoFrameSize", N_("Video Frame Size"), "Dimensions", xmpText, xmpInternal, N_("The frame size. For example: w:720, h: 480, unit:pixels") },
{ "videoPixelAspectRatio", N_("Video Pixel Aspect Ratio"), "Rational", xmpText, xmpInternal, N_("The aspect ratio, expressed as ht/wd. For example: \"648/720\" = 0.9") },
{ "videoPixelDepth", N_("Video Pixel Depth"), "closed Choice of Text", xmpText, xmpInternal, N_("The size in bits of each color component of a pixel. Standard Windows 32-bit "
"pixels have 8 bits per component. One of: 8Int, 16Int, 32Int, 32Float.") },
{ "videoColorSpace", N_("Video Color Space"), "closed Choice of Text", xmpText, xmpInternal, N_("The color space. One of: sRGB (used by Photoshop), CCIR-601 (used for NTSC), "
"CCIR-709 (used for HD).") },
{ "videoAlphaMode", N_("Video Alpha Mode"), "closed Choice of Text", xmpText, xmpExternal, N_("The alpha mode. One of: straight, pre-multiplied.") },
{ "videoAlphaPremultipleColor", N_("Video Alpha Premultiple Color"), "Colorant", xmpText, xmpExternal, N_("A color in CMYK or RGB to be used as the pre-multiple color when "
"alpha mode is pre-multiplied.") },
{ "videoAlphaUnityIsTransparent", N_("Video Alpha Unity Is Transparent"), "Boolean", xmpText, xmpInternal, N_("When true, unity is clear, when false, it is opaque.") },
{ "videoCompressor", N_("Video Compressor"), "Text", xmpText, xmpInternal, N_("Video compression used. For example, jpeg.") },
{ "videoFieldOrder", N_("Video Field Order"), "closed Choice of Text", xmpText, xmpInternal, N_("The field order for video. One of: Upper, Lower, Progressive.") },
{ "pullDown", N_("Pull Down"), "closed Choice of Text", xmpText, xmpInternal, N_("The sampling phase of film to be converted to video (pull-down). One of: "
"WSSWW, SSWWW, SWWWS, WWWSS, WWSSW, WSSWW_24p, SSWWW_24p, SWWWS_24p, WWWSS_24p, WWSSW_24p.") },
{ "audioSampleRate", N_("Audio Sample Rate"), "Integer", xmpText, xmpInternal, N_("The audio sample rate. Can be any value, but commonly 32000, 41100, or 48000.") },
{ "audioSampleType", N_("Audio Sample Type"), "closed Choice of Text", xmpText, xmpInternal, N_("The audio sample type. One of: 8Int, 16Int, 32Int, 32Float.") },
{ "audioChannelType", N_("Audio Channel Type"), "closed Choice of Text", xmpText, xmpInternal, N_("The audio channel type. One of: Mono, Stereo, 5.1, 7.1.") },
{ "audioCompressor", N_("Audio Compressor"), "Text", xmpText, xmpInternal, N_("The audio compression used. For example, MP3.") },
{ "speakerPlacement", N_("Speaker Placement"), "Text", xmpText, xmpExternal, N_("A description of the speaker angles from center front in degrees. For example: "
"\"Left = -30, Right = 30, Center = 0, LFE = 45, Left Surround = -110, Right Surround = 110\"") },
{ "fileDataRate", N_("File Data Rate"), "Rational", xmpText, xmpInternal, N_("The file data rate in megabytes per second. For example: \"36/10\" = 3.6 MB/sec") },
{ "tapeName", N_("Tape Name"), "Text", xmpText, xmpExternal, N_("The name of the tape from which the clip was captured, as set during the capture process.") },
{ "altTapeName", N_("Alternative Tape Name"), "Text", xmpText, xmpExternal, N_("An alternative tape name, set via the project window or timecode dialog in Premiere. "
"If an alternative name has been set and has not been reverted, that name is displayed.") },
{ "startTimecode", N_("Start Time Code"), "Timecode", xmpText, xmpInternal, N_("The timecode of the first frame of video in the file, as obtained from the device control.") },
{ "altTimecode", N_("Alternative Time code"), "Timecode", xmpText, xmpExternal, N_("A timecode set by the user. When specified, it is used instead of the startTimecode.") },
{ "duration", N_("Duration"), "Time", xmpText, xmpInternal, N_("The duration of the media file.") },
{ "scene", N_("Scene"), "Text", xmpText, xmpExternal, N_("The name of the scene.") },
{ "shotName", N_("Shot Name"), "Text", xmpText, xmpExternal, N_("The name of the shot or take.") },
{ "shotDate", N_("Shot Date"), "Date", xmpText, xmpExternal, N_("The date and time when the video was shot.") },
{ "shotLocation", N_("Shot Location"), "Text", xmpText, xmpExternal, N_("The name of the location where the video was shot. For example: \"Oktoberfest, Munich Germany\" "
"For more accurate positioning, use the EXIF GPS values.") },
{ "logComment", N_("Log Comment"), "Text", xmpText, xmpExternal, N_("User's log comments.") },
{ "markers", N_("Markers"), "seq Marker", xmpText, xmpInternal, N_("An ordered list of markers") },
{ "contributedMedia", N_("Contributed Media"), "bag Media", xmpText, xmpInternal, N_("An unordered list of all media used to create this media.") },
{ "absPeakAudioFilePath", N_("Absolute Peak Audio File Path"), "URI", xmpText, xmpInternal, N_("The absolute path to the file's peak audio file. If empty, no peak file exists.") },
{ "relativePeakAudioFilePath", N_("Relative Peak Audio File Path"), "URI", xmpText, xmpInternal, N_("The relative path to the file's peak audio file. If empty, no peak file exists.") },
{ "videoModDate", N_("Video Modified Date"), "Date", xmpText, xmpInternal, N_("The date and time when the video was last modified.") },
{ "audioModDate", N_("Audio Modified Date"), "Date", xmpText, xmpInternal, N_("The date and time when the audio was last modified.") },
{ "metadataModDate", N_("Metadata Modified Date"), "Date", xmpText, xmpInternal, N_("The date and time when the metadata was last modified.") },
{ "artist", N_("Artist"), "Text", xmpText, xmpExternal, N_("The name of the artist or artists.") },
{ "album", N_("Album"), "Text", xmpText, xmpExternal, N_("The name of the album.") },
{ "trackNumber", N_("Track Number"), "Integer", xmpText, xmpExternal, N_("A numeric value indicating the order of the audio file within its original recording.") },
{ "genre", N_("Genre"), "Text", xmpText, xmpExternal, N_("The name of the genre.") },
{ "copyright", N_("Copyright"), "Text", xmpText, xmpExternal, N_("The copyright information.") },
{ "releaseDate", N_("Release Date"), "Date", xmpText, xmpExternal, N_("The date the title was released.") },
{ "composer", N_("Composer"), "Text", xmpText, xmpExternal, N_("The composer's name.") },
{ "engineer", N_("Engineer"), "Text", xmpText, xmpExternal, N_("The engineer's name.") },
{ "tempo", N_("Tempo"), "Real", xmpText, xmpInternal, N_("The audio's tempo.") },
{ "instrument", N_("Instrument"), "Text", xmpText, xmpExternal, N_("The musical instrument.") },
{ "introTime", N_("Intro Time"), "Time", xmpText, xmpInternal, N_("The duration of lead time for queuing music.") },
{ "outCue", N_("Out Cue"), "Time", xmpText, xmpInternal, N_("The time at which to fade out.") },
{ "relativeTimestamp", N_("Relative Timestamp"), "Time", xmpText, xmpInternal, N_("The start time of the media inside the audio project.") },
{ "loop", N_("Loop"), "Boolean", xmpText, xmpInternal, N_("When true, the clip can be looped seemlessly.") },
{ "numberOfBeats", N_("Number Of Beats"), "Real", xmpText, xmpInternal, N_("The number of beats.") },
{ "key", N_("Key"), "closed Choice of Text", xmpText, xmpInternal, N_("The audio's musical key. One of: C, C#, D, D#, E, F, F#, G, G#, A, A#, B.") },
{ "stretchMode", N_("Stretch Mode"), "closed Choice of Text", xmpText, xmpInternal, N_("The audio stretch mode. One of: Fixed length, Time-Scale, Resample, Beat Splice, Hybrid.") },
{ "timeScaleParams", N_("Time Scale Parameters"), "timeScaleStretch", xmpText, xmpInternal, N_("Additional parameters for Time-Scale stretch mode.") },
{ "resampleParams", N_("Resample Parameters"), "resampleStretch", xmpText, xmpInternal, N_("Additional parameters for Resample stretch mode.") },
{ "beatSpliceParams", N_("Beat Splice Parameters"), "beatSpliceStretch", xmpText, xmpInternal, N_("Additional parameters for Beat Splice stretch mode.") },
{ "timeSignature", N_("Time Signature"), "closed Choice of Text", xmpText, xmpInternal, N_("The time signature of the music. One of: 2/4, 3/4, 4/4, 5/4, 7/4, 6/8, 9/8, 12/8, other.") },
{ "scaleType", N_("Scale Type"), "closed Choice of Text", xmpText, xmpInternal, N_("The musical scale used in the music. One of: Major, Minor, Both, Neither. "
"Neither is most often used for instruments with no associated scale, such as drums.") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPropertyInfo xmpPdfInfo[] = {
{ "Keywords", N_("Keywords"), "Text", xmpText, xmpExternal, N_("Keywords.") },
{ "PDFVersion", N_("PDF Version"), "Text", xmpText, xmpInternal, N_("The PDF file version (for example: 1.0, 1.3, and so on).") },
{ "Producer", N_("Producer"), "AgentName", xmpText, xmpInternal, N_("The name of the tool that created the PDF document.") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPropertyInfo xmpPhotoshopInfo[] = {
{ "AuthorsPosition", N_("Authors Position"), "Text", xmpText, xmpExternal, N_("By-line title.") },
{ "CaptionWriter", N_("Caption Writer"), "ProperName", xmpText, xmpExternal, N_("Writer/editor.") },
{ "Category", N_("Category"), "Text", xmpText, xmpExternal, N_("Category. Limited to 3 7-bit ASCII characters.") },
{ "City", N_("City"), "Text", xmpText, xmpExternal, N_("City.") },
{ "Country", N_("Country"), "Text", xmpText, xmpExternal, N_("Country/primary location.") },
{ "Credit", N_("Credit"), "Text", xmpText, xmpExternal, N_("Credit.") },
{ "DateCreated", N_("Date Created"), "Date", xmpText, xmpExternal, N_("The date the intellectual content of the document was created (rather than the creation "
"date of the physical representation), following IIM conventions. For example, a photo "
"taken during the American Civil War would have a creation date during that epoch "
"(1861-1865) rather than the date the photo was digitized for archiving.") },
{ "Headline", N_("Headline"), "Text", xmpText, xmpExternal, N_("Headline.") },
{ "Instructions", N_("Instructions"), "Text", xmpText, xmpExternal, N_("Special instructions.") },
{ "Source", N_("Source"), "Text", xmpText, xmpExternal, N_("Source.") },
{ "State", N_("State"), "Text", xmpText, xmpExternal, N_("Province/state.") },
{ "SupplementalCategories", N_("Supplemental Categories"), "bag Text", xmpBag, xmpExternal, N_("Supplemental category.") },
{ "TransmissionReference", N_("Transmission Reference"), "Text", xmpText, xmpExternal, N_("Original transmission reference.") },
{ "Urgency", N_("Urgency"), "Integer", xmpText, xmpExternal, N_("Urgency. Valid range is 1-8.") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
//! crs:CropUnits
extern const TagDetails xmpCrsCropUnits[] = {
{ 0, N_("pixels") },
{ 1, N_("inches") },
{ 2, N_("cm") }
};
extern const XmpPropertyInfo xmpCrsInfo[] = {
{ "AutoBrightness", N_("Auto Brightness"), "Boolean", xmpText, xmpExternal, N_("When true, \"Brightness\" is automatically adjusted.") },
{ "AutoContrast", N_("Auto Contrast"), "Boolean", xmpText, xmpExternal, N_("When true, \"Contrast\" is automatically adjusted.") },
{ "AutoExposure", N_("Auto Exposure"), "Boolean", xmpText, xmpExternal, N_("When true, \"Exposure\" is automatically adjusted.") },
{ "AutoShadows", N_("Auto Shadows"), "Boolean", xmpText, xmpExternal, N_("When true,\"Shadows\" is automatically adjusted.") },
{ "BlueHue", N_("Blue Hue"), "Integer", xmpText, xmpExternal, N_("\"Blue Hue\" setting. Range -100 to 100.") },
{ "BlueSaturation", N_("Blue Saturation"), "Integer", xmpText, xmpExternal, N_("\"Blue Saturation\" setting. Range -100 to +100.") },
{ "Brightness", N_("Brightness"), "Integer", xmpText, xmpExternal, N_("\"Brightness\" setting. Range 0 to +150.") },
{ "CameraProfile", N_("Camera Profile"), "Text", xmpText, xmpExternal, N_("\"Camera Profile\" setting.") },
{ "ChromaticAberrationB", N_("Chromatic Aberration Blue"), "Integer", xmpText, xmpExternal, N_("\"Chromatic Aberration, Fix Blue/Yellow Fringe\" setting. Range -100 to +100.") },
{ "ChromaticAberrationR", N_("Chromatic Aberration Red"), "Integer", xmpText, xmpExternal, N_("\"Chromatic Aberration, Fix Red/Cyan Fringe\" setting. Range -100 to +100.") },
{ "ColorNoiseReduction", N_("Color Noise Reduction"), "Integer", xmpText, xmpExternal, N_("\"Color Noise Reducton\" setting. Range 0 to +100.") },
{ "Contrast", N_("Contrast"), "Integer", xmpText, xmpExternal, N_("\"Contrast\" setting. Range -50 to +100.") },
{ "CropTop", N_("Crop Top"), "Real", xmpText, xmpExternal, N_("When \"Has Crop\" is true, top of crop rectangle") },
{ "CropLeft", N_("Crop Left"), "Real", xmpText, xmpExternal, N_("When \"Has Crop\" is true, left of crop rectangle.") },
{ "CropBottom", N_("Crop Bottom"), "Real", xmpText, xmpExternal, N_("When \"Has Crop\" is true, bottom of crop rectangle.") },
{ "CropRight", N_("Crop Right"), "Real", xmpText, xmpExternal, N_("When \"Has Crop\" is true, right of crop rectangle.") },
{ "CropAngle", N_("Crop Angle"), "Real", xmpText, xmpExternal, N_("When \"Has Crop\" is true, angle of crop rectangle.") },
{ "CropWidth", N_("Crop Width"), "Real", xmpText, xmpExternal, N_("Width of resulting cropped image in CropUnits units.") },
{ "CropHeight", N_("Crop Height"), "Real", xmpText, xmpExternal, N_("Height of resulting cropped image in CropUnits units.") },
{ "CropUnits", N_("Crop Units"), "Integer", xmpText, xmpExternal, N_("Units for CropWidth and CropHeight. 0=pixels, 1=inches, 2=cm") },
{ "Exposure", N_("Exposure"), "Real", xmpText, xmpExternal, N_("\"Exposure\" setting. Range -4.0 to +4.0.") },
{ "GreenHue", N_("GreenHue"), "Integer", xmpText, xmpExternal, N_("\"Green Hue\" setting. Range -100 to +100.") },
{ "GreenSaturation", N_("Green Saturation"), "Integer", xmpText, xmpExternal, N_("\"Green Saturation\" setting. Range -100 to +100.") },
{ "HasCrop", N_("Has Crop"), "Boolean", xmpText, xmpExternal, N_("When true, image has a cropping rectangle.") },
{ "HasSettings", N_("Has Settings"), "Boolean", xmpText, xmpExternal, N_("When true, non-default camera raw settings.") },
{ "LuminanceSmoothing", N_("Luminance Smoothing"), "Integer", xmpText, xmpExternal, N_("\"Luminance Smoothing\" setting. Range 0 to +100.") },
{ "RawFileName", N_("Raw File Name"), "Text", xmpText, xmpInternal, N_("File name of raw file (not a complete path).") },
{ "RedHue", N_("Red Hue"), "Integer", xmpText, xmpExternal, N_("\"Red Hue\" setting. Range -100 to +100.") },
{ "RedSaturation", N_("Red Saturation"), "Integer", xmpText, xmpExternal, N_("\"Red Saturation\" setting. Range -100 to +100.") },
{ "Saturation", N_("Saturation"), "Integer", xmpText, xmpExternal, N_("\"Saturation\" setting. Range -100 to +100.") },
{ "Shadows", N_("Shadows"), "Integer", xmpText, xmpExternal, N_("\"Shadows\" setting. Range 0 to +100.") },
{ "ShadowTint", N_("Shadow Tint"), "Integer", xmpText, xmpExternal, N_("\"Shadow Tint\" setting. Range -100 to +100.") },
{ "Sharpness", N_("Sharpness"), "Integer", xmpText, xmpExternal, N_("\"Sharpness\" setting. Range 0 to +100.") },
{ "Temperature", N_("Temperature"), "Integer", xmpText, xmpExternal, N_("\"Temperature\" setting. Range 2000 to 50000.") },
{ "Tint", N_("Tint"), "Integer", xmpText, xmpExternal, N_("\"Tint\" setting. Range -150 to +150.") },
{ "ToneCurve", N_("Tone Curve"), "Seq of points (Integer, Integer)", xmpText, xmpExternal, N_("Array of points (Integer, Integer) defining a \"Tone Curve\".") },
{ "ToneCurveName", N_("Tone Curve Name"), "Choice Text", xmpText, xmpInternal, N_("The name of the Tone Curve described by ToneCurve. One of: Linear, Medium Contrast, "
"Strong Contrast, Custom or a user-defined preset name.") },
{ "Version", N_("Version"), "Text", xmpText, xmpInternal, N_("Version of Camera Raw plugin.") },
{ "VignetteAmount", N_("Vignette Amount"), "Integer", xmpText, xmpExternal, N_("\"Vignetting Amount\" setting. Range -100 to +100.") },
{ "VignetteMidpoint", N_("Vignette Midpoint"), "Integer", xmpText, xmpExternal, N_("\"Vignetting Midpoint\" setting. Range 0 to +100.") },
{ "WhiteBalance", N_("White Balance"), "Closed Choice Text", xmpText, xmpExternal, N_("\"White Balance\" setting. One of: As Shot, Auto, Daylight, Cloudy, Shade, Tungsten, "
"Fluorescent, Flash, Custom") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPropertyInfo xmpTiffInfo[] = {
{ "ImageWidth", N_("Image Width"), "Integer", xmpText, xmpInternal, N_("TIFF tag 256, 0x100. Image width in pixels.") },
{ "ImageLength", N_("Image Length"), "Integer", xmpText, xmpInternal, N_("TIFF tag 257, 0x101. Image height in pixels.") },
{ "BitsPerSample", N_("Bits Per Sample"), "seq Integer", xmpSeq, xmpInternal, N_("TIFF tag 258, 0x102. Number of bits per component in each channel.") },
{ "Compression", N_("Compression"), "Closed Choice of Integer", xmpText, xmpInternal, N_("TIFF tag 259, 0x103. Compression scheme: 1 = uncompressed; 6 = JPEG.") },
{ "PhotometricInterpretation", N_("Photometric Interpretation"), "Closed Choice of Integer", xmpText, xmpInternal, N_("TIFF tag 262, 0x106. Pixel Composition: 2 = RGB; 6 = YCbCr.") },
{ "Orientation", N_("Orientation"), "Closed Choice of Integer", xmpText, xmpInternal, N_("TIFF tag 274, 0x112. Orientation:"
"1 = 0th row at top, 0th column at left "
"2 = 0th row at top, 0th column at right "
"3 = 0th row at bottom, 0th column at right "
"4 = 0th row at bottom, 0th column at left "
"5 = 0th row at left, 0th column at top "
"6 = 0th row at right, 0th column at top "
"7 = 0th row at right, 0th column at bottom "
"8 = 0th row at left, 0th column at bottom") },
{ "SamplesPerPixel", N_("Samples Per Pixel"), "Integer", xmpText, xmpInternal, N_("TIFF tag 277, 0x115. Number of components per pixel.") },
{ "PlanarConfiguration", N_("Planar Configuration"), "Closed Choice of Integer", xmpText, xmpInternal, N_("TIFF tag 284, 0x11C. Data layout:1 = chunky; 2 = planar.") },
{ "YCbCrSubSampling", N_("YCbCr Sub Sampling"), "Closed Choice of seq Integer", xmpSeq, xmpInternal, N_("TIFF tag 530, 0x212. Sampling ratio of chrominance "
"components: [2, 1] = YCbCr4:2:2; [2, 2] = YCbCr4:2:0") },
{ "YCbCrPositioning", N_("YCbCr Positioning"), "Closed Choice of Integer", xmpText, xmpInternal, N_("TIFF tag 531, 0x213. Position of chrominance vs. "
"luminance components: 1 = centered; 2 = co-sited.") },
{ "XResolution", N_("X Resolution"), "Rational", xmpText, xmpInternal, N_("TIFF tag 282, 0x11A. Horizontal resolution in pixels per unit.") },
{ "YResolution", N_("Y Resolution"), "Rational", xmpText, xmpInternal, N_("TIFF tag 283, 0x11B. Vertical resolution in pixels per unit.") },
{ "ResolutionUnit", N_("Resolution Unit"), "Closed Choice of Integer", xmpText, xmpInternal, N_("TIFF tag 296, 0x128. Unit used for XResolution and "
"YResolution. Value is one of: 2 = inches; 3 = centimeters.") },
{ "TransferFunction", N_("Transfer Function"), "seq Integer", xmpSeq, xmpInternal, N_("TIFF tag 301, 0x12D. Transfer function for image "
"described in tabular style with 3 * 256 entries.") },
{ "WhitePoint", N_("White Point"), "seq Rational", xmpSeq, xmpInternal, N_("TIFF tag 318, 0x13E. Chromaticity of white point.") },
{ "PrimaryChromaticities", N_("Primary Chromaticities"), "seq Rational", xmpSeq, xmpInternal, N_("TIFF tag 319, 0x13F. Chromaticity of the three primary colors.") },
{ "YCbCrCoefficients", N_("YCbCr Coefficients"), "seq Rational", xmpSeq, xmpInternal, N_("TIFF tag 529, 0x211. Matrix coefficients for RGB to YCbCr transformation.") },
{ "ReferenceBlackWhite", N_("Reference Black White"), "seq Rational", xmpSeq, xmpInternal, N_("TIFF tag 532, 0x214. Reference black and white point values.") },
{ "DateTime", N_("Date and Time"), "Date", date, xmpInternal, N_("TIFF tag 306, 0x132 (primary) and EXIF tag 37520, "
"0x9290 (subseconds). Date and time of image creation "
"(no time zone in EXIF), stored in ISO 8601 format, not "
"the original EXIF format. This property includes the "
"value for the EXIF SubSecTime attribute. "
"NOTE: This property is stored in XMP as xmp:ModifyDate.") },
{ "ImageDescription", N_("Image Description"), "Lang Alt", langAlt, xmpExternal, N_("TIFF tag 270, 0x10E. Description of the image. Note: This property is stored in XMP as dc:description.") },
{ "Make", N_("Make"), "ProperName", xmpText, xmpInternal, N_("TIFF tag 271, 0x10F. Manufacturer of recording equipment.") },
{ "Model", N_("Model"), "ProperName", xmpText, xmpInternal, N_("TIFF tag 272, 0x110. Model name or number of equipment.") },
{ "Software", N_("Software"), "AgentName", xmpText, xmpInternal, N_("TIFF tag 305, 0x131. Software or firmware used to generate image. "
"Note: This property is stored in XMP as xmp:CreatorTool. ") },
{ "Artist", N_("Artist"), "ProperName", xmpText, xmpExternal, N_("TIFF tag 315, 0x13B. Camera owner, photographer or image creator. "
"Note: This property is stored in XMP as the first item in the dc:creator array.") },
{ "Copyright", N_("Copyright"), "Lang Alt", langAlt, xmpExternal, N_("TIFF tag 33432, 0x8298. Copyright information. "
"Note: This property is stored in XMP as dc:rights.") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
//! exif:GPSAltitudeRef
extern const TagDetails xmpExifGPSAltitudeRef[] = {
{ 0, N_("Above sea level") },
{ 1, N_("Below sea level") }
};
//! exif:GPSStatus
extern const TagDetails xmpExifGPSStatus[] = {
{ 'A', N_("measurement in progress") },
{ 'V', N_("measurement is interoperability") }
};
//! exif:GPSMeasureMode
extern const TagDetails xmpExifGPSMeasureMode[] = {
{ 2, N_("two-dimensional measurement") },
{ 3, N_("three-dimensional measurement") }
};
//! exif:GPSSpeedRef
extern const TagDetails xmpExifGPSSpeedRef[] = {
{ 'K', N_("kilometers per hour") },
{ 'M', N_("miles per hour") },
{ 'N', N_("knots") }
};
//! exif:GPSTrackRef, exif:GPSImgDirectionRef, exif:GPSDestBearingRef
extern const TagDetails xmpExifGPSDirection[] = {
{ 'T', N_("true direction") },
{ 'M', N_("magnetic direction") }
};
//! exif:GPSDestDistanceRef
extern const TagDetails xmpExifGPSDestDistanceRef[] = {
{ 'K', N_("kilometers") },
{ 'M', N_("miles") },
{ 'N', N_("knots") }
};
//! exif:GPSDifferential
extern const TagDetails xmpExifGPSDifferential[] = {
{ 0, N_("Without correction") },
{ 1, N_("Correction applied") }
};
extern const XmpPropertyInfo xmpExifInfo[] = {
{ "ExifVersion", N_("Exif Version"), "Closed Choice of Text", xmpText, xmpInternal, N_("EXIF tag 36864, 0x9000. EXIF version number.") },
{ "FlashpixVersion", N_("Flashpix Version"), "Closed Choice of Text", xmpText, xmpInternal, N_("EXIF tag 40960, 0xA000. Version of FlashPix.") },
{ "ColorSpace", N_("Color Space"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 40961, 0xA001. Color space information") },
{ "ComponentsConfiguration", N_("Components Configuration"), "Closed Choice of seq Integer", xmpSeq, xmpInternal, N_("EXIF tag 37121, 0x9101. Configuration of components in data: 4 5 6 0 (if RGB compressed data), "
"1 2 3 0 (other cases).") },
{ "CompressedBitsPerPixel", N_("Compressed Bits Per Pixel"), "Rational", xmpText, xmpInternal, N_("EXIF tag 37122, 0x9102. Compression mode used for a compressed image is indicated "
"in unit bits per pixel.") },
{ "PixelXDimension", N_("Pixel X Dimension"), "Integer", xmpText, xmpInternal, N_("EXIF tag 40962, 0xA002. Valid image width, in pixels.") },
{ "PixelYDimension", N_("Pixel Y Dimension"), "Integer", xmpText, xmpInternal, N_("EXIF tag 40963, 0xA003. Valid image height, in pixels.") },
{ "UserComment", N_("User Comment"), "Lang Alt", langAlt, xmpExternal, N_("EXIF tag 37510, 0x9286. Comments from user.") },
{ "RelatedSoundFile", N_("Related Sound File"), "Text", xmpText, xmpInternal, N_("EXIF tag 40964, 0xA004. An \"8.3\" file name for the related sound file.") },
{ "DateTimeOriginal", N_("Date and Time Original"), "Date", xmpText, xmpInternal, N_("EXIF tags 36867, 0x9003 (primary) and 37521, 0x9291 (subseconds). "
"Date and time when original image was generated, in ISO 8601 format. "
"Includes the EXIF SubSecTimeOriginal data.") },
{ "DateTimeDigitized", N_("Date and Time Digitized"), "Date", xmpText, xmpInternal, N_("EXIF tag 36868, 0x9004 (primary) and 37522, 0x9292 (subseconds). Date and time when "
"image was stored as digital data, can be the same as DateTimeOriginal if originally "
"stored in digital form. Stored in ISO 8601 format. Includes the EXIF "
"SubSecTimeDigitized data.") },
{ "ExposureTime", N_("Exposure Time"), "Rational", xmpText, xmpInternal, N_("EXIF tag 33434, 0x829A. Exposure time in seconds.") },
{ "FNumber", N_("F Number"), "Rational", xmpText, xmpInternal, N_("EXIF tag 33437, 0x829D. F number.") },
{ "ExposureProgram", N_("Exposure Program"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 34850, 0x8822. Class of program used for exposure.") },
{ "SpectralSensitivity", N_("Spectral Sensitivity"), "Text", xmpText, xmpInternal, N_("EXIF tag 34852, 0x8824. Spectral sensitivity of each channel.") },
{ "ISOSpeedRatings", N_("ISOSpeedRatings"), "seq Integer", xmpSeq, xmpInternal, N_("EXIF tag 34855, 0x8827. ISO Speed and ISO Latitude of the input device as "
"specified in ISO 12232.") },
{ "OECF", N_("OECF"), "OECF/SFR", xmpText, xmpInternal, N_("EXIF tag 34856, 0x8828. Opto-Electoric Conversion Function as specified in ISO 14524.") },
{ "ShutterSpeedValue", N_("Shutter Speed Value"), "Rational", xmpText, xmpInternal, N_("EXIF tag 37377, 0x9201. Shutter speed, unit is APEX. See Annex C of the EXIF specification.") },
{ "ApertureValue", N_("Aperture Value"), "Rational", xmpText, xmpInternal, N_("EXIF tag 37378, 0x9202. Lens aperture, unit is APEX.") },
{ "BrightnessValue", N_("Brightness Value"), "Rational", xmpText, xmpInternal, N_("EXIF tag 37379, 0x9203. Brightness, unit is APEX.") },
{ "ExposureBiasValue", N_("Exposure Bias Value"), "Rational", xmpText, xmpInternal, N_("EXIF tag 37380, 0x9204. Exposure bias, unit is APEX.") },
{ "MaxApertureValue", N_("Maximum Aperture Value"), "Rational", xmpText, xmpInternal, N_("EXIF tag 37381, 0x9205. Smallest F number of lens, in APEX.") },
{ "SubjectDistance", N_("Subject Distance"), "Rational", xmpText, xmpInternal, N_("EXIF tag 37382, 0x9206. Distance to subject, in meters.") },
{ "MeteringMode", N_("Metering Mode"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 37383, 0x9207. Metering mode.") },
{ "LightSource", N_("Light Source"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 37384, 0x9208. Light source.") },
{ "Flash", N_("Flash"), "Flash", xmpText, xmpInternal, N_("EXIF tag 37385, 0x9209. Strobe light (flash) source data.") },
{ "FocalLength", N_("Focal Length"), "Rational", xmpText, xmpInternal, N_("EXIF tag 37386, 0x920A. Focal length of the lens, in millimeters.") },
{ "SubjectArea", N_("Subject Area"), "seq Integer", xmpSeq, xmpInternal, N_("EXIF tag 37396, 0x9214. The location and area of the main subject in the overall scene.") },
{ "FlashEnergy", N_("Flash Energy"), "Rational", xmpText, xmpInternal, N_("EXIF tag 41483, 0xA20B. Strobe energy during image capture.") },
{ "SpatialFrequencyResponse", N_("Spatial Frequency Response"), "OECF/SFR", xmpText, xmpInternal, N_("EXIF tag 41484, 0xA20C. Input device spatial frequency table and SFR values as "
"specified in ISO 12233.") },
{ "FocalPlaneXResolution", N_("Focal Plane X Resolution"), "Rational", xmpText, xmpInternal, N_("EXIF tag 41486, 0xA20E. Horizontal focal resolution, measured pixels per unit.") },
{ "FocalPlaneYResolution", N_("Focal Plane Y Resolution"), "Rational", xmpText, xmpInternal, N_("EXIF tag 41487, 0xA20F. Vertical focal resolution, measured in pixels per unit.") },
{ "FocalPlaneResolutionUnit", N_("Focal Plane Resolution Unit"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 41488, 0xA210. Unit used for FocalPlaneXResolution and FocalPlaneYResolution.") },
{ "SubjectLocation", N_("Subject Location"), "seq Integer", xmpSeq, xmpInternal, N_("EXIF tag 41492, 0xA214. Location of the main subject of the scene. The first value is the "
"horizontal pixel and the second value is the vertical pixel at which the "
"main subject appears.") },
{ "ExposureIndex", N_("Exposure Index"), "Rational", xmpText, xmpInternal, N_("EXIF tag 41493, 0xA215. Exposure index of input device.") },
{ "SensingMethod", N_("Sensing Method"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 41495, 0xA217. Image sensor type on input device.") },
{ "FileSource", N_("File Source"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 41728, 0xA300. Indicates image source.") },
{ "SceneType", N_("Scene Type"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 41729, 0xA301. Indicates the type of scene.") },
{ "CFAPattern", N_("CFA Pattern"), "CFAPattern", xmpText, xmpInternal, N_("EXIF tag 41730, 0xA302. Color filter array geometric pattern of the image sense.") },
{ "CustomRendered", N_("Custom Rendered"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 41985, 0xA401. Indicates the use of special processing on image data.") },
{ "ExposureMode", N_("Exposure Mode"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 41986, 0xA402. Indicates the exposure mode set when the image was shot.") },
{ "WhiteBalance", N_("White Balance"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 41987, 0xA403. Indicates the white balance mode set when the image was shot.") },
{ "DigitalZoomRatio", N_("Digital Zoom Ratio"), "Rational", xmpText, xmpInternal, N_("EXIF tag 41988, 0xA404. Indicates the digital zoom ratio when the image was shot.") },
{ "FocalLengthIn35mmFilm", N_("Focal Length In 35mm Film"), "Integer", xmpText, xmpInternal, N_("EXIF tag 41989, 0xA405. Indicates the equivalent focal length assuming a 35mm film "
"camera, in mm. A value of 0 means the focal length is unknown. Note that this tag "
"differs from the FocalLength tag.") },
{ "SceneCaptureType", N_("Scene Capture Type"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 41990, 0xA406. Indicates the type of scene that was shot.") },
{ "GainControl", N_("Gain Control"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 41991, 0xA407. Indicates the degree of overall image gain adjustment.") },
{ "Contrast", N_("Contrast"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 41992, 0xA408. Indicates the direction of contrast processing applied by the camera.") },
{ "Saturation", N_("Saturation"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 41993, 0xA409. Indicates the direction of saturation processing applied by the camera.") },
{ "Sharpness", N_("Sharpness"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 41994, 0xA40A. Indicates the direction of sharpness processing applied by the camera.") },
{ "DeviceSettingDescription", N_("Device Setting Description"), "DeviceSettings", xmpText, xmpInternal, N_("EXIF tag 41995, 0xA40B. Indicates information on the picture-taking conditions of a particular camera model.") },
{ "SubjectDistanceRange", N_("Subject Distance Range"), "Closed Choice of Integer", xmpText, xmpInternal, N_("EXIF tag 41996, 0xA40C. Indicates the distance to the subject.") },
{ "ImageUniqueID", N_("Image Unique ID"), "Text", xmpText, xmpInternal, N_("EXIF tag 42016, 0xA420. An identifier assigned uniquely to each image. It is recorded as a 32 "
"character ASCII string, equivalent to hexadecimal notation and 128-bit fixed length.") },
{ "GPSVersionID", N_("GPS Version ID"), "Text", xmpText, xmpInternal, N_("GPS tag 0, 0x00. A decimal encoding of each of the four EXIF bytes with period separators. "
"The current value is \"2.0.0.0\".") },
{ "GPSLatitude", N_("GPS Latitude"), "GPSCoordinate", xmpText, xmpInternal, N_("GPS tag 2, 0x02 (position) and 1, 0x01 (North/South). Indicates latitude.") },
{ "GPSLongitude", N_("GPS Longitude"), "GPSCoordinate", xmpText, xmpInternal, N_("GPS tag 4, 0x04 (position) and 3, 0x03 (East/West). Indicates longitude.") },
{ "GPSAltitudeRef", N_("GPS Altitude Reference"), "Closed Choice of Integer", xmpText, xmpInternal, N_("GPS tag 5, 0x5. Indicates whether the altitude is above or below sea level.") },
{ "GPSAltitude", N_("GPS Altitude"), "Rational", xmpText, xmpInternal, N_("GPS tag 6, 0x06. Indicates altitude in meters.") },
{ "GPSTimeStamp", N_("GPS Time Stamp"), "Date", xmpText, xmpInternal, N_("GPS tag 29 (date), 0x1D, and, and GPS tag 7 (time), 0x07. Time stamp of GPS data, "
"in Coordinated Universal Time. Note: The GPSDateStamp tag is new in EXIF 2.2. "
"The GPS timestamp in EXIF 2.1 does not include a date. If not present, "
"the date component for the XMP should be taken from exif:DateTimeOriginal, or if that is "
"also lacking from exif:DateTimeDigitized. If no date is available, do not write "
"exif:GPSTimeStamp to XMP.") },
{ "GPSSatellites", N_("GPS Satellites"), "Text", xmpText, xmpInternal, N_("GPS tag 8, 0x08. Satellite information, format is unspecified.") },
{ "GPSStatus", N_("GPS Status"), "Closed Choice of Text", xmpText, xmpInternal, N_("GPS tag 9, 0x09. Status of GPS receiver at image creation time.") },
{ "GPSMeasureMode", N_("GPS Measure Mode"), "Text", xmpText, xmpInternal, N_("GPS tag 10, 0x0A. GPS measurement mode, Text type.") },
{ "GPSDOP", N_("GPS DOP"), "Rational", xmpText, xmpInternal, N_("GPS tag 11, 0x0B. Degree of precision for GPS data.") },
{ "GPSSpeedRef", N_("GPS Speed Reference"), "Closed Choice of Text", xmpText, xmpInternal, N_("GPS tag 12, 0x0C. Units used to speed measurement.") },
{ "GPSSpeed", N_("GPS Speed"), "Rational", xmpText, xmpInternal, N_("GPS tag 13, 0x0D. Speed of GPS receiver movement.") },
{ "GPSTrackRef", N_("GPS Track Reference"), "Closed Choice of Text", xmpText, xmpInternal, N_("GPS tag 14, 0x0E. Reference for movement direction.") },
{ "GPSTrack", N_("GPS Track"), "Rational", xmpText, xmpInternal, N_("GPS tag 15, 0x0F. Direction of GPS movement, values range from 0 to 359.99.") },
{ "GPSImgDirectionRef", N_("GPS Image Direction Reference"), "Closed Choice of Text", xmpText, xmpInternal, N_("GPS tag 16, 0x10. Reference for movement direction.") },
{ "GPSImgDirection", N_("GPS Image Direction"), "Rational", xmpText, xmpInternal, N_("GPS tag 17, 0x11. Direction of image when captured, values range from 0 to 359.99.") },
{ "GPSMapDatum", N_("GPS Map Datum"), "Text", xmpText, xmpInternal, N_("GPS tag 18, 0x12. Geodetic survey data.") },
{ "GPSDestLatitude", N_("GPS Destination Latitude"), "GPSCoordinate", xmpText, xmpInternal, N_("GPS tag 20, 0x14 (position) and 19, 0x13 (North/South). Indicates destination latitude.") },
{ "GPSDestLongitude", N_("GPS Destination Longitude"), "GPSCoordinate", xmpText, xmpInternal, N_("GPS tag 22, 0x16 (position) and 21, 0x15 (East/West). Indicates destination longitude.") },
{ "GPSDestBearingRef", N_("GPS Destination Bearing Reference"), "Closed Choice of Text", xmpText, xmpInternal, N_("GPS tag 23, 0x17. Reference for movement direction.") },
{ "GPSDestBearing", N_("GPS Destination Bearing"), "Rational", xmpText, xmpInternal, N_("GPS tag 24, 0x18. Destination bearing, values from 0 to 359.99.") },
{ "GPSDestDistanceRef", N_("GPS Destination Distance Refefrence"), "Closed Choice of Text", xmpText, xmpInternal, N_("GPS tag 25, 0x19. Units used for speed measurement.") },
{ "GPSDestDistance", N_("GPS Destination Distance"), "Rational", xmpText, xmpInternal, N_("GPS tag 26, 0x1A. Distance to destination.") },
{ "GPSProcessingMethod", N_("GPS Processing Method"), "Text", xmpText, xmpInternal, N_("GPS tag 27, 0x1B. A character string recording the name of the method used for location finding.") },
{ "GPSAreaInformation", N_("GPS Area Information"), "Text", xmpText, xmpInternal, N_("GPS tag 28, 0x1C. A character string recording the name of the GPS area.") },
{ "GPSDifferential", N_("GPS Differential"), "Closed Choice of Integer", xmpText, xmpInternal, N_("GPS tag 30, 0x1E. Indicates whether differential correction is applied to the GPS receiver.") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPropertyInfo xmpAuxInfo[] = {
{ "Lens", N_("Lens"), "Text", xmpText, xmpInternal, N_("A description of the lens used to take the photograph. For example, \"70-200 mm f/2.8-4.0\".") },
{ "SerialNumber", N_("SerialNumber"), "Text", xmpText, xmpInternal, N_("The serial number of the camera or camera body used to take the photograph.") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPropertyInfo xmpIptcInfo[] = {
{ "CiAdrCity", N_("Contact Info-City"), "Text", xmpText, xmpExternal, N_("The contact information city part.") },
{ "CiAdrCtry", N_("Contact Info-Country"), "Text", xmpText, xmpExternal, N_("The contact information country part.") },
{ "CiAdrExtadr", N_("Contact Info-Address"), "Text", xmpText, xmpExternal, N_("The contact information address part. Comprises an optional company name and all required "
"information to locate the building or postbox to which mail should be sent.") },
{ "CiAdrPcode", N_("Contact Info-Postal Code"), "Text", xmpText, xmpExternal, N_("The contact information part denoting the local postal code.") },
{ "CiAdrRegion", N_("Contact Info-State/Province"), "Text", xmpText, xmpExternal, N_("The contact information part denoting regional information like state or province.") },
{ "CiEmailWork", N_("Contact Info-Email"), "Text", xmpText, xmpExternal, N_("The contact information email address part.") },
{ "CiTelWork", N_("Contact Info-Phone"), "Text", xmpText, xmpExternal, N_("The contact information phone number part.") },
{ "CiUrlWork", N_("Contact Info-Web URL"), "Text", xmpText, xmpExternal, N_("The contact information web address part.") },
{ "CountryCode", N_("Country Code"), "closed Choice of Text", xmpText, xmpExternal, N_("Code of the country the content is focussing on -- either the country shown in visual "
"media or referenced in text or audio media. This element is at the top/first level of "
"a top-down geographical hierarchy. The code should be taken from ISO 3166 two or three "
"letter code. The full name of a country should go to the \"Country\" element.") },
{ "CreatorContactInfo", N_("Creator's Contact Info"), "ContactInfo", xmpText, xmpExternal, N_("The creator's contact information provides all necessary information to get in contact "
"with the creator of this news object and comprises a set of sub-properties for proper addressing.") },
{ "IntellectualGenre", N_("Intellectual Genre"), "Text", xmpText, xmpExternal, N_("Describes the nature, intellectual or journalistic characteristic of a news object, not "
"specifically its content.") },
{ "Location", N_("Location"), "Text", xmpText, xmpExternal, N_("Name of a location the content is focussing on -- either the location shown in visual "
"media or referenced by text or audio media. This location name could either be the name "
"of a sublocation to a city or the name of a well known location or (natural) monument "
"outside a city. In the sense of a sublocation to a city this element is at the fourth "
"level of a top-down geographical hierarchy.") },
{ "Scene", N_("IPTC Scene"), "bag closed Choice of Text", xmpBag, xmpExternal, N_("Describes the scene of a photo content. Specifies one or more terms from the IPTC "
"\"Scene-NewsCodes\". Each Scene is represented as a string of 6 digits in an unordered list.") },
{ "SubjectCode", N_("IPTC Subject Code"), "bag closed Choice of Text", xmpBag, xmpExternal, N_("Specifies one or more Subjects from the IPTC \"Subject-NewsCodes\" taxonomy to "
"categorize the content. Each Subject is represented as a string of 8 digits in an unordered list.") },
// End of list marker
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPrintInfo xmpPrintInfo[] = {
{"Xmp.crs.CropUnits", EXV_PRINT_TAG(xmpCrsCropUnits) },
{"Xmp.exif.ApertureValue", print0x9202 },
{"Xmp.exif.BrightnessValue", printFloat },
{"Xmp.exif.ColorSpace", print0xa001 },
{"Xmp.exif.ComponentsConfiguration", print0x9101 },
{"Xmp.exif.Contrast", printNormalSoftHard },
{"Xmp.exif.CreateDate", printXmpDate },
{"Xmp.exif.CustomRendered", print0xa401 },
{"Xmp.exif.DateTimeOriginal", printXmpDate },
{"Xmp.exif.ExifVersion", printXmpVersion },
{"Xmp.exif.ExposureBiasValue", print0x9204 },
{"Xmp.exif.ExposureMode", print0xa402 },
{"Xmp.exif.ExposureProgram", print0x8822 },
{"Xmp.exif.FileSource", print0xa300 },
{"Xmp.exif.FlashpixVersion", printXmpVersion },
{"Xmp.exif.FNumber", print0x829d },
{"Xmp.exif.FocalLength", print0x920a },
{"Xmp.exif.FocalPlaneResolutionUnit", printExifUnit },
{"Xmp.exif.FocalPlaneXResolution", printFloat },
{"Xmp.exif.FocalPlaneYResolution", printFloat },
{"Xmp.exif.GainControl", print0xa407 },
{"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", print0x9208 },
{"Xmp.exif.MeteringMode", print0x9207 },
{"Xmp.exif.ModifyDate", printXmpDate },
{"Xmp.exif.Saturation", print0xa409 },
{"Xmp.exif.SceneCaptureType", print0xa406 },
{"Xmp.exif.SceneType", print0xa301 },
{"Xmp.exif.SensingMethod", print0xa217 },
{"Xmp.exif.Sharpness", printNormalSoftHard },
{"Xmp.exif.ShutterSpeedValue", print0x9201 },
{"Xmp.exif.SubjectDistanceRange", print0xa40c },
{"Xmp.exif.WhiteBalance", print0xa403 },
{"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)
: ns_(ns)
{
}
XmpNsInfo::Prefix::Prefix(const std::string& prefix)
: prefix_(prefix)
{
}
bool XmpNsInfo::operator==(const XmpNsInfo::Ns& ns) const
{
std::string n(ns_);
return n == ns.ns_;
}
bool XmpNsInfo::operator==(const XmpNsInfo::Prefix& prefix) const
{
std::string p(prefix_);
return p == prefix.prefix_;
}
bool XmpPropertyInfo::operator==(const std::string& name) const
{
std::string n(name_);
return n == name;
}
bool XmpPrintInfo::operator==(const std::string& key) const
{
return std::string(key_) == key;
}
XmpProperties::NsRegistry XmpProperties::nsRegistry_;
const XmpNsInfo* XmpProperties::lookupNsRegistry(const XmpNsInfo::Prefix& prefix)
{
for (NsRegistry::const_iterator i = nsRegistry_.begin();
i != nsRegistry_.end(); ++i) {
if (i->second == prefix) return &(i->second);
}
return 0;
}
void XmpProperties::registerNs(const std::string& ns,
const std::string& prefix)
{
std::string ns2 = ns;
if ( ns2.substr(ns2.size() - 1, 1) != "/"
&& ns2.substr(ns2.size() - 1, 1) != "#") ns2 += "/";
// Allocated memory is freed when the namespace is unregistered.
// Using malloc/free for better system compatibility in case
// users don't unregister their namespaces explicitely.
XmpNsInfo xn;
char* c = static_cast<char*>(std::malloc(ns2.size() + 1));
std::strcpy(c, ns2.c_str());
xn.ns_ = c;
c = static_cast<char*>(std::malloc(prefix.size() + 1));
std::strcpy(c, prefix.c_str());
xn.prefix_ = c;
xn.xmpPropertyInfo_ = 0;
xn.desc_ = "";
nsRegistry_[ns2] = xn;
XmpParser::registerNs(ns2, prefix);
}
void XmpProperties::unregisterNs(const std::string& ns)
{
NsRegistry::iterator i = nsRegistry_.find(ns);
if (i != nsRegistry_.end()) {
XmpParser::unregisterNs(ns);
std::free(const_cast<char*>(i->second.prefix_));
std::free(const_cast<char*>(i->second.ns_));
nsRegistry_.erase(i);
}
}
void XmpProperties::unregisterNs()
{
NsRegistry::iterator i = nsRegistry_.begin();
while (i != nsRegistry_.end()) {
NsRegistry::iterator kill = i++;
unregisterNs(kill->first);
}
}
std::string XmpProperties::prefix(const std::string& ns)
{
std::string ns2 = ns;
if (ns2.substr(ns2.size() - 1, 1) != "/") ns2 += "/";
NsRegistry::const_iterator i = nsRegistry_.find(ns2);
std::string p;
if (i != nsRegistry_.end()) {
p = i->second.prefix_;
}
else {
const XmpNsInfo* xn = find(xmpNsInfo, XmpNsInfo::Ns(ns2));
if (xn) p = std::string(xn->prefix_);
}
return p;
}
std::string XmpProperties::ns(const std::string& prefix)
{
const XmpNsInfo* xn = lookupNsRegistry(XmpNsInfo::Prefix(prefix));
if (xn != 0) return xn->ns_;
return nsInfo(prefix)->ns_;
}
const char* XmpProperties::propertyTitle(const XmpKey& key)
{
const XmpPropertyInfo* pi = propertyInfo(key);
return pi ? pi->title_ : 0;
}
const char* XmpProperties::propertyDesc(const XmpKey& key)
{
const XmpPropertyInfo* pi = propertyInfo(key);
return pi ? pi->desc_ : 0;
}
TypeId XmpProperties::propertyType(const XmpKey& key)
{
const XmpPropertyInfo* pi = propertyInfo(key);
return pi ? pi->typeId_ : xmpText;
}
const XmpPropertyInfo* XmpProperties::propertyInfo(const XmpKey& key)
{
const XmpPropertyInfo* pl = propertyList(key.groupName());
if (!pl) return 0;
const XmpPropertyInfo* pi = 0;
for (int i = 0; pl[i].name_ != 0; ++i) {
if (std::string(pl[i].name_) == key.tagName()) {
pi = pl + i;
break;
}
}
return pi;
}
const char* XmpProperties::nsDesc(const std::string& prefix)
{
return nsInfo(prefix)->desc_;
}
const XmpPropertyInfo* XmpProperties::propertyList(const std::string& prefix)
{
return nsInfo(prefix)->xmpPropertyInfo_;
}
const XmpNsInfo* XmpProperties::nsInfo(const std::string& prefix)
{
const XmpNsInfo::Prefix pf(prefix);
const XmpNsInfo* xn = lookupNsRegistry(pf);
if (!xn) xn = find(xmpNsInfo, pf);
if (!xn) throw Error(35, prefix);
return xn;
}
void XmpProperties::printProperties(std::ostream& os, const std::string& prefix)
{
const XmpPropertyInfo* pl = propertyList(prefix);
if (pl) {
for (int i = 0; pl[i].name_ != 0; ++i) {
os << pl[i];
}
}
} // XmpProperties::printProperties
std::ostream& XmpProperties::printProperty(std::ostream& os,
const std::string& key,
const Value& value)
{
PrintFct fct = printValue;
if (value.count() != 0) {
const XmpPrintInfo* info = find(xmpPrintInfo, key);
if (info) fct = info->printFct_;
}
return fct(os, value);
}
//! @cond IGNORE
//! Internal Pimpl structure with private members and data of class XmpKey.
struct XmpKey::Impl {
Impl() {} //!< Default constructor
Impl(const std::string& prefix, const std::string& property); //!< Constructor
/*!
@brief Parse and convert the \em key string into property and prefix.
Updates data members if the string can be decomposed, or throws
\em Error.
@throw Error if the key cannot be decomposed.
*/
void decomposeKey(const std::string& key);
// DATA
static const char* familyName_; //!< "Xmp"
std::string prefix_; //!< Prefix
std::string property_; //!< Property name
};
//! @endcond
XmpKey::Impl::Impl(const std::string& prefix, const std::string& property)
{
// Validate prefix
if (XmpProperties::ns(prefix).empty()) throw Error(46, prefix);
property_ = property;
prefix_ = prefix;
}
const char* XmpKey::Impl::familyName_ = "Xmp";
XmpKey::XmpKey(const std::string& key)
: p_(new Impl)
{
p_->decomposeKey(key);
}
XmpKey::XmpKey(const std::string& prefix, const std::string& property)
: p_(new Impl(prefix, property))
{
}
XmpKey::~XmpKey()
{
delete p_;
}
XmpKey::XmpKey(const XmpKey& rhs)
: Key(rhs), p_(new Impl(*rhs.p_))
{
}
XmpKey& XmpKey::operator=(const XmpKey& rhs)
{
if (this == &rhs) return *this;
*p_ = *rhs.p_;
return *this;
}
XmpKey::AutoPtr XmpKey::clone() const
{
return AutoPtr(clone_());
}
XmpKey* XmpKey::clone_() const
{
return new XmpKey(*this);
}
std::string XmpKey::key() const
{
return std::string(p_->familyName_) + "." + p_->prefix_ + "." + p_->property_;
}
const char* XmpKey::familyName() const
{
return p_->familyName_;
}
std::string XmpKey::groupName() const
{
return p_->prefix_;
}
std::string XmpKey::tagName() const
{
return p_->property_;
}
std::string XmpKey::tagLabel() const
{
return XmpProperties::propertyTitle(*this);
}
std::string XmpKey::ns() const
{
return XmpProperties::ns(p_->prefix_);
}
void XmpKey::Impl::decomposeKey(const std::string& key)
{
// Get the family name, prefix and property name parts of the key
std::string::size_type pos1 = key.find('.');
if (pos1 == std::string::npos) throw Error(6, key);
std::string familyName = key.substr(0, pos1);
if (familyName != std::string(familyName_)) {
throw Error(6, key);
}
std::string::size_type pos0 = pos1 + 1;
pos1 = key.find('.', pos0);
if (pos1 == std::string::npos) throw Error(6, key);
std::string prefix = key.substr(pos0, pos1 - pos0);
if (prefix == "") throw Error(6, key);
std::string property = key.substr(pos1 + 1);
if (property == "") throw Error(6, key);
// Validate prefix
if (XmpProperties::ns(prefix).empty()) throw Error(46, prefix);
property_ = property;
prefix_ = prefix;
} // XmpKey::Impl::decomposeKey
// *************************************************************************
// free functions
std::ostream& operator<<(std::ostream& os, const XmpPropertyInfo& property)
{
return os << property.name_ << ",\t"
<< property.title_ << ",\t"
<< property.xmpValueType_ << ",\t"
<< TypeInfo::typeName(property.typeId_) << ",\t"
<< ( property.xmpCategory_ == xmpExternal ? "External" : "Internal" ) << ",\t"
<< property.desc_ << "\n";
}
} // namespace Exiv2