1 #ifndef __TXMPFiles_hpp__ 2 #define __TXMPFiles_hpp__ 1 3 4 #if ( ! __XMP_hpp__ ) 5 #error "Do not directly include, use XMP.hpp" 6 #endif 7 8 // ================================================================================================= 9 // ADOBE SYSTEMS INCORPORATED 10 // Copyright 2002 Adobe Systems Incorporated 11 // All Rights Reserved 12 // 13 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms 14 // of the Adobe license agreement accompanying it. 15 // ================================================================================================= 16 17 // ================================================================================================= 18 /// \file TXMPFiles.hpp 19 /// \brief API for access to the main (document-level) metadata in a file_. 20 /// 21 /// The Adobe XMP Toolkit's file handling component, XMPFiles, is a front end to a set of 22 /// format-specific file handlers that support file I/O for XMP. The file handlers implement smart, 23 /// efficient support for those file formats for which the means to embed XMP is defined in the XMP 24 /// Specification. Where possible, this support allows: 25 /// \li Injection of XMP where none currently exists 26 /// \li Expansion of XMP without regard to existing padding 27 /// \li Reconciliation of the XMP and other legacy forms of metadata. 28 /// 29 /// \c TXMPFiles is designed for use by clients interested in the metadata and not in the primary 30 /// file content; the Adobe Bridge application is a typical example. \c TXMPFiles is not intended to 31 /// be appropriate for files authored by an application; that is, those files for which the 32 /// application has explicit knowledge of the file format. 33 // ================================================================================================= 34 35 36 // ================================================================================================= 37 /// \class TXMPFiles TXMPFiles.hpp 38 /// \brief API for access to the main (document-level) metadata in a file. 39 /// 40 /// \c TXMPFiles is a template class that provides the API for the Adobe XMP Toolkit's XMPFiles 41 /// component. This provides convenient access to the main, or document level, XMP for a file. Use 42 /// it to obtain metadata from a file, which you can then manipulate with the XMP Core component 43 /// (the classes \c TXMPMeta, \c TXMPUtils, and \c TXMPIterator); and to write new or changed 44 /// metadata back out to a file. 45 /// 46 /// The functions allow you to open a file, read and write the metadata, then close the file. 47 /// While open, portions of the file might be maintained in RAM data structures. Memory 48 /// usage can vary considerably depending onfile format and access options. 49 /// 50 /// A file can be opened for read-only or read-write access, with typical exclusion for both 51 /// modes. Errors result in the throw of an \c XMPError exception. 52 /// 53 /// \c TXMPFiles is the template class. It must be instantiated with a string class such as 54 /// \c std::string. Read the Toolkit Overview for information about the overall architecture of the XMP 55 /// API, and the documentation for \c XMP.hpp for specific instantiation instructions. 56 /// 57 /// Access these functions through the concrete class, \c SXMPFiles. 58 // ================================================================================================= 59 60 61 #if XMP_StaticBuild // ! Client XMP_IO objects can only be used in static builds. 62 #include "XMP_IO.hpp" 63 #endif 64 65 66 template <class tStringObj> 67 class TXMPFiles { 68 69 public: 70 71 // ============================================================================================= 72 /// \name Initialization and termination 73 /// @{ 74 /// 75 /// A \c TXMPFiles object must be initialized before use and can be terminated when done. 76 77 // --------------------------------------------------------------------------------------------- 78 /// @brief \c GetVersionInfo() retrieves version information for the XMPFiles component. 79 /// 80 /// Can be called before \c #Initialize(). This function is static; make the call directly from 81 /// the concrete class (\c SXMPFiles). 82 /// 83 /// @param versionInfo [out] A buffer in which to return the version information. 84 85 static void GetVersionInfo ( XMP_VersionInfo * versionInfo ); 86 87 // --------------------------------------------------------------------------------------------- 88 /// @brief Initializes the XMPFiles library; must be called before creating an \c SXMPFiles object. 89 /// 90 /// The main action is to activate the available smart file handlers. Must be called before 91 /// using any methods except \c GetVersionInfo(). 92 /// 93 /// This function is static; make the call directly from the concrete class (\c SXMPFiles). 94 /// 95 /// @return True on success. 96 97 static bool Initialize(); 98 99 // --------------------------------------------------------------------------------------------- 100 /// @brief Initializes the XMPFiles library; must be called before creating an \c SXMPFiles object. 101 /// 102 /// This overload of TXMPFiles::Initialize() accepts option bits to customize the initialization 103 /// actions. At this time no option is defined. 104 /// 105 /// The main action is to activate the available smart file handlers. Must be called before 106 /// using any methods except \c GetVersionInfo(). 107 /// 108 /// This function is static; make the call directly from the concrete class (\c SXMPFiles). 109 /// 110 /// @param options Option flags to control the initialization actions. 111 /// 112 /// @return True on success. 113 114 static bool Initialize ( XMP_OptionBits options ); 115 116 // --------------------------------------------------------------------------------------------- 117 /// @brief Initializes the XMPFiles library; must be called before creating an \c SXMPFiles object. 118 /// 119 /// This overload of TXMPFiles::Initialize() accepts plugin directory and name of the plug-ins 120 /// as a comma separated list to load the file handler plug-ins. If plugins == NULL, then all 121 /// plug-ins present in the plug-in directory will be loaded. 122 /// 123 /// The main action is to activate the available smart file handlers. Must be called before 124 /// using any methods except \c GetVersionInfo(). 125 /// 126 /// This function is static; make the call directly from the concrete class (\c SXMPFiles). 127 /// 128 /// @param pluginFolder Pugin directorty to load the file handler plug-ins. 129 /// @param plugins Comma sepearted list of plug-ins which should be loaded from the plug-in directory. 130 /// If plugin == NULL, then all plug-ins availbale in the plug-in directory will be loaded. 131 /// 132 /// @return True on success. 133 134 static bool Initialize ( const char* pluginFolder, const char* plugins = NULL ); 135 136 // --------------------------------------------------------------------------------------------- 137 /// @brief Initializes the XMPFiles library; must be called before creating an \c SXMPFiles object. 138 /// 139 /// This overload of TXMPFiles::Initialize( XMP_OptionBits options ) accepts plugin directory and 140 /// name of the plug-ins as a comma separated list to load the file handler plug-ins. 141 /// If plugins == NULL, then all plug-ins present in the plug-in directory will be loaded. 142 /// 143 /// The main action is to activate the available smart file handlers. Must be called before 144 /// using any methods except \c GetVersionInfo(). 145 /// 146 /// This function is static; make the call directly from the concrete class (\c SXMPFiles). 147 /// 148 /// @param options Option flags to control the initialization actions. 149 /// @param pluginFolder Pugin directorty to load the file handler plug-ins. 150 /// @param plugins Comma sepearted list of plug-ins which should be loaded from the plug-in directory. 151 /// If plugin == NULL, then all plug-ins availbale in the plug-in directory will be loaded. 152 /// 153 /// @return True on success. 154 155 static bool Initialize ( XMP_OptionBits options, const char* pluginFolder, const char* plugins = NULL ); 156 157 // --------------------------------------------------------------------------------------------- 158 /// @brief Terminates use of the XMPFiles library. 159 /// 160 /// Optional. Deallocates global data structures created by intialization. Its main action is to 161 /// deallocate heap-allocated global storage, for the benefit of client leak checkers. 162 /// 163 /// This function is static; make the call directly from the concrete class (\c SXMPFiles). 164 165 static void Terminate(); 166 167 /// @} 168 169 // ============================================================================================= 170 /// \name Constructors and destructor 171 /// @{ 172 /// 173 /// The default constructor initializes an object that is associated with no file. The alternate 174 /// constructors call \c OpenFile(). 175 176 // --------------------------------------------------------------------------------------------- 177 /// @brief Default constructor initializes an object that is associated with no file. 178 179 TXMPFiles(); 180 181 // --------------------------------------------------------------------------------------------- 182 /// @brief Destructor; typical virtual destructor. 183 /// 184 /// The destructor does not call \c CloseFile(); pending updates are lost when the destructor is run. 185 /// 186 /// @see \c OpenFile(), \c CloseFile() 187 188 virtual ~TXMPFiles() throw(); 189 190 // --------------------------------------------------------------------------------------------- 191 /// @brief Alternate constructor associates the new \c XMPFiles object with a specific file. 192 /// 193 /// Calls \c OpenFile() to open the specified file after performing a default construct. 194 /// 195 /// @param filePath The path for the file, specified as a nul-terminated UTF-8 string. 196 /// 197 /// @param format A format hint for the file, if known. 198 /// 199 /// @param openFlags Options for how the file is to be opened (for read or read/write, for 200 /// example). Use a logical OR of these bit-flag constants: 201 /// 202 /// \li \c #kXMPFiles_OpenForRead 203 /// \li \c #kXMPFiles_OpenForUpdate 204 /// \li \c #kXMPFiles_OpenOnlyXMP 205 /// \li \c #kXMPFiles_OpenStrictly 206 /// \li \c #kXMPFiles_OpenUseSmartHandler 207 /// \li \c #kXMPFiles_OpenUsePacketScanning 208 /// \li \c #kXMPFiles_OpenLimitedScanning 209 /// 210 /// @return The new \c TXMPFiles object. 211 212 TXMPFiles ( XMP_StringPtr filePath, 213 XMP_FileFormat format = kXMP_UnknownFile, 214 XMP_OptionBits openFlags = 0 ); 215 216 // --------------------------------------------------------------------------------------------- 217 /// @brief Alternate constructor associates the new \c XMPFiles object with a specific file, 218 /// using a string object. 219 /// 220 /// Overloads the basic form of the function, allowing you to pass a string object 221 /// for the file path. It is otherwise identical; see details in the canonical form. 222 223 TXMPFiles ( const tStringObj & filePath, 224 XMP_FileFormat format = kXMP_UnknownFile, 225 XMP_OptionBits openFlags = 0 ); 226 227 // --------------------------------------------------------------------------------------------- 228 /// @brief Copy constructor 229 /// 230 /// Increments an internal reference count but does not perform a deep copy. 231 /// 232 /// @param original The existing \c TXMPFiles object to copy. 233 /// 234 /// @return The new \c TXMPFiles object. 235 236 TXMPFiles ( const TXMPFiles<tStringObj> & original ); 237 238 // --------------------------------------------------------------------------------------------- 239 /// @brief Assignment operator 240 /// 241 /// Increments an internal reference count but does not perform a deep copy. 242 /// 243 /// @param rhs The existing \c TXMPFiles object. 244 245 void operator= ( const TXMPFiles<tStringObj> & rhs ); 246 247 // --------------------------------------------------------------------------------------------- 248 /// @brief Reconstructs a \c TXMPFiles object from an internal reference. 249 /// 250 /// This constructor creates a new \c TXMPFiles object that refers to the underlying reference 251 /// object of an existing \c TXMPFiles object. Use to safely pass \c SXMPFiles references across 252 /// DLL boundaries. 253 /// 254 /// @param xmpFilesObj The underlying reference object, obtained from some other XMP object 255 /// with \c TXMPFiles::GetInternalRef(). 256 /// 257 /// @return The new object. 258 259 TXMPFiles ( XMPFilesRef xmpFilesObj ); 260 261 // --------------------------------------------------------------------------------------------- 262 /// @brief GetInternalRef() retrieves an internal reference that can be safely passed across DLL 263 /// boundaries and reconstructed. 264 /// 265 /// Use with the reconstruction constructor to safely pass \c SXMPFiles references across DLL 266 /// boundaries where the clients might have used different string types when instantiating 267 /// \c TXMPFiles. 268 /// 269 /// @return The internal reference. 270 /// 271 /// @see \c TXMPMeta::GetInternalRef() for usage. 272 273 XMPFilesRef GetInternalRef(); 274 275 /// @} 276 277 // ============================================================================================= 278 /// \name File handler information 279 /// @{ 280 /// 281 /// Call this static function from the concrete class, \c SXMPFiles, to obtain information about 282 /// the file handlers for the XMPFiles component. 283 284 // --------------------------------------------------------------------------------------------- 285 /// @brief GetFormatInfo() reports what features are supported for a specific file format. 286 /// 287 /// The file handlers for different file formats vary considerably in what features they 288 /// support. Support depends on both the general capabilities of the format and the 289 /// implementation of the handler for that format. 290 /// 291 ///This function is static; make the call directly from the concrete class (\c SXMPFiles). 292 /// 293 /// @param format The file format whose support flags are desired. 294 /// 295 /// @param handlerFlags [out] A buffer in which to return a logical OR of option bit flags. 296 /// The following constants are defined: 297 /// 298 /// \li \c #kXMPFiles_CanInjectXMP - Can inject first-time XMP into an existing file. 299 /// \li \c #kXMPFiles_CanExpand - Can expand XMP or other metadata in an existing file. 300 /// \li \c #kXMPFiles_CanRewrite - Can copy one file to another, writing new metadata (as in SaveAs) 301 /// \li \c #kXMPFiles_CanReconcile - Supports reconciliation between XMP and other forms. 302 /// \li \c #kXMPFiles_AllowsOnlyXMP - Allows access to just the XMP, ignoring other forms. 303 /// This is only meaningful if \c #kXMPFiles_CanReconcile is set. 304 /// \li \c #kXMPFiles_ReturnsRawPacket - File handler returns raw XMP packet information and string. 305 /// 306 /// Even if \c #kXMPFiles_ReturnsRawPacket is set, the returned packet information might have an 307 /// offset of -1 to indicate an unknown offset. While all file handlers should be able to return 308 /// the raw packet, some might not know the offset of the packet within the file. This is 309 /// typical in cases where external libraries are used. These cases might not even allow return 310 /// of the raw packet. 311 /// 312 /// @return True if the format has explicit "smart" support, false if the format is handled by 313 /// the default packet scanning plus heuristics. */ 314 315 316 static bool GetFormatInfo ( XMP_FileFormat format, 317 XMP_OptionBits * handlerFlags = 0 ); 318 319 /// @} 320 321 // ============================================================================================= 322 /// \name File operations 323 /// @{ 324 /// 325 /// These functions allow you to open, close, and query files. 326 327 // --------------------------------------------------------------------------------------------- 328 /// @brief \c CheckFileFormat() tries to determine the format of a file. 329 /// 330 /// Tries to determine the format of a file, returning an \c #XMP_FileFormat value. Uses the 331 /// same logic as \c OpenFile() to select a smart handler. 332 /// 333 /// @param filePath The path for the file, appropriate for the local operating system. Passed as 334 /// a nul-terminated UTF-8 string. The path is the same as would be passed to \c OpenFile. 335 /// 336 /// @return The file's format if a smart handler would be selected by \c OpenFile(), otherwise 337 /// \c #kXMP_UnknownFile. 338 339 static XMP_FileFormat CheckFileFormat ( XMP_StringPtr filePath ); 340 341 // --------------------------------------------------------------------------------------------- 342 /// @brief \c CheckPackageFormat() tries to determine the format of a "package" folder. 343 /// 344 /// Tries to determine the format of a package, given the name of the top-level folder. Returns 345 /// an \c #XMP_FileFormat value. Examples of recognized packages include the video formats P2, 346 /// XDCAM, or Sony HDV. These packages contain collections of "clips", stored as multiple files 347 /// in specific subfolders. 348 /// 349 /// @param folderPath The path for the top-level folder, appropriate for the local operating 350 /// system. Passed as a nul-terminated UTF-8 string. This is not the same path you would pass to 351 /// \c OpenFile(). For example, the top-level path for a package might be ".../MyMovie", while 352 /// the path to a file you wish to open would be ".../MyMovie/SomeClip". 353 /// 354 /// @return The package's format if it can be determined, otherwise \c #kXMP_UnknownFile. 355 356 static XMP_FileFormat CheckPackageFormat ( XMP_StringPtr folderPath ); 357 358 // --------------------------------------------------------------------------------------------- 359 /// @brief \c GetFileModDate() returns the last modification date of all files that are returned 360 /// by \c GetAssociatedResources() 361 /// 362 /// Returns the most recent O/S file modification date of all associated files. In the typical case 363 /// of a single file containing embedded XMP, returned date value is the modification date of the 364 /// same file. For sidecar and folder based video packages, returned date value is the modification 365 /// date of that associated file which was updated last. 366 /// 367 /// @param filePath A path exactly as would be passed to \c OpenFile. 368 /// 369 /// @param modDate A required pointer to return the last modification date. 370 /// 371 /// @param format A format hint as would be passed to \c OpenFile. 372 /// 373 /// @param options An optional set of option flags. The only defined one is \c kXMPFiles_ForceGivenHandler, 374 /// used to shortcut the handler selection logic if the caller is certain of the format. 375 /// 376 /// @return Returns true if the file path is valid to select a smart handler, false for an 377 /// invalid path or if fallback packet scanning would be selected. 378 379 static bool GetFileModDate ( XMP_StringPtr filePath, 380 XMP_DateTime * modDate, 381 XMP_FileFormat * format = 0, 382 XMP_OptionBits options = 0 ); 383 384 385 // --------------------------------------------------------------------------------------------- 386 /// @brief \c GetAssociatedResources() returns a list of files and folders associated to filePath. 387 /// 388 /// \c GetAssociatedResources is provided to locate all files that are associated to the given 389 /// filePath such as sidecar-based XMP or folder-based video packages.If a smart 390 /// handler can be selected (not fallback packet scanning) then a list of file/folder paths is 391 /// returned for the related files that can be safely copied/imported to a different location, 392 /// keeping intact metadata(XMP and non-XMP),content and the necessary folder structure of the 393 /// format. The necessary folder structure here is the structure that is needed to uniquely 394 /// identify a folder-based format.The filePath and format parameters are exactly as would be 395 /// used for OpenFile. In the simple embedded XMP case just one path is returned. In the simple 396 /// sidecar case one or two paths will be returned, one if there is no sidecar XMP and two if 397 /// sidecar XMP exists. For folder-based handlers paths to all associated files is returned, 398 /// including the files and folders necessary to identify the format.In general, all the returned 399 /// paths are existent.In case of folder based video formats the first associated resource in the 400 /// resourceList is the root folder. 401 /// 402 /// @param filePath A path exactly as would be passed to \c OpenFile. 403 /// 404 /// @param resourceList Address of a vector of strings to receive all associated resource paths. 405 /// 406 /// @param format A format hint as would be passed to \c OpenFile. 407 /// 408 /// @param options An optional set of option flags. The only defined one is \c kXMPFiles_ForceGivenHandler, 409 /// used to shortcut the handler selection logic if the caller is certain of the format. 410 /// 411 /// @return Returns true if the file path is valid to select a smart handler, false for an 412 /// invalid path or if fallback packet scanning would be selected. Can also return false for 413 /// unexpected errors that prevent knowledge of the file usage. 414 415 static bool GetAssociatedResources ( XMP_StringPtr filePath, 416 std::vector<tStringObj>* resourceList, 417 XMP_FileFormat format = kXMP_UnknownFile, 418 XMP_OptionBits options = 0); 419 420 // --------------------------------------------------------------------------------------------- 421 /// @brief \c IsMetadataWritable() returns true if metadata can be updated for the given media path. 422 /// 423 /// \c IsMetadataWritable is provided to check if metadata can be updated or written to the format.In 424 /// the case of folder-based video formats only if all the metadata files can be written to, true is 425 /// returned.In other words, false is returned for a partial-write state of metadata files in 426 /// folder-based media formats. 427 /// 428 /// @param filePath A path exactly as would be passed to \c OpenFile. 429 /// 430 /// @param writable A pointer to the result flag. Is true if the metadata can be updated in the format, 431 /// otherwise false. 432 /// 433 /// @param format A format hint as would be passed to \c OpenFile. 434 /// 435 /// @param options An optional set of option flags. The only defined one is \c kXMPFiles_ForceGivenHandler, 436 /// used to shortcut the handler selection logic if the caller is certain of the format. 437 /// 438 /// @return Returns true if the file path is valid to select a smart handler, false for an 439 /// invalid path or if fallback packet scanning would be selected. 440 441 static bool IsMetadataWritable (XMP_StringPtr filePath, 442 bool * writable, 443 XMP_FileFormat format = kXMP_UnknownFile, 444 XMP_OptionBits options = 0 ); 445 446 // --------------------------------------------------------------------------------------------- 447 /// @brief \c OpenFile() opens a file for metadata access. 448 /// 449 /// Opens a file for the requested forms of metadata access. Opening the file at a minimum 450 /// causes the raw XMP packet to be read from the file. If the file handler supports legacy 451 /// metadata reconciliation then legacy metadata is also read, unless \c #kXMPFiles_OpenOnlyXMP 452 /// is passed. 453 /// 454 /// If the file is opened for read-only access (passing \c #kXMPFiles_OpenForRead), the disk 455 /// file is closed immediately after reading the data from it; the \c XMPFiles object, however, 456 /// remains in the open state. You must call \c CloseFile() when finished using it. Other 457 /// methods, such as \c GetXMP(), can only be used between the \c OpenFile() and \c CloseFile() 458 /// calls. The \c XMPFiles destructor does not call \c CloseFile(); if you call it without 459 /// closing, any pending updates are lost. 460 /// 461 /// If the file is opened for update (passing \c #kXMPFiles_OpenForUpdate), the disk file 462 /// remains open until \c CloseFile() is called. The disk file is only updated once, when 463 /// \c CloseFile() is called, regardless of how many calls are made to \c PutXMP(). 464 /// 465 /// Typically, the XMP is not parsed and legacy reconciliation is not performed until \c GetXMP() 466 /// is called, but this is not guaranteed. Specific file handlers might do earlier parsing of 467 /// the XMP. Delayed parsing and early disk file close for read-only access are optimizations 468 /// to help clients implementing file browsers, so that they can access the file briefly 469 /// and possibly display a thumbnail, then postpone more expensive XMP processing until later. 470 /// 471 /// @param filePath The path for the file, appropriate for the local operating system. Passed as 472 /// a nul-terminated UTF-8 string. 473 /// 474 /// @param format The format of the file. If the format is unknown (\c #kXMP_UnknownFile) the 475 /// format is determined from the file content. The first handler to check is guessed from the 476 /// file's extension. Passing a specific format value is generally just a hint about what file 477 /// handler to try first (instead of the one based on the extension). If 478 /// \c #kXMPFiles_OpenStrictly is set, then any format other than \c #kXMP_UnknownFile requires 479 /// that the file actually be that format; otherwise an exception is thrown. 480 /// 481 /// @param openFlags A set of option flags that describe the desired access. By default (zero) 482 /// the file is opened for read-only access and the format handler decides on the level of 483 /// reconciliation that will be performed. A logical OR of these bit-flag constants: 484 /// 485 /// \li \c #kXMPFiles_OpenForRead - Open for read-only access. 486 /// \li \c #kXMPFiles_OpenForUpdate - Open for reading and writing. 487 /// \li \c #kXMPFiles_OpenOnlyXMP - Only the XMP is wanted, no reconciliation. 488 /// \li \c #kXMPFiles_OpenStrictly - Be strict about locating XMP and reconciling with other 489 /// forms. By default, a best effort is made to locate the correct XMP and to reconcile XMP 490 /// with other forms (if reconciliation is done). This option forces stricter rules, resulting 491 /// in exceptions for errors. The definition of strictness is specific to each handler, there 492 /// might be no difference. 493 /// \li \c #kXMPFiles_OpenUseSmartHandler - Require the use of a smart handler. 494 /// \li \c #kXMPFiles_OpenUsePacketScanning - Force packet scanning, do not use a smart handler. 495 /// \li \c #kXMPFiles_OptimizeFileLayout - When updating a file, spend the effort necessary 496 /// to optimize file layout. 497 /// 498 /// @return True if the file is succesfully opened and attached to a file handler. False for 499 /// anticipated problems, such as passing \c #kXMPFiles_OpenUseSmartHandler but not having an 500 /// appropriate smart handler. Throws an exception for serious problems. 501 502 bool OpenFile ( XMP_StringPtr filePath, 503 XMP_FileFormat format = kXMP_UnknownFile, 504 XMP_OptionBits openFlags = 0 ); 505 506 // --------------------------------------------------------------------------------------------- 507 /// @brief \c OpenFile() opens a file for metadata access, using a string object 508 /// 509 /// Overloads the basic form of the function, allowing you to pass a string object for the file 510 /// path. It is otherwise identical; see details in the canonical form. 511 512 bool OpenFile ( const tStringObj & filePath, 513 XMP_FileFormat format = kXMP_UnknownFile, 514 XMP_OptionBits openFlags = 0 ); 515 516 #if XMP_StaticBuild // ! Client XMP_IO objects can only be used in static builds. 517 // --------------------------------------------------------------------------------------------- 518 /// @brief \c OpenFile() opens a client-provided XMP_IO object for metadata access. 519 /// 520 /// Alternative to the basic form of the function, allowing you to pass an XMP_IO object for 521 /// client-managed I/O. 522 /// 523 524 bool OpenFile ( XMP_IO * clientIO, 525 XMP_FileFormat format = kXMP_UnknownFile, 526 XMP_OptionBits openFlags = 0 ); 527 #endif 528 529 // --------------------------------------------------------------------------------------------- 530 /// @brief CloseFile() explicitly closes an opened file. 531 /// 532 /// Performs any necessary output to the file and closes it. Files that are opened for update 533 /// are written to only when closing. 534 /// 535 /// If the file is opened for read-only access (passing \c #kXMPFiles_OpenForRead), the disk 536 /// file is closed immediately after reading the data from it; the \c XMPFiles object, however, 537 /// remains in the open state. You must call \c CloseFile() when finished using it. Other 538 /// methods, such as \c GetXMP(), can only be used between the \c OpenFile() and \c CloseFile() 539 /// calls. The \c XMPFiles destructor does not call \c CloseFile(); if you call it without closing, 540 /// any pending updates are lost. 541 /// 542 /// If the file is opened for update (passing \c #kXMPFiles_OpenForUpdate), the disk file remains 543 /// open until \c CloseFile() is called. The disk file is only updated once, when \c CloseFile() 544 /// is called, regardless of how many calls are made to \c PutXMP(). 545 /// 546 /// @param closeFlags Option flags for optional closing actions. This bit-flag constant is 547 /// defined: 548 /// 549 /// \li \c #kXMPFiles_UpdateSafely - Write into a temporary file then swap for crash safety. 550 551 void CloseFile ( XMP_OptionBits closeFlags = 0 ); 552 553 // --------------------------------------------------------------------------------------------- 554 /// @brief \c GetFileInfo() retrieves basic information about an opened file. 555 /// 556 /// @param filePath [out] A buffer in which to return the path passed to \c OpenFile(). Can be 557 /// null if value is not wanted. 558 /// 559 /// @param openFlags [out] A buffer in which to return the option flags passed to 560 /// \c OpenFile(). Can be null if value is not wanted. 561 /// 562 /// @param format [out] A buffer in which to return the file format. Can be null if value is not 563 /// wanted. 564 /// @param handlerFlags [out] A buffer in which to return the handler's capability flags. Can 565 /// be null if value is not wanted. 566 /// 567 /// @return True if the file object is in the open state; that is, \c OpenFile() has been called 568 /// but \c CloseFile() has not. False otherwise. Even if the file object is open, the actual 569 /// disk file might be closed in the host file-system sense; see \c OpenFile(). 570 571 bool GetFileInfo ( tStringObj * filePath = 0, 572 XMP_OptionBits * openFlags = 0, 573 XMP_FileFormat * format = 0, 574 XMP_OptionBits * handlerFlags = 0 ); 575 576 // --------------------------------------------------------------------------------------------- 577 /// @brief \c SetAbortProc() registers a callback function used to check for a user-signaled abort. 578 /// 579 /// The specified procedure is called periodically to allow a user to cancel time-consuming 580 /// operations. The callback function should return true to signal an abort, which results in an 581 /// exception being thrown. 582 /// 583 /// @param abortProc The callback function. 584 /// 585 /// @param abortArg A pointer to caller-defined data to pass to the callback function. 586 587 void SetAbortProc ( XMP_AbortProc abortProc, 588 void * abortArg ); 589 590 /// @} 591 592 // ============================================================================================= 593 /// \name Accessing metadata 594 /// @{ 595 /// 596 /// These functions allow you to retrieve XMP metadata from open files, so that you can use the 597 /// \c TXMPMeta API to manipulate it. The \c PutXMP() functions update the XMP packet in memory. 598 /// Changed XMP is not actually written out to the file until the file is closed. 599 600 // --------------------------------------------------------------------------------------------- 601 /// @brief \c GetXMP() retrieves the XMP metadata from an open file. 602 /// 603 /// The function reports whether XMP is present in the file; you can choose to retrieve any or 604 /// all of the parsed XMP, the raw XMP packet,or information about the raw XMP packet. The 605 /// options provided when the file was opened determine if reconciliation is done with other 606 /// forms of metadata. 607 /// 608 /// @param xmpObj [out] An XMP object in which to return the parsed XMP metadata. Can be null. 609 /// 610 /// @param xmpPacket [out] An string object in which to return the raw XMP packet as stored in 611 /// the file. Can be null. The encoding of the packet is given in the \c packetInfo. Returns an 612 /// empty string if the low level file handler does not provide the raw packet. 613 /// 614 /// @param packetInfo [out] An string object in which to return the location and form of the raw 615 /// XMP in the file. \c #XMP_PacketInfo::charForm and \c #XMP_PacketInfo::writeable reflect the 616 /// raw XMP in the file. The parsed XMP property values are always UTF-8. The writeable flag is 617 /// taken from the packet trailer; it applies only to "format ignorant" writing. The 618 /// \c #XMP_PacketInfo structure always reflects the state of the XMP in the file. The offset, 619 /// length, and character form do not change as a result of calling \c PutXMP() unless the file 620 /// is also written. Some file handlers might not return location or contents of the raw packet 621 /// string. To determine whether one does, check the \c #kXMPFiles_ReturnsRawPacket bit returned 622 /// by \c GetFormatInfo(). If the low-level file handler does not provide the raw packet 623 /// location, \c #XMP_PacketInfo::offset and \c #XMP_PacketInfo::length are both 0, 624 /// \c #XMP_PacketInfo::charForm is UTF-8, and \c #XMP_PacketInfo::writeable is false. 625 /// 626 /// @return True if the file has XMP, false otherwise. 627 628 bool GetXMP ( SXMPMeta * xmpObj = 0, 629 tStringObj * xmpPacket = 0, 630 XMP_PacketInfo * packetInfo = 0 ); 631 632 // --------------------------------------------------------------------------------------------- 633 /// @brief \c PutXMP() updates the XMP metadata in this object without writing out the file. 634 /// 635 /// This function supplies new XMP for the file. However, the disk file is not written until the 636 /// object is closed with \c CloseFile(). The options provided when the file was opened 637 /// determine if reconciliation is done with other forms of metadata. 638 /// 639 /// @param xmpObj The new metadata as an XMP object. 640 641 void PutXMP ( const SXMPMeta & xmpObj ); 642 643 // --------------------------------------------------------------------------------------------- 644 /// @brief \c PutXMP() updates the XMP metadata in this object without writing out the file, 645 /// using a string object for input. 646 /// 647 /// Overloads the basic form of the function, allowing you to pass the metadata as a string object 648 /// instead of an XMP object. It is otherwise identical; see details in the canonical form. 649 /// 650 /// @param xmpPacket The new metadata as a string object containing a complete XMP packet. 651 652 void PutXMP ( const tStringObj & xmpPacket ); 653 654 // --------------------------------------------------------------------------------------------- 655 /// @brief \c PutXMP() updates the XMP metadata in this object without writing out the file, 656 /// using a string object and optional length. 657 /// 658 /// Overloads the basic form of the function, allowing you to pass the metadata as a string object 659 /// instead of an XMP object. It is otherwise identical; see details in the canonical form. 660 /// 661 /// @param xmpPacket The new metadata as a <tt>const char *</tt> string containing an XMP packet. 662 /// 663 /// @param xmpLength Optional. The number of bytes in the string. If not supplied, the string is 664 /// assumed to be nul-terminated. 665 666 void PutXMP ( XMP_StringPtr xmpPacket, 667 XMP_StringLen xmpLength = kXMP_UseNullTermination ); 668 669 // --------------------------------------------------------------------------------------------- 670 /// @brief \c CanPutXMP() reports whether this file can be updated with a specific XMP packet. 671 /// 672 /// Use to determine if the file can probably be updated with a given set of XMP metadata. This 673 /// depends on the size of the packet, the options with which the file was opened, and the 674 /// capabilities of the handler for the file format. The function obtains the length of the 675 /// serialized packet for the provided XMP, but does not keep it or modify it, and does not 676 /// cause the file to be written when closed. This is implemented roughly as follows: 677 /// 678 /// <pre> 679 /// bool CanPutXMP ( XMP_StringPtr xmpPacket ) 680 /// { 681 /// XMP_FileFormat format; 682 /// this->GetFileInfo ( 0, &format, 0 ); 683 /// 684 /// XMP_OptionBits formatFlags; 685 /// GetFormatInfo ( format, &formatFlags ); 686 /// 687 /// if ( (formatFlags & kXMPFiles_CanInjectXMP) && (formatFlags & kXMPFiles_CanExpand) ) return true; 688 /// 689 /// XMP_PacketInfo packetInfo; 690 /// bool hasXMP = this->GetXMP ( 0, 0, &packetInfo ); 691 /// 692 /// if ( ! hasXMP ) { 693 /// if ( formatFlags & kXMPFiles_CanInjectXMP ) return true; 694 /// } else { 695 /// if ( (formatFlags & kXMPFiles_CanExpand) || 696 /// (packetInfo.length >= strlen(xmpPacket)) ) return true; 697 /// } 698 /// return false; 699 /// } 700 /// </pre> 701 /// 702 /// @param xmpObj The proposed new metadata as an XMP object. 703 704 bool CanPutXMP ( const SXMPMeta & xmpObj ); 705 706 // --------------------------------------------------------------------------------------------- 707 /// @brief \c CanPutXMP() reports whether this file can be updated with a specific XMP packet, 708 /// passed in a string object. 709 /// 710 /// Overloads the basic form of the function, allowing you to pass the metadata as a string object 711 /// instead of an XMP object. It is otherwise identical; see details in the canonical form. 712 /// 713 /// @param xmpPacket The proposed new metadata as a string object containing an XMP packet. 714 715 bool CanPutXMP ( const tStringObj & xmpPacket ); 716 717 // --------------------------------------------------------------------------------------------- 718 /// @brief \c CanPutXMP() reports whether this file can be updated with a specific XMP packet, 719 /// passed in a string object. 720 /// 721 /// Overloads the basic form of the function, allowing you to pass the metadata as a string object 722 /// instead of an XMP object. It is otherwise identical; see details in the canonical form. 723 /// 724 /// @param xmpPacket The proposed new metadata as a <tt>const char *</tt> string containing an XMP packet. 725 /// 726 /// @param xmpLength Optional. The number of bytes in the string. If not supplied, the string 727 /// is assumed to be nul-terminated. 728 729 bool CanPutXMP ( XMP_StringPtr xmpPacket, 730 XMP_StringLen xmpLength = kXMP_UseNullTermination ); 731 732 /// @} 733 734 // ============================================================================================= 735 /// \name Progress notifications 736 /// @{ 737 /// 738 /// These functions allow track the progress of file operations. Initially only file updates are 739 /// tracked, these all occur within calls to SXMPFiles::CloseFile. There are no plans to track 740 /// other operations at this time. Tracking support must be added to specific file handlers, 741 /// there are no guarantees about which handlers will have support. To simplify the logic only 742 /// file writes will be estimated and measured. 743 744 // --------------------------------------------------------------------------------------------- 745 /// @brief \c SetDefaultProgressCallback() sets a global default for progress tracking. This is 746 /// used as a default for XMPFiles (library) objects created after the default is set. This does 747 /// not affect the callback for new SXMPFiles (client) objects with an existing XMPFiles object. 748 /// 749 /// @param proc The client's callback function. Can be zero to disable notifications. 750 /// 751 /// @param context A pointer used to carry client-private context. 752 /// 753 /// @param interval The desired number of seconds between notifications. Ideally the first 754 /// notification is sent after this interval, then at each following multiple of this interval. 755 /// 756 /// @param sendStartStop A Boolean value indicating if initial and final notifications are 757 /// wanted in addition to those at the reporting intervals. 758 759 static void SetDefaultProgressCallback ( XMP_ProgressReportProc proc, void * context = 0, 760 float interval = 1.0, bool sendStartStop = false ); 761 762 // --------------------------------------------------------------------------------------------- 763 /// @brief \c SetProgressCallback() sets the progress notification callback for the associated 764 /// XMPFiles (library) object. 765 /// 766 /// @param proc The client's callback function. Can be zero to disable notifications. 767 /// 768 /// @param context A pointer used to carry client-private context. 769 /// 770 /// @param interval The desired number of seconds between notifications. Ideally the first 771 /// notification is sent after this interval, then at each following multiple of this interval. 772 /// 773 /// @param sendStartStop A Boolean value indicating if initial and final notifications are 774 /// wanted in addition to those at the reporting intervals. 775 776 void SetProgressCallback ( XMP_ProgressReportProc proc, void * context = 0, 777 float interval = 1.0, bool sendStartStop = false ); 778 779 /// @} 780 781 // ============================================================================================= 782 // Error notifications 783 // =================== 784 785 // --------------------------------------------------------------------------------------------- 786 /// \name Error notifications 787 /// @{ 788 /// 789 /// From the beginning through version 5.5, XMP Toolkit errors result in throwing an \c XMP_Error 790 /// exception. For the most part exceptions were thrown early and thus API calls aborted as soon 791 /// as an error was detected. Starting in version 5.5, support has been added for notifications 792 /// of errors arising in calls to \c TXMPFiles functions. 793 /// 794 /// A client can register an error notification callback function for a \c TXMPFile object. This 795 /// can be done as a global default or individually to each object. The global default applies 796 /// to all objects created after it is registered. Within the object there is no difference 797 /// between the global default or explicitly registered callback. The callback function returns 798 /// a \c bool value indicating if recovery should be attempted (true) or an exception thrown 799 /// (false). If no callback is registered, a best effort at recovery and continuation will be 800 /// made with an exception thrown if recovery is not possible. 801 /// 802 /// The number of notifications delivered for a given TXMPFiles object can be limited. This is 803 /// intended to reduce chatter from multiple or cascading errors. The limit is set when the 804 /// callback function is registered. This limits the number of notifications of the highest 805 /// severity delivered or less. If a higher severity error occurs, the counting starts again. 806 /// The limit and counting can be reset at any time, see \c ResetErrorCallbackLimit. 807 808 // -------------------------------------------------------------------------------------------- 809 /// @brief SetDefaultErrorCallback() registers a global default error notification callback. 810 /// 811 /// @param proc The client's callback function. 812 /// 813 /// @param context Client-provided context for the callback. 814 /// 815 /// @param limit A limit on the number of notifications to be delivered. 816 817 static void SetDefaultErrorCallback ( XMPFiles_ErrorCallbackProc proc, void* context = 0, XMP_Uns32 limit = 1 ); 818 819 // -------------------------------------------------------------------------------------------- 820 /// @brief SetErrorCallback() registers an error notification callback. 821 /// 822 /// @param proc The client's callback function. 823 /// 824 /// @param context Client-provided context for the callback. 825 /// 826 /// @param limit A limit on the number of notifications to be delivered. 827 828 void SetErrorCallback ( XMPFiles_ErrorCallbackProc proc, void* context = 0, XMP_Uns32 limit = 1 ); 829 830 // -------------------------------------------------------------------------------------------- 831 /// @brief ResetErrorCallbackLimit() resets the error notification limit and counting. It has no 832 /// effect if an error notification callback function is not registered. 833 /// 834 /// @param limit A limit on the number of notifications to be delivered. 835 836 void ResetErrorCallbackLimit ( XMP_Uns32 limit = 1 ); 837 838 /// @} 839 840 // ============================================================================================= 841 842 private: 843 844 XMPFilesRef xmpFilesRef; 845 846 // These are used as callbacks from the library code to the client when returning values that 847 // involve heap allocations. This ensures the allocations occur within the client. 848 static void SetClientString ( void * clientPtr, XMP_StringPtr valuePtr, XMP_StringLen valueLen ); 849 static void SetClientStringVector ( void * clientPtr, XMP_StringPtr* arrayPtr, XMP_Uns32 stringCount ); 850 }; // class TXMPFiles 851 852 // ================================================================================================= 853 854 #endif // __TXMPFiles_hpp__ 855