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