Coverage Report

Created: 2026-09-13 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/exiv2/src/xmp_lifecycle.hpp
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
3
#ifndef EXIV2_XMP_LIFECYCLE_HPP
4
#define EXIV2_XMP_LIFECYCLE_HPP
5
6
#include "error.hpp"
7
#include "exiv2lib_export.h"
8
#include "properties.hpp"
9
10
#include <mutex>
11
12
// Adobe XMP Toolkit
13
#ifdef EXV_HAVE_XMP_TOOLKIT
14
#ifdef EXV_ADOBE_XMPSDK
15
#include <XMP.hpp>
16
#else
17
#include <XMPSDK.hpp>
18
#endif
19
#endif  // EXV_HAVE_XMP_TOOLKIT
20
21
namespace Exiv2 {
22
23
/*!
24
  @brief Ensure the XMP Toolkit is initialized.
25
         This function is thread-safe and idempotent.
26
         It throws Exiv2::Error if initialization fails.
27
 */
28
void xmpToolkitEnsureInitialized();
29
30
#ifdef EXV_HAVE_XMP_TOOLKIT
31
class XmpToolkitLifetimeManager {
32
 public:
33
3
  XmpToolkitLifetimeManager() {
34
3
    if (SXMPMeta::Initialize()) {
35
#ifdef EXV_ADOBE_XMPSDK
36
      SXMPMeta::RegisterNamespace("http://ns.adobe.com/lightroom/1.0/", "lr", nullptr);
37
      SXMPMeta::RegisterNamespace("http://rs.tdwg.org/dwc/index.htm", "dwc", nullptr);
38
      SXMPMeta::RegisterNamespace("http://purl.org/dc/terms/", "dcterms", nullptr);
39
      SXMPMeta::RegisterNamespace("http://www.digikam.org/ns/1.0/", "digiKam", nullptr);
40
      SXMPMeta::RegisterNamespace("http://www.digikam.org/ns/kipi/1.0/", "kipi", nullptr);
41
      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.0/", "MicrosoftPhoto", nullptr);
42
      SXMPMeta::RegisterNamespace("http://ns.acdsee.com/iptc/1.0/", "acdsee", nullptr);
43
      SXMPMeta::RegisterNamespace("http://iptc.org/std/Iptc4xmpExt/2008-02-29/", "iptcExt", nullptr);
44
      SXMPMeta::RegisterNamespace("http://ns.useplus.org/ldf/xmp/1.0/", "plus", nullptr);
45
      SXMPMeta::RegisterNamespace("http://ns.iview-multimedia.com/mediapro/1.0/", "mediapro", nullptr);
46
      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/expressionmedia/1.0/", "expressionmedia", nullptr);
47
      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.2/", "MP", nullptr);
48
      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.2/t/RegionInfo#", "MPRI", nullptr);
49
      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.2/t/Region#", "MPReg", nullptr);
50
      SXMPMeta::RegisterNamespace("http://ns.google.com/photos/1.0/panorama/", "GPano", nullptr);
51
      SXMPMeta::RegisterNamespace("http://www.metadataworkinggroup.com/schemas/regions/", "mwg-rs", nullptr);
52
      SXMPMeta::RegisterNamespace("http://www.metadataworkinggroup.com/schemas/keywords/", "mwg-kw", nullptr);
53
      SXMPMeta::RegisterNamespace("http://ns.adobe.com/xmp/sType/Area#", "stArea", nullptr);
54
      SXMPMeta::RegisterNamespace("http://cipa.jp/exif/1.0/", "exifEX", nullptr);
55
      SXMPMeta::RegisterNamespace("http://ns.adobe.com/camera-raw-saved-settings/1.0/", "crss", nullptr);
56
      SXMPMeta::RegisterNamespace("http://www.audio/", "audio", nullptr);
57
      SXMPMeta::RegisterNamespace("http://www.video/", "video", nullptr);
58
#else
59
3
      SXMPMeta::RegisterNamespace("http://ns.adobe.com/lightroom/1.0/", "lr");
60
3
      SXMPMeta::RegisterNamespace("http://rs.tdwg.org/dwc/index.htm", "dwc");
61
3
      SXMPMeta::RegisterNamespace("http://purl.org/dc/terms/", "dcterms");
62
3
      SXMPMeta::RegisterNamespace("http://www.digikam.org/ns/1.0/", "digiKam");
63
3
      SXMPMeta::RegisterNamespace("http://www.digikam.org/ns/kipi/1.0/", "kipi");
64
3
      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.0/", "MicrosoftPhoto");
65
3
      SXMPMeta::RegisterNamespace("http://ns.acdsee.com/iptc/1.0/", "acdsee");
66
3
      SXMPMeta::RegisterNamespace("http://iptc.org/std/Iptc4xmpExt/2008-02-29/", "iptcExt");
67
3
      SXMPMeta::RegisterNamespace("http://ns.useplus.org/ldf/xmp/1.0/", "plus");
68
3
      SXMPMeta::RegisterNamespace("http://ns.iview-multimedia.com/mediapro/1.0/", "mediapro");
69
3
      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/expressionmedia/1.0/", "expressionmedia");
70
3
      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.2/", "MP");
71
3
      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.2/t/RegionInfo#", "MPRI");
72
3
      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.2/t/Region#", "MPReg");
73
3
      SXMPMeta::RegisterNamespace("http://ns.google.com/photos/1.0/panorama/", "GPano");
74
3
      SXMPMeta::RegisterNamespace("http://www.metadataworkinggroup.com/schemas/regions/", "mwg-rs");
75
3
      SXMPMeta::RegisterNamespace("http://www.metadataworkinggroup.com/schemas/keywords/", "mwg-kw");
76
3
      SXMPMeta::RegisterNamespace("http://ns.adobe.com/xmp/sType/Area#", "stArea");
77
3
      SXMPMeta::RegisterNamespace("http://cipa.jp/exif/1.0/", "exifEX");
78
3
      SXMPMeta::RegisterNamespace("http://ns.adobe.com/camera-raw-saved-settings/1.0/", "crss");
79
3
      SXMPMeta::RegisterNamespace("http://www.audio/", "audio");
80
3
      SXMPMeta::RegisterNamespace("http://www.video/", "video");
81
3
#endif
82
3
    } else {
83
0
      throw Error(ErrorCode::kerXMPToolkitError, 2, "Failed to initialize XMP Toolkit");
84
0
    }
85
3
  }
86
87
3
  ~XmpToolkitLifetimeManager() {
88
    // Use Unsafe version to avoid acquiring mutex during static destruction.
89
    // This is safe because static destruction is single-threaded per C++ standard.
90
3
    XmpProperties::unregisterAllNsNoLock(XmpProperties::LifetimeKey{});
91
3
    SXMPMeta::Terminate();
92
3
  }
93
};
94
#endif  // EXV_HAVE_XMP_TOOLKIT
95
96
}  // namespace Exiv2
97
98
#endif  // EXIV2_XMP_LIFECYCLE_HPP