mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-23 10:22:48 +00:00
kimgio: new RAW-specialized plugin
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
73532012e0
commit
7a137a6a9f
7 changed files with 312 additions and 35 deletions
|
@ -163,6 +163,7 @@ set_package_properties(LibLZMA PROPERTIES
|
|||
|
||||
kde4_optional_find_package(ImageMagick COMPONENTS Magick++)
|
||||
set_package_properties(ImageMagick PROPERTIES
|
||||
DESCRIPTION "Software suite to create, edit, and compose bitmap images"
|
||||
URL "https://imagemagick.org/"
|
||||
PURPOSE "Support for various image formats"
|
||||
TYPE OPTIONAL
|
||||
|
@ -172,6 +173,15 @@ kde4_optional_find_package(WebP)
|
|||
set_package_properties(WebP PROPERTIES
|
||||
DESCRIPTION "A new image format for the Web"
|
||||
URL "https://developers.google.com/speed/webp"
|
||||
PURPOSE "Support for WebP image format"
|
||||
TYPE OPTIONAL
|
||||
)
|
||||
|
||||
kde4_optional_find_package(LibRaw)
|
||||
set_package_properties(LibRaw PROPERTIES
|
||||
DESCRIPTION "Simple and unified interface for extracting out of RAW files"
|
||||
URL "https://www.libraw.org/"
|
||||
PURPOSE "Support for RAW image format"
|
||||
TYPE OPTIONAL
|
||||
)
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*
|
||||
* Currently supported formats include:
|
||||
* @li WEBP \<read\> \<write\>
|
||||
* @li RAW \<read\>
|
||||
* @li PGM \<read\>
|
||||
* @li XBM \<read\>
|
||||
* @li BMP \<read\>
|
||||
|
@ -32,7 +33,6 @@
|
|||
* @li JPEG \<read\>
|
||||
* @li JP2 \<read\>
|
||||
* @li GIF \<read\>
|
||||
* @li RAW \<read\>
|
||||
*
|
||||
* @todo move to kdeui
|
||||
*/
|
||||
|
|
|
@ -42,3 +42,24 @@ if(WEBP_FOUND)
|
|||
DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}/plugins/imageformats
|
||||
)
|
||||
endif(WEBP_FOUND)
|
||||
|
||||
##################################
|
||||
|
||||
if(LIBRAW_FOUND)
|
||||
include_directories(${LIBRAW_INCLUDE_DIR})
|
||||
kde4_add_plugin(kimg_raw raw.cpp)
|
||||
target_link_libraries(kimg_raw
|
||||
${KDE4_KDECORE_LIBS}
|
||||
${QT_QTGUI_LIBRARY}
|
||||
${LIBRAW_LIBRARIES}
|
||||
)
|
||||
set_target_properties(kimg_raw PROPERTIES
|
||||
COMPILE_FLAGS "${KDE4_ENABLE_EXCEPTIONS}"
|
||||
OUTPUT_NAME raw
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS kimg_raw
|
||||
DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}/plugins/imageformats
|
||||
)
|
||||
endif(LIBRAW_FOUND)
|
||||
|
|
|
@ -4,6 +4,7 @@ writing a new handler.
|
|||
Current formats include:
|
||||
|
||||
WEBP <read> <write>
|
||||
RAW <read>
|
||||
|
||||
along with whatever ImageMagick supports but it is assumed that it supports
|
||||
reading atleast the following formats (even if they cannot be loaded because
|
||||
|
@ -16,7 +17,6 @@ ICO <read>
|
|||
JPEG <read>
|
||||
JP2 <read>
|
||||
GIF <read>
|
||||
RAW <read>
|
||||
|
||||
If you want to contribute plugin for image format and there is no solid
|
||||
C/C++ library for it (like there is for WebP) then it is unlikely it will be
|
||||
|
|
|
@ -59,24 +59,15 @@ static const struct HeadersTblData {
|
|||
};
|
||||
static const qint16 HeadersTblSize = sizeof(HeadersTbl) / sizeof(HeadersTblData);
|
||||
|
||||
static QList<std::string> s_blacklist = QList<std::string>()
|
||||
// borked coders
|
||||
<< std::string("PDF")
|
||||
<< std::string("EPDF")
|
||||
<< std::string("PS")
|
||||
<< std::string("HTML")
|
||||
<< std::string("SHTML")
|
||||
<< std::string("TXT")
|
||||
<< std::string("VIDEO")
|
||||
<< std::string("TTF")
|
||||
// kdelibs provides these
|
||||
<< std::string("WEBP")
|
||||
// Katie provides these, SVG coders are very borked
|
||||
<< std::string("SVG")
|
||||
<< std::string("SVGZ")
|
||||
<< std::string("XPM")
|
||||
<< std::string("PBM")
|
||||
<< std::string("PPM");
|
||||
static QList<std::string> s_whitelist = QList<std::string>()
|
||||
<< std::string("PGM")
|
||||
<< std::string("XBM")
|
||||
<< std::string("BMP")
|
||||
<< std::string("ICO")
|
||||
<< std::string("JPEG")
|
||||
<< std::string("JP2")
|
||||
<< std::string("GIF")
|
||||
<< std::string("PNG");
|
||||
|
||||
int initMagick()
|
||||
{
|
||||
|
@ -97,19 +88,18 @@ int initMagick()
|
|||
kWarning() << "Exception raised";
|
||||
}
|
||||
foreach (const Magick::CoderInfo &magickcoder, magickcoderlist) {
|
||||
foreach (const std::string &blacklist, s_blacklist) {
|
||||
if (magickcoder.name() == blacklist) {
|
||||
kDebug() << "Blacklisting coder" << blacklist.c_str();
|
||||
try {
|
||||
magickcoder.unregister();
|
||||
} catch(Magick::Exception &err) {
|
||||
kWarning() << err.what();
|
||||
} catch(std::exception &err) {
|
||||
kWarning() << err.what();
|
||||
} catch (...) {
|
||||
kWarning() << "Exception raised";
|
||||
}
|
||||
}
|
||||
if (s_whitelist.contains(magickcoder.name())) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
kDebug() << "Blacklisting coder" << magickcoder.name().c_str();
|
||||
magickcoder.unregister();
|
||||
} catch(Magick::Exception &err) {
|
||||
kWarning() << err.what();
|
||||
} catch(std::exception &err) {
|
||||
kWarning() << err.what();
|
||||
} catch (...) {
|
||||
kWarning() << "Exception raised";
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -267,7 +257,11 @@ bool MagickHandler::canRead(QIODevice *device, QByteArray *actualformat)
|
|||
);
|
||||
if (isvalid) {
|
||||
kDebug() << "Magick format detected" << magickformat;
|
||||
actualformat->append(magickformat);
|
||||
if (s_whitelist.contains(std::string(magickformat, qstrlen(magickformat)))) {
|
||||
actualformat->append(magickformat);
|
||||
} else {
|
||||
isvalid = false;
|
||||
}
|
||||
}
|
||||
} catch(Magick::Exception &err) {
|
||||
kWarning() << err.what();
|
||||
|
@ -343,7 +337,6 @@ QList<QByteArray> MagickPlugin::mimeTypes() const
|
|||
<< "image/x-portable-bitmap"
|
||||
<< "image/x-portable-graymap"
|
||||
<< "image/x-portable-pixmap"
|
||||
<< "image/x-dcraw"
|
||||
<< "image/x-xbitmap";
|
||||
return list;
|
||||
}
|
||||
|
|
203
kimgio/raw.cpp
Normal file
203
kimgio/raw.cpp
Normal file
|
@ -0,0 +1,203 @@
|
|||
/* This file is part of the KDE libraries
|
||||
Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License version 2, as published by the Free Software Foundation.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "raw.h"
|
||||
|
||||
#include <QImage>
|
||||
#include <kdebug.h>
|
||||
|
||||
#include <libraw/libraw.h>
|
||||
|
||||
static const char* const s_rawpluginformat = "raw";
|
||||
|
||||
RAWHandler::RAWHandler()
|
||||
{
|
||||
}
|
||||
|
||||
RAWHandler::~RAWHandler()
|
||||
{
|
||||
}
|
||||
|
||||
bool RAWHandler::canRead() const
|
||||
{
|
||||
if (RAWHandler::canRead(device())) {
|
||||
setFormat(s_rawpluginformat);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RAWHandler::read(QImage *image)
|
||||
{
|
||||
const qint64 devicepos = device()->pos();
|
||||
QByteArray data = device()->readAll();
|
||||
device()->seek(devicepos);
|
||||
|
||||
if (Q_UNLIKELY(data.isEmpty())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
LibRaw raw;
|
||||
raw.imgdata.params.output_color = LIBRAW_COLORSPACE_sRGB;
|
||||
|
||||
int rawresult = raw.open_buffer(data.data(), data.size());
|
||||
if (rawresult != LIBRAW_SUCCESS) {
|
||||
kWarning() << libraw_strerror(rawresult);
|
||||
raw.recycle();
|
||||
return false;
|
||||
}
|
||||
|
||||
rawresult = raw.unpack();
|
||||
if (rawresult != LIBRAW_SUCCESS) {
|
||||
kWarning() << libraw_strerror(rawresult);
|
||||
raw.recycle();
|
||||
return false;
|
||||
}
|
||||
|
||||
rawresult = raw.dcraw_process();
|
||||
if (rawresult != LIBRAW_SUCCESS) {
|
||||
kWarning() << libraw_strerror(rawresult);
|
||||
raw.recycle();
|
||||
return false;
|
||||
}
|
||||
|
||||
libraw_processed_image_t* rawimg = raw.dcraw_make_mem_image(&rawresult);
|
||||
if (!rawimg || rawresult != LIBRAW_SUCCESS) {
|
||||
kWarning() << libraw_strerror(rawresult);
|
||||
raw.recycle();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rawimg->colors != 3) {
|
||||
kWarning() << "Color components count not supported" << rawimg->colors;
|
||||
raw.dcraw_clear_mem(rawimg);
|
||||
raw.recycle();
|
||||
return false;
|
||||
}
|
||||
|
||||
*image = QImage(rawimg->width, rawimg->height, QImage::Format_ARGB32);
|
||||
if (image->isNull()) {
|
||||
kWarning() << "Could not create QImage";
|
||||
raw.dcraw_clear_mem(rawimg);
|
||||
raw.recycle();
|
||||
return false;
|
||||
}
|
||||
|
||||
QRgb* imagebits = reinterpret_cast<QRgb*>(image->bits());
|
||||
for (uint i = 0 ; i < rawimg->data_size; i += 3) {
|
||||
*imagebits = qRgba(rawimg->data[i], rawimg->data[i + 1], rawimg->data[i + 2], 0xff);
|
||||
imagebits++;
|
||||
}
|
||||
|
||||
raw.dcraw_clear_mem(rawimg);
|
||||
raw.recycle();
|
||||
} catch (...) {
|
||||
kWarning() << "Exception raised";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RAWHandler::write(const QImage &image)
|
||||
{
|
||||
// this plugin is a read-only kind of plugin
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray RAWHandler::name() const
|
||||
{
|
||||
return s_rawpluginformat;
|
||||
}
|
||||
|
||||
bool RAWHandler::canRead(QIODevice *device)
|
||||
{
|
||||
if (Q_UNLIKELY(!device)) {
|
||||
kWarning() << "Called with no device";
|
||||
return false;
|
||||
}
|
||||
|
||||
const qint64 devicepos = device->pos();
|
||||
QByteArray data = device->readAll();
|
||||
device->seek(devicepos);
|
||||
|
||||
if (Q_UNLIKELY(data.isEmpty())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
LibRaw raw;
|
||||
raw.imgdata.params.output_color = LIBRAW_COLORSPACE_sRGB;
|
||||
|
||||
const int rawresult = raw.open_buffer(data.data(), data.size());
|
||||
if (rawresult == LIBRAW_FILE_UNSUPPORTED) {
|
||||
kDebug() << libraw_strerror(rawresult);
|
||||
raw.recycle();
|
||||
return false;
|
||||
} else if (rawresult != LIBRAW_SUCCESS) {
|
||||
kWarning() << libraw_strerror(rawresult);
|
||||
raw.recycle();
|
||||
return false;
|
||||
}
|
||||
|
||||
raw.recycle();
|
||||
} catch (...) {
|
||||
kWarning() << "Exception raised";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList RAWPlugin::keys() const
|
||||
{
|
||||
return QStringList() << s_rawpluginformat;
|
||||
}
|
||||
|
||||
QList<QByteArray> RAWPlugin::mimeTypes() const
|
||||
{
|
||||
static const QList<QByteArray> list = QList<QByteArray>()
|
||||
<< "image/x-dcraw";
|
||||
return list;
|
||||
}
|
||||
|
||||
QImageIOPlugin::Capabilities RAWPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||
{
|
||||
if (format == s_rawpluginformat)
|
||||
return QImageIOPlugin::Capabilities(QImageIOPlugin::CanRead);
|
||||
if (!format.isEmpty())
|
||||
return 0;
|
||||
if (!device->isOpen())
|
||||
return 0;
|
||||
|
||||
QImageIOPlugin::Capabilities cap;
|
||||
if (device->isReadable() && RAWHandler::canRead(device))
|
||||
cap |= QImageIOPlugin::CanRead;
|
||||
return cap;
|
||||
}
|
||||
|
||||
QImageIOHandler *RAWPlugin::create(QIODevice *device, const QByteArray &format) const
|
||||
{
|
||||
QImageIOHandler *handler = new RAWHandler();
|
||||
handler->setDevice(device);
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN2(raw, RAWPlugin)
|
50
kimgio/raw.h
Normal file
50
kimgio/raw.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* This file is part of the KDE libraries
|
||||
Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License version 2, as published by the Free Software Foundation.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef KIMG_RAW_H
|
||||
#define KIMG_RAW_H
|
||||
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtGui/qimageiohandler.h>
|
||||
|
||||
class RAWHandler : public QImageIOHandler
|
||||
{
|
||||
public:
|
||||
RAWHandler();
|
||||
~RAWHandler();
|
||||
|
||||
bool canRead() const final;
|
||||
bool read(QImage *image) final;
|
||||
bool write(const QImage &image) final;
|
||||
|
||||
QByteArray name() const final;
|
||||
|
||||
static bool canRead(QIODevice *device);
|
||||
};
|
||||
|
||||
class RAWPlugin : public QImageIOPlugin
|
||||
{
|
||||
public:
|
||||
QStringList keys() const;
|
||||
QList<QByteArray> mimeTypes() const;
|
||||
Capabilities capabilities(QIODevice *device, const QByteArray &format) const final;
|
||||
QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const final;
|
||||
};
|
||||
|
||||
#endif // KIMG_RAW_H
|
||||
|
Loading…
Add table
Reference in a new issue