diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e7e703..724b596 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,12 @@ include(CheckIncludeFiles) set(REQUIRED_QT_VERSION 5.3.0) find_package(Qt5Gui ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE) +find_package(KF5Archive) +set_package_properties(KF5Archive PROPERTIES + TYPE OPTIONAL + PURPOSE "Required for the QImage plugin for Krita and OpenRaster images" +) + # EPS support depends on the gs utility; non-UNIX systems are unlikely to have # this available in PATH set(BUILD_EPS_PLUGIN FALSE) diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 853607e..7909f3a 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -61,6 +61,14 @@ kimageformats_read_tests( rgb tga ) + +if (KF5Archive_FOUND) + kimageformats_read_tests( + kra + ora + ) +endif() + # Allow some fuzziness when reading this formats, to allow for # rounding errors (eg: in alpha blending). kimageformats_read_tests(FUZZ 1 diff --git a/autotests/read/kra/src.kra b/autotests/read/kra/src.kra new file mode 100644 index 0000000..5c1ba6b Binary files /dev/null and b/autotests/read/kra/src.kra differ diff --git a/autotests/read/kra/src.png b/autotests/read/kra/src.png new file mode 100644 index 0000000..77e8aab Binary files /dev/null and b/autotests/read/kra/src.png differ diff --git a/autotests/read/ora/src.ora b/autotests/read/ora/src.ora new file mode 100644 index 0000000..f81b9c0 Binary files /dev/null and b/autotests/read/ora/src.ora differ diff --git a/autotests/read/ora/src.png b/autotests/read/ora/src.png new file mode 100644 index 0000000..77e8aab Binary files /dev/null and b/autotests/read/ora/src.png differ diff --git a/src/imageformats/CMakeLists.txt b/src/imageformats/CMakeLists.txt index 8cf8d54..0db2ae8 100644 --- a/src/imageformats/CMakeLists.txt +++ b/src/imageformats/CMakeLists.txt @@ -89,3 +89,20 @@ target_link_libraries(kimg_xcf Qt5::Gui) install(TARGETS kimg_xcf DESTINATION ${KDE_INSTALL_QTPLUGINDIR}/imageformats/) install(FILES xcf.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/) +################################## + +if (KF5Archive_FOUND) + + add_library(kimg_kra MODULE kra.cpp) + target_link_libraries(kimg_kra Qt5::Gui KF5::Archive) + + install(TARGETS kimg_kra DESTINATION ${KDE_INSTALL_QTPLUGINDIR}/imageformats/) + install(FILES kra.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/) + + add_library(kimg_ora MODULE ora.cpp) + target_link_libraries(kimg_ora Qt5::Gui KF5::Archive) + + install(TARGETS kimg_ora DESTINATION ${KDE_INSTALL_QTPLUGINDIR}/imageformats/) + install(FILES ora.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/) + +endif() diff --git a/src/imageformats/kra.cpp b/src/imageformats/kra.cpp new file mode 100644 index 0000000..072f29a --- /dev/null +++ b/src/imageformats/kra.cpp @@ -0,0 +1,88 @@ +/* This file is part of the KDE project + Copyright (C) 2013 Boudewijn Rempt + + This program is free software; you can redistribute it and/or + modify it under the terms of the Lesser GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This code is based on Thacher Ulrich PSD loading code released + on public domain. See: http://tulrich.com/geekstuff/ +*/ + +#include "kra.h" + +#include + +#include +#include +#include + +KraHandler::KraHandler() +{ +} + +bool KraHandler::canRead() const +{ + if (canRead(device())) { + setFormat("kra"); + return true; + } + return false; +} + +bool KraHandler::read(QImage *image) +{ + KZip zip(device()); + if (!zip.open(QIODevice::ReadOnly)) return false; + + const KArchiveEntry *entry = zip.directory()->entry(QLatin1String("mergedimage.png")); + if (!entry || !entry->isFile()) return false; + + const KZipFileEntry* fileZipEntry = static_cast(entry); + + image->loadFromData(fileZipEntry->data(), "PNG"); + + return true; +} + +bool KraHandler::canRead(QIODevice *device) +{ + if (!device) { + qWarning("KraHandler::canRead() called with no device"); + return false; + } + + char buff[57]; + if (device->peek(buff, sizeof(buff)) == sizeof(buff)) + return qstrcmp(buff + 0x26, "application/x-krita") == 0; + + return false; +} + +QImageIOPlugin::Capabilities KraPlugin::capabilities(QIODevice *device, const QByteArray &format) const +{ + if (format == "kra" || format == "KRA") { + return Capabilities(CanRead); + } + if (!format.isEmpty()) { + return 0; + } + if (!device->isOpen()) { + return 0; + } + + Capabilities cap; + if (device->isReadable() && KraHandler::canRead(device)) { + cap |= CanRead; + } + return cap; +} + +QImageIOHandler *KraPlugin::create(QIODevice *device, const QByteArray &format) const +{ + QImageIOHandler *handler = new KraHandler; + handler->setDevice(device); + handler->setFormat(format); + return handler; +} diff --git a/src/imageformats/kra.desktop b/src/imageformats/kra.desktop new file mode 100644 index 0000000..a258504 --- /dev/null +++ b/src/imageformats/kra.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=QImageIOPlugins +X-KDE-ImageFormat=kra +X-KDE-MimeType=application/x-krita +X-KDE-Read=true +X-KDE-Write=false diff --git a/src/imageformats/kra.h b/src/imageformats/kra.h new file mode 100644 index 0000000..3aff1ae --- /dev/null +++ b/src/imageformats/kra.h @@ -0,0 +1,39 @@ +/* This file is part of the KDE project + Copyright (c) 2013 Boudewijn Rempt + + This program is free software; you can redistribute it and/or + modify it under the terms of the Lesser GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. +*/ + +#ifndef KIMG_KRA_H +#define KIMG_KRA_H + +#include + +class KraHandler : public QImageIOHandler +{ +public: + KraHandler(); + + bool canRead() const Q_DECL_OVERRIDE; + bool read(QImage *image) Q_DECL_OVERRIDE; + + static bool canRead(QIODevice *device); +}; + +class KraPlugin : public QImageIOPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "kra.json") + +public: + Capabilities capabilities(QIODevice *device, const QByteArray &format) const; + QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const; +}; + + + +#endif + diff --git a/src/imageformats/kra.json b/src/imageformats/kra.json new file mode 100644 index 0000000..00755ab --- /dev/null +++ b/src/imageformats/kra.json @@ -0,0 +1,5 @@ +{ + "Keys": [ "kra" ], + "MimeTypes": [ "application/x-krita", "application/x-krita" ] +} + diff --git a/src/imageformats/ora.cpp b/src/imageformats/ora.cpp new file mode 100644 index 0000000..0ce34b1 --- /dev/null +++ b/src/imageformats/ora.cpp @@ -0,0 +1,87 @@ +/* This file is part of the KDE project + Copyright (C) 2013 Boudewijn Rempt + + This program is free software; you can redistribute it and/or + modify it under the terms of the Lesser GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This code is based on Thacher Ulrich PSD loading code released + on public domain. See: http://tulrich.com/geekstuff/ +*/ + +#include "ora.h" + +#include +#include + +#include + +OraHandler::OraHandler() +{ +} + +bool OraHandler::canRead() const +{ + if (canRead(device())) { + setFormat("ora"); + return true; + } + return false; +} + +bool OraHandler::read(QImage *image) +{ + KZip zip(device()); + if (!zip.open(QIODevice::ReadOnly)) return false; + + const KArchiveEntry *entry = zip.directory()->entry(QLatin1String("mergedimage.png")); + if (!entry || !entry->isFile()) return false; + + const KZipFileEntry* fileZipEntry = static_cast(entry); + + image->loadFromData(fileZipEntry->data(), "PNG"); + + return true; +} + +bool OraHandler::canRead(QIODevice *device) +{ + if (!device) { + qWarning("OraHandler::canRead() called with no device"); + return false; + } + + char buff[54]; + if (device->peek(buff, sizeof(buff)) == sizeof(buff)) + return qstrcmp(buff + 0x26, "image/openraster") == 0; + + return false; +} + +QImageIOPlugin::Capabilities OraPlugin::capabilities(QIODevice *device, const QByteArray &format) const +{ + if (format == "ora" || format == "ORA") { + return Capabilities(CanRead); + } + if (!format.isEmpty()) { + return 0; + } + if (!device->isOpen()) { + return 0; + } + + Capabilities cap; + if (device->isReadable() && OraHandler::canRead(device)) { + cap |= CanRead; + } + return cap; +} + +QImageIOHandler *OraPlugin::create(QIODevice *device, const QByteArray &format) const +{ + QImageIOHandler *handler = new OraHandler; + handler->setDevice(device); + handler->setFormat(format); + return handler; +} diff --git a/src/imageformats/ora.desktop b/src/imageformats/ora.desktop new file mode 100644 index 0000000..7bb7865 --- /dev/null +++ b/src/imageformats/ora.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=QImageIOPlugins +X-KDE-ImageFormat=ora +X-KDE-MimeType=image/openraster +X-KDE-Read=true +X-KDE-Write=false diff --git a/src/imageformats/ora.h b/src/imageformats/ora.h new file mode 100644 index 0000000..68a426e --- /dev/null +++ b/src/imageformats/ora.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (c) 2013 Boudewijn Rempt + + This program is free software; you can redistribute it and/or + modify it under the terms of the Lesser GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. +*/ + +#ifndef KIMG_ORA_H +#define KIMG_ORA_H + +#include + +class OraHandler : public QImageIOHandler +{ +public: + OraHandler(); + + bool canRead() const Q_DECL_OVERRIDE; + bool read(QImage *image) Q_DECL_OVERRIDE; + + static bool canRead(QIODevice *device); +}; + + +class OraPlugin : public QImageIOPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "ora.json") +public: + Capabilities capabilities(QIODevice *device, const QByteArray &format) const Q_DECL_OVERRIDE; + QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const Q_DECL_OVERRIDE; +}; + + +#endif + diff --git a/src/imageformats/ora.json b/src/imageformats/ora.json new file mode 100644 index 0000000..24e9ced --- /dev/null +++ b/src/imageformats/ora.json @@ -0,0 +1,5 @@ +{ + "Keys": [ "ora" ], + "MimeTypes": [ "image/openraster", "image/openraster" ] +} +