1 /*
2  * exempi - xmp.h
3  *
4  * Copyright (C) 2007-2016 Hubert Figuiere
5  * Copyright 2002-2007 Adobe Systems Incorporated
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1 Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2 Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3 Neither the name of the Authors, nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software wit hout specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
35  * OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #ifndef __EXEMPI_XMP_H_
39 #define __EXEMPI_XMP_H_
40 
41 #include <stdlib.h>
42 /* stdbool choke on Sun (bug #14612) */
43 #if !(defined(__sun) && defined(__cplusplus))
44 #include <stdbool.h>
45 #endif
46 #include <stdint.h>
47 
48 #include <time.h>
49 
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 
54 /* enums grafted from XMP_Const.h */
55 
56 /** Option bits for xmp_files_open() */
57 typedef enum {
58     XMP_OPEN_NOOPTION = 0x00000000,        /**< No open option */
59     XMP_OPEN_READ = 0x00000001,            /**< Open for read-only access. */
60     XMP_OPEN_FORUPDATE = 0x00000002,       /**< Open for reading and writing. */
61     XMP_OPEN_ONLYXMP = 0x00000004,         /**< Only the XMP is wanted,
62                                             * allows space/time optimizations. */
63     XMP_OPEN_CACHETNAIL = 0x00000008,      /**< Cache thumbnail if possible,
64                                             * GetThumbnail will be called. */
65     XMP_OPEN_STRICTLY = 0x00000010,        /**< Be strict about locating XMP
66                                             * and reconciling with other forms. */
67     XMP_OPEN_USESMARTHANDLER = 0x00000020, /**< Require the use of a smart
68                                             * handler. */
69     XMP_OPEN_USEPACKETSCANNING = 0x00000040, /**< Force packet scanning,
70                                               * don't use a smart handler. */
71     XMP_OPEN_LIMITSCANNING = 0x00000080,     /**< Only packet scan files "known"
72                                               * to need scanning. */
73     XMP_OPEN_REPAIR_FILE =
74         0x00000100, /**< Attempt to repair a file opened for update,
75                      * default is to not open (throw an exception). */
76     XMP_OPEN_OPTIMIZEFILELAYOUT =
77         0x00000200, /**< Optimize MPEG4 to support stream when updating
78                      * This can take some time */
79     XMP_OPEN_INBACKGROUND = 0x10000000 /**< Set if calling from background
80                                         * thread. */
81 } XmpOpenFileOptions;
82 
83 /** Option bits for xmp_files_close() */
84 typedef enum {
85     XMP_CLOSE_NOOPTION = 0x0000,  /**< No close option */
86     XMP_CLOSE_SAFEUPDATE = 0x0001 /**< Write into a temporary file and
87                                    * swap for crash safety. */
88 } XmpCloseFileOptions;
89 
90 typedef enum {
91 
92     /* Public file formats. Hex used to avoid gcc warnings. */
93     /* ! Leave them as big endian. There seems to be no decent way on UNIX to
94        determine the target */
95     /* ! endianness at compile time. Forcing it on the client isn't acceptable.
96        */
97 
98     XMP_FT_PDF = 0x50444620UL, /* 'PDF ' */
99     XMP_FT_PS = 0x50532020UL,  /* 'PS  ', general PostScript following DSC
100                                   conventions. */
101     XMP_FT_EPS = 0x45505320UL, /* 'EPS ', encapsulated PostScript. */
102 
103     XMP_FT_JPEG = 0x4A504547UL,   /* 'JPEG' */
104     XMP_FT_JPEG2K = 0x4A505820UL, /* 'JPX ', ISO 15444-1 */
105     XMP_FT_TIFF = 0x54494646UL,   /* 'TIFF' */
106     XMP_FT_GIF = 0x47494620UL,    /* 'GIF ' */
107     XMP_FT_PNG = 0x504E4720UL,    /* 'PNG ' */
108     XMP_FT_WEBP = 0x57454250UL,   /* 'WEBP' */
109 
110     XMP_FT_SWF = 0x53574620UL, /* 'SWF ' */
111     XMP_FT_FLA = 0x464C4120UL, /* 'FLA ' */
112     XMP_FT_FLV = 0x464C5620UL, /* 'FLV ' */
113 
114     XMP_FT_MOV = 0x4D4F5620UL,   /* 'MOV ', Quicktime */
115     XMP_FT_AVI = 0x41564920UL,   /* 'AVI ' */
116     XMP_FT_CIN = 0x43494E20UL,   /* 'CIN ', Cineon */
117     XMP_FT_WAV = 0x57415620UL,   /* 'WAV ' */
118     XMP_FT_MP3 = 0x4D503320UL,   /* 'MP3 ' */
119     XMP_FT_SES = 0x53455320UL,   /* 'SES ', Audition session */
120     XMP_FT_CEL = 0x43454C20UL,   /* 'CEL ', Audition loop */
121     XMP_FT_MPEG = 0x4D504547UL,  /* 'MPEG' */
122     XMP_FT_MPEG2 = 0x4D503220UL, /* 'MP2 ' */
123     XMP_FT_MPEG4 = 0x4D503420UL, /* 'MP4 ', ISO 14494-12 and -14 */
124     XMP_FT_WMAV = 0x574D4156UL,  /* 'WMAV', Windows Media Audio and Video */
125     XMP_FT_AIFF = 0x41494646UL,  /* 'AIFF' */
126 
127     XMP_FT_HTML = 0x48544D4CUL, /* 'HTML' */
128     XMP_FT_XML = 0x584D4C20UL,  /* 'XML ' */
129     XMP_FT_TEXT = 0x74657874UL, /* 'text' */
130 
131     /* Adobe application file formats. */
132     XMP_FT_PHOTOSHOP = 0x50534420UL,   /* 'PSD ' */
133     XMP_FT_ILLUSTRATOR = 0x41492020UL, /* 'AI  ' */
134     XMP_FT_INDESIGN = 0x494E4444UL,    /* 'INDD' */
135     XMP_FT_AEPROJECT = 0x41455020UL,   /* 'AEP ' */
136     XMP_FT_AEPROJTEMPLATE =
137         0x41455420UL, /* 'AET ', After Effects Project Template */
138     XMP_FT_AEFILTERPRESET = 0x46465820UL,  /* 'FFX ' */
139     XMP_FT_ENCOREPROJECT = 0x4E434F52UL,   /* 'NCOR' */
140     XMP_FT_PREMIEREPROJECT = 0x5052504AUL, /* 'PRPJ' */
141     XMP_FT_PREMIERETITLE = 0x5052544CUL,   /* 'PRTL' */
142 
143     /* Catch all. */
144     XMP_FT_UNKNOWN = 0x20202020UL /* '    ' */
145 } XmpFileType;
146 
147 typedef enum {
148 
149     XMP_FMT_CAN_INJECT_XMP = 0x00000001,
150     XMP_FMT_CAN_EXPAND = 0x00000002,
151     XMP_FMT_CAN_REWRITE = 0x00000004,
152     XMP_FMT_PREFERS_IN_PLACE = 0x00000008,
153     XMP_FMT_CAN_RECONCILE = 0x00000010,
154     XMP_FMT_ALLOWS_ONLY_XMP = 0x00000020,
155     XMP_FMT_RETURNS_RAW_PACKET = 0x00000040,
156     XMP_FMT_HANDLER_OWNS_FILE = 0x00000100,
157     XMP_FMT_ALLOW_SAFE_UPDATE = 0x00000200,
158     XMP_FMT_NEEDS_READONLY_PACKET = 0x00000400,
159     XMP_FMT_USE_SIDECAR_XMP = 0x00000800,
160     XMP_FMT_FOLDER_BASED_FORMAT = 0x00001000,
161 
162     _XMP_FMT_LAST
163 } XmpFileFormatOptions;
164 
165 typedef enum {
166     XMP_ITER_CLASSMASK = 0x00FFUL,  /**< The low 8 bits are an enum of
167                                      * what data structure to iterate. */
168     XMP_ITER_PROPERTIES = 0x0000UL, /**< Iterate the property tree of
169                                      * a TXMPMeta object. */
170     XMP_ITER_ALIASES = 0x0001UL,    /**< Iterate the global alias table. */
171     XMP_ITER_NAMESPACES = 0x0002UL, /**< Iterate the global namespace table. */
172     XMP_ITER_JUSTCHILDREN = 0x0100UL,   /**< Just do the immediate children
173                                          * of the root, default is subtree. */
174     XMP_ITER_JUSTLEAFNODES = 0x0200UL,  /**< Just do the leaf nodes, default
175                                          * is all nodes in the subtree. */
176     XMP_ITER_JUSTLEAFNAME = 0x0400UL,   /**< Return just the leaf part of the
177                                          * path, default is the full path. */
178     XMP_ITER_INCLUDEALIASES = 0x0800UL, /**< Include aliases, default is just
179                                          * actual properties. */
180     XMP_ITER_OMITQUALIFIERS = 0x1000UL  /* Omit all qualifiers. */
181 } XmpIterOptions;
182 
183 typedef enum {
184     XMP_ITER_SKIPSUBTREE = 0x0001UL, /**< Skip the subtree below the
185                                       * current node. */
186     XMP_ITER_SKIPSIBLINGS =
187         0x0002UL /**< Skip the subtree below and remaining
188                                                       * siblings of the current
189                   * node. */
190 } XmpIterSkipOptions;
191 
192 typedef enum {
193     /** Options relating to the XML string form of the property value. */
194     XMP_PROP_VALUE_IS_URI = 0x00000002UL, /**< The value is a URI, use
195                                            * rdf:resource attribute.
196                                            * DISCOURAGED */
197     /** Options relating to qualifiers attached to a property. */
198     XMP_PROP_HAS_QUALIFIERS = 0x00000010UL, /**< The property has qualifiers,
199                                              * includes rdf:type and
200                                              * xml:lang. */
201     XMP_PROP_IS_QUALIFIER = 0x00000020UL,   /**< This is a qualifier,
202                                              * includes rdf:type and
203                                              * xml:lang. */
204     XMP_PROP_HAS_LANG = 0x00000040UL,       /**< Implies XMP_PropHasQualifiers,
205                                              * property has xml:lang. */
206     XMP_PROP_HAS_TYPE = 0x00000080UL,       /**< Implies XMP_PropHasQualifiers,
207                                              * property has rdf:type. */
208 
209     /* Options relating to the data structure form. */
210     XMP_PROP_VALUE_IS_STRUCT = 0x00000100UL, /**< The value is a structure
211                                               * with nested fields. */
212     XMP_PROP_VALUE_IS_ARRAY = 0x00000200UL,  /**< The value is an array
213                                               * (RDF alt/bag/seq). */
214     XMP_PROP_ARRAY_IS_UNORDERED = XMP_PROP_VALUE_IS_ARRAY, /**< The item order
215                                                             * does not matter.*/
216     XMP_PROP_ARRAY_IS_ORDERED = 0x00000400UL, /**< Implies XMP_PropValueIsArray,
217                                                * item order matters. */
218     XMP_PROP_ARRAY_IS_ALT = 0x00000800UL, /**< Implies XMP_PropArrayIsOrdered,
219                                            * items are alternates. */
220 
221     /** Additional struct and array options. */
222     XMP_PROP_ARRAY_IS_ALTTEXT =
223         0x00001000UL, /**< Implies kXMP_PropArrayIsAlternate,
224                        * items are localized text. */
225     XMP_PROP_ARRAY_INSERT_BEFORE =
226         0x00004000UL,                           /**< Used by array functions. */
227     XMP_PROP_ARRAY_INSERT_AFTER = 0x00008000UL, /**< Used by array functions. */
228 
229     /* Other miscellaneous options. */
230     XMP_PROP_IS_ALIAS = 0x00010000UL,    /**< This property is an alias name for
231                                             another property. */
232     XMP_PROP_HAS_ALIASES = 0x00020000UL, /**< This property is the base value
233                                             for a set of aliases. */
234     XMP_PROP_IS_INTERNAL = 0x00040000UL, /**< This property is an "internal"
235                                             property, owned by applications. */
236     XMP_PROP_IS_STABLE = 0x00100000UL,   /**< This property is not derived from
237                                           * the document content.
238                                             */
239     XMP_PROP_IS_DERIVED = 0x00200000UL,  /**< This property is derived from the
240                                             document content. */
241     /* kXMPUtil_AllowCommas   = 0x10000000UL,  ! Used by
242        TXMPUtils::CatenateArrayItems and ::SeparateArrayItems. */
243     /* kXMP_DeleteExisting    = 0x20000000UL,  ! Used by TXMPMeta::SetXyz
244        functions to delete any pre-existing property. */
245     /* kXMP_SchemaNode        = 0x80000000UL,  ! Returned by iterators - #define
246        to avoid warnings */
247 
248     /* Masks that are multiple flags. */
249     XMP_PROP_ARRAY_FORM_MASK = XMP_PROP_VALUE_IS_ARRAY |
250                                XMP_PROP_ARRAY_IS_ORDERED |
251                                XMP_PROP_ARRAY_IS_ALT |
252                                XMP_PROP_ARRAY_IS_ALTTEXT,
253     XMP_PROP_COMPOSITE_MASK = XMP_PROP_VALUE_IS_STRUCT |
254                               XMP_PROP_ARRAY_FORM_MASK, /* Is it simple or
255                                                            composite (array or
256                                                            struct)? */
257     XMP_IMPL_RESERVED_MASK =
258         0x70000000L /**< Reserved for transient use by the implementation. */
259 } XmpPropsBits;
260 
261 /* convenience macros */
262 
263 /** set option bits */
264 #define XMP_SET_OPTION(var, opt) var |= (opt)
265 /** clear option bits */
266 #define XMP_CLEAR_OPTION(var, opt) var &= ~(opt)
267 /** test if option is set */
268 #define XMP_TEST_OPTION_SET(var, opt) (((var) & (opt)) != 0)
269 /** test if option is clear */
270 #define XMP_TEST_OPTION_CLEAR(var, opt) (((var) & (opt)) == 0)
271 
272 #define XMP_IS_PROP_SIMPLE(opt) (((opt)&XMP_PROP_COMPOSITE_MASK) == 0)
273 #define XMP_IS_PROP_STRUCT(opt) (((opt)&XMP_PROP_VALUE_IS_STRUCT) != 0)
274 #define XMP_IS_PROP_ARRAY(opt) (((opt)&XMP_PROP_VALUE_IS_ARRAY) != 0)
275 #define XMP_IS_ARRAY_UNORDERED(opt) (((opt)&XMP_PROP_ARRAY_IS_ORDERED) == 0)
276 #define XMP_IS_ARRAY_ORDERED(opt) (((opt)&XMP_PROP_ARRAY_IS_ORDERED) != 0)
277 #define XMP_IS_ARRAY_ALT(opt) (((opt)&XMP_PROP_ARRAY_IS_ALT) != 0)
278 #define XMP_IS_ARRAY_ALTTEXT(opt) (((opt)&XMP_PROP_ARRAY_IS_ALTTEXT) != 0)
279 
280 #define XMP_HAS_PROP_QUALIFIERS(opt) (((opt)&XMP_PROP_HAS_QUALIFIERS) != 0)
281 #define XMP_IS_PROP_QUALIFIER(opt) (((opt)&XMP_PROP_IS_QUALIFIER) != 0)
282 #define XMP_HAS_PROP_LANG(opt) (((opt)&XMP_PROP_HAS_LANG) != 0)
283 
284 #define XMP_IS_NODE_SCHEMA(opt) (((opt)&XMP_SCHEMA_NODE) != 0)
285 #define XMP_IS_PROP_ALIAS(opt) (((opt)&XMP_PROP_IS_ALIAS) != 0)
286 
287 enum {                                          /* Options for xmp_serialize */
288        XMP_SERIAL_OMITPACKETWRAPPER = 0x0010UL, /**< Omit the XML packet
289                                                  * wrapper. */
290        XMP_SERIAL_READONLYPACKET = 0x0020UL,    /**< Default is a writeable
291                                                  * packet. */
292        XMP_SERIAL_USECOMPACTFORMAT = 0x0040UL,  /**< Use a compact form of
293                                                  * RDF. */
294 
295        XMP_SERIAL_INCLUDETHUMBNAILPAD =
296            0x0100UL,                            /**< Include a padding allowance
297                                                  * for a thumbnail image. */
298        XMP_SERIAL_EXACTPACKETLENGTH = 0x0200UL, /**< The padding parameter is
299                                                  * the overall packet length. */
300        XMP_SERIAL_WRITEALIASCOMMENTS = 0x0400UL, /**< Show aliases as XML
301                                                   * comments. */
302        XMP_SERIAL_OMITALLFORMATTING = 0x0800UL,  /**< Omit all formatting
303                                                   * whitespace. */
304 
305        _XMP_LITTLEENDIAN_BIT =
306            0x0001UL, /* ! Don't use directly, see the combined values below! */
307        _XMP_UTF16_BIT = 0x0002UL,
308        _XMP_UTF32_BIT = 0x0004UL,
309 
310        XMP_SERIAL_ENCODINGMASK = 0x0007UL,
311        XMP_SERIAL_ENCODEUTF8 = 0UL,
312        XMP_SERIAL_ENCODEUTF16BIG = _XMP_UTF16_BIT,
313        XMP_SERIAL_ENCODEUTF16LITTLE = _XMP_UTF16_BIT | _XMP_LITTLEENDIAN_BIT,
314        XMP_SERIAL_ENCODEUTF32BIG = _XMP_UTF32_BIT,
315        XMP_SERIAL_ENCODEUTF32LITTLE = _XMP_UTF32_BIT | _XMP_LITTLEENDIAN_BIT
316 };
317 
318 /** pointer to XMP packet. Opaque. */
319 typedef struct _Xmp *XmpPtr;
320 typedef struct _XmpFile *XmpFilePtr;
321 typedef struct _XmpString *XmpStringPtr;
322 typedef struct _XmpIterator *XmpIteratorPtr;
323 
324 typedef struct _XmpDateTime {
325     int32_t year;
326     int32_t month;    /* 1..12 */
327     int32_t day;      /* 1..31 */
328     int32_t hour;     /* 0..23 */
329     int32_t minute;   /* 0..59 */
330     int32_t second;   /* 0..59 */
331     int32_t tzSign;   /* -1..+1, 0 means UTC, -1 is west, +1 is east. */
332     int32_t tzHour;   /* 0..23 */
333     int32_t tzMinute; /* 0..59 */
334     int32_t nanoSecond;
335 } XmpDateTime;
336 
337 typedef struct _XmpPacketInfo {
338   /// Packet offset in the file in bytes, -1 if unknown.
339   int64_t offset;
340   /// Packet length in the file in bytes, -1 if unknown.
341   int32_t length;
342   /// Packet padding size in bytes, zero if unknown.
343   int32_t padSize;
344 
345   /// Character format using the values \c kXMP_Char8Bit,
346   /// \c kXMP_Char16BitBig, etc.
347   uint8_t  charForm;
348   /// True if there is a packet wrapper and the trailer says writeable
349   /// by dumb packet scanners.
350   bool  writeable;
351   /// True if there is a packet wrapper, the "<?xpacket...>"
352   /// XML processing instructions.
353   bool  hasWrapper;
354 
355   /// Padding to make the struct's size be a multiple 4.
356   uint8_t  pad;
357 } XmpPacketInfo;
358 
359 /** Values used for tzSign field. */
360 enum {
361     XMP_TZ_WEST = -1, /**< West of UTC   */
362     XMP_TZ_UTC = 0,   /**< UTC           */
363     XMP_TZ_EAST = +1  /**< East of UTC   */
364 };
365 
366 /** Init the library. Must be called before anything else */
367 bool xmp_init(void);
368 void xmp_terminate(void);
369 
370 /** get the error code that last occurred.
371  * @todo make this thread-safe. Getting the error code
372  * from another thread than the on it occurred in is undefined.
373  */
374 int xmp_get_error(void);
375 
376 XmpFilePtr xmp_files_new(void);
377 
378 /** Open a file to load the XMP from.
379  * @param path the file path
380  * @param options open flags
381  * @return an XmpFilePtr if successful.
382  */
383 XmpFilePtr xmp_files_open_new(const char *path, XmpOpenFileOptions options);
384 
385 /** Open a file to load the XMP from into an existing XmpFile.
386  * See %xmp_file_open_new
387  * @paran xf the XmpFilePtr to load into.
388  * @param path the file path
389  * @param options open flags
390  * @return true if successful.
391  */
392 bool xmp_files_open(XmpFilePtr xf, const char *path, XmpOpenFileOptions options);
393 
394 /** Close an XMP file. Will flush the changes
395  * @param xf the file object
396  * @param options the options to close.
397  * @return true on succes, false on error
398  * xmp_get_error() will give the error code.
399  */
400 bool xmp_files_close(XmpFilePtr xf, XmpCloseFileOptions options);
401 
402 /** Get the XMP packet from the file
403  * If the file has a handler, the handler will be used and reconcile depending
404  * on the options. Otherwise it will try to locate the XMP packet wrapper.
405  * Note: a XMP sidecar shouldn't have a pacet wrapper, therefor it shouldn't
406  * recognized by this.
407  * @param xf the %XmpFilePtr to get the XMP packet from
408  * @return a newly allocated XmpPtr. Use %xmp_free to release it.
409  */
410 XmpPtr xmp_files_get_new_xmp(XmpFilePtr xf);
411 
412 /** File the XMP packet from the file
413  * See %xmp_files_get_new_xmp
414  * @param xf the %XmpFilePtr to get the XMP packet from
415  * @param xmp the XMP Packet to fill. Must be valid.
416  */
417 bool xmp_files_get_xmp(XmpFilePtr xf, XmpPtr xmp);
418 bool xmp_files_get_xmp_xmpstring(XmpFilePtr xf, XmpStringPtr xmp_packet,
419                                  XmpPacketInfo* packet_info);
420 
421 bool xmp_files_can_put_xmp(XmpFilePtr xf, XmpPtr xmp);
422 bool xmp_files_can_put_xmp_xmpstring(XmpFilePtr xf, XmpStringPtr xmp_packet);
423 bool xmp_files_can_put_xmp_cstr(XmpFilePtr xf, const char* xmp_packet,
424                                 size_t len);
425 
426 bool xmp_files_put_xmp(XmpFilePtr xf, XmpPtr xmp);
427 bool xmp_files_put_xmp_xmpstring(XmpFilePtr xf, XmpStringPtr xmp_packet);
428 bool xmp_files_put_xmp_cstr(XmpFilePtr xf, const char* xmp_packet, size_t len);
429 
430 /** Get the file info from the open file
431  * @param xf the file object
432  * @param[out] filePath the file path object to store the path in. Pass NULL if
433  * not needed.
434  * @param[out] options the options for open. Pass NULL if not needed.
435  * @param[out] file_format the detected file format. Pass NULL if not needed.
436  * @param[out] handler_flags the format options like from
437  * %xmp_files_get_format_info.
438  * @return false in case of error.
439  */
440 bool xmp_files_get_file_info(XmpFilePtr xf, XmpStringPtr filePath,
441                              XmpOpenFileOptions *options,
442                              XmpFileType *file_format,
443                              XmpFileFormatOptions *handler_flags);
444 
445 /** Free a XmpFilePtr
446  * @param xf the file ptr. Cannot be NULL
447  * @return false on error.
448  * Calll %xmp_get_error to retrieve the error code.
449  */
450 bool xmp_files_free(XmpFilePtr xf);
451 
452 /** Get the format info
453  * @param format type identifier
454  * @param options the options for the file format handler
455  * @return false on error
456  */
457 bool xmp_files_get_format_info(XmpFileType format,
458                                XmpFileFormatOptions *options);
459 
460 /** Check the file format of a file. Use the same logic as in xmp_files_open().
461  * A file that doesn't have a handler will be considered as unknown. This doesn't
462  * mean that xmp_files_get_new_xmp() will fail.
463  * @param filePath the path to the file
464  * @return XMP_FT_UNKNOWN on error or if the file type is unknown
465  */
466 XmpFileType xmp_files_check_file_format(const char *filePath);
467 
468 /** Register a new namespace to add properties to
469  *  This is done automatically when reading the metadata block
470  *  @param namespaceURI the namespace URI to register
471  *  @param suggestedPrefix the suggested prefix
472  *  @param registeredPrefix the really registered prefix. Not necessarily
473  *  %suggestedPrefix.
474  *  @return true if success, false otherwise.
475  */
476 bool xmp_register_namespace(const char *namespaceURI,
477                             const char *suggestedPrefix,
478                             XmpStringPtr registeredPrefix);
479 
480 /** Check is a namespace is registered
481  *  @param ns the namespace to check.
482  *  @param prefix The prefix associated if registered. Pass NULL
483  *  if not interested.
484  *  @return true if registered.
485  *  NEW in 2.1
486  */
487 bool xmp_namespace_prefix(const char *ns, XmpStringPtr prefix);
488 
489 /** Check if a ns prefix is registered.
490  *  @param prefix the prefix to check.
491  *  @param ns the namespace associated if registered. Pass NULL
492  *  if not interested.
493  *  @return true if registered.
494  *  NEW in 2.1
495  */
496 bool xmp_prefix_namespace_uri(const char *prefix, XmpStringPtr ns);
497 
498 /** Create a new empty XMP packet
499  * @return the packet pointer. Must be free with xmp_free()
500  */
501 XmpPtr xmp_new_empty(void);
502 
503 /** Create a new XMP packet
504  * @param buffer the buffer to load data from. UTF-8 encoded.
505  * @param len the buffer length in byte
506  * @return the packet pointer. Must be free with xmp_free()
507  */
508 XmpPtr xmp_new(const char *buffer, size_t len);
509 
510 /** Create a new XMP packet from the one passed.
511  * @param xmp the instance to copy. Can be NULL.
512  * @return the packet pointer. NULL is failer (or NULL is passed).
513  */
514 XmpPtr xmp_copy(XmpPtr xmp);
515 
516 /** Free the xmp packet
517  * @param xmp the xmp packet to free
518  */
519 bool xmp_free(XmpPtr xmp);
520 
521 /** Parse the XML passed through the buffer and load it.
522  * @param xmp the XMP packet.
523  * @param buffer the buffer.
524  * @param len the length of the buffer.
525  */
526 bool xmp_parse(XmpPtr xmp, const char *buffer, size_t len);
527 
528 /** Serialize the XMP Packet to the given buffer
529  * @param xmp the XMP Packet
530  * @param buffer the buffer to write the XMP to
531  * @param options options on how to write the XMP.  See XMP_SERIAL_*
532  * @param padding number of bytes of padding, useful for modifying
533  *                embedded XMP in place.
534  * @return TRUE if success.
535  */
536 bool xmp_serialize(XmpPtr xmp, XmpStringPtr buffer, uint32_t options,
537                    uint32_t padding);
538 
539 /** Serialize the XMP Packet to the given buffer with formatting
540  * @param xmp the XMP Packet
541  * @param buffer the buffer to write the XMP to
542  * @param options options on how to write the XMP.  See XMP_SERIAL_*
543  * @param padding number of bytes of padding, useful for modifying
544  *                embedded XMP in place.
545  * @param newline the new line character to use
546  * @param tab the indentation character to use
547  * @param indent the initial indentation level
548  * @return TRUE if success.
549  */
550 bool xmp_serialize_and_format(XmpPtr xmp, XmpStringPtr buffer, uint32_t options,
551                               uint32_t padding, const char *newline,
552                               const char *tab, int32_t indent);
553 
554 /** Get an XMP property and it option bits from the XMP packet
555  * @param xmp the XMP packet
556  * @param schema
557  * @param name
558  * @param property the allocated XmpStringPtr
559  * @param propsBits pointer to the option bits. Pass NULL if not needed
560  * @return true if found
561  */
562 bool xmp_get_property(XmpPtr xmp, const char *schema, const char *name,
563                       XmpStringPtr property, uint32_t *propsBits);
564 
565 bool xmp_get_property_date(XmpPtr xmp, const char *schema, const char *name,
566                            XmpDateTime *property, uint32_t *propsBits);
567 bool xmp_get_property_float(XmpPtr xmp, const char *schema, const char *name,
568                             double *property, uint32_t *propsBits);
569 bool xmp_get_property_bool(XmpPtr xmp, const char *schema, const char *name,
570                            bool *property, uint32_t *propsBits);
571 bool xmp_get_property_int32(XmpPtr xmp, const char *schema, const char *name,
572                             int32_t *property, uint32_t *propsBits);
573 bool xmp_get_property_int64(XmpPtr xmp, const char *schema, const char *name,
574                             int64_t *property, uint32_t *propsBits);
575 
576 /** Get an item frpm an array property
577  * @param xmp the xmp meta
578  * @param schema the schema
579  * @param name the property name
580  * @param index the index in the array
581  * @param property the property value
582  * @param propsBits the property bits. Pass NULL is unwanted.
583  * @return TRUE if success.
584  */
585 bool xmp_get_array_item(XmpPtr xmp, const char *schema, const char *name,
586                         int32_t index, XmpStringPtr property,
587                         uint32_t *propsBits);
588 
589 /** Set an XMP property in the XMP packet
590  * @param xmp the XMP packet
591  * @param schema
592  * @param name
593  * @param value 0 terminated string
594  * @param optionBits
595  * @return false if failure
596  */
597 bool xmp_set_property(XmpPtr xmp, const char *schema, const char *name,
598                       const char *value, uint32_t optionBits);
599 
600 /** Set a date XMP property in the XMP packet
601  * @param xmp the XMP packet
602  * @param schema
603  * @param name
604  * @param value the date-time struct
605  * @param optionBits
606  * @return false if failure
607  */
608 bool xmp_set_property_date(XmpPtr xmp, const char *schema, const char *name,
609                            const XmpDateTime *value, uint32_t optionBits);
610 
611 /** Set a float XMP property in the XMP packet
612  * @param xmp the XMP packet
613  * @param schema
614  * @param name
615  * @param value the float value
616  * @param optionBits
617  * @return false if failure
618  */
619 bool xmp_set_property_float(XmpPtr xmp, const char *schema, const char *name,
620                             double value, uint32_t optionBits);
621 bool xmp_set_property_bool(XmpPtr xmp, const char *schema, const char *name,
622                            bool value, uint32_t optionBits);
623 bool xmp_set_property_int32(XmpPtr xmp, const char *schema, const char *name,
624                             int32_t value, uint32_t optionBits);
625 bool xmp_set_property_int64(XmpPtr xmp, const char *schema, const char *name,
626                             int64_t value, uint32_t optionBits);
627 
628 bool xmp_set_array_item(XmpPtr xmp, const char *schema, const char *name,
629                         int32_t index, const char *value, uint32_t optionBits);
630 
631 /** Append a value to the XMP Property array in the XMP Packet provided
632  * @param xmp the XMP packet
633  * @param schema the schema of the property
634  * @param name the name of the property
635  * @param arrayOptions option bits of the parent array
636  * @param value null-terminated string
637  * @param optionBits option bits of the value itself.
638  */
639 bool xmp_append_array_item(XmpPtr xmp, const char *schema, const char *name,
640                            uint32_t arrayOptions, const char *value,
641                            uint32_t optionBits);
642 
643 /** Delete a property from the XMP Packet provided
644  * @param xmp the XMP packet
645  * @param schema the schema of the property
646  * @param name the name of the property
647  */
648 bool xmp_delete_property(XmpPtr xmp, const char *schema, const char *name);
649 
650 /** Determines if a property exists in the XMP Packet provided
651  * @param xmp the XMP packet
652  * @param schema the schema of the property. Can't be NULL or empty.
653  * @param name the name of the property. Can't be NULL or empty.
654  * @return true is the property exists
655  */
656 bool xmp_has_property(XmpPtr xmp, const char *schema, const char *name);
657 
658 /** Get a localised text from a localisable property.
659  * @param xmp the XMP packet
660  * @param schema the schema
661  * @param name the property name.
662  * @param genericLang the generic language you may want as a fall back.
663  * Can be NULL or empty.
664  * @param specificLang the specific language you want. Can't be NULL or empty.
665  * @param actualLang the actual language of the value. Can be NULL if
666  * not wanted.
667  * @param itemValue the localized value. Can be NULL if not wanted.
668  * @param propBits the options flags describing the property. Can be NULL.
669  * @return true if found, false otherwise.
670  */
671 bool xmp_get_localized_text(XmpPtr xmp, const char *schema, const char *name,
672                             const char *genericLang, const char *specificLang,
673                             XmpStringPtr actualLang, XmpStringPtr itemValue,
674                             uint32_t *propBits);
675 
676 /** Set a localised text in a localisable property.
677  * @param xmp the XMP packet
678  * @param schema the schema
679  * @param name the property name.
680  * @param genericLang the generic language you may want to set too.
681  * Can be NULL or empty.
682  * @param specificLang the specific language you want. Can't be NULL or empty.
683  * @param value the localized value. Cannot be NULL.
684  * @param optionBits the options flags describing the property.
685  * @return true if set, false otherwise.
686  */
687 bool xmp_set_localized_text(XmpPtr xmp, const char *schema, const char *name,
688                             const char *genericLang, const char *specificLang,
689                             const char *value, uint32_t optionBits);
690 
691 bool xmp_delete_localized_text(XmpPtr xmp, const char *schema, const char *name,
692                                const char *genericLang,
693                                const char *specificLang);
694 
695 /** Instanciate a new string
696  * @return the new instance. Must be freed with
697  * xmp_string_free()
698  */
699 XmpStringPtr xmp_string_new(void);
700 
701 /** Free a XmpStringPtr
702  * @param s the string to free
703  */
704 void xmp_string_free(XmpStringPtr s);
705 
706 /** Get the C string from the XmpStringPtr
707  * @param s the string object
708  * @return the const char * for the XmpStringPtr. It
709  * belong to the object.
710  */
711 const char * xmp_string_cstr(XmpStringPtr s);
712 
713 /** Get the string length from the XmpStringPtr
714  * @param s the string object
715  * @return the string length. The unerlying implementation has it.
716  */
717 size_t xmp_string_len(XmpStringPtr s);
718 
719 /** Create a new iterator.
720  * @param xmp the packet
721  * @param schema the property schema
722  * @param propName the property name
723  * @param options
724  * @return an iterator must be freed with % xmp_iterator_free
725  */
726 XmpIteratorPtr xmp_iterator_new(XmpPtr xmp, const char *schema,
727                                 const char *propName, XmpIterOptions options);
728 
729 /** Free an iterator.
730  * @param iter the iterator to free.
731  */
732 bool xmp_iterator_free(XmpIteratorPtr iter);
733 
734 /** Iterate to the next value
735  * @param iter the iterator
736  * @param schema the schema name. Pass NULL if not wanted
737  * @param propName the property path. Pass NULL if not wanted
738  * @param propValue the value of the property. Pass NULL if not wanted.
739  * @param options the options for the property. Pass NULL if not wanted.
740  * @return true if still something, false if none
741  */
742 bool xmp_iterator_next(XmpIteratorPtr iter, XmpStringPtr schema,
743                        XmpStringPtr propName, XmpStringPtr propValue,
744                        uint32_t *options);
745 
746 /**
747  */
748 bool xmp_iterator_skip(XmpIteratorPtr iter, XmpIterSkipOptions options);
749 
750 /** Compare two XmpDateTime
751  * @param left value
752  * @param right value
753  * @return if left < right, return < 0. If left > right, return > 0.
754  * if left == right, return 0.
755  */
756 int xmp_datetime_compare(XmpDateTime *left, XmpDateTime *right);
757 
758 #ifdef __cplusplus
759 }
760 #endif
761 
762 #endif
763