[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-kimageshop
Subject: =?utf-8?q?=5Bgraphics/krita=5D_/=3A_Refactor_metadata_backends_into_their_own_plugins?=
From: Dmitry Kazakov <null () kde ! org>
Date: 2021-09-04 13:35:59
Message-ID: 20210904133559.1E9E31241554 () leptone ! kde ! org
[Download RAW message or body]
Git commit 4a8195729427cc45f8236eef08f43aa9e04f5e89 by Dmitry Kazakov, on behalf of \
L. E. Segovia. Committed on 04/09/2021 at 13:08.
Pushed by dkazakov into branch 'master'.
Refactor metadata backends into their own plugins
This commit turns the Exif, IPTC, and XMP backends into loadable
KPlugins.
CCMAIL: kimageshop@kde.org
M +2 -1 libs/metadata/CMakeLists.txt
A +42 -0 libs/metadata/kis_meta_data_backend_registry.cpp [License: \
LGPL(v2.1+)] A +20 -0 libs/metadata/kis_meta_data_backend_registry.h \
[License: LGPL(v2.1+)] D +0 -33 libs/metadata/kis_meta_data_io_backend.cc
M +11 -29 libs/metadata/kis_meta_data_io_backend.h
M +1 -6 libs/ui/CMakeLists.txt
M +2 -13 libs/ui/KisApplication.cpp
M +0 -1 libs/ui/KisApplication.h
M +15 -15 libs/ui/kis_png_converter.cpp
D +0 -1 libs/ui/kisexiv2/.krazy
D +0 -32 libs/ui/kisexiv2/kis_exiv2.h
M +0 -8 libs/ui/tests/CMakeLists.txt
M +1 -0 plugins/CMakeLists.txt
M +7 -7 plugins/impex/heif/HeifExport.cpp
M +9 -8 plugins/impex/heif/HeifImport.cpp
M +15 -15 plugins/impex/jpeg/kis_jpeg_converter.cc
M +2 -2 plugins/impex/jpeg/tests/CMakeLists.txt
M +3 -3 plugins/impex/jpeg/tests/kis_jpeg_test.cpp
M +22 -23 plugins/impex/libkra/kis_kra_load_visitor.cpp
M +13 -13 plugins/impex/libkra/kis_kra_save_visitor.cpp
M +3 -4 plugins/impex/tiff/tests/kis_tiff_test.cpp
A +7 -0 plugins/metadata/CMakeLists.txt
R +40 -45 plugins/metadata/common/kis_exiv2_common.h [from: \
libs/ui/kisexiv2/kis_exiv2.cpp - 081% similarity] R +0 -0 \
plugins/metadata/common/kis_exiv2_constants.h [from: \
libs/ui/kisexiv2/kis_exiv2_constants.h - 100% similarity] A +17 -0 \
plugins/metadata/exif/CMakeLists.txt R +115 -108 \
plugins/metadata/exif/kis_exif_io.cpp [from: libs/ui/kisexiv2/kis_exif_io.cpp - 076% \
similarity] R +17 -12 plugins/metadata/exif/kis_exif_io.h [from: \
libs/ui/kisexiv2/kis_exif_io.h - 054% similarity] A +29 -0 \
plugins/metadata/exif/kis_exif_plugin.cpp [License: GPL(v2.0+)] A +21 -0 \
plugins/metadata/exif/kis_exif_plugin.h [License: GPL(v2.0+)] A +9 -0 \
plugins/metadata/exif/kritaexif.json A +17 -0 \
plugins/metadata/iptc/CMakeLists.txt R +59 -58 \
plugins/metadata/iptc/kis_iptc_io.cpp [from: libs/ui/kisexiv2/kis_iptc_io.cpp - 051% \
similarity] R +20 -12 plugins/metadata/iptc/kis_iptc_io.h [from: \
libs/ui/kisexiv2/kis_iptc_io.h - 056% similarity] A +29 -0 \
plugins/metadata/iptc/kis_iptc_plugin.cpp [License: GPL(v2.0+)] A +21 -0 \
plugins/metadata/iptc/kis_iptc_plugin.h [License: GPL(v2.0+)] A +7 -0 \
plugins/metadata/iptc/kritaiptc.json A +21 -0 \
plugins/metadata/tests/CMakeLists.txt R +- -- \
plugins/metadata/tests/data/metadata/hpim3238.exv [from: \
libs/ui/tests/data/metadata/hpim3238.exv - 100% similarity] R +34 -29 \
plugins/metadata/tests/kis_exif_test.cpp [from: libs/ui/tests/kis_exiv2_test.cpp - \
065% similarity] R +2 -1 plugins/metadata/tests/kis_exif_test.h [from: \
libs/ui/tests/kis_exiv2_test.h - 073% similarity] A +17 -0 \
plugins/metadata/xmp/CMakeLists.txt R +72 -56 \
plugins/metadata/xmp/kis_xmp_io.cpp [from: libs/ui/kisexiv2/kis_xmp_io.cpp - 075% \
similarity] R +17 -11 plugins/metadata/xmp/kis_xmp_io.h [from: \
libs/ui/kisexiv2/kis_xmp_io.h - 055% similarity] A +29 -0 \
plugins/metadata/xmp/kis_xmp_plugin.cpp [License: GPL(v2.0+)] A +21 -0 \
plugins/metadata/xmp/kis_xmp_plugin.h [License: GPL(v2.0+)] A +9 -0 \
plugins/metadata/xmp/kritaxmp.json
https://invent.kde.org/graphics/krita/commit/4a8195729427cc45f8236eef08f43aa9e04f5e89
diff --git a/libs/metadata/CMakeLists.txt b/libs/metadata/CMakeLists.txt
index a0cccc48b8..952ef22466 100644
--- a/libs/metadata/CMakeLists.txt
+++ b/libs/metadata/CMakeLists.txt
@@ -4,7 +4,6 @@ set(kritametadata_LIB_SRCS
kis_meta_data_filter_p.cc
kis_meta_data_filter_registry.cc
kis_meta_data_filter_registry_model.cc
- kis_meta_data_io_backend.cc
kis_meta_data_merge_strategy.cc
kis_meta_data_merge_strategy_p.cc
kis_meta_data_merge_strategy_registry.cc
@@ -15,6 +14,8 @@ set(kritametadata_LIB_SRCS
kis_meta_data_type_info.cc
kis_meta_data_validator.cc
kis_meta_data_value.cc
+
+ kis_meta_data_backend_registry.cpp
)
add_library(kritametadata SHARED ${kritametadata_LIB_SRCS} )
diff --git a/libs/metadata/kis_meta_data_backend_registry.cpp \
b/libs/metadata/kis_meta_data_backend_registry.cpp new file mode 100644
index 0000000000..0808a4d29a
--- /dev/null
+++ b/libs/metadata/kis_meta_data_backend_registry.cpp
@@ -0,0 +1,42 @@
+/*
+ * SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net>
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "kis_meta_data_backend_registry.h"
+
+#include <QGlobalStatic>
+
+#include <KoPluginLoader.h>
+
+#include <kis_debug.h>
+
+Q_GLOBAL_STATIC(KisMetadataBackendRegistry, s_instance)
+
+KisMetadataBackendRegistry::KisMetadataBackendRegistry()
+{
+}
+
+KisMetadataBackendRegistry::~KisMetadataBackendRegistry()
+{
+ Q_FOREACH (const QString &id, keys()) {
+ delete get(id);
+ }
+ dbgRegistry << "Deleting KisMetadataBackendRegistry";
+}
+
+void KisMetadataBackendRegistry::init()
+{
+ KoPluginLoader::instance()->load("Krita/Metadata", "(Type == 'Service') and \
([X-Krita-Version] == 28)"); +}
+
+KisMetadataBackendRegistry *KisMetadataBackendRegistry::instance()
+{
+ if (!s_instance.exists()) {
+ dbgRegistry << "initializing KisMetadataBackendRegistry";
+ s_instance->init();
+ }
+ return s_instance;
+}
diff --git a/libs/metadata/kis_meta_data_backend_registry.h \
b/libs/metadata/kis_meta_data_backend_registry.h new file mode 100644
index 0000000000..c50fcb8b2c
--- /dev/null
+++ b/libs/metadata/kis_meta_data_backend_registry.h
@@ -0,0 +1,20 @@
+/*
+ * SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net>
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include <KoGenericRegistry.h>
+#include <kis_meta_data_io_backend.h>
+
+#include "kritametadata_export.h"
+
+class KRITAMETADATA_EXPORT KisMetadataBackendRegistry : public \
KoGenericRegistry<KisMetaData::IOBackend *> +{
+public:
+ KisMetadataBackendRegistry();
+ ~KisMetadataBackendRegistry() override;
+ void init();
+ static KisMetadataBackendRegistry *instance();
+};
diff --git a/libs/metadata/kis_meta_data_io_backend.cc \
b/libs/metadata/kis_meta_data_io_backend.cc deleted file mode 100644
index 88a50f04ce..0000000000
--- a/libs/metadata/kis_meta_data_io_backend.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net>
- *
- * SPDX-License-Identifier: LGPL-2.1-or-later
- */
-
-#include "kis_meta_data_io_backend.h"
-
-using namespace KisMetaData;
-
-#include <QGlobalStatic>
-#include "kis_debug.h"
-
-Q_GLOBAL_STATIC(IOBackendRegistry, s_instance)
-
-
-IOBackendRegistry::IOBackendRegistry()
-{
-}
-
-IOBackendRegistry::~IOBackendRegistry()
-{
- Q_FOREACH (const QString &id, keys()) {
- delete get(id);
- }
-}
-
-
-IOBackendRegistry* IOBackendRegistry::instance()
-{
- // XXX: load backend plugins
- return s_instance;
-}
diff --git a/libs/metadata/kis_meta_data_io_backend.h \
b/libs/metadata/kis_meta_data_io_backend.h index 3de9e21f67..52af754cd1 100644
--- a/libs/metadata/kis_meta_data_io_backend.h
+++ b/libs/metadata/kis_meta_data_io_backend.h
@@ -1,17 +1,17 @@
/*
-* SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net>
-*
-* SPDX-License-Identifier: LGPL-2.1-or-later
-*/
+ * SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net>
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
#ifndef _KIS_META_DATA_IO_BACKEND_H_
#define _KIS_META_DATA_IO_BACKEND_H_
#include <kritametadata_export.h>
-#include <KoGenericRegistry.h>
-
class QIODevice;
+class QString;
namespace KisMetaData
{
@@ -24,15 +24,11 @@ class Store;
class KRITAMETADATA_EXPORT IOBackend
{
public:
-
/**
* Tell whether the backend input/output from/to binary data
* or text (XML or RDF) data.
*/
- enum BackendType {
- Binary,
- Text
- };
+ enum BackendType { Binary, Text };
enum HeaderType {
NoHeader, ///< Don't append any header
@@ -40,8 +36,7 @@ public:
};
public:
-
- virtual ~IOBackend() {};
+ virtual ~IOBackend(){};
virtual QString id() const = 0;
@@ -64,14 +59,14 @@ public:
* which type of header
* @return true if the save was successful (XXX: actually, all backends always \
return true...)
*/
- virtual bool saveTo(Store* store, QIODevice* ioDevice, HeaderType headerType = \
NoHeader) const = 0; + virtual bool saveTo(Store *store, QIODevice *ioDevice, \
HeaderType headerType = NoHeader) const = 0;
/**
* @param store the list of metadata
* @return true if this backend is capable of saving all the metadata
* of the store
*/
- virtual bool canSaveAllEntries(Store* store) const = 0;
+ virtual bool canSaveAllEntries(Store *store) const = 0;
/**
* @return true if this backend support loading
@@ -83,21 +78,8 @@ public:
* @param ioDevice the device from where the metadata will be loaded
* @return true if the load was successful
*/
- virtual bool loadFrom(Store* store, QIODevice* ioDevice) const = 0;
-};
-
-class KRITAMETADATA_EXPORT IOBackendRegistry : public KoGenericRegistry<IOBackend*>
-{
-
-public:
-
- IOBackendRegistry();
- ~IOBackendRegistry() override;
- static IOBackendRegistry* instance();
-
+ virtual bool loadFrom(Store *store, QIODevice *ioDevice) const = 0;
};
-
}
-
#endif
diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt
index 770eab3a99..5180076e11 100644
--- a/libs/ui/CMakeLists.txt
+++ b/libs/ui/CMakeLists.txt
@@ -167,11 +167,6 @@ set(kritaui_LIB_SRCS
KisChangeCloneLayersCommand.cpp
KisUiFont.cpp
- kisexiv2/kis_exif_io.cpp
- kisexiv2/kis_exiv2.cpp
- kisexiv2/kis_iptc_io.cpp
- kisexiv2/kis_xmp_io.cpp
-
opengl/kis_opengl.cpp
opengl/kis_opengl_canvas2.cpp
opengl/kis_opengl_canvas_debugger.cpp
@@ -648,7 +643,7 @@ add_library(kritaui SHARED ${kritaui_HEADERS_MOC} \
${kritaui_LIB_SRCS} ) generate_export_header(kritaui BASE_NAME kritaui)
target_link_libraries(kritaui KF5::CoreAddons KF5::Completion KF5::I18n \
KF5::ItemViews Qt5::Network
- kritaversion kritaimpex kritacolor kritaimage kritalibbrush \
kritawidgets kritawidgetutils kritaresources ${PNG_LIBRARIES} LibExiv2::LibExiv2 + \
kritaversion kritaimpex kritacolor kritaimage kritalibbrush kritawidgets \
kritawidgetutils kritaresources ${PNG_LIBRARIES} )
if (ANDROID)
diff --git a/libs/ui/KisApplication.cpp b/libs/ui/KisApplication.cpp
index cd06f77d36..c16c411aa4 100644
--- a/libs/ui/KisApplication.cpp
+++ b/libs/ui/KisApplication.cpp
@@ -63,7 +63,7 @@
#include <generator/kis_generator.h>
#include <brushengine/kis_paintop_registry.h>
#include <kis_meta_data_io_backend.h>
-#include "kisexiv2/kis_exiv2.h"
+#include <kis_meta_data_backend_registry.h>
#include "KisApplicationArguments.h"
#include <kis_debug.h>
#include "kis_action_registry.h"
@@ -347,15 +347,7 @@ void KisApplication::loadPlugins()
KisPaintOpRegistry::instance();
KoToolRegistry::instance();
KoDockRegistry::instance();
-}
-
-void KisApplication::loadGuiPlugins()
-{
- // XXX_EXIV: make the exiv io backends real plugins
- setSplashScreenLoadingText(i18n("Loading Plugins Exiv/IO..."));
- processEvents();
- // qDebug() << "loading exiv2";
- KisExiv2::initialize();
+ KisMetadataBackendRegistry::instance();
}
bool KisApplication::start(const KisApplicationArguments &args)
@@ -428,9 +420,6 @@ bool KisApplication::start(const KisApplicationArguments &args)
return false;
}
- // Load the gui plugins
- loadGuiPlugins();
-
KisPart *kisPart = KisPart::instance();
if (needsMainWindow) {
// show a mainWindow asap, if we want that
diff --git a/libs/ui/KisApplication.h b/libs/ui/KisApplication.h
index 8b8ff409b0..19b70c7679 100644
--- a/libs/ui/KisApplication.h
+++ b/libs/ui/KisApplication.h
@@ -85,7 +85,6 @@ public:
void addResourceTypes();
bool registerResources();
void loadPlugins();
- void loadGuiPlugins();
void initializeGlobals(const KisApplicationArguments &args);
public Q_SLOTS:
diff --git a/libs/ui/kis_png_converter.cpp b/libs/ui/kis_png_converter.cpp
index 0ec098ff4f..84b941695d 100644
--- a/libs/ui/kis_png_converter.cpp
+++ b/libs/ui/kis_png_converter.cpp
@@ -37,23 +37,23 @@
#include <KoColor.h>
#include <KoUnit.h>
-#include <kis_config.h>
-#include <kis_painter.h>
+#include "dialogs/kis_dlg_png_import.h"
+#include "kis_clipboard.h"
+#include "kis_undo_stores.h"
#include <KisDocument.h>
+#include <KoColorModelStandardIds.h>
+#include <kis_config.h>
+#include <kis_cursor_override_hijacker.h>
+#include <kis_group_layer.h>
#include <kis_image.h>
#include <kis_iterator_ng.h>
#include <kis_layer.h>
+#include <kis_meta_data_backend_registry.h>
+#include <kis_meta_data_store.h>
#include <kis_paint_device.h>
-#include <kis_transaction.h>
#include <kis_paint_layer.h>
-#include <kis_group_layer.h>
-#include <kis_meta_data_io_backend.h>
-#include <kis_meta_data_store.h>
-#include <KoColorModelStandardIds.h>
-#include "dialogs/kis_dlg_png_import.h"
-#include "kis_clipboard.h"
-#include <kis_cursor_override_hijacker.h>
-#include "kis_undo_stores.h"
+#include <kis_painter.h>
+#include <kis_transaction.h>
#include <kis_assert.h>
@@ -240,7 +240,7 @@ QByteArray png_read_raw_profile(png_textp text)
void decode_meta_data(png_textp text, KisMetaData::Store* store, QString type, int \
headerSize) {
dbgFile << "Decoding " << type << " " << text[0].key;
- KisMetaData::IOBackend* exifIO = \
KisMetaData::IOBackendRegistry::instance()->value(type); + KisMetaData::IOBackend \
*exifIO = KisMetadataBackendRegistry::instance()->value(type); Q_ASSERT(exifIO);
QByteArray rawProfile = png_read_raw_profile(text);
@@ -1244,7 +1244,7 @@ KisImportExportErrorCode KisPNGConverter::buildFile(QIODevice* \
iodevice, const Q if (options.exif) {
dbgFile << "Trying to save exif information";
- KisMetaData::IOBackend* exifIO = \
KisMetaData::IOBackendRegistry::instance()->value("exif"); + \
KisMetaData::IOBackend *exifIO = \
KisMetadataBackendRegistry::instance()->value("exif"); Q_ASSERT(exifIO);
QBuffer buffer;
@@ -1254,7 +1254,7 @@ KisImportExportErrorCode KisPNGConverter::buildFile(QIODevice* \
iodevice, const Q // Save IPTC
if (options.iptc) {
dbgFile << "Trying to save exif information";
- KisMetaData::IOBackend* iptcIO = \
KisMetaData::IOBackendRegistry::instance()->value("iptc"); + \
KisMetaData::IOBackend *iptcIO = \
KisMetadataBackendRegistry::instance()->value("iptc"); Q_ASSERT(iptcIO);
QBuffer buffer;
@@ -1266,7 +1266,7 @@ KisImportExportErrorCode KisPNGConverter::buildFile(QIODevice* \
iodevice, const Q // Save XMP
if (options.xmp) {
dbgFile << "Trying to save XMP information";
- KisMetaData::IOBackend* xmpIO = \
KisMetaData::IOBackendRegistry::instance()->value("xmp"); + \
KisMetaData::IOBackend *xmpIO = KisMetadataBackendRegistry::instance()->value("xmp"); \
Q_ASSERT(xmpIO);
QBuffer buffer;
diff --git a/libs/ui/kisexiv2/.krazy b/libs/ui/kisexiv2/.krazy
deleted file mode 100644
index cbcf2fb7c9..0000000000
--- a/libs/ui/kisexiv2/.krazy
+++ /dev/null
@@ -1 +0,0 @@
-EXCLUDE typedefs
diff --git a/libs/ui/kisexiv2/kis_exiv2.h b/libs/ui/kisexiv2/kis_exiv2.h
deleted file mode 100644
index 7b565a1584..0000000000
--- a/libs/ui/kisexiv2/kis_exiv2.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net>
- *
- * SPDX-License-Identifier: LGPL-2.1-or-later
- */
-
-#ifndef _KIS_EXIV2_H_
-#define _KIS_EXIV2_H_
-
-
-#include <kis_meta_data_value.h>
-#include <exiv2/exiv2.hpp>
-#include "kritaui_export.h"
-
-/// Convert an exiv value to a KisMetaData value
-KisMetaData::Value exivValueToKMDValue(const Exiv2::Value::AutoPtr value, bool \
forceSeq, KisMetaData::Value::ValueType arrayType = \
KisMetaData::Value::UnorderedArray);
-
-/// Convert a KisMetaData to an Exiv value
-Exiv2::Value* kmdValueToExivValue(const KisMetaData::Value& value, Exiv2::TypeId \
type);
-
-/**
- * Convert a KisMetaData to an Exiv value, without knowing the targeted \
Exiv2::TypeId
- * This function should be used for saving to XMP.
- */
-Exiv2::Value* kmdValueToExivXmpValue(const KisMetaData::Value& value);
-
-struct KRITAUI_EXPORT KisExiv2 {
-
- static void initialize();
-
-};
-#endif
diff --git a/libs/ui/tests/CMakeLists.txt b/libs/ui/tests/CMakeLists.txt
index 2f08704aa4..b2b7921288 100644
--- a/libs/ui/tests/CMakeLists.txt
+++ b/libs/ui/tests/CMakeLists.txt
@@ -272,13 +272,6 @@ endif()
NAME_PREFIX "libs-ui-"
${MACOS_GUI_TEST})
-
- krita_add_broken_unit_test( kis_exiv2_test.cpp
- TEST_NAME KisExiv2Test
- LINK_LIBRARIES kritaui Qt5::Test
- NAME_PREFIX "libs-ui-"
- ${MACOS_GUI_TEST})
-
krita_add_broken_unit_test( kis_clipboard_test.cpp
TEST_NAME KisClipboardTest
LINK_LIBRARIES kritaui Qt5::Test
@@ -349,7 +342,6 @@ endif()
macos_test_fixrpath(
${BROKEN_TESTS}
- KisExiv2Test
KisClipboardTest
KisSelectionManagerTest
KisNodeManagerTest
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index f22788342b..1d92f7e198 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -19,6 +19,7 @@ add_subdirectory( filters )
add_subdirectory( flake )
add_subdirectory( generators )
add_subdirectory( impex )
+add_subdirectory( metadata )
add_subdirectory( paintops )
add_subdirectory( tools )
add_subdirectory( qt )
diff --git a/plugins/impex/heif/HeifExport.cpp b/plugins/impex/heif/HeifExport.cpp
index 48f1339664..c8e514d864 100644
--- a/plugins/impex/heif/HeifExport.cpp
+++ b/plugins/impex/heif/HeifExport.cpp
@@ -37,14 +37,14 @@
#include <kis_paint_device.h>
#include <kis_paint_layer.h>
-#include <kis_meta_data_store.h>
+#include <kis_exif_info_visitor.h>
+#include <kis_meta_data_backend_registry.h>
#include <kis_meta_data_entry.h>
-#include <kis_meta_data_value.h>
+#include <kis_meta_data_filter_registry_model.h>
#include <kis_meta_data_schema.h>
#include <kis_meta_data_schema_registry.h>
-#include <kis_meta_data_filter_registry_model.h>
-#include <kis_exif_info_visitor.h>
-#include <kis_meta_data_io_backend.h>
+#include <kis_meta_data_store.h>
+#include <kis_meta_data_value.h>
#include "kis_iterator_ng.h"
@@ -479,7 +479,7 @@ KisImportExportErrorCode HeifExport::convert(KisDocument \
*document, QIODevice *i
if (!metaDataStore->empty()) {
{
- KisMetaData::IOBackend* exifIO = \
KisMetaData::IOBackendRegistry::instance()->value("exif"); + \
KisMetaData::IOBackend *exifIO = \
KisMetadataBackendRegistry::instance()->value("exif"); QBuffer buffer;
exifIO->saveTo(metaDataStore.data(), &buffer, \
KisMetaData::IOBackend::NoHeader); // Or JpegHeader? Or something else? QByteArray \
data = buffer.data(); @@ -490,7 +490,7 @@ KisImportExportErrorCode \
HeifExport::convert(KisDocument *document, QIODevice *i }
}
{
- KisMetaData::IOBackend* xmpIO = \
KisMetaData::IOBackendRegistry::instance()->value("xmp"); + \
KisMetaData::IOBackend *xmpIO = KisMetadataBackendRegistry::instance()->value("xmp"); \
QBuffer buffer;
xmpIO->saveTo(metaDataStore.data(), &buffer, \
KisMetaData::IOBackend::NoHeader); // Or JpegHeader? Or something else? QByteArray \
data = buffer.data();
diff --git a/plugins/impex/heif/HeifImport.cpp b/plugins/impex/heif/HeifImport.cpp
index fe72e747c8..6ae3d788c0 100644
--- a/plugins/impex/heif/HeifImport.cpp
+++ b/plugins/impex/heif/HeifImport.cpp
@@ -30,10 +30,10 @@
#include <kis_node.h>
#include <kis_group_layer.h>
+#include <kis_meta_data_backend_registry.h>
#include <kis_meta_data_entry.h>
-#include <kis_meta_data_value.h>
#include <kis_meta_data_store.h>
-#include <kis_meta_data_io_backend.h>
+#include <kis_meta_data_value.h>
#include "kis_iterator_ng.h"
@@ -458,12 +458,13 @@ KisImportExportErrorCode HeifImport::convert(KisDocument \
*document, QIODevice *i
size_t skip = ((exif_data[0]<<24) | (exif_data[1]<<16) | \
(exif_data[2]<<8) | exif_data[3]) + 4;
if (exif_data.size()>skip) {
- KisMetaData::IOBackend* exifIO = \
KisMetaData::IOBackendRegistry::instance()->value("exif"); + \
KisMetaData::IOBackend *exifIO = \
KisMetadataBackendRegistry::instance()->value("exif");
- // Copy the exif data into the byte array
- QByteArray ba(reinterpret_cast<char *>(exif_data.data()+skip), \
static_cast<int>(exif_data.size()-skip));
- QBuffer buf(&ba);
- exifIO->loadFrom(layer->metaData(), &buf);
+ // Copy the exif data into the byte array
+ QByteArray ba(reinterpret_cast<char *>(exif_data.data() + skip),
+ static_cast<int>(exif_data.size() - skip));
+ QBuffer buf(&ba);
+ exifIO->loadFrom(layer->metaData(), &buf);
}
}
}
@@ -474,7 +475,7 @@ KisImportExportErrorCode HeifImport::convert(KisDocument \
*document, QIODevice *i
std::vector<uint8_t> xmp_data = handle.get_metadata(id);
- KisMetaData::IOBackend* xmpIO = \
KisMetaData::IOBackendRegistry::instance()->value("xmp"); + \
KisMetaData::IOBackend *xmpIO = KisMetadataBackendRegistry::instance()->value("xmp"); \
// Copy the xmp data into the byte array
QByteArray ba(reinterpret_cast<char *>(xmp_data.data()), \
static_cast<int>(xmp_data.size()));
diff --git a/plugins/impex/jpeg/kis_jpeg_converter.cc \
b/plugins/impex/jpeg/kis_jpeg_converter.cc index 8b22279bc6..3364ae6eda 100644
--- a/plugins/impex/jpeg/kis_jpeg_converter.cc
+++ b/plugins/impex/jpeg/kis_jpeg_converter.cc
@@ -36,21 +36,21 @@ extern "C" {
#include <KoUnit.h>
#include "KoColorModelStandardIds.h"
-#include <kis_painter.h>
#include <KisDocument.h>
-#include <kis_image.h>
-#include <kis_paint_layer.h>
-#include <kis_transaction.h>
#include <kis_group_layer.h>
+#include <kis_image.h>
+#include <kis_iterator_ng.h>
+#include <kis_jpeg_destination.h>
+#include <kis_jpeg_source.h>
+#include <kis_meta_data_backend_registry.h>
#include <kis_meta_data_entry.h>
-#include <kis_meta_data_value.h>
#include <kis_meta_data_store.h>
-#include <kis_meta_data_io_backend.h>
+#include <kis_meta_data_value.h>
#include <kis_paint_device.h>
+#include <kis_paint_layer.h>
+#include <kis_painter.h>
+#include <kis_transaction.h>
#include <kis_transform_worker.h>
-#include <kis_jpeg_source.h>
-#include <kis_jpeg_destination.h>
-#include "kis_iterator_ng.h"
#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */
#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */
@@ -311,7 +311,7 @@ KisImportExportErrorCode KisJPEGConverter::decode(QIODevice *io)
continue; /* no Exif header */
dbgFile << "Found exif information of length :" << marker->data_length;
- KisMetaData::IOBackend* exifIO = \
KisMetaData::IOBackendRegistry::instance()->value("exif"); + \
KisMetaData::IOBackend *exifIO = \
KisMetadataBackendRegistry::instance()->value("exif"); Q_ASSERT(exifIO);
QByteArray byteArray((const char*)marker->data + 6, marker->data_length \
- 6); QBuffer buf(&byteArray);
@@ -369,7 +369,7 @@ KisImportExportErrorCode KisJPEGConverter::decode(QIODevice *io)
}
dbgFile << "Found Photoshop information of length :" << \
marker->data_length;
- KisMetaData::IOBackend* iptcIO = \
KisMetaData::IOBackendRegistry::instance()->value("iptc"); + \
KisMetaData::IOBackend *iptcIO = \
KisMetadataBackendRegistry::instance()->value("iptc"); Q_ASSERT(iptcIO);
const Exiv2::byte *record = 0;
uint32_t sizeIptc = 0;
@@ -402,7 +402,7 @@ KisImportExportErrorCode KisJPEGConverter::decode(QIODevice *io)
}
dbgFile << "Found XMP Marker of length " << marker->data_length;
QByteArray byteArray((const char*)marker->data + 29, marker->data_length \
- 29);
- KisMetaData::IOBackend* xmpIO = \
KisMetaData::IOBackendRegistry::instance()->value("xmp"); + \
KisMetaData::IOBackend *xmpIO = KisMetadataBackendRegistry::instance()->value("xmp"); \
Q_ASSERT(xmpIO); xmpIO->loadFrom(layer->metaData(), new QBuffer(&byteArray));
break;
@@ -562,7 +562,7 @@ KisImportExportErrorCode KisJPEGConverter::buildFile(QIODevice \
*io, KisPaintLaye if (options.exif) {
dbgFile << "Trying to save exif information";
- KisMetaData::IOBackend* exifIO = \
KisMetaData::IOBackendRegistry::instance()->value("exif"); + \
KisMetaData::IOBackend *exifIO = \
KisMetadataBackendRegistry::instance()->value("exif"); Q_ASSERT(exifIO);
QBuffer buffer;
@@ -579,7 +579,7 @@ KisImportExportErrorCode KisJPEGConverter::buildFile(QIODevice \
*io, KisPaintLaye // Save IPTC
if (options.iptc) {
dbgFile << "Trying to save exif information";
- KisMetaData::IOBackend* iptcIO = \
KisMetaData::IOBackendRegistry::instance()->value("iptc"); + \
KisMetaData::IOBackend *iptcIO = \
KisMetadataBackendRegistry::instance()->value("iptc"); Q_ASSERT(iptcIO);
QBuffer buffer;
@@ -596,7 +596,7 @@ KisImportExportErrorCode KisJPEGConverter::buildFile(QIODevice \
*io, KisPaintLaye // Save XMP
if (options.xmp) {
dbgFile << "Trying to save XMP information";
- KisMetaData::IOBackend* xmpIO = \
KisMetaData::IOBackendRegistry::instance()->value("xmp"); + \
KisMetaData::IOBackend *xmpIO = KisMetadataBackendRegistry::instance()->value("xmp"); \
Q_ASSERT(xmpIO);
QBuffer buffer;
diff --git a/plugins/impex/jpeg/tests/CMakeLists.txt \
b/plugins/impex/jpeg/tests/CMakeLists.txt index bbe98e1d57..d7f067cb73 100644
--- a/plugins/impex/jpeg/tests/CMakeLists.txt
+++ b/plugins/impex/jpeg/tests/CMakeLists.txt
@@ -7,7 +7,7 @@ if (APPLE)
krita_add_broken_unit_tests(
kis_jpeg_test.cpp
- LINK_LIBRARIES kritaui Qt5::Test
+ LINK_LIBRARIES kritametadata kritaui Qt5::Test
NAME_PREFIX "plugins-impex-"
TARGET_NAMES_VAR BROKEN_TESTS
${MACOS_GUI_TEST}
@@ -19,7 +19,7 @@ else (APPLE)
ecm_add_test(
kis_jpeg_test.cpp
TEST_NAME kis_jpeg_test
- LINK_LIBRARIES kritaui Qt5::Test
+ LINK_LIBRARIES kritametadata kritaui Qt5::Test
NAME_PREFIX "plugins-impex-"
)
diff --git a/plugins/impex/jpeg/tests/kis_jpeg_test.cpp \
b/plugins/impex/jpeg/tests/kis_jpeg_test.cpp index de2c82af88..e9eef81664 100644
--- a/plugins/impex/jpeg/tests/kis_jpeg_test.cpp
+++ b/plugins/impex/jpeg/tests/kis_jpeg_test.cpp
@@ -9,10 +9,10 @@
#include <simpletest.h>
#include <QCoreApplication>
-#include "kisexiv2/kis_exiv2.h"
#include "filestest.h"
#include "jpeglib.h"
-#include <sdk/tests/testui.h>
+#include <kis_meta_data_backend_registry.h>
+#include <sdk/tests/testui.h>
#ifndef FILES_DATA_DIR
#error "FILES_DATA_DIR not set. A directory with the data used for testing the \
importing of files in krita" @@ -26,7 +26,7 @@ const QString JpegMimetype = \
"image/jpeg";
void KisJpegTest::testFiles()
{
- KisExiv2::initialize();
+ KisMetadataBackendRegistry::instance();
/**
* Different versions of JPEG library may produce a bit different
* result, so just compare in a weak way, i.e, only the size for real
diff --git a/plugins/impex/libkra/kis_kra_load_visitor.cpp \
b/plugins/impex/libkra/kis_kra_load_visitor.cpp index fe30ebfd03..873a83cb71 100644
--- a/plugins/impex/libkra/kis_kra_load_visitor.cpp
+++ b/plugins/impex/libkra/kis_kra_load_visitor.cpp
@@ -28,37 +28,36 @@
#include <KisGlobalResourcesInterface.h>
// kritaimage
-#include <kis_meta_data_io_backend.h>
-#include <kis_meta_data_store.h>
-#include <kis_types.h>
-#include <kis_node_visitor.h>
-#include <kis_image.h>
-#include <kis_selection.h>
-#include <kis_layer.h>
-#include <kis_paint_layer.h>
-#include <kis_group_layer.h>
-#include <kis_adjustment_layer.h>
+#include "kis_colorize_dom_utils.h"
+#include "kis_dom_utils.h"
+#include "kis_filter_registry.h"
+#include "kis_generator_registry.h"
+#include "kis_paint_device_frames_interface.h"
+#include "kis_raster_keyframe_channel.h"
+#include "kis_shape_selection.h"
+#include "kis_transform_mask_params_factory_registry.h"
#include <filter/kis_filter_configuration.h>
-#include <kis_datamanager.h>
#include <generator/kis_generator_layer.h>
-#include <kis_pixel_selection.h>
+#include <kis_adjustment_layer.h>
#include <kis_clone_layer.h>
+#include <kis_datamanager.h>
#include <kis_filter_mask.h>
+#include <kis_group_layer.h>
+#include <kis_image.h>
+#include <kis_layer.h>
+#include <kis_meta_data_backend_registry.h>
+#include <kis_meta_data_store.h>
+#include <kis_node_visitor.h>
+#include <kis_paint_layer.h>
+#include <kis_pixel_selection.h>
+#include <kis_selection.h>
+#include <kis_selection_mask.h>
#include <kis_transform_mask.h>
#include <kis_transform_mask_params_interface.h>
-#include "kis_transform_mask_params_factory_registry.h"
#include <kis_transparency_mask.h>
-#include <kis_selection_mask.h>
+#include <kis_types.h>
#include <lazybrush/kis_colorize_mask.h>
#include <lazybrush/kis_lazy_fill_tools.h>
-#include "kis_shape_selection.h"
-#include "kis_colorize_dom_utils.h"
-#include "kis_dom_utils.h"
-#include "kis_raster_keyframe_channel.h"
-#include "kis_paint_device_frames_interface.h"
-#include "kis_filter_registry.h"
-#include "kis_generator_registry.h"
-
using namespace KRA;
@@ -693,7 +692,7 @@ bool KisKraLoadVisitor::loadMetaData(KisNode* node)
KisLayer* layer = qobject_cast<KisLayer*>(node);
if (!layer) return true;
- KisMetaData::IOBackend* backend = \
KisMetaData::IOBackendRegistry::instance()->get("xmp"); + KisMetaData::IOBackend \
*backend = KisMetadataBackendRegistry::instance()->get("xmp");
if (!backend || !backend->supportLoading()) {
if (backend)
diff --git a/plugins/impex/libkra/kis_kra_save_visitor.cpp \
b/plugins/impex/libkra/kis_kra_save_visitor.cpp index b5b1ecf41b..a8c8935f51 100644
--- a/plugins/impex/libkra/kis_kra_save_visitor.cpp
+++ b/plugins/impex/libkra/kis_kra_save_visitor.cpp
@@ -16,31 +16,31 @@
#include <KoStore.h>
#include <KoColorSpace.h>
+#include "lazybrush/kis_colorize_mask.h"
+#include <KisReferenceImage.h>
+#include <KisReferenceImagesLayer.h>
#include <filter/kis_filter_configuration.h>
#include <generator/kis_generator_layer.h>
#include <kis_adjustment_layer.h>
#include <kis_annotation.h>
+#include <kis_clone_layer.h>
+#include <kis_file_layer.h>
+#include <kis_filter_mask.h>
#include <kis_group_layer.h>
#include <kis_image.h>
#include <kis_layer.h>
+#include <kis_mask.h>
+#include <kis_meta_data_backend_registry.h>
+#include <kis_meta_data_store.h>
#include <kis_paint_layer.h>
+#include <kis_pixel_selection.h>
#include <kis_selection.h>
+#include <kis_selection_component.h>
+#include <kis_selection_mask.h>
#include <kis_shape_layer.h>
-#include <KisReferenceImagesLayer.h>
-#include <KisReferenceImage.h>
-#include <kis_file_layer.h>
-#include <kis_clone_layer.h>
-#include <kis_mask.h>
-#include <kis_filter_mask.h>
#include <kis_transform_mask.h>
#include <kis_transform_mask_params_interface.h>
#include <kis_transparency_mask.h>
-#include <kis_selection_mask.h>
-#include "lazybrush/kis_colorize_mask.h"
-#include <kis_selection_component.h>
-#include <kis_pixel_selection.h>
-#include <kis_meta_data_store.h>
-#include <kis_meta_data_io_backend.h>
#include "kis_config.h"
#include "kis_store_paintdevice_writer.h"
@@ -502,7 +502,7 @@ bool KisKraSaveVisitor::saveMetaData(KisNode* node)
if (metadata->isEmpty()) return true;
// Serialize all the types of metadata there are
- KisMetaData::IOBackend* backend = \
KisMetaData::IOBackendRegistry::instance()->get("xmp"); + KisMetaData::IOBackend \
*backend = KisMetadataBackendRegistry::instance()->get("xmp"); if \
(!backend->supportSaving()) {
dbgFile << "Backend " << backend->id() << " does not support saving.";
return false;
diff --git a/plugins/impex/tiff/tests/kis_tiff_test.cpp \
b/plugins/impex/tiff/tests/kis_tiff_test.cpp index 2b2f081ca5..5cc215f309 100644
--- a/plugins/impex/tiff/tests/kis_tiff_test.cpp
+++ b/plugins/impex/tiff/tests/kis_tiff_test.cpp
@@ -15,9 +15,9 @@
#include <KoColorModelStandardIds.h>
#include <KoColor.h>
-#include "kisexiv2/kis_exiv2.h"
-#include <sdk/tests/testui.h>
#include <KoColorModelStandardIdsUtils.h>
+#include <kis_meta_data_backend_registry.h>
+#include <sdk/tests/testui.h>
#ifndef FILES_DATA_DIR
#error "FILES_DATA_DIR not set. A directory with the data used for testing the \
importing of files in krita" @@ -28,8 +28,7 @@ const QString TiffMimetype = \
"image/tiff";
void KisTiffTest::testFiles()
{
- // XXX: make the exiv io backends real plugins
- KisExiv2::initialize();
+ KisMetadataBackendRegistry::instance();
QStringList excludes;
diff --git a/plugins/metadata/CMakeLists.txt b/plugins/metadata/CMakeLists.txt
new file mode 100644
index 0000000000..9c7a9e3f75
--- /dev/null
+++ b/plugins/metadata/CMakeLists.txt
@@ -0,0 +1,7 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common)
+
+add_subdirectory(exif)
+add_subdirectory(iptc)
+add_subdirectory(xmp)
+
+add_subdirectory(tests)
diff --git a/libs/ui/kisexiv2/kis_exiv2.cpp \
b/plugins/metadata/common/kis_exiv2_common.h similarity index 81%
rename from libs/ui/kisexiv2/kis_exiv2.cpp
rename to plugins/metadata/common/kis_exiv2_common.h
index 211afca4ee..3c3299e3b7 100644
--- a/libs/ui/kisexiv2/kis_exiv2.cpp
+++ b/plugins/metadata/common/kis_exiv2_common.h
@@ -5,21 +5,23 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
-#include "kis_exiv2.h"
+#ifndef _KIS_EXIV2_COMMON_H_
+#define _KIS_EXIV2_COMMON_H_
#include <QDateTime>
-#include "kis_iptc_io.h"
-#include "kis_exif_io.h"
-#include "kis_xmp_io.h"
+#include <exiv2/exiv2.hpp>
-#include <kis_meta_data_value.h>
#include <kis_debug.h>
+#include <kis_meta_data_value.h>
// ---- Generic conversion functions ---- //
// Convert an exiv value to a KisMetaData value
-KisMetaData::Value exivValueToKMDValue(const Exiv2::Value::AutoPtr value, bool \
forceSeq, KisMetaData::Value::ValueType arrayType) +inline KisMetaData::Value
+exivValueToKMDValue(const Exiv2::Value::AutoPtr value,
+ bool forceSeq,
+ KisMetaData::Value::ValueType arrayType = \
KisMetaData::Value::UnorderedArray) {
switch (value->typeId()) {
case Exiv2::signedByte:
@@ -30,8 +32,8 @@ KisMetaData::Value exivValueToKMDValue(const Exiv2::Value::AutoPtr \
value, bool f return KisMetaData::Value();
case Exiv2::undefined: {
dbgMetaData << "Undefined value :" << value->typeId() << " value =" << \
value->toString().c_str();
- QByteArray array(value->count() , 0);
- value->copy((Exiv2::byte*)array.data(), Exiv2::invalidByteOrder);
+ QByteArray array(value->count(), 0);
+ value->copy((Exiv2::byte *)array.data(), Exiv2::invalidByteOrder);
return KisMetaData::Value(QString(array.toBase64()));
}
case Exiv2::unsignedByte:
@@ -90,23 +92,22 @@ KisMetaData::Value exivValueToKMDValue(const \
Exiv2::Value::AutoPtr value, bool f case Exiv2::langAlt:
default: {
dbgMetaData << "Unknown type id :" << value->typeId() << " value =" << \
value->toString().c_str();
- //Q_ASSERT(false); // This point must never be reached !
+ // Q_ASSERT(false); // This point must never be reached !
return KisMetaData::Value();
}
}
dbgMetaData << "Unknown type id :" << value->typeId() << " value =" << \
value->toString().c_str();
- //Q_ASSERT(false); // This point must never be reached !
+ // Q_ASSERT(false); // This point must never be reached !
return KisMetaData::Value();
}
-
// Convert a QtVariant to an Exiv value
-Exiv2::Value* variantToExivValue(const QVariant& variant, Exiv2::TypeId type)
+inline Exiv2::Value *variantToExivValue(const QVariant &variant, Exiv2::TypeId type)
{
switch (type) {
case Exiv2::undefined: {
QByteArray arr = QByteArray::fromBase64(variant.toString().toLatin1());
- return new Exiv2::DataValue((Exiv2::byte*)arr.data(), arr.size());
+ return new Exiv2::DataValue((Exiv2::byte *)arr.data(), arr.size());
}
case Exiv2::unsignedByte:
return new Exiv2::ValueType<uint16_t>((uint16_t)variant.toUInt());
@@ -124,12 +125,14 @@ Exiv2::Value* variantToExivValue(const QVariant& variant, \
Exiv2::TypeId type) }
case Exiv2::asciiString:
if (variant.type() == QVariant::DateTime) {
- return new \
Exiv2::AsciiValue(qPrintable(QLocale::c().toString(variant.toDateTime(), \
QStringLiteral("yyyy:MM:dd hh:mm:ss")))); + return new Exiv2::AsciiValue(
+ qPrintable(QLocale::c().toString(variant.toDateTime(), \
QStringLiteral("yyyy:MM:dd hh:mm:ss")))); } else
return new Exiv2::AsciiValue(qPrintable(variant.toString()));
case Exiv2::string: {
if (variant.type() == QVariant::DateTime) {
- return new \
Exiv2::StringValue(qPrintable(QLocale::c().toString(variant.toDateTime(), \
QStringLiteral("yyyy:MM:dd hh:mm:ss")))); + return new Exiv2::StringValue(
+ qPrintable(QLocale::c().toString(variant.toDateTime(), \
QStringLiteral("yyyy:MM:dd hh:mm:ss")))); } else
return new Exiv2::StringValue(qPrintable(variant.toString()));
}
@@ -137,23 +140,23 @@ Exiv2::Value* variantToExivValue(const QVariant& variant, \
Exiv2::TypeId type) return new Exiv2::CommentValue(qPrintable(variant.toString()));
default:
dbgMetaData << "Unhandled type:" << type;
- //Q_ASSERT(false);
+ // Q_ASSERT(false);
return 0;
}
}
template<typename _TYPE_>
-Exiv2::Value* arrayToExivValue(const KisMetaData::Value& value)
+Exiv2::Value *arrayToExivValue(const KisMetaData::Value &value)
{
- Exiv2::ValueType<_TYPE_>* ev = new Exiv2::ValueType<_TYPE_>();
+ Exiv2::ValueType<_TYPE_> *ev = new Exiv2::ValueType<_TYPE_>();
for (int i = 0; i < value.asArray().size(); ++i) {
ev->value_.push_back(qvariant_cast<_TYPE_>(value.asArray()[i].asVariant()));
}
return ev;
}
-// Convert a KisMetaData to an Exiv value
-Exiv2::Value* kmdValueToExivValue(const KisMetaData::Value& value, Exiv2::TypeId \
type) +/// Convert a KisMetaData to an Exiv value
+inline Exiv2::Value *kmdValueToExivValue(const KisMetaData::Value &value, \
Exiv2::TypeId type) {
switch (value.type()) {
case KisMetaData::Value::Invalid:
@@ -162,7 +165,7 @@ Exiv2::Value* kmdValueToExivValue(const KisMetaData::Value& \
value, Exiv2::TypeId return variantToExivValue(value.asVariant(), type);
}
case KisMetaData::Value::Rational:
- //Q_ASSERT(type == Exiv2::signedRational || type == \
Exiv2::unsignedRational); + // Q_ASSERT(type == Exiv2::signedRational || type \
== Exiv2::unsignedRational); if (type == Exiv2::signedRational) {
return new Exiv2::RationalValue({value.asRational().numerator, \
value.asRational().denominator}); } else {
@@ -185,10 +188,11 @@ Exiv2::Value* kmdValueToExivValue(const KisMetaData::Value& \
value, Exiv2::TypeId case Exiv2::signedLong:
return arrayToExivValue<int32_t>(value);
case Exiv2::string: {
- Exiv2::StringValue* ev = new Exiv2::StringValue();
+ Exiv2::StringValue *ev = new Exiv2::StringValue();
for (int i = 0; i < value.asArray().size(); ++i) {
ev->value_ += \
qvariant_cast<QString>(value.asArray()[i].asVariant()).toLatin1().constData();
- if (i != value.asArray().size() - 1) ev->value_ += ',';
+ if (i != value.asArray().size() - 1)
+ ev->value_ += ',';
}
return ev;
}
@@ -223,9 +227,11 @@ Exiv2::Value* kmdValueToExivValue(const KisMetaData::Value& \
value, Exiv2::TypeId return 0;
}
-Exiv2::Value* kmdValueToExivXmpValue(const KisMetaData::Value& value)
+/// Convert a KisMetaData to an Exiv value, without knowing the targeted \
Exiv2::TypeId +/// This function should be used for saving to XMP.
+inline Exiv2::Value *kmdValueToExivXmpValue(const KisMetaData::Value &value)
{
- //Q_ASSERT(value.type() != KisMetaData::Value::Structure);
+ // Q_ASSERT(value.type() != KisMetaData::Value::Structure);
switch (value.type()) {
case KisMetaData::Value::Invalid:
return new Exiv2::DataValue(Exiv2::invalidTypeId);
@@ -238,7 +244,7 @@ Exiv2::Value* kmdValueToExivXmpValue(const KisMetaData::Value& \
value) return new Exiv2::XmpTextValue("False");
}
} else {
- //Q_ASSERT(var.canConvert(QVariant::String));
+ // Q_ASSERT(var.canConvert(QVariant::String));
return new Exiv2::XmpTextValue(var.toString().toLatin1().constData());
}
}
@@ -251,7 +257,7 @@ Exiv2::Value* kmdValueToExivXmpValue(const KisMetaData::Value& \
value) case KisMetaData::Value::AlternativeArray:
case KisMetaData::Value::OrderedArray:
case KisMetaData::Value::UnorderedArray: {
- Exiv2::XmpArrayValue* arrV = new Exiv2::XmpArrayValue;
+ Exiv2::XmpArrayValue *arrV = new Exiv2::XmpArrayValue;
switch (value.type()) {
case KisMetaData::Value::OrderedArray:
arrV->setXmpArrayType(Exiv2::XmpValue::xaSeq);
@@ -266,8 +272,8 @@ Exiv2::Value* kmdValueToExivXmpValue(const KisMetaData::Value& \
value) // Cannot happen
;
}
- Q_FOREACH (const KisMetaData::Value& v, value.asArray()) {
- Exiv2::Value* ev = kmdValueToExivXmpValue(v);
+ Q_FOREACH (const KisMetaData::Value &v, value.asArray()) {
+ Exiv2::Value *ev = kmdValueToExivXmpValue(v);
if (ev) {
arrV->read(ev->toString());
delete ev;
@@ -276,17 +282,16 @@ Exiv2::Value* kmdValueToExivXmpValue(const KisMetaData::Value& \
value) return arrV;
}
case KisMetaData::Value::LangArray: {
- Exiv2::Value* arrV = new Exiv2::LangAltValue;
+ Exiv2::Value *arrV = new Exiv2::LangAltValue;
QMap<QString, KisMetaData::Value> langArray = value.asLangArray();
- for (QMap<QString, KisMetaData::Value>::iterator it = langArray.begin();
- it != langArray.end(); ++it) {
+ for (QMap<QString, KisMetaData::Value>::iterator it = langArray.begin(); it \
!= langArray.end(); ++it) { QString exivVal;
if (it.key() != "x-default") {
exivVal = "lang=" + it.key() + ' ';
}
- //Q_ASSERT(it.value().type() == KisMetaData::Value::Variant);
+ // Q_ASSERT(it.value().type() == KisMetaData::Value::Variant);
QVariant var = it.value().asVariant();
- //Q_ASSERT(var.type() == QVariant::String);
+ // Q_ASSERT(var.type() == QVariant::String);
exivVal += var.toString();
arrV->read(exivVal.toLatin1().constData());
}
@@ -297,18 +302,8 @@ Exiv2::Value* kmdValueToExivXmpValue(const KisMetaData::Value& \
value) warnKrita << "KisExiv2: Unhandled value type";
return 0;
}
-
}
warnKrita << "KisExiv2: Unhandled value type";
return 0;
}
-
-void KisExiv2::initialize()
-{
- // XXX_EXIV: make the exiv io backends real plugins
-
- KisMetaData::IOBackendRegistry* ioreg = \
KisMetaData::IOBackendRegistry::instance();
- ioreg->add(new KisIptcIO);
- ioreg->add(new KisExifIO);
- ioreg->add(new KisXMPIO);
-}
+#endif
diff --git a/libs/ui/kisexiv2/kis_exiv2_constants.h \
b/plugins/metadata/common/kis_exiv2_constants.h similarity index 100%
rename from libs/ui/kisexiv2/kis_exiv2_constants.h
rename to plugins/metadata/common/kis_exiv2_constants.h
diff --git a/plugins/metadata/exif/CMakeLists.txt \
b/plugins/metadata/exif/CMakeLists.txt new file mode 100644
index 0000000000..a6cf68541a
--- /dev/null
+++ b/plugins/metadata/exif/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(kritaexif_SOURCES
+ kis_exif_io.cpp
+ kis_exif_plugin.cpp
+)
+
+add_library(kritaexif MODULE ${kritaexif_SOURCES})
+
+generate_export_header(kritaexif)
+
+target_link_libraries(kritaexif
+ PRIVATE
+ kritametadata
+ KF5::CoreAddons
+ LibExiv2::LibExiv2
+)
+
+install(TARGETS kritaexif DESTINATION ${KRITA_PLUGIN_INSTALL_DIR})
diff --git a/libs/ui/kisexiv2/kis_exif_io.cpp b/plugins/metadata/exif/kis_exif_io.cpp
similarity index 76%
rename from libs/ui/kisexiv2/kis_exif_io.cpp
rename to plugins/metadata/exif/kis_exif_io.cpp
index 8477ba3459..e12107e14c 100644
--- a/libs/ui/kisexiv2/kis_exif_io.cpp
+++ b/plugins/metadata/exif/kis_exif_io.cpp
@@ -7,8 +7,8 @@
#include "kis_exif_io.h"
-#include <exiv2/exif.hpp>
#include <exiv2/error.hpp>
+#include <exiv2/exif.hpp>
#include <QByteArray>
#include <QDate>
@@ -20,42 +20,37 @@
#include <QtEndian>
#include <kis_debug.h>
-#include <kis_meta_data_store.h>
+#include <kis_exiv2_common.h>
+#include <kis_exiv2_constants.h>
#include <kis_meta_data_entry.h>
-#include <kis_meta_data_value.h>
#include <kis_meta_data_schema.h>
#include <kis_meta_data_schema_registry.h>
-
-#include "kis_exiv2.h"
-#include "kis_exiv2_constants.h"
-
-struct KisExifIO::Private {
-};
+#include <kis_meta_data_store.h>
+#include <kis_meta_data_value.h>
// ---- Exception conversion functions ---- //
// convert ExifVersion and FlashpixVersion to a KisMetaData value
KisMetaData::Value exifVersionToKMDValue(const Exiv2::Value::AutoPtr value)
{
- const Exiv2::DataValue* dvalue = dynamic_cast<const Exiv2::DataValue*>(&*value);
+ const Exiv2::DataValue *dvalue = dynamic_cast<const Exiv2::DataValue \
*>(&*value); if (dvalue) {
Q_ASSERT(dvalue);
QByteArray array(dvalue->count(), 0);
- dvalue->copy((Exiv2::byte*)array.data());
+ dvalue->copy((Exiv2::byte *)array.data());
return KisMetaData::Value(QString(array));
- }
- else {
+ } else {
Q_ASSERT(value->typeId() == Exiv2::asciiString);
return KisMetaData::Value(QString::fromLatin1(value->toString().c_str()));
}
}
// convert from KisMetaData value to ExifVersion and FlashpixVersion
-Exiv2::Value* kmdValueToExifVersion(const KisMetaData::Value& value)
+Exiv2::Value *kmdValueToExifVersion(const KisMetaData::Value &value)
{
- Exiv2::DataValue* dvalue = new Exiv2::DataValue;
+ Exiv2::DataValue *dvalue = new Exiv2::DataValue;
QString ver = value.asVariant().toString();
- dvalue->read((const Exiv2::byte*)ver.toLatin1().constData(), ver.size());
+ dvalue->read((const Exiv2::byte *)ver.toLatin1().constData(), ver.size());
return dvalue;
}
@@ -63,7 +58,7 @@ Exiv2::Value* kmdValueToExifVersion(const KisMetaData::Value& \
value) KisMetaData::Value exifArrayToKMDIntOrderedArray(const Exiv2::Value::AutoPtr \
value) {
QList<KisMetaData::Value> v;
- const Exiv2::DataValue* dvalue = dynamic_cast<const Exiv2::DataValue*>(&*value);
+ const Exiv2::DataValue *dvalue = dynamic_cast<const Exiv2::DataValue \
*>(&*value); if (dvalue) {
for (long i = 0; i < dvalue->count(); i++) {
v.push_back({(int)dvalue->toLong(i)});
@@ -77,7 +72,7 @@ KisMetaData::Value exifArrayToKMDIntOrderedArray(const \
Exiv2::Value::AutoPtr val }
// Convert a KisMetaData array of integer to an exif array of integer string
-Exiv2::Value* kmdIntOrderedArrayToExifArray(const KisMetaData::Value& value)
+Exiv2::Value *kmdIntOrderedArrayToExifArray(const KisMetaData::Value &value)
{
std::vector<Exiv2::byte> v;
for (const KisMetaData::Value &it : value.asArray()) {
@@ -120,22 +115,23 @@ Exiv2::ByteOrder invertByteOrder(Exiv2::ByteOrder order)
return Exiv2::invalidByteOrder;
}
-
KisMetaData::Value exifOECFToKMDOECFStructure(const Exiv2::Value::AutoPtr value, \
Exiv2::ByteOrder order) {
QMap<QString, KisMetaData::Value> oecfStructure;
- const Exiv2::DataValue* dvalue = dynamic_cast<const Exiv2::DataValue*>(&*value);
+ const Exiv2::DataValue *dvalue = dynamic_cast<const Exiv2::DataValue \
*>(&*value); Q_ASSERT(dvalue);
QByteArray array(dvalue->count(), 0);
- dvalue->copy((Exiv2::byte*)array.data());
- int columns = fixEndianess<quint16>((reinterpret_cast<quint16*>(array.data()))[0], \
order);
- int rows = fixEndianess<quint16>((reinterpret_cast<quint16*>(array.data()))[1], \
order); + dvalue->copy((Exiv2::byte *)array.data());
+ int columns = fixEndianess<quint16>((reinterpret_cast<quint16 \
*>(array.data()))[0], order); + int rows = \
fixEndianess<quint16>((reinterpret_cast<quint16 *>(array.data()))[1], order);
- if ((columns * rows + 4) > dvalue->count()) { // Sometime byteOrder get messed \
up (especially if metadata got saved with kexiv2 library, or any library that doesn't \
save back with the same byte order as the camera) + if ((columns * rows + 4)
+ > dvalue->count()) { // Sometime byteOrder get messed up (especially if \
metadata got saved with kexiv2 library, + // or any \
library that doesn't save back with the same byte order as the camera) order = \
invertByteOrder(order);
- columns = fixEndianess<quint16>((reinterpret_cast<quint16*>(array.data()))[0], \
order);
- rows = fixEndianess<quint16>((reinterpret_cast<quint16*>(array.data()))[1], \
order); + columns = fixEndianess<quint16>((reinterpret_cast<quint16 \
*>(array.data()))[0], order); + rows = \
fixEndianess<quint16>((reinterpret_cast<quint16 *>(array.data()))[1], order); \
Q_ASSERT((columns * rows + 4) > dvalue->count()); }
oecfStructure["Columns"] = KisMetaData::Value(columns);
@@ -156,10 +152,11 @@ KisMetaData::Value exifOECFToKMDOECFStructure(const \
Exiv2::Value::AutoPtr value,
oecfStructure["Names"] = KisMetaData::Value(names, \
KisMetaData::Value::OrderedArray); QList<KisMetaData::Value> values;
- qint32* dataIt = reinterpret_cast<qint32*>(array.data() + index);
+ qint32 *dataIt = reinterpret_cast<qint32 *>(array.data() + index);
for (int i = 0; i < columns; i++) {
for (int j = 0; j < rows; j++) {
- values.append(KisMetaData::Value(KisMetaData::Rational(fixEndianess<qint32>(dataIt[0], \
order), fixEndianess<qint32>(dataIt[1], order)))); + \
values.append(KisMetaData::Value( + \
KisMetaData::Rational(fixEndianess<qint32>(dataIt[0], order), \
fixEndianess<qint32>(dataIt[1], order)))); dataIt += 2;
}
}
@@ -168,7 +165,7 @@ KisMetaData::Value exifOECFToKMDOECFStructure(const \
Exiv2::Value::AutoPtr value, return KisMetaData::Value(oecfStructure);
}
-Exiv2::Value* kmdOECFStructureToExifOECF(const KisMetaData::Value& value)
+Exiv2::Value *kmdOECFStructureToExifOECF(const KisMetaData::Value &value)
{
QMap<QString, KisMetaData::Value> oecfStructure = value.asStructure();
const quint16 columns = \
static_cast<quint16>(oecfStructure["Columns"].asVariant().toUInt()); @@ -176,7 +173,7 \
@@ Exiv2::Value* kmdOECFStructureToExifOECF(const KisMetaData::Value& value)
QList<KisMetaData::Value> names = oecfStructure["Names"].asArray();
QList<KisMetaData::Value> values = oecfStructure["Values"].asArray();
- Q_ASSERT(columns*rows == values.size());
+ Q_ASSERT(columns * rows == values.size());
int length = 4 + rows * columns * 8; // The 4 byte for storing rows/columns and \
the rows*columns*sizeof(rational)
bool saveNames = (!names.empty() && names[0].asVariant().toString().size() > 0);
if (saveNames) {
@@ -185,8 +182,8 @@ Exiv2::Value* kmdOECFStructureToExifOECF(const \
KisMetaData::Value& value) }
}
QByteArray array(length, 0);
- (reinterpret_cast<quint16*>(array.data()))[0] = columns;
- (reinterpret_cast<quint16*>(array.data()))[1] = rows;
+ (reinterpret_cast<quint16 *>(array.data()))[0] = columns;
+ (reinterpret_cast<quint16 *>(array.data()))[1] = rows;
int index = 4;
if (saveNames) {
for (int i = 0; i < columns; i++) {
@@ -196,13 +193,13 @@ Exiv2::Value* kmdOECFStructureToExifOECF(const \
KisMetaData::Value& value) index += name.size();
}
}
- qint32* dataIt = reinterpret_cast<qint32*>(array.data() + index);
+ qint32 *dataIt = reinterpret_cast<qint32 *>(array.data() + index);
for (const KisMetaData::Value &it : values) {
dataIt[0] = it.asRational().numerator;
dataIt[1] = it.asRational().denominator;
dataIt += 2;
}
- return new Exiv2::DataValue((const Exiv2::byte*)array.data(), array.size());
+ return new Exiv2::DataValue((const Exiv2::byte *)array.data(), array.size());
}
KisMetaData::Value deviceSettingDescriptionExifToKMD(const Exiv2::Value::AutoPtr \
value) @@ -210,29 +207,29 @@ KisMetaData::Value \
deviceSettingDescriptionExifToKMD(const Exiv2::Value::AutoPtr QMap<QString, \
KisMetaData::Value> deviceSettingStructure; QByteArray array;
- const Exiv2::DataValue* dvalue = dynamic_cast<const Exiv2::DataValue*>(&*value);
+ const Exiv2::DataValue *dvalue = dynamic_cast<const Exiv2::DataValue \
*>(&*value); if (dvalue) {
array.resize(dvalue->count());
- dvalue->copy((Exiv2::byte*)array.data());
+ dvalue->copy((Exiv2::byte *)array.data());
} else {
Q_ASSERT(value->typeId() == Exiv2::unsignedShort);
array.resize(2 * value->count());
- value->copy((Exiv2::byte*)array.data(), Exiv2::littleEndian);
+ value->copy((Exiv2::byte *)array.data(), Exiv2::littleEndian);
}
- int columns = (reinterpret_cast<quint16*>(array.data()))[0];
- int rows = (reinterpret_cast<quint16*>(array.data()))[1];
+ int columns = (reinterpret_cast<quint16 *>(array.data()))[0];
+ int rows = (reinterpret_cast<quint16 *>(array.data()))[1];
deviceSettingStructure["Columns"] = KisMetaData::Value(columns);
deviceSettingStructure["Rows"] = KisMetaData::Value(rows);
QList<KisMetaData::Value> settings;
QByteArray null(2, 0);
- for (int index = 4; index < array.size(); )
- {
+ for (int index = 4; index < array.size();) {
const int lastIndex = array.indexOf(null, index);
- if (lastIndex < 0) break; // Data is not a String, ignore
+ if (lastIndex < 0)
+ break; // Data is not a String, ignore
const int numChars = (lastIndex - index) / 2; // including trailing zero
- QString setting = QString::fromUtf16((ushort*)(void*)( array.data() + \
index), numChars); + QString setting = QString::fromUtf16((ushort *)(void \
*)(array.data() + index), numChars); index = lastIndex + 2;
dbgMetaData << "Setting << " << setting;
settings.append(KisMetaData::Value(setting));
@@ -241,39 +238,41 @@ KisMetaData::Value deviceSettingDescriptionExifToKMD(const \
Exiv2::Value::AutoPtr return KisMetaData::Value(deviceSettingStructure);
}
-Exiv2::Value* deviceSettingDescriptionKMDToExif(const KisMetaData::Value& value)
+Exiv2::Value *deviceSettingDescriptionKMDToExif(const KisMetaData::Value &value)
{
QMap<QString, KisMetaData::Value> deviceSettingStructure = value.asStructure();
const quint16 columns = \
static_cast<quint16>(deviceSettingStructure["Columns"].asVariant().toUInt());
quint16 rows = static_cast<quint16>(deviceSettingStructure["Rows"].asVariant().toUInt());
- QTextCodec* codec = QTextCodec::codecForName("UTF-16");
+ QTextCodec *codec = QTextCodec::codecForName("UTF-16");
QList<KisMetaData::Value> settings = \
deviceSettingStructure["Settings"].asArray(); QByteArray array(4, 0);
- (reinterpret_cast<quint16*>(array.data()))[0] = columns;
- (reinterpret_cast<quint16*>(array.data()))[1] = rows;
+ (reinterpret_cast<quint16 *>(array.data()))[0] = columns;
+ (reinterpret_cast<quint16 *>(array.data()))[1] = rows;
for (const KisMetaData::Value &v : settings) {
const QString str = v.asVariant().toString();
QByteArray setting = codec->fromUnicode(str);
array.append(setting);
}
- return new Exiv2::DataValue((const Exiv2::byte*)array.data(), array.size());
+ return new Exiv2::DataValue((const Exiv2::byte *)array.data(), array.size());
}
KisMetaData::Value cfaPatternExifToKMD(const Exiv2::Value::AutoPtr value, \
Exiv2::ByteOrder order) {
QMap<QString, KisMetaData::Value> cfaPatternStructure;
- const Exiv2::DataValue* dvalue = dynamic_cast<const Exiv2::DataValue*>(&*value);
+ const Exiv2::DataValue *dvalue = dynamic_cast<const Exiv2::DataValue \
*>(&*value); Q_ASSERT(dvalue);
QByteArray array(dvalue->count(), 0);
- dvalue->copy((Exiv2::byte*)array.data());
- int columns = fixEndianess<quint16>((reinterpret_cast<quint16*>(array.data()))[0], \
order);
- int rows = fixEndianess<quint16>((reinterpret_cast<quint16*>(array.data()))[1], \
order);
- if ((columns * rows + 4) != dvalue->count()) { // Sometime byteOrder get messed \
up (especially if metadata got saved with kexiv2 library, or any library that doesn't \
save back with the same byte order as the camera) + dvalue->copy((Exiv2::byte \
*)array.data()); + int columns = fixEndianess<quint16>((reinterpret_cast<quint16 \
*>(array.data()))[0], order); + int rows = \
fixEndianess<quint16>((reinterpret_cast<quint16 *>(array.data()))[1], order); + if \
((columns * rows + 4) + != dvalue->count()) { // Sometime byteOrder get messed \
up (especially if metadata got saved with kexiv2 library, + \
// or any library that doesn't save back with the same byte order as the camera) \
order = invertByteOrder(order);
- columns = fixEndianess<quint16>((reinterpret_cast<quint16*>(array.data()))[0], \
order);
- rows = fixEndianess<quint16>((reinterpret_cast<quint16*>(array.data()))[1], \
order); + columns = fixEndianess<quint16>((reinterpret_cast<quint16 \
*>(array.data()))[0], order); + rows = \
fixEndianess<quint16>((reinterpret_cast<quint16 *>(array.data()))[1], order); \
Q_ASSERT((columns * rows + 4) == dvalue->count()); }
cfaPatternStructure["Columns"] = KisMetaData::Value(columns);
@@ -285,27 +284,28 @@ KisMetaData::Value cfaPatternExifToKMD(const \
Exiv2::Value::AutoPtr value, Exiv2: index++;
}
cfaPatternStructure["Values"] = KisMetaData::Value(values, \
KisMetaData::Value::OrderedArray);
- dbgMetaData << "CFAPattern " << ppVar(columns) << " " << ppVar(rows) << \
ppVar(values.size()) << ppVar(dvalue->count()); + dbgMetaData << "CFAPattern " << \
ppVar(columns) << " " << ppVar(rows) << ppVar(values.size()) + << \
ppVar(dvalue->count()); return KisMetaData::Value(cfaPatternStructure);
}
-Exiv2::Value* cfaPatternKMDToExif(const KisMetaData::Value& value)
+Exiv2::Value *cfaPatternKMDToExif(const KisMetaData::Value &value)
{
QMap<QString, KisMetaData::Value> cfaStructure = value.asStructure();
const quint16 columns = \
static_cast<quint16>(cfaStructure["Columns"].asVariant().toUInt());
const quint16 rows = \
static_cast<quint16>(cfaStructure["Rows"].asVariant().toUInt());
QList<KisMetaData::Value> values = cfaStructure["Values"].asArray();
- Q_ASSERT(columns*rows == values.size());
- QByteArray array(4 + columns*rows, 0);
- (reinterpret_cast<quint16*>(array.data()))[0] = columns;
- (reinterpret_cast<quint16*>(array.data()))[1] = rows;
+ Q_ASSERT(columns * rows == values.size());
+ QByteArray array(4 + columns * rows, 0);
+ (reinterpret_cast<quint16 *>(array.data()))[0] = columns;
+ (reinterpret_cast<quint16 *>(array.data()))[1] = rows;
for (int i = 0; i < columns * rows; i++) {
const quint8 val = (quint8)values[i].asVariant().toUInt();
*(array.data() + 4 + i) = (char)val;
}
dbgMetaData << "Cfa Array " << ppVar(columns) << ppVar(rows) << \
ppVar(array.size());
- return new Exiv2::DataValue((const Exiv2::byte*)array.data(), array.size());
+ return new Exiv2::DataValue((const Exiv2::byte *)array.data(), array.size());
}
// Read and write Flash //
@@ -314,20 +314,20 @@ KisMetaData::Value flashExifToKMD(const Exiv2::Value::AutoPtr \
value) {
const uint16_t v = static_cast<uint16_t>(value->toLong());
QMap<QString, KisMetaData::Value> flashStructure;
- bool fired = (v & 0x01); // bit 1 is whether flash was fired or not
+ bool fired = (v & 0x01); // bit 1 is whether flash was fired or not
flashStructure["Fired"] = QVariant(fired);
- int ret = ((v >> 1) & 0x03); // bit 2 and 3 are Return
+ int ret = ((v >> 1) & 0x03); // bit 2 and 3 are Return
flashStructure["Return"] = QVariant(ret);
- int mode = ((v >> 3) & 0x03); // bit 4 and 5 are Mode
+ int mode = ((v >> 3) & 0x03); // bit 4 and 5 are Mode
flashStructure["Mode"] = QVariant(mode);
- bool function = ((v >> 5) & 0x01); // bit 6 if function
+ bool function = ((v >> 5) & 0x01); // bit 6 if function
flashStructure["Function"] = QVariant(function);
- bool redEye = ((v >> 6) & 0x01); // bit 7 if function
+ bool redEye = ((v >> 6) & 0x01); // bit 7 if function
flashStructure["RedEyeMode"] = QVariant(redEye);
return KisMetaData::Value(flashStructure);
}
-Exiv2::Value* flashKMDToExif(const KisMetaData::Value& value)
+Exiv2::Value *flashKMDToExif(const KisMetaData::Value &value)
{
uint16_t v = 0;
QMap<QString, KisMetaData::Value> flashStructure = value.asStructure();
@@ -339,20 +339,17 @@ Exiv2::Value* flashKMDToExif(const KisMetaData::Value& value)
return new Exiv2::ValueType<uint16_t>(v);
}
-
-
// ---- Implementation of KisExifIO ----//
-KisExifIO::KisExifIO() : d(new Private)
+KisExifIO::KisExifIO()
+ : KisMetaData::IOBackend()
{
}
KisExifIO::~KisExifIO()
{
- delete d;
}
-
-bool KisExifIO::saveTo(KisMetaData::Store* store, QIODevice* ioDevice, HeaderType \
headerType) const +bool KisExifIO::saveTo(KisMetaData::Store *store, QIODevice \
*ioDevice, HeaderType headerType) const {
ioDevice->open(QIODevice::WriteOnly);
Exiv2::ExifData exifData;
@@ -369,11 +366,13 @@ bool KisExifIO::saveTo(KisMetaData::Store* store, QIODevice* \
ioDevice, HeaderTyp
for (const KisMetaData::Entry &entry : *store) {
try {
- dbgMetaData << "Trying to save: " << entry.name() << " of " << \
entry.schema()->prefix() << ":" << entry.schema()->uri(); + dbgMetaData << \
"Trying to save: " << entry.name() << " of " << entry.schema()->prefix() << ":" + \
<< entry.schema()->uri(); QString exivKey;
if (entry.schema()->uri() == KisMetaData::Schema::TIFFSchemaUri) {
exivKey = "Exif.Image." + entry.name();
- } else if (entry.schema()->uri() == KisMetaData::Schema::EXIFSchemaUri) \
{ // Distinguish between exif and gps + } else if (entry.schema()->uri()
+ == KisMetaData::Schema::EXIFSchemaUri) { // Distinguish \
between exif and gps if (entry.name().left(3) == "GPS") {
exivKey = "Exif.GPSInfo." + entry.name();
} else {
@@ -403,15 +402,15 @@ bool KisExifIO::saveTo(KisMetaData::Store* store, QIODevice* \
ioDevice, HeaderTyp
dbgMetaData << entry.qualifiedName() << " is unsavable to EXIF";
} else {
Exiv2::ExifKey exifKey(qPrintable(exivKey));
- Exiv2::Value* v = 0;
+ Exiv2::Value *v = 0;
if (exivKey == "Exif.Photo.ExifVersion" || exivKey == \
"Exif.Photo.FlashpixVersion") { v = kmdValueToExifVersion(entry.value());
} else if (exivKey == "Exif.Photo.FileSource") {
- char s[] = { 0x03 };
- v = new Exiv2::DataValue((const Exiv2::byte*)s, 1);
+ char s[] = {0x03};
+ v = new Exiv2::DataValue((const Exiv2::byte *)s, 1);
} else if (exivKey == "Exif.Photo.SceneType") {
- char s[] = { 0x01 };
- v = new Exiv2::DataValue((const Exiv2::byte*)s, 1);
+ char s[] = {0x01};
+ v = new Exiv2::DataValue((const Exiv2::byte *)s, 1);
} else if (exivKey == "Exif.Photo.ComponentsConfiguration") {
v = kmdIntOrderedArrayToExifArray(entry.value());
} else if (exivKey == "Exif.Image.Artist") { // load as dc:creator
@@ -419,7 +418,7 @@ bool KisExifIO::saveTo(KisMetaData::Store* store, QIODevice* \
ioDevice, HeaderTyp if (entry.value().asArray().size() > 0) {
creator = entry.value().asArray()[0];
}
-#if !EXIV2_TEST_VERSION(0,21,0)
+#if !EXIV2_TEST_VERSION(0, 21, 0)
v = kmdValueToExivValue(creator, \
Exiv2::ExifTags::tagType(exifKey.tag(), exifKey.ifdId())); #else
v = kmdValueToExivValue(creator, exifKey.defaultTypeId());
@@ -436,21 +435,23 @@ bool KisExifIO::saveTo(KisMetaData::Store* store, QIODevice* \
ioDevice, HeaderTyp
Q_ASSERT(entry.value().type() == KisMetaData::Value::LangArray);
QMap<QString, KisMetaData::Value> langArr = \
entry.value().asLangArray(); if (langArr.contains("x-default")) {
-#if !EXIV2_TEST_VERSION(0,21,0)
- v = kmdValueToExivValue(langArr.value("x-default"), \
Exiv2::ExifTags::tagType(exifKey.tag(), exifKey.ifdId())); +#if \
!EXIV2_TEST_VERSION(0, 21, 0) + v = \
kmdValueToExivValue(langArr.value("x-default"), + \
Exiv2::ExifTags::tagType(exifKey.tag(), exifKey.ifdId())); #else
v = kmdValueToExivValue(langArr.value("x-default"), \
exifKey.defaultTypeId()); #endif
} else if (langArr.size() > 0) {
-#if !EXIV2_TEST_VERSION(0,21,0)
- v = kmdValueToExivValue(langArr.begin().value(), \
Exiv2::ExifTags::tagType(exifKey.tag(), exifKey.ifdId())); +#if \
!EXIV2_TEST_VERSION(0, 21, 0) + v = \
kmdValueToExivValue(langArr.begin().value(), + \
Exiv2::ExifTags::tagType(exifKey.tag(), exifKey.ifdId())); #else
v = kmdValueToExivValue(langArr.begin().value(), \
exifKey.defaultTypeId()); #endif
}
} else {
dbgMetaData << exifKey.tag();
-#if !EXIV2_TEST_VERSION(0,21,0)
+#if !EXIV2_TEST_VERSION(0, 21, 0)
v = kmdValueToExivValue(entry.value(), \
Exiv2::ExifTags::tagType(exifKey.tag(), exifKey.ifdId())); #else
v = kmdValueToExivValue(entry.value(), exifKey.defaultTypeId());
@@ -460,16 +461,17 @@ bool KisExifIO::saveTo(KisMetaData::Store* store, QIODevice* \
ioDevice, HeaderTyp
dbgMetaData << "Saving key" << exivKey << " of KMD value" << \
entry.value(); exifData.add(exifKey, v);
} else {
- dbgMetaData << "No exif value was created for" << \
entry.qualifiedName() << " as" << exivKey;// << " of KMD value" << entry.value(); + \
dbgMetaData << "No exif value was created for" << entry.qualifiedName() << " as" + \
<< exivKey; // << " of KMD value" << entry.value(); }
}
- } catch (Exiv2::AnyError& e) {
+ } catch (Exiv2::AnyError &e) {
dbgMetaData << "exiv error " << e.what();
}
}
-#if !EXIV2_TEST_VERSION(0,18,0)
+#if !EXIV2_TEST_VERSION(0, 18, 0)
Exiv2::DataBuf rawData = exifData.copy();
- ioDevice->write((const char*) rawData.pData_, rawData.size_);
+ ioDevice->write((const char *)rawData.pData_, rawData.size_);
#else
Exiv2::Blob rawData;
Exiv2::ExifParser::encode(rawData, Exiv2::littleEndian, exifData);
@@ -479,13 +481,12 @@ bool KisExifIO::saveTo(KisMetaData::Store* store, QIODevice* \
ioDevice, HeaderTyp return true;
}
-bool KisExifIO::canSaveAllEntries(KisMetaData::Store* /*store*/) const
+bool KisExifIO::canSaveAllEntries(KisMetaData::Store * /*store*/) const
{
return false; // It's a known fact that exif can't save all information, but \
TODO: write the check }
-
-bool KisExifIO::loadFrom(KisMetaData::Store* store, QIODevice* ioDevice) const
+bool KisExifIO::loadFrom(KisMetaData::Store *store, QIODevice *ioDevice) const
{
if (!ioDevice->open(QIODevice::ReadOnly)) {
return false;
@@ -493,40 +494,45 @@ bool KisExifIO::loadFrom(KisMetaData::Store* store, QIODevice* \
ioDevice) const QByteArray arr(ioDevice->readAll());
Exiv2::ExifData exifData;
Exiv2::ByteOrder byteOrder;
-#if !EXIV2_TEST_VERSION(0,18,0)
- exifData.load((const Exiv2::byte*)arr.data(), arr.size());
+#if !EXIV2_TEST_VERSION(0, 18, 0)
+ exifData.load((const Exiv2::byte *)arr.data(), arr.size());
byteOrder = exifData.byteOrder();
#else
try {
- byteOrder = Exiv2::ExifParser::decode(exifData, (const Exiv2::byte \
*)arr.data(), static_cast<uint32_t>(arr.size()));
- }
- catch (const std::exception& ex) {
+ byteOrder =
+ Exiv2::ExifParser::decode(exifData, (const Exiv2::byte *)arr.data(), \
static_cast<uint32_t>(arr.size())); + } catch (const std::exception &ex) {
warnKrita << "Received exception trying to parse exiv data" << ex.what();
return false;
- }
- catch (...) {
+ } catch (...) {
dbgKrita << "Received unknown exception trying to parse exiv data";
return false;
}
#endif
dbgMetaData << "Byte order = " << byteOrder << ppVar(Exiv2::bigEndian) << \
ppVar(Exiv2::littleEndian);
dbgMetaData << "There are" << exifData.count() << " entries in the exif \
section";
- const KisMetaData::Schema* tiffSchema = \
KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::TIFFSchemaUri);
+ const KisMetaData::Schema *tiffSchema =
+ KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::TIFFSchemaUri);
Q_ASSERT(tiffSchema);
- const KisMetaData::Schema* exifSchema = \
KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::EXIFSchemaUri);
+ const KisMetaData::Schema *exifSchema =
+ KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::EXIFSchemaUri);
Q_ASSERT(exifSchema);
- const KisMetaData::Schema* dcSchema = \
KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::DublinCoreSchemaUri);
+ const KisMetaData::Schema *dcSchema =
+ KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::DublinCoreSchemaUri);
Q_ASSERT(dcSchema);
- const KisMetaData::Schema* xmpSchema = \
KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::XMPSchemaUri);
+ const KisMetaData::Schema *xmpSchema =
+ KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::XMPSchemaUri);
Q_ASSERT(xmpSchema);
- const KisMetaData::Schema *makerNoteSchema = \
KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::MakerNoteSchemaUri);
+ const KisMetaData::Schema *makerNoteSchema =
+ KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::MakerNoteSchemaUri);
Q_ASSERT(makerNoteSchema);
for (const Exiv2::Exifdatum &it : exifData) {
const uint16_t tag = it.tag();
if (tag == Exif::Image::StripOffsets || tag == Exif::Image::RowsPerStrip || \
tag == Exif::Image::StripByteCounts
- || tag == Exif::Image::JPEGInterchangeFormat || tag == \
Exif::Image::JPEGInterchangeFormatLength || it.tagName() == "0x0000") { + \
|| tag == Exif::Image::JPEGInterchangeFormat || tag == \
Exif::Image::JPEGInterchangeFormatLength + || it.tagName() == "0x0000") {
dbgMetaData << it.key().c_str() << " is ignored";
} else if (tag == Exif::Photo::MakerNote) {
store->addEntry({makerNoteSchema, "RawData", \
exivValueToKMDValue(it.getValue(), false)}); @@ -602,7 +608,8 @@ bool \
KisExifIO::loadFrom(KisMetaData::Store* store, QIODevice* ioDevice) \
const
metaDataValue = exivValueToKMDValue(it.getValue(), forceSeq, \
arrayType); }
if (tag == Exif::Photo::InteroperabilityTag
- || metaDataValue.type() == KisMetaData::Value::Invalid) { // \
InteroperabilityTag isn't useful for XMP, 0xea1d isn't a valid Exif tag + \
|| metaDataValue.type() == KisMetaData::Value::Invalid) { // InteroperabilityTag \
isn't useful for XMP, + \
// 0xea1d isn't a valid Exif tag warnMetaData << "Ignoring " << it.key().c_str();
} else {
store->addEntry({exifSchema, it.tagName().c_str(), metaDataValue});
diff --git a/libs/ui/kisexiv2/kis_exif_io.h b/plugins/metadata/exif/kis_exif_io.h
similarity index 54%
rename from libs/ui/kisexiv2/kis_exif_io.h
rename to plugins/metadata/exif/kis_exif_io.h
index af9effd975..b2b3bd9547 100644
--- a/libs/ui/kisexiv2/kis_exif_io.h
+++ b/plugins/metadata/exif/kis_exif_io.h
@@ -1,5 +1,6 @@
/*
* SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net>
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
@@ -7,36 +8,40 @@
#ifndef _KIS_EXIF_IO_H_
#define _KIS_EXIF_IO_H_
-#include <kis_meta_data_io_backend.h>
+#include <QObject>
#include <klocalizedstring.h>
+#include <kis_meta_data_io_backend.h>
+
class KisExifIO : public KisMetaData::IOBackend
{
- struct Private;
public:
KisExifIO();
~KisExifIO() override;
- QString id() const override {
+ QString id() const override
+ {
return "exif";
}
- QString name() const override {
+ QString name() const override
+ {
return i18n("Exif");
}
- BackendType type() const override {
+ BackendType type() const override
+ {
return Binary;
}
- bool supportSaving() const override {
+ bool supportSaving() const override
+ {
return true;
}
- bool saveTo(KisMetaData::Store* store, QIODevice* ioDevice, HeaderType \
headerType = NoHeader) const override;
- bool canSaveAllEntries(KisMetaData::Store* store) const override;
- bool supportLoading() const override {
+ bool saveTo(KisMetaData::Store *store, QIODevice *ioDevice, HeaderType \
headerType = NoHeader) const override; + bool canSaveAllEntries(KisMetaData::Store \
*store) const override; + bool supportLoading() const override
+ {
return true;
}
- bool loadFrom(KisMetaData::Store* store, QIODevice* ioDevice) const override;
-private:
- Private* const d;
+ bool loadFrom(KisMetaData::Store *store, QIODevice *ioDevice) const override;
};
#endif
diff --git a/plugins/metadata/exif/kis_exif_plugin.cpp \
b/plugins/metadata/exif/kis_exif_plugin.cpp new file mode 100644
index 0000000000..3ea4b6882e
--- /dev/null
+++ b/plugins/metadata/exif/kis_exif_plugin.cpp
@@ -0,0 +1,29 @@
+/*
+ * This file is part of Krita
+ *
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "kis_exif_plugin.h"
+
+#include <kpluginfactory.h>
+
+#include <kis_meta_data_backend_registry.h>
+
+#include "kis_exif_io.h"
+
+K_PLUGIN_FACTORY_WITH_JSON(KisExifIOPluginFactory, "kritaexif.json", \
registerPlugin<KisExifPlugin>();) +
+KisExifPlugin::KisExifPlugin(QObject *parent, const QVariantList &)
+ : QObject(parent)
+{
+ KisMetadataBackendRegistry::instance()->add(new KisExifIO());
+}
+
+KisExifPlugin::~KisExifPlugin()
+{
+}
+
+#include "kis_exif_plugin.moc"
diff --git a/plugins/metadata/exif/kis_exif_plugin.h \
b/plugins/metadata/exif/kis_exif_plugin.h new file mode 100644
index 0000000000..4cbc6e56e3
--- /dev/null
+++ b/plugins/metadata/exif/kis_exif_plugin.h
@@ -0,0 +1,21 @@
+/*
+ * This file is part of Krita
+ *
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef _KIS_EXIF_PLUGIN_H_
+#define _KIS_EXIF_PLUGIN_H_
+
+#include <QObject>
+
+class KisExifPlugin : public QObject
+{
+public:
+ KisExifPlugin(QObject *parent, const QVariantList &);
+ ~KisExifPlugin() override;
+};
+
+#endif // _KIS_EXIF_PLUGIN_H_
diff --git a/plugins/metadata/exif/kritaexif.json \
b/plugins/metadata/exif/kritaexif.json new file mode 100644
index 0000000000..56f1314ccb
--- /dev/null
+++ b/plugins/metadata/exif/kritaexif.json
@@ -0,0 +1,9 @@
+{
+ "Id": "EXIF",
+ "Type": "Service",
+ "X-KDE-Library": "kritaexif",
+ "X-KDE-ServiceTypes": [
+ "Krita/Metadata"
+ ],
+ "X-Krita-Version": "28"
+}
diff --git a/plugins/metadata/iptc/CMakeLists.txt \
b/plugins/metadata/iptc/CMakeLists.txt new file mode 100644
index 0000000000..813a1d6a8d
--- /dev/null
+++ b/plugins/metadata/iptc/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(kritaiptc_SOURCES
+ kis_iptc_io.cpp
+ kis_iptc_plugin.cpp
+)
+
+add_library(kritaiptc MODULE ${kritaiptc_SOURCES})
+
+generate_export_header(kritaiptc)
+
+target_link_libraries(kritaiptc
+ PRIVATE
+ kritametadata
+ KF5::CoreAddons
+ LibExiv2::LibExiv2
+)
+
+install(TARGETS kritaiptc DESTINATION ${KRITA_PLUGIN_INSTALL_DIR})
diff --git a/libs/ui/kisexiv2/kis_iptc_io.cpp b/plugins/metadata/iptc/kis_iptc_io.cpp
similarity index 51%
rename from libs/ui/kisexiv2/kis_iptc_io.cpp
rename to plugins/metadata/iptc/kis_iptc_io.cpp
index cc43918d32..05f66eef29 100644
--- a/libs/ui/kisexiv2/kis_iptc_io.cpp
+++ b/plugins/metadata/iptc/kis_iptc_io.cpp
@@ -1,26 +1,25 @@
/*
* SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net>
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "kis_iptc_io.h"
-#include <kis_debug.h>
-
#include <exiv2/iptc.hpp>
-#include "kis_exiv2.h"
-
-#include <kis_meta_data_store.h>
+#include <kis_debug.h>
+#include <kis_exiv2_common.h>
#include <kis_meta_data_entry.h>
-#include <kis_meta_data_value.h>
#include <kis_meta_data_schema.h>
#include <kis_meta_data_schema_registry.h>
+#include <kis_meta_data_store.h>
+#include <kis_meta_data_value.h>
const char photoshopMarker[] = "Photoshop 3.0\0";
const char photoshopBimId_[] = "8BIM";
const uint16_t photoshopIptc = 0x0404;
-const QByteArray photoshopIptc_((char*)&photoshopIptc, 2);
+const QByteArray photoshopIptc_((char *)&photoshopIptc, 2);
struct IPTCToKMD {
QString exivTag;
@@ -29,30 +28,30 @@ struct IPTCToKMD {
};
static const IPTCToKMD mappings[] = {
- { "Iptc.Application2.City", KisMetaData::Schema::PhotoshopSchemaUri, "City" },
- { "Iptc.Application2.Copyright", KisMetaData::Schema::DublinCoreSchemaUri, \
"rights" },
- { "Iptc.Application2.CountryName", KisMetaData::Schema::PhotoshopSchemaUri, \
"Country" },
- { "Iptc.Application2.CountryCode", KisMetaData::Schema::IPTCSchemaUri, \
"CountryCode" },
- { "Iptc.Application2.Byline", KisMetaData::Schema::DublinCoreSchemaUri, \
"creator" },
- { "Iptc.Application2.BylineTitle", KisMetaData::Schema::PhotoshopSchemaUri, \
"AuthorsPosition" },
- { "Iptc.Application2.DateCreated", KisMetaData::Schema::PhotoshopSchemaUri, \
"DateCreated" },
- { "Iptc.Application2.Caption", KisMetaData::Schema::DublinCoreSchemaUri, \
"description" },
- { "Iptc.Application2.Writer", KisMetaData::Schema::PhotoshopSchemaUri, \
"CaptionWriter" },
- { "Iptc.Application2.Headline", KisMetaData::Schema::PhotoshopSchemaUri, \
"Headline" },
- { "Iptc.Application2.SpecialInstructions", \
KisMetaData::Schema::PhotoshopSchemaUri, "Instructions" },
- { "Iptc.Application2.ObjectAttribute", KisMetaData::Schema::IPTCSchemaUri, \
"IntellectualGenre" },
- { "Iptc.Application2.TransmissionReference", \
KisMetaData::Schema::PhotoshopSchemaUri, "JobID" },
- { "Iptc.Application2.Keywords", KisMetaData::Schema::DublinCoreSchemaUri, \
"subject" },
- { "Iptc.Application2.SubLocation", KisMetaData::Schema::IPTCSchemaUri, \
"Location" },
- { "Iptc.Application2.Credit", KisMetaData::Schema::PhotoshopSchemaUri, "Credit" \
},
- { "Iptc.Application2.ProvinceState", KisMetaData::Schema::PhotoshopSchemaUri, \
"State" },
- { "Iptc.Application2.Source", KisMetaData::Schema::PhotoshopSchemaUri, "Source" \
},
- { "Iptc.Application2.Subject", KisMetaData::Schema::IPTCSchemaUri, "SubjectCode" \
},
- { "Iptc.Application2.ObjectName", KisMetaData::Schema::DublinCoreSchemaUri, \
"title" },
- { "Iptc.Application2.Urgency", KisMetaData::Schema::PhotoshopSchemaUri, \
"Urgency" },
- { "Iptc.Application2.Category", KisMetaData::Schema::PhotoshopSchemaUri, \
"Category" },
- { "Iptc.Application2.SuppCategory", KisMetaData::Schema::PhotoshopSchemaUri, \
"SupplementalCategory" },
- { "", "", "" } // indicates the end of the array
+ {"Iptc.Application2.City", KisMetaData::Schema::PhotoshopSchemaUri, "City"},
+ {"Iptc.Application2.Copyright", KisMetaData::Schema::DublinCoreSchemaUri, \
"rights"}, + {"Iptc.Application2.CountryName", \
KisMetaData::Schema::PhotoshopSchemaUri, "Country"}, + \
{"Iptc.Application2.CountryCode", KisMetaData::Schema::IPTCSchemaUri, "CountryCode"}, \
+ {"Iptc.Application2.Byline", KisMetaData::Schema::DublinCoreSchemaUri, \
"creator"}, + {"Iptc.Application2.BylineTitle", \
KisMetaData::Schema::PhotoshopSchemaUri, "AuthorsPosition"}, + \
{"Iptc.Application2.DateCreated", KisMetaData::Schema::PhotoshopSchemaUri, \
"DateCreated"}, + {"Iptc.Application2.Caption", \
KisMetaData::Schema::DublinCoreSchemaUri, "description"}, + \
{"Iptc.Application2.Writer", KisMetaData::Schema::PhotoshopSchemaUri, \
"CaptionWriter"}, + {"Iptc.Application2.Headline", \
KisMetaData::Schema::PhotoshopSchemaUri, "Headline"}, + \
{"Iptc.Application2.SpecialInstructions", KisMetaData::Schema::PhotoshopSchemaUri, \
"Instructions"}, + {"Iptc.Application2.ObjectAttribute", \
KisMetaData::Schema::IPTCSchemaUri, "IntellectualGenre"}, + \
{"Iptc.Application2.TransmissionReference", KisMetaData::Schema::PhotoshopSchemaUri, \
"JobID"}, + {"Iptc.Application2.Keywords", \
KisMetaData::Schema::DublinCoreSchemaUri, "subject"}, + \
{"Iptc.Application2.SubLocation", KisMetaData::Schema::IPTCSchemaUri, "Location"}, + \
{"Iptc.Application2.Credit", KisMetaData::Schema::PhotoshopSchemaUri, "Credit"}, + \
{"Iptc.Application2.ProvinceState", KisMetaData::Schema::PhotoshopSchemaUri, \
"State"}, + {"Iptc.Application2.Source", KisMetaData::Schema::PhotoshopSchemaUri, \
"Source"}, + {"Iptc.Application2.Subject", KisMetaData::Schema::IPTCSchemaUri, \
"SubjectCode"}, + {"Iptc.Application2.ObjectName", \
KisMetaData::Schema::DublinCoreSchemaUri, "title"}, + \
{"Iptc.Application2.Urgency", KisMetaData::Schema::PhotoshopSchemaUri, "Urgency"}, + \
{"Iptc.Application2.Category", KisMetaData::Schema::PhotoshopSchemaUri, "Category"}, \
+ {"Iptc.Application2.SuppCategory", KisMetaData::Schema::PhotoshopSchemaUri, \
"SupplementalCategory"}, + {"", "", ""} // indicates the end of the array
};
struct KisIptcIO::Private {
@@ -60,8 +59,10 @@ struct KisIptcIO::Private {
QHash<QString, IPTCToKMD> kmdToIPTC;
};
-// ---- Implementation of KisExifIO ----//
-KisIptcIO::KisIptcIO() : d(new Private)
+// ---- Implementation of KisIptcIO ----//
+KisIptcIO::KisIptcIO()
+ : KisMetaData::IOBackend()
+ , d(new Private)
{
}
@@ -75,46 +76,46 @@ void KisIptcIO::initMappingsTable() const
// For some reason, initializing the tables in the constructor makes the it \
crash if (d->iptcToKMD.size() == 0) {
for (int i = 0; !mappings[i].exivTag.isEmpty(); i++) {
- dbgKrita << "mapping[i] = " << mappings[i].exivTag << " " << \
mappings[i].namespaceUri << " " << mappings[i].name; + dbgKrita << \
"mapping[i] = " << mappings[i].exivTag << " " << mappings[i].namespaceUri << " " + \
<< mappings[i].name; d->iptcToKMD[mappings[i].exivTag] = mappings[i];
- d->kmdToIPTC[
- KisMetaData::SchemaRegistry::instance()
- ->schemaFromUri(mappings[i].namespaceUri)
- ->generateQualifiedName(mappings[i].name)] = mappings[i];
+ d->kmdToIPTC[KisMetaData::SchemaRegistry::instance()
+ ->schemaFromUri(mappings[i].namespaceUri)
+ ->generateQualifiedName(mappings[i].name)] = \
mappings[i]; }
}
}
-bool KisIptcIO::saveTo(KisMetaData::Store* store, QIODevice* ioDevice, HeaderType \
headerType) const +bool KisIptcIO::saveTo(KisMetaData::Store *store, QIODevice \
*ioDevice, HeaderType headerType) const {
QStringList blockedEntries = QStringList() << "photoshop:DateCreated";
initMappingsTable();
ioDevice->open(QIODevice::WriteOnly);
Exiv2::IptcData iptcData;
- for (QHash<QString, KisMetaData::Entry>::const_iterator it = store->begin();
- it != store->end(); ++it) {
- const KisMetaData::Entry& entry = *it;
+ for (QHash<QString, KisMetaData::Entry>::const_iterator it = store->begin(); it \
!= store->end(); ++it) { + const KisMetaData::Entry &entry = *it;
if (d->kmdToIPTC.contains(entry.qualifiedName())) {
if (blockedEntries.contains(entry.qualifiedName())) {
warnKrita << "skipping" << entry.qualifiedName() << entry.value();
continue;
}
try {
- QString iptcKeyStr = d->kmdToIPTC[ entry.qualifiedName()].exivTag;
+ QString iptcKeyStr = d->kmdToIPTC[entry.qualifiedName()].exivTag;
Exiv2::IptcKey iptcKey(qPrintable(iptcKeyStr));
- Exiv2::Value *v = kmdValueToExivValue(entry.value(),
- \
Exiv2::IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record())); + \
Exiv2::Value *v = + kmdValueToExivValue(entry.value(),
+ \
Exiv2::IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record()));
if (v && v->typeId() != Exiv2::invalidTypeId) {
iptcData.add(iptcKey, v);
}
- } catch (Exiv2::AnyError& e) {
+ } catch (Exiv2::AnyError &e) {
dbgMetaData << "exiv error " << e.what();
}
}
}
-#if !EXIV2_TEST_VERSION(0,18,0)
+#if !EXIV2_TEST_VERSION(0, 18, 0)
Exiv2::DataBuf rawData = iptcData.copy();
#else
Exiv2::DataBuf rawData = Exiv2::IptcParser::encode(iptcData);
@@ -123,7 +124,7 @@ bool KisIptcIO::saveTo(KisMetaData::Store* store, QIODevice* \
ioDevice, HeaderTyp if (headerType == KisMetaData::IOBackend::JpegHeader) {
QByteArray header;
header.append(photoshopMarker);
- header.append(QByteArray(1, 0)); // Null terminated string
+ header.append(QByteArray(1, 0)); // Null terminated string
header.append(photoshopBimId_);
header.append(photoshopIptc_);
header.append(QByteArray(2, 0));
@@ -137,36 +138,36 @@ bool KisIptcIO::saveTo(KisMetaData::Store* store, QIODevice* \
ioDevice, HeaderTyp ioDevice->write(header);
}
- ioDevice->write((const char*) rawData.pData_, rawData.size_);
+ ioDevice->write((const char *)rawData.pData_, rawData.size_);
ioDevice->close();
return true;
}
-bool KisIptcIO::canSaveAllEntries(KisMetaData::Store* store) const
+bool KisIptcIO::canSaveAllEntries(KisMetaData::Store *store) const
{
Q_UNUSED(store);
return false;
}
-bool KisIptcIO::loadFrom(KisMetaData::Store* store, QIODevice* ioDevice) const
+bool KisIptcIO::loadFrom(KisMetaData::Store *store, QIODevice *ioDevice) const
{
initMappingsTable();
dbgMetaData << "Loading IPTC Tags";
ioDevice->open(QIODevice::ReadOnly);
QByteArray arr = ioDevice->readAll();
Exiv2::IptcData iptcData;
-#if !EXIV2_TEST_VERSION(0,18,0)
- iptcData.load((const Exiv2::byte*)arr.data(), arr.size());
+#if !EXIV2_TEST_VERSION(0, 18, 0)
+ iptcData.load((const Exiv2::byte *)arr.data(), arr.size());
#else
- Exiv2::IptcParser::decode(iptcData, (const Exiv2::byte*)arr.data(), arr.size());
+ Exiv2::IptcParser::decode(iptcData, (const Exiv2::byte *)arr.data(), \
arr.size()); #endif
dbgMetaData << "There are" << iptcData.count() << " entries in the IPTC \
section";
- for (Exiv2::IptcMetadata::const_iterator it = iptcData.begin();
- it != iptcData.end(); ++it) {
+ for (Exiv2::IptcMetadata::const_iterator it = iptcData.begin(); it != \
iptcData.end(); ++it) { dbgMetaData << "Reading info for key" << it->key().c_str();
if (d->iptcToKMD.contains(it->key().c_str())) {
- const IPTCToKMD& iptcToKMd = d->iptcToKMD[it->key().c_str()];
- const KisMetaData::Schema* schema = \
KisMetaData::SchemaRegistry::instance()->schemaFromUri(iptcToKMd.namespaceUri); + \
const IPTCToKMD &iptcToKMd = d->iptcToKMD[it->key().c_str()]; + const \
KisMetaData::Schema *schema = + \
KisMetaData::SchemaRegistry::instance()->schemaFromUri(iptcToKMd.namespaceUri); \
KisMetaData::Value value; if (iptcToKMd.exivTag == "Iptc.Application2.Keywords") {
Q_ASSERT(it->getValue()->typeId() == Exiv2::string);
diff --git a/libs/ui/kisexiv2/kis_iptc_io.h b/plugins/metadata/iptc/kis_iptc_io.h
similarity index 56%
rename from libs/ui/kisexiv2/kis_iptc_io.h
rename to plugins/metadata/iptc/kis_iptc_io.h
index 3b4ea2fa92..a7092f78e8 100644
--- a/libs/ui/kisexiv2/kis_iptc_io.h
+++ b/plugins/metadata/iptc/kis_iptc_io.h
@@ -1,5 +1,6 @@
/*
* SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net>
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
@@ -7,38 +8,45 @@
#ifndef _KIS_IPTC_IO_H_
#define _KIS_IPTC_IO_H_
-#include <kis_meta_data_io_backend.h>
-
#include <klocalizedstring.h>
+#include <kis_meta_data_io_backend.h>
+
class KisIptcIO : public KisMetaData::IOBackend
{
- struct Private;
public:
KisIptcIO();
~KisIptcIO() override;
- QString id() const override {
+ QString id() const override
+ {
return "iptc";
}
- QString name() const override {
+ QString name() const override
+ {
return i18n("Iptc");
}
- BackendType type() const override {
+ BackendType type() const override
+ {
return Binary;
}
- bool supportSaving() const override {
+ bool supportSaving() const override
+ {
return true;
}
- bool saveTo(KisMetaData::Store* store, QIODevice* ioDevice, HeaderType \
headerType = NoHeader) const override;
- bool canSaveAllEntries(KisMetaData::Store* store) const override;
- bool supportLoading() const override {
+ bool saveTo(KisMetaData::Store *store, QIODevice *ioDevice, HeaderType \
headerType = NoHeader) const override; + bool canSaveAllEntries(KisMetaData::Store \
*store) const override; + bool supportLoading() const override
+ {
return true;
}
- bool loadFrom(KisMetaData::Store* store, QIODevice* ioDevice) const override;
+ bool loadFrom(KisMetaData::Store *store, QIODevice *ioDevice) const override;
+
private:
void initMappingsTable() const;
+
private:
- Private* const d;
+ struct Private;
+ Private *const d;
};
#endif
diff --git a/plugins/metadata/iptc/kis_iptc_plugin.cpp \
b/plugins/metadata/iptc/kis_iptc_plugin.cpp new file mode 100644
index 0000000000..dea647cf2f
--- /dev/null
+++ b/plugins/metadata/iptc/kis_iptc_plugin.cpp
@@ -0,0 +1,29 @@
+/*
+ * This file is part of Krita
+ *
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "kis_iptc_plugin.h"
+
+#include <kpluginfactory.h>
+
+#include <kis_meta_data_backend_registry.h>
+
+#include "kis_iptc_io.h"
+
+K_PLUGIN_FACTORY_WITH_JSON(KisIptcIOPluginFactory, "kritaiptc.json", \
registerPlugin<KisIptcPlugin>();) +
+KisIptcPlugin::KisIptcPlugin(QObject *parent, const QVariantList &)
+ : QObject(parent)
+{
+ KisMetadataBackendRegistry::instance()->add(new KisIptcIO());
+}
+
+KisIptcPlugin::~KisIptcPlugin()
+{
+}
+
+#include "kis_iptc_plugin.moc"
diff --git a/plugins/metadata/iptc/kis_iptc_plugin.h \
b/plugins/metadata/iptc/kis_iptc_plugin.h new file mode 100644
index 0000000000..2d3d813173
--- /dev/null
+++ b/plugins/metadata/iptc/kis_iptc_plugin.h
@@ -0,0 +1,21 @@
+/*
+ * This file is part of Krita
+ *
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef _KIS_IPTC_PLUGIN_H_
+#define _KIS_IPTC_PLUGIN_H_
+
+#include <QObject>
+
+class KisIptcPlugin : public QObject
+{
+public:
+ KisIptcPlugin(QObject *parent, const QVariantList &);
+ ~KisIptcPlugin() override;
+};
+
+#endif // _KIS_IPTC_PLUGIN_H_
diff --git a/plugins/metadata/iptc/kritaiptc.json \
b/plugins/metadata/iptc/kritaiptc.json new file mode 100644
index 0000000000..6af4fac9fc
--- /dev/null
+++ b/plugins/metadata/iptc/kritaiptc.json
@@ -0,0 +1,7 @@
+{
+ "Id" : "IPTC",
+ "Type" : "Service",
+ "X-KDE-Library" : "kritaiptc",
+ "X-KDE-ServiceTypes" : ["Krita/Metadata"],
+ "X-Krita-Version" : "28"
+}
diff --git a/plugins/metadata/tests/CMakeLists.txt \
b/plugins/metadata/tests/CMakeLists.txt new file mode 100644
index 0000000000..c50efe5f08
--- /dev/null
+++ b/plugins/metadata/tests/CMakeLists.txt
@@ -0,0 +1,21 @@
+include_directories(${CMAKE_SOURCE_DIR}/sdk/tests )
+
+include(ECMAddTests)
+
+macro_add_unittest_definitions()
+
+include(KritaAddBrokenUnitTest)
+
+##### Tests that currently fail and should be fixed #####
+
+# Works under Linux but does not work under Windows
+krita_add_broken_unit_test( kis_exif_test.cpp
+ TEST_NAME KisExifTest
+ LINK_LIBRARIES kritametadata kritaui Qt5::Test
+ NAME_PREFIX "plugins-metadata-"
+ ${MACOS_GUI_TEST})
+
+macos_test_fixrpath(
+ ${BROKEN_TESTS}
+ KisExifTest
+ )
diff --git a/libs/ui/tests/data/metadata/hpim3238.exv \
b/plugins/metadata/tests/data/metadata/hpim3238.exv similarity index 100%
rename from libs/ui/tests/data/metadata/hpim3238.exv
rename to plugins/metadata/tests/data/metadata/hpim3238.exv
diff --git a/libs/ui/tests/kis_exiv2_test.cpp \
b/plugins/metadata/tests/kis_exif_test.cpp similarity index 65%
rename from libs/ui/tests/kis_exiv2_test.cpp
rename to plugins/metadata/tests/kis_exif_test.cpp
index c515c259dc..86a9aca026 100644
--- a/libs/ui/tests/kis_exiv2_test.cpp
+++ b/plugins/metadata/tests/kis_exif_test.cpp
@@ -1,27 +1,28 @@
/*
* SPDX-FileCopyrightText: 2009 Cyrille Berger <cberger@cberger.net>
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
-#include "kis_exiv2_test.h"
+#include "kis_exif_test.h"
+#include <filestest.h>
+#include <sdk/tests/testui.h>
#include <simpletest.h>
-#include <QCoreApplication>
#include <QBuffer>
+#include <QCoreApplication>
-#include "kis_debug.h"
-#include "kis_meta_data_entry.h"
-#include "kis_meta_data_io_backend.h"
-#include "kis_meta_data_schema.h"
-#include "kis_meta_data_schema_registry.h"
-#include "kis_meta_data_store.h"
-#include "kis_meta_data_validator.h"
+#include <kis_debug.h>
+#include <kis_meta_data_backend_registry.h>
+#include <kis_meta_data_entry.h>
+#include <kis_meta_data_io_backend.h>
+#include <kis_meta_data_schema.h>
+#include <kis_meta_data_schema_registry.h>
+#include <kis_meta_data_store.h>
+#include <kis_meta_data_validator.h>
#include <kis_meta_data_value.h>
-#include "kisexiv2/kis_exiv2.h"
-#include "filestest.h"
-#include "sdk/tests/testui.h"
#ifndef FILES_DATA_DIR
#error "FILES_DATA_DIR not set. A directory with the data used for testing the \
metadata parser in krita" @@ -29,11 +30,9 @@
using namespace KisMetaData;
-void KisExiv2Test::testExifLoader()
+void KisExifTest::testExifLoader()
{
- KisExiv2::initialize();
-
- IOBackend* exifIO = IOBackendRegistry::instance()->get("exif");
+ IOBackend *exifIO = KisMetadataBackendRegistry::instance()->get("exif");
QVERIFY(exifIO);
QFile exifFile(QString(FILES_DATA_DIR) + "/metadata/hpim3238.exv");
exifFile.open(QIODevice::ReadOnly);
@@ -41,20 +40,22 @@ void KisExiv2Test::testExifLoader()
QByteArray exifBytes = exifFile.readAll();
QBuffer exifBuffer(&exifBytes);
- Store* store = new Store;
+ Store *store = new Store;
bool loadSuccess = exifIO->loadFrom(store, &exifBuffer);
QVERIFY(loadSuccess);
Validator validator(store);
for (QMap<QString, Validator::Reason>::const_iterator it = \
validator.invalidEntries().begin();
- it != validator.invalidEntries().end(); ++it) {
+ it != validator.invalidEntries().end();
+ ++it) {
dbgKrita << it.key() << " = " << it.value().type() << " entry = " << \
store->getEntry(it.key()); }
QCOMPARE(validator.countInvalidEntries(), 0);
QCOMPARE(validator.countValidEntries(), 51);
- const KisMetaData::Schema* tiffSchema = \
KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::TIFFSchemaUri);
+ const KisMetaData::Schema *tiffSchema =
+ KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::TIFFSchemaUri);
QCOMPARE(store->getEntry(tiffSchema, "Make").value(), Value("Hewlett-Packard"));
QCOMPARE(store->getEntry(tiffSchema, "Model").value(), Value("HP PhotoSmart R707 \
(V01.00) ")); @@ -64,16 +65,19 @@ void KisExiv2Test::testExifLoader()
QCOMPARE(store->getEntry(tiffSchema, "ResolutionUnit").value(), Value(2));
QCOMPARE(store->getEntry(tiffSchema, "YCbCrPositioning").value(), Value(1));
- const KisMetaData::Schema* exifSchema = \
KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::EXIFSchemaUri);
+ const KisMetaData::Schema *exifSchema =
+ KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::EXIFSchemaUri);
QCOMPARE(store->getEntry(exifSchema, "ExposureTime").value(), \
Value(Rational(35355, 100000)));
QCOMPARE(store->getEntry(exifSchema, "FNumber").value(), Value(Rational(280, \
100)));
QCOMPARE(store->getEntry(exifSchema, "ExposureProgram").value(), Value(2));
-// QCOMPARE(store->getEntry(exifSchema, "ISOSpeedRatings").value(), Value(100)); \
// TODO it's a list + // QCOMPARE(store->getEntry(exifSchema, \
"ISOSpeedRatings").value(), Value(100)); // TODO it's a list // TODO test OECF
QCOMPARE(store->getEntry(exifSchema, "ExifVersion").value(), Value("0220"));
- QCOMPARE(store->getEntry(exifSchema, "DateTimeOriginal").value(), \
Value(QDateTime(QDate(2007, 5, 8), QTime(0, 19, 18))));
- QCOMPARE(store->getEntry(exifSchema, "DateTimeDigitized").value(), \
Value(QDateTime(QDate(2007, 5, 8), QTime(0, 19, 18)))); + \
QCOMPARE(store->getEntry(exifSchema, "DateTimeOriginal").value(), + \
Value(QDateTime(QDate(2007, 5, 8), QTime(0, 19, 18)))); + \
QCOMPARE(store->getEntry(exifSchema, "DateTimeDigitized").value(), + \
Value(QDateTime(QDate(2007, 5, 8), QTime(0, 19, 18)))); // TODO \
ComponentsConfiguration
QCOMPARE(store->getEntry(exifSchema, "ShutterSpeedValue").value(), \
Value(Rational(384, 256)));
QCOMPARE(store->getEntry(exifSchema, "ApertureValue").value(), \
Value(Rational(780, 256))); @@ -82,17 +86,18 @@ void KisExiv2Test::testExifLoader()
QCOMPARE(store->getEntry(exifSchema, "MaxApertureValue").value(), \
Value(Rational(280, 100)));
QCOMPARE(store->getEntry(exifSchema, "SubjectDistance").value(), \
Value(Rational(65535, 1000)));
-
- const KisMetaData::Schema* dcSchema = \
KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::DublinCoreSchemaUri);
+ const KisMetaData::Schema *dcSchema =
+ KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::DublinCoreSchemaUri);
Q_UNUSED(dcSchema);
- const KisMetaData::Schema* xmpSchema = \
KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::XMPSchemaUri);
+ const KisMetaData::Schema *xmpSchema =
+ KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::XMPSchemaUri);
QCOMPARE(store->getEntry(xmpSchema, "CreatorTool").value(), \
Value("digiKam-0.9.1"));
QCOMPARE(store->getEntry(xmpSchema, "ModifyDate").value(), \
Value(QDateTime(QDate(2007, 5, 8), QTime(0, 19, 18))));
- const KisMetaData::Schema* mknSchema = \
KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::MakerNoteSchemaUri);
+ const KisMetaData::Schema *mknSchema =
+ KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::MakerNoteSchemaUri);
QCOMPARE(store->getEntry(mknSchema, "RawData").value(), Value("SFBNZXQ="));
}
-KISTEST_MAIN(KisExiv2Test)
-
+KISTEST_MAIN(KisExifTest)
diff --git a/libs/ui/tests/kis_exiv2_test.h b/plugins/metadata/tests/kis_exif_test.h
similarity index 73%
rename from libs/ui/tests/kis_exiv2_test.h
rename to plugins/metadata/tests/kis_exif_test.h
index 11c9f11c0f..d45d8708ea 100644
--- a/libs/ui/tests/kis_exiv2_test.h
+++ b/plugins/metadata/tests/kis_exif_test.h
@@ -1,5 +1,6 @@
/*
* SPDX-FileCopyrightText: 2009 Cyrille Berger <cberger@cberger.net>
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
@@ -9,7 +10,7 @@
#include <QObject>
-class KisExiv2Test : public QObject
+class KisExifTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
diff --git a/plugins/metadata/xmp/CMakeLists.txt \
b/plugins/metadata/xmp/CMakeLists.txt new file mode 100644
index 0000000000..052452febc
--- /dev/null
+++ b/plugins/metadata/xmp/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(kritaxmp_SOURCES
+ kis_xmp_io.cpp
+ kis_xmp_plugin.cpp
+)
+
+add_library(kritaxmp MODULE ${kritaxmp_SOURCES})
+
+generate_export_header(kritaxmp)
+
+target_link_libraries(kritaxmp
+ PRIVATE
+ kritametadata
+ KF5::CoreAddons
+ LibExiv2::LibExiv2
+)
+
+install(TARGETS kritaxmp DESTINATION ${KRITA_PLUGIN_INSTALL_DIR})
diff --git a/libs/ui/kisexiv2/kis_xmp_io.cpp b/plugins/metadata/xmp/kis_xmp_io.cpp
similarity index 75%
rename from libs/ui/kisexiv2/kis_xmp_io.cpp
rename to plugins/metadata/xmp/kis_xmp_io.cpp
index af36fcd6b1..7a1f4e7553 100644
--- a/libs/ui/kisexiv2/kis_xmp_io.cpp
+++ b/plugins/metadata/xmp/kis_xmp_io.cpp
@@ -1,5 +1,6 @@
/*
* SPDX-FileCopyrightText: 2008-2010 Cyrille Berger <cberger@cberger.net>
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
@@ -7,19 +8,19 @@
#include <string>
-#include "kis_exiv2.h"
-
-#include <kis_meta_data_store.h>
+#include <kis_exiv2_common.h>
#include <kis_meta_data_entry.h>
#include <kis_meta_data_parser.h>
-#include <kis_meta_data_value.h>
#include <kis_meta_data_schema.h>
#include <kis_meta_data_schema_registry.h>
+#include <kis_meta_data_store.h>
#include <kis_meta_data_type_info.h>
+#include <kis_meta_data_value.h>
#include <kis_debug.h>
KisXMPIO::KisXMPIO()
+ : KisMetaData::IOBackend()
{
}
@@ -27,7 +28,7 @@ KisXMPIO::~KisXMPIO()
{
}
-inline std::string exiv2Prefix(const KisMetaData::Schema* _schema)
+inline std::string exiv2Prefix(const KisMetaData::Schema *_schema)
{
const QByteArray latin1SchemaUri = _schema->uri().toLatin1();
std::string prefix = Exiv2::XmpProperties::prefix(latin1SchemaUri.constData());
@@ -41,12 +42,15 @@ inline std::string exiv2Prefix(const KisMetaData::Schema* \
_schema)
namespace
{
-void saveStructure(Exiv2::XmpData& xmpData_, const QString& name, const std::string& \
prefix, const QMap<QString, KisMetaData::Value>& structure, const \
KisMetaData::Schema* structureSchema) +void saveStructure(Exiv2::XmpData &xmpData_,
+ const QString &name,
+ const std::string &prefix,
+ const QMap<QString, KisMetaData::Value> &structure,
+ const KisMetaData::Schema *structureSchema)
{
std::string structPrefix = exiv2Prefix(structureSchema);
- for (QMap<QString, KisMetaData::Value>::const_iterator it = structure.begin();
- it != structure.end(); ++it) {
- Q_ASSERT(it.value().type() != KisMetaData::Value::Structure); // Can't \
nest structure + for (QMap<QString, KisMetaData::Value>::const_iterator it = \
structure.begin(); it != structure.end(); ++it) { + Q_ASSERT(it.value().type() \
!= KisMetaData::Value::Structure); // Can't nest structure
QString key = \
QString("%1/%2:%3").arg(name).arg(structPrefix.c_str()).arg(it.key()); Exiv2::XmpKey \
ekey(prefix, key.toLatin1().constData()); dbgMetaData << ppVar(key) << \
ppVar(ekey.key().c_str()); @@ -58,25 +62,24 @@ void saveStructure(Exiv2::XmpData& \
xmpData_, const QString& name, const std::str }
}
-bool KisXMPIO::saveTo(KisMetaData::Store* store, QIODevice* ioDevice, HeaderType \
headerType) const +bool KisXMPIO::saveTo(KisMetaData::Store *store, QIODevice \
*ioDevice, HeaderType headerType) const {
dbgMetaData << "Save XMP Data";
Exiv2::XmpData xmpData_;
- for (QHash<QString, KisMetaData::Entry>::const_iterator it = store->begin();
- it != store->end(); ++it) {
- const KisMetaData::Entry& entry = *it;
+ for (QHash<QString, KisMetaData::Entry>::const_iterator it = store->begin(); it \
!= store->end(); ++it) { + const KisMetaData::Entry &entry = *it;
// Check whether the prefix and namespace are know to exiv2
std::string prefix = exiv2Prefix(entry.schema());
dbgMetaData << "Saving " << entry.name();
- const KisMetaData::Value& value = entry.value();
+ const KisMetaData::Value &value = entry.value();
- const KisMetaData::TypeInfo* typeInfo = \
entry.schema()->propertyType(entry.name()); + const KisMetaData::TypeInfo \
*typeInfo = entry.schema()->propertyType(entry.name()); if (value.type() == \
KisMetaData::Value::Structure) {
QMap<QString, KisMetaData::Value> structure = value.asStructure();
- const KisMetaData::Schema* structureSchema = 0;
+ const KisMetaData::Schema *structureSchema = 0;
if (typeInfo) {
structureSchema = typeInfo->structureSchema();
}
@@ -88,10 +91,11 @@ bool KisXMPIO::saveTo(KisMetaData::Store* store, QIODevice* \
ioDevice, HeaderType
saveStructure(xmpData_, entry.name(), prefix, structure, \
structureSchema); } else {
Exiv2::XmpKey key(prefix, entry.name().toLatin1().constData());
- if (typeInfo && (typeInfo->propertyType() == \
KisMetaData::TypeInfo::OrderedArrayType
- || typeInfo->propertyType() == \
KisMetaData::TypeInfo::UnorderedArrayType
- || typeInfo->propertyType() == \
KisMetaData::TypeInfo::AlternativeArrayType)
- && typeInfo->embeddedPropertyType()->propertyType() == \
KisMetaData::TypeInfo::StructureType) { + if (typeInfo
+ && (typeInfo->propertyType() == \
KisMetaData::TypeInfo::OrderedArrayType + || \
typeInfo->propertyType() == KisMetaData::TypeInfo::UnorderedArrayType + \
|| typeInfo->propertyType() == KisMetaData::TypeInfo::AlternativeArrayType) + \
&& typeInfo->embeddedPropertyType()->propertyType() == \
KisMetaData::TypeInfo::StructureType) { // Here is the bad part, again we need to do \
it by hand Exiv2::XmpTextValue tv;
switch (typeInfo->propertyType()) {
@@ -109,8 +113,8 @@ bool KisXMPIO::saveTo(KisMetaData::Store* store, QIODevice* \
ioDevice, HeaderType ;
}
xmpData_.add(key, &tv); // set the arrya type
- const KisMetaData::TypeInfo* stuctureTypeInfo = \
typeInfo->embeddedPropertyType();
- const KisMetaData::Schema* structureSchema = 0;
+ const KisMetaData::TypeInfo *stuctureTypeInfo = \
typeInfo->embeddedPropertyType(); + const KisMetaData::Schema \
*structureSchema = 0; if (stuctureTypeInfo) {
structureSchema = stuctureTypeInfo->structureSchema();
}
@@ -121,7 +125,11 @@ bool KisXMPIO::saveTo(KisMetaData::Store* store, QIODevice* \
ioDevice, HeaderType Q_ASSERT(structureSchema);
QList<KisMetaData::Value> array = value.asArray();
for (int idx = 0; idx < array.size(); ++idx) {
- saveStructure(xmpData_, \
QString("%1[%2]").arg(entry.name()).arg(idx + 1), prefix, array[idx].asStructure(), \
structureSchema); + saveStructure(xmpData_,
+ QString("%1[%2]").arg(entry.name()).arg(idx + 1),
+ prefix,
+ array[idx].asStructure(),
+ structureSchema);
}
} else {
dbgMetaData << ppVar(key.key().c_str());
@@ -149,7 +157,7 @@ bool parseTagName(const QString &tagString,
QString &structName,
int &arrayIndex,
QString &tagName,
- const KisMetaData::TypeInfo** typeInfo,
+ const KisMetaData::TypeInfo **typeInfo,
const KisMetaData::Schema *schema)
{
arrayIndex = -1;
@@ -164,12 +172,11 @@ bool parseTagName(const QString &tagString,
return true;
}
-
if (numSubNames == 2) {
QRegExp regexp("([A-Za-z]\\w+)/([A-Za-z]\\w+):([A-Za-z]\\w+)");
if (regexp.indexIn(tagString) != -1) {
structName = regexp.capturedTexts()[1];
- tagName = regexp.capturedTexts()[3];
+ tagName = regexp.capturedTexts()[3];
*typeInfo = schema->propertyType(structName);
if (*typeInfo && (*typeInfo)->propertyType() == \
KisMetaData::TypeInfo::StructureType) { @@ -203,7 +210,7 @@ bool parseTagName(const \
QString &tagString, return false;
}
-bool KisXMPIO::loadFrom(KisMetaData::Store* store, QIODevice* ioDevice) const
+bool KisXMPIO::loadFrom(KisMetaData::Store *store, QIODevice *ioDevice) const
{
ioDevice->open(QIODevice::ReadOnly);
dbgMetaData << "Load XMP Data";
@@ -211,20 +218,24 @@ bool KisXMPIO::loadFrom(KisMetaData::Store* store, QIODevice* \
ioDevice) const QByteArray arr = ioDevice->readAll();
xmpPacket_.assign(arr.data(), arr.length());
dbgMetaData << xmpPacket_.length();
-// dbgMetaData << xmpPacket_.c_str();
+ // dbgMetaData << xmpPacket_.c_str();
Exiv2::XmpData xmpData_;
Exiv2::XmpParser::decode(xmpData_, xmpPacket_);
- QMap< const KisMetaData::Schema*, QMap<QString, QMap<QString, \
KisMetaData::Value> > > structures;
- QMap< const KisMetaData::Schema*, QMap<QString, QVector< QMap<QString, \
KisMetaData::Value> > > > arraysOfStructures; + QMap<const KisMetaData::Schema *, \
QMap<QString, QMap<QString, KisMetaData::Value>>> structures; + QMap<const \
KisMetaData::Schema *, QMap<QString, QVector<QMap<QString, KisMetaData::Value>>>> \
arraysOfStructures;
for (Exiv2::XmpData::iterator it = xmpData_.begin(); it != xmpData_.end(); ++it) \
{ dbgMetaData << "Start iteration" << it->key().c_str();
Exiv2::XmpKey key(it->key());
dbgMetaData << key.groupName().c_str() << " " << key.tagName().c_str() << " \
" << key.ns().c_str();
- if ((key.groupName() == "exif" || key.groupName() == "tiff") && \
key.tagName() == "NativeDigest") { // TODO: someone who has time to lose can look in \
adding support for NativeDigest, it's undocumented use by the XMP SDK to check if \
exif data has been changed while XMP hasn't been updated + if \
((key.groupName() == "exif" || key.groupName() == "tiff") + && \
key.tagName() == "NativeDigest") { // TODO: someone who has time to lose can look in \
adding support for + // \
NativeDigest, it's undocumented use by the XMP SDK to check if exif + \
// data has been changed while XMP hasn't been updated dbgMetaData << "dropped";
} else {
- const KisMetaData::Schema* schema = \
KisMetaData::SchemaRegistry::instance()->schemaFromPrefix(key.groupName().c_str()); + \
const KisMetaData::Schema *schema = + \
KisMetaData::SchemaRegistry::instance()->schemaFromPrefix(key.groupName().c_str()); \
if (!schema) {
schema = \
KisMetaData::SchemaRegistry::instance()->schemaFromUri(key.ns().c_str()); if \
(!schema) { @@ -237,32 +248,29 @@ bool KisXMPIO::loadFrom(KisMetaData::Store* store, \
QIODevice* ioDevice) const QString structName;
int arrayIndex = -1;
QString tagName;
- const KisMetaData::TypeInfo* typeInfo = 0;
+ const KisMetaData::TypeInfo *typeInfo = 0;
- if (!parseTagName(key.tagName().c_str(),
- structName, arrayIndex, tagName,
- &typeInfo, schema)) continue;
+ if (!parseTagName(key.tagName().c_str(), structName, arrayIndex, \
tagName, &typeInfo, schema)) + continue;
bool isStructureEntry = !structName.isEmpty() && arrayIndex == -1;
bool isStructureInArrayEntry = !structName.isEmpty() && arrayIndex != \
-1;
Q_ASSERT(isStructureEntry != isStructureInArrayEntry || \
!isStructureEntry);
-
KisMetaData::Value v;
bool ignoreValue = false;
// Compute the value
- if (value->typeId() == Exiv2::xmpBag
- || value->typeId() == Exiv2::xmpSeq
- || value->typeId() == Exiv2::xmpAlt) {
- const KisMetaData::TypeInfo* embeddedTypeInfo = 0;
+ if (value->typeId() == Exiv2::xmpBag || value->typeId() == Exiv2::xmpSeq
+ || value->typeId() == Exiv2::xmpAlt) {
+ const KisMetaData::TypeInfo *embeddedTypeInfo = 0;
if (typeInfo) {
embeddedTypeInfo = typeInfo->embeddedPropertyType();
}
- const KisMetaData::Parser* parser = 0;
+ const KisMetaData::Parser *parser = 0;
if (embeddedTypeInfo) {
parser = embeddedTypeInfo->parser();
}
- const Exiv2::XmpArrayValue* xav = dynamic_cast<const \
Exiv2::XmpArrayValue*>(value.get()); + const Exiv2::XmpArrayValue *xav \
= dynamic_cast<const Exiv2::XmpArrayValue *>(value.get()); Q_ASSERT(xav);
QList<KisMetaData::Value> array;
for (int i = 0; i < xav->count(); ++i) {
@@ -291,10 +299,11 @@ bool KisXMPIO::loadFrom(KisMetaData::Store* store, QIODevice* \
ioDevice) const }
v = KisMetaData::Value(array, vt);
} else if (value->typeId() == Exiv2::langAlt) {
- const Exiv2::LangAltValue* xav = dynamic_cast<const \
Exiv2::LangAltValue*>(value.get()); + const Exiv2::LangAltValue *xav = \
dynamic_cast<const Exiv2::LangAltValue *>(value.get()); QList<KisMetaData::Value> \
alt;
- for (std::map< std::string, std::string>::const_iterator it = \
xav->value_.begin();
- it != xav->value_.end(); ++it) {
+ for (std::map<std::string, std::string>::const_iterator it = \
xav->value_.begin(); + it != xav->value_.end();
+ ++it) {
KisMetaData::Value valt(it->second.c_str());
valt.addPropertyQualifier("xml:lang", \
KisMetaData::Value(it->first.c_str())); alt.push_back(valt);
@@ -338,18 +347,25 @@ bool KisXMPIO::loadFrom(KisMetaData::Store* store, QIODevice* \
ioDevice) const }
}
- for (QMap< const KisMetaData::Schema*, QMap<QString, QMap<QString, \
KisMetaData::Value> > >::iterator it = structures.begin();
- it != structures.end(); ++it) {
- const KisMetaData::Schema* schema = it.key();
- for (QMap<QString, QMap<QString, KisMetaData::Value> >::iterator it2 = \
it.value().begin();
- it2 != it.value().end(); ++it2) {
+ for (QMap<const KisMetaData::Schema *, QMap<QString, QMap<QString, \
KisMetaData::Value>>>::iterator it = + structures.begin();
+ it != structures.end();
+ ++it) {
+ const KisMetaData::Schema *schema = it.key();
+ for (QMap<QString, QMap<QString, KisMetaData::Value>>::iterator it2 = \
it.value().begin(); + it2 != it.value().end();
+ ++it2) {
store->addEntry(KisMetaData::Entry(schema, it2.key(), \
KisMetaData::Value(it2.value()))); }
}
- for (QMap< const KisMetaData::Schema*, QMap<QString, QVector< QMap<QString, \
KisMetaData::Value> > > >::iterator it = arraysOfStructures.begin(); it != \
arraysOfStructures.end(); ++it) {
- const KisMetaData::Schema* schema = it.key();
- for (QMap<QString, QVector<QMap<QString, KisMetaData::Value> > >::iterator \
it2 = it.value().begin();
- it2 != it.value().end(); ++it2) {
+ for (QMap<const KisMetaData::Schema *, QMap<QString, QVector<QMap<QString, \
KisMetaData::Value>>>>::iterator it = + arraysOfStructures.begin();
+ it != arraysOfStructures.end();
+ ++it) {
+ const KisMetaData::Schema *schema = it.key();
+ for (QMap<QString, QVector<QMap<QString, KisMetaData::Value>>>::iterator it2 \
= it.value().begin(); + it2 != it.value().end();
+ ++it2) {
KisMetaData::Value::ValueType type = KisMetaData::Value::OrderedArray;
QString entryName = it2.key();
if (schema->propertyType(entryName)) {
@@ -375,7 +391,7 @@ bool KisXMPIO::loadFrom(KisMetaData::Store* store, QIODevice* \
ioDevice) const }
store->removeEntry(schema, entryName);
if (type != KisMetaData::Value::Invalid) {
- QList< KisMetaData::Value > valueList;
+ QList<KisMetaData::Value> valueList;
for (int i = 0; i < it2.value().size(); ++i) {
valueList.append(it2.value()[i]);
}
diff --git a/libs/ui/kisexiv2/kis_xmp_io.h b/plugins/metadata/xmp/kis_xmp_io.h
similarity index 55%
rename from libs/ui/kisexiv2/kis_xmp_io.h
rename to plugins/metadata/xmp/kis_xmp_io.h
index 9160933212..6cfd0fa75e 100644
--- a/libs/ui/kisexiv2/kis_xmp_io.h
+++ b/plugins/metadata/xmp/kis_xmp_io.h
@@ -1,5 +1,6 @@
/*
* SPDX-FileCopyrightText: 2008 Cyrille Berger <cberger@cberger.net>
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
@@ -7,36 +8,41 @@
#ifndef _KIS_XMP_IO_H_
#define _KIS_XMP_IO_H_
-#include <kis_meta_data_io_backend.h>
-
#include <klocalizedstring.h>
+#include <kis_meta_data_io_backend.h>
+
class KisXMPIO : public KisMetaData::IOBackend
{
- struct Private;
public:
KisXMPIO();
~KisXMPIO() override;
- QString id() const override {
+ QString id() const override
+ {
return "xmp";
}
- QString name() const override {
+ QString name() const override
+ {
return i18n("XMP");
}
- BackendType type() const override {
+ BackendType type() const override
+ {
return Text;
}
- bool supportSaving() const override {
+ bool supportSaving() const override
+ {
return true;
}
- bool saveTo(KisMetaData::Store* store, QIODevice* ioDevice, HeaderType \
headerType = NoHeader) const override;
- bool canSaveAllEntries(KisMetaData::Store*) const override {
+ bool saveTo(KisMetaData::Store *store, QIODevice *ioDevice, HeaderType \
headerType = NoHeader) const override; + bool canSaveAllEntries(KisMetaData::Store \
*) const override + {
return true;
}
- bool supportLoading() const override {
+ bool supportLoading() const override
+ {
return true;
}
- bool loadFrom(KisMetaData::Store* store, QIODevice* ioDevice) const override;
+ bool loadFrom(KisMetaData::Store *store, QIODevice *ioDevice) const override;
};
#endif
diff --git a/plugins/metadata/xmp/kis_xmp_plugin.cpp \
b/plugins/metadata/xmp/kis_xmp_plugin.cpp new file mode 100644
index 0000000000..bb85466fbb
--- /dev/null
+++ b/plugins/metadata/xmp/kis_xmp_plugin.cpp
@@ -0,0 +1,29 @@
+/*
+ * This file is part of Krita
+ *
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "kis_xmp_plugin.h"
+
+#include <kpluginfactory.h>
+
+#include <kis_meta_data_backend_registry.h>
+
+#include "kis_xmp_io.h"
+
+K_PLUGIN_FACTORY_WITH_JSON(KisIptcIOPluginFactory, "kritaxmp.json", \
registerPlugin<KisXmpPlugin>();) +
+KisXmpPlugin::KisXmpPlugin(QObject *parent, const QVariantList &)
+ : QObject(parent)
+{
+ KisMetadataBackendRegistry::instance()->add(new KisXMPIO());
+}
+
+KisXmpPlugin::~KisXmpPlugin()
+{
+}
+
+#include "kis_xmp_plugin.moc"
diff --git a/plugins/metadata/xmp/kis_xmp_plugin.h \
b/plugins/metadata/xmp/kis_xmp_plugin.h new file mode 100644
index 0000000000..fa670de9ae
--- /dev/null
+++ b/plugins/metadata/xmp/kis_xmp_plugin.h
@@ -0,0 +1,21 @@
+/*
+ * This file is part of Krita
+ *
+ * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef _KIS_XMP_PLUGIN_H_
+#define _KIS_XMP_PLUGIN_H_
+
+#include <QObject>
+
+class KisXmpPlugin : public QObject
+{
+public:
+ KisXmpPlugin(QObject *parent, const QVariantList &);
+ ~KisXmpPlugin() override;
+};
+
+#endif // _KIS_IPTC_PLUGIN_H_
diff --git a/plugins/metadata/xmp/kritaxmp.json b/plugins/metadata/xmp/kritaxmp.json
new file mode 100644
index 0000000000..b6128ad7c5
--- /dev/null
+++ b/plugins/metadata/xmp/kritaxmp.json
@@ -0,0 +1,9 @@
+{
+ "Id": "XMP",
+ "Type": "Service",
+ "X-KDE-Library": "kritaxmp",
+ "X-KDE-ServiceTypes": [
+ "Krita/Metadata"
+ ],
+ "X-Krita-Version": "28"
+}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic