1 // ***************************************************************** -*- C++ -*-
2 /*
3  * Copyright (C) 2004-2017 Andreas Huggel <ahuggel@gmx.net>
4  *
5  * This program is part of the Exiv2 distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
20  */
21 /*!
22   @file    datasets.hpp
23   @brief   IPTC dataset and type information
24   @version $Rev: 3091 $
25   @author  Brad Schick (brad) <brad@robotbattle.com>
26   @date    24-Jul-04, brad: created
27  */
28 #ifndef DATASETS_HPP_
29 #define DATASETS_HPP_
30 
31 // *****************************************************************************
32 // included header files
33 #include "types.hpp"
34 #include "metadatum.hpp"
35 
36 // + standard includes
37 #include <string>
38 #include <utility>                              // for std::pair
39 #include <iosfwd>
40 #include <memory>
41 #include <set>
42 #include <vector>
43 #include <map>
44 
45 // *****************************************************************************
46 // namespace extensions
47 namespace Exiv2 {
48 
49 // *****************************************************************************
50 // class definitions
51 
52     //! Details of an IPTC record.
53     struct EXIV2API RecordInfo {
54         //! Constructor
55         RecordInfo(uint16_t recordId, const char* name, const char* desc);
56         uint16_t recordId_;                     //!< Record id
57         const char* name_;                      //!< Record name (one word)
58         const char* desc_;                      //!< Record description
59     };
60 
61     //! Details of an IPTC dataset.
62     struct EXIV2API DataSet {
63         //! Constructor
64         DataSet(
65             uint16_t number,
66             const char* name,
67             const char* title,
68             const char* desc,
69             bool mandatory,
70             bool repeatable,
71             uint32_t minbytes,
72             uint32_t maxbytes,
73             TypeId type,
74             uint16_t recordId,
75             const char* photoshop
76         );
77         uint16_t number_;                       //!< Dataset number
78         const char* name_;                      //!< Dataset name
79         const char* title_;                     //!< Dataset title or label
80         const char* desc_;                      //!< Dataset description
81         bool mandatory_;                        //!< True if dataset is mandatory
82         bool repeatable_;                       //!< True if dataset is repeatable
83         uint32_t minbytes_;                     //!< Minimum number of bytes
84         uint32_t maxbytes_;                     //!< Maximum number of bytes
85         TypeId type_;                           //!< Exiv2 default type
86         uint16_t recordId_;                     //!< Record id
87         const char* photoshop_;                 //!< Photoshop string
88     }; // struct DataSet
89 
90     //! IPTC dataset reference, implemented as a static class.
91     class EXIV2API IptcDataSets {
92     public:
93         /*!
94           @name Record identifiers
95           @brief Record identifiers to logically group dataSets. There are other
96                  possible record types, but they are not standardized by the IPTC
97                  IIM4 standard (and not commonly used in images).
98          */
99         //@{
100         static const uint16_t invalidRecord = 0;
101         static const uint16_t envelope = 1;
102         static const uint16_t application2 = 2;
103         //@}
104 
105         //! @name Dataset identifiers
106         //@{
107         static const uint16_t ModelVersion           = 0;
108         static const uint16_t Destination            = 5;
109         static const uint16_t FileFormat             = 20;
110         static const uint16_t FileVersion            = 22;
111         static const uint16_t ServiceId              = 30;
112         static const uint16_t EnvelopeNumber         = 40;
113         static const uint16_t ProductId              = 50;
114         static const uint16_t EnvelopePriority       = 60;
115         static const uint16_t DateSent               = 70;
116         static const uint16_t TimeSent               = 80;
117         static const uint16_t CharacterSet           = 90;
118         static const uint16_t UNO                    = 100;
119         static const uint16_t ARMId                  = 120;
120         static const uint16_t ARMVersion             = 122;
121         static const uint16_t RecordVersion          = 0;
122         static const uint16_t ObjectType             = 3;
123         static const uint16_t ObjectAttribute        = 4;
124         static const uint16_t ObjectName             = 5;
125         static const uint16_t EditStatus             = 7;
126         static const uint16_t EditorialUpdate        = 8;
127         static const uint16_t Urgency                = 10;
128         static const uint16_t Subject                = 12;
129         static const uint16_t Category               = 15;
130         static const uint16_t SuppCategory           = 20;
131         static const uint16_t FixtureId              = 22;
132         static const uint16_t Keywords               = 25;
133         static const uint16_t LocationCode           = 26;
134         static const uint16_t LocationName           = 27;
135         static const uint16_t ReleaseDate            = 30;
136         static const uint16_t ReleaseTime            = 35;
137         static const uint16_t ExpirationDate         = 37;
138         static const uint16_t ExpirationTime         = 38;
139         static const uint16_t SpecialInstructions    = 40;
140         static const uint16_t ActionAdvised          = 42;
141         static const uint16_t ReferenceService       = 45;
142         static const uint16_t ReferenceDate          = 47;
143         static const uint16_t ReferenceNumber        = 50;
144         static const uint16_t DateCreated            = 55;
145         static const uint16_t TimeCreated            = 60;
146         static const uint16_t DigitizationDate       = 62;
147         static const uint16_t DigitizationTime       = 63;
148         static const uint16_t Program                = 65;
149         static const uint16_t ProgramVersion         = 70;
150         static const uint16_t ObjectCycle            = 75;
151         static const uint16_t Byline                 = 80;
152         static const uint16_t BylineTitle            = 85;
153         static const uint16_t City                   = 90;
154         static const uint16_t SubLocation            = 92;
155         static const uint16_t ProvinceState          = 95;
156         static const uint16_t CountryCode            = 100;
157         static const uint16_t CountryName            = 101;
158         static const uint16_t TransmissionReference  = 103;
159         static const uint16_t Headline               = 105;
160         static const uint16_t Credit                 = 110;
161         static const uint16_t Source                 = 115;
162         static const uint16_t Copyright              = 116;
163         static const uint16_t Contact                = 118;
164         static const uint16_t Caption                = 120;
165         static const uint16_t Writer                 = 122;
166         static const uint16_t RasterizedCaption      = 125;
167         static const uint16_t ImageType              = 130;
168         static const uint16_t ImageOrientation       = 131;
169         static const uint16_t Language               = 135;
170         static const uint16_t AudioType              = 150;
171         static const uint16_t AudioRate              = 151;
172         static const uint16_t AudioResolution        = 152;
173         static const uint16_t AudioDuration          = 153;
174         static const uint16_t AudioOutcue            = 154;
175         static const uint16_t PreviewFormat          = 200;
176         static const uint16_t PreviewVersion         = 201;
177         static const uint16_t Preview                = 202;
178         //@}
179 
180     private:
181         //! Prevent construction: not implemented.
IptcDataSets()182         IptcDataSets() {}
183         //! Prevent copy-construction: not implemented.
184         IptcDataSets(const IptcDataSets& rhs);
185         //! Prevent assignment: not implemented.
186         IptcDataSets& operator=(const IptcDataSets& rhs);
187 
188     public:
189         /*!
190           @brief Return the name of the dataset.
191           @param number The dataset number
192           @param recordId The IPTC record Id
193           @return The name of the dataset or a string containing the hexadecimal
194                   value of the dataset in the form "0x01ff", if this is an unknown
195                   dataset.
196          */
197         static std::string dataSetName(uint16_t number, uint16_t recordId);
198         /*!
199           @brief Return the title (label) of the dataset.
200           @param number The dataset number
201           @param recordId The IPTC record Id
202           @return The title (label) of the dataset
203          */
204         static const char* dataSetTitle(uint16_t number, uint16_t recordId);
205         /*!
206           @brief Return the description of the dataset.
207           @param number The dataset number
208           @param recordId The IPTC record Id
209           @return The description of the dataset
210          */
211         static const char* dataSetDesc(uint16_t number, uint16_t recordId);
212         /*!
213           @brief Return the photohsop name of a given dataset.
214           @param number The dataset number
215           @param recordId The IPTC record Id
216           @return The name used by photoshop for a dataset or an empty
217                  string if photoshop does not use the dataset.
218          */
219         static const char* dataSetPsName(uint16_t number, uint16_t recordId);
220         /*!
221           @brief Check if a given dataset is repeatable
222           @param number The dataset number
223           @param recordId The IPTC record Id
224           @return true if the given dataset is repeatable otherwise false
225          */
226         static bool dataSetRepeatable(uint16_t number, uint16_t recordId);
227         /*!
228           @brief Return the dataSet number for dataset name and record id
229 
230           @param dataSetName dataSet name
231           @param recordId recordId
232 
233           @return dataSet number
234 
235           @throw Error if the \em dataSetName or \em recordId are invalid
236          */
237         static uint16_t dataSet(const std::string& dataSetName, uint16_t recordId);
238         //! Return the type for dataSet number and Record id
239         static TypeId dataSetType(uint16_t number, uint16_t recordId);
240         /*!
241           @brief Return the name of the Record
242           @param recordId The record id
243           @return The name of the record or a string containing the hexadecimal
244                   value of the record in the form "0x01ff", if this is an
245                   unknown record.
246          */
247         static std::string recordName(uint16_t recordId);
248         /*!
249            @brief Return the description of a record
250            @param recordId Record Id number
251            @return the description of the Record
252          */
253         static const char* recordDesc(uint16_t recordId);
254         /*!
255            @brief Return the Id number of a record
256            @param recordName Name of a record type
257            @return the Id number of a Record
258            @throw Error if the record is not known;
259          */
260         static uint16_t recordId(const std::string& recordName);
261         //! Return read-only list of built-in Envelope Record datasets
262         static const DataSet* envelopeRecordList();
263         //! Return read-only list of built-in Application2 Record datasets
264         static const DataSet* application2RecordList();
265         //! Print a list of all dataSets to output stream
266         static void dataSetList(std::ostream& os);
267 
268     private:
269         static int dataSetIdx(uint16_t number, uint16_t recordId);
270         static int dataSetIdx(const std::string& dataSetName, uint16_t recordId);
271 
272         static const DataSet* records_[];
273         static const RecordInfo recordInfo_[];
274 
275     }; // class IptcDataSets
276 
277     /*!
278       @brief Concrete keys for IPTC metadata.
279      */
280     class EXIV2API IptcKey : public Key {
281     public:
282         //! Shortcut for an %IptcKey auto pointer.
283         typedef std::auto_ptr<IptcKey> AutoPtr;
284 
285         //! @name Creators
286         //@{
287         /*!
288           @brief Constructor to create an IPTC key from a key string.
289 
290           @param key The key string.
291           @throw Error if the first part of the key is not '<b>Iptc</b>' or
292                  the remaining parts of the key cannot be parsed and
293                  converted to a record name and a dataset name.
294         */
295         explicit IptcKey(const std::string& key);
296         /*!
297           @brief Constructor to create an IPTC key from dataset and record ids.
298           @param tag Dataset id
299           @param record Record id
300          */
301         IptcKey(uint16_t tag, uint16_t record);
302         //! Copy constructor
303         IptcKey(const IptcKey& rhs);
304         //! Destructor
305         virtual ~IptcKey();
306         //@}
307 
308         //! @name Manipulators
309         //@{
310         /*!
311           @brief Assignment operator.
312          */
313         IptcKey& operator=(const IptcKey& rhs);
314         //@}
315 
316         //! @name Accessors
317         //@{
318         virtual std::string key() const;
319         virtual const char* familyName() const;
320         /*!
321           @brief Return the name of the group (the second part of the key).
322                  For IPTC keys, the group name is the record name.
323         */
324         virtual std::string groupName() const;
325         virtual std::string tagName() const;
326         virtual std::string tagLabel() const;
327         virtual uint16_t tag() const;
328         AutoPtr clone() const;
329         //! Return the name of the record
330         std::string recordName() const;
331         //! Return the record id
332         uint16_t record() const;
333         //@}
334 
335     protected:
336         //! @name Manipulators
337         //@{
338         /*!
339           @brief Set the key corresponding to the dataset and record id.
340                  The key is of the form '<b>Iptc</b>.recordName.dataSetName'.
341          */
342         void makeKey();
343         /*!
344           @brief Parse and convert the key string into dataset and record id.
345                  Updates data members if the string can be decomposed, or throws
346                  \em Error.
347 
348           @throw Error if the key cannot be decomposed.
349          */
350         void decomposeKey();
351         //@}
352 
353     private:
354         //! Internal virtual copy constructor.
355         EXV_DLLLOCAL virtual IptcKey* clone_() const;
356 
357         // DATA
358         static const char* familyName_;
359 
360         uint16_t tag_;                 //!< Tag value
361         uint16_t record_;              //!< Record value
362         std::string key_;              //!< Key
363 
364     }; // class IptcKey
365 
366     /*!
367       @brief typedef for string:string map
368      */
369     typedef std::map<std::string,std::string>                 Dictionary;
370     /*!
371       @brief typedef for Dictionary*
372      */
373     typedef Dictionary*                                       Dictionary_p;
374     /*!
375       @brief typedef for Dictionary iterator
376      */
377     typedef Dictionary::const_iterator                        Dictionary_i;
378 
379     /*!
380       @brief typedef for string set (unique strings)
381      */
382     typedef std::set<std::string>                             StringSet;
383     /*!
384       @brief typedef for StringSet*
385      */
386     typedef StringSet*                                        StringSet_p;
387     /*!
388       @brief Class to provide a StringSet iterator
389      */
390     typedef std::set<std::string>::const_iterator             StringSet_i;
391 
392     /*!
393       @brief typedef for string vector
394      */
395     typedef std::vector<std::string>                          StringVector;
396     /*!
397       @brief typedef for StringVector pointer
398      */
399     typedef StringVector*                                     StringVector_p;
400     /*!
401       @brief Class to provide a StringVector iterator
402      */
403     typedef StringVector::const_iterator                      StringVector_i;
404 
405     /*!
406       @brief typedef for uint32_t vector
407      */
408     typedef std::vector<uint32_t>                             Uint32Vector  ;
409     /*!
410       @brief typedef for Uint32Vector pointer
411      */
412     typedef Uint32Vector*                                     Uint32Vector_p;
413     /*!
414       @brief typedef for Uint32Vector iterator
415      */
416     typedef Uint32Vector::const_iterator                      Uint32Vector_i;
417 
418 
419 // *****************************************************************************
420 // free functions
421 
422     //! Output operator for dataSet
423     EXIV2API std::ostream& operator<<(std::ostream& os, const DataSet& dataSet);
424 
425 }                                       // namespace Exiv2
426 
427 #endif                                  // #ifndef DATASETS_HPP_
428