[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [calligra/krita-gmic-ltvrdy] krita/plugins/extensions/gmic: Implement import/export processing visit
From: Lukáš Tvrdý <lukast.dev () gmail ! com>
Date: 2013-08-31 19:08:14
Message-ID: E1VFqWs-00027r-R9 () scm ! kde ! org
[Download RAW message or body]
Git commit 223d37e40234950093b0bf7161fcde570a748fa6 by Lukáš Tvrdý.
Committed on 31/08/2013 at 19:06.
Pushed by lukast into branch 'krita-gmic-ltvrdy'.
Implement import/export processing visitors
o now undo works correctly
o prepare the code for supporting gmic input/output layer modes
M +4 -0 krita/plugins/extensions/gmic/CMakeLists.txt
A +60 -0 krita/plugins/extensions/gmic/kis_export_gmic_processing_visitor.cpp \
[License: GPL (v2+)] A +55 -0 \
krita/plugins/extensions/gmic/kis_export_gmic_processing_visitor.h [License: GPL \
(v2+)] A +106 -0 krita/plugins/extensions/gmic/kis_gmic_command.cpp \
[License: GPL (v2+)] C +21 -20 krita/plugins/extensions/gmic/kis_gmic_command.h \
[from: krita/plugins/extensions/gmic/kis_gmic_plugin.h - 054% similarity] M +68 -4 \
krita/plugins/extensions/gmic/kis_gmic_plugin.cpp M +1 -0 \
krita/plugins/extensions/gmic/kis_gmic_plugin.h A +264 -0 \
krita/plugins/extensions/gmic/kis_gmic_simple_convertor.cpp [License: GPL (v2+)] \
A +85 -0 krita/plugins/extensions/gmic/kis_gmic_simple_convertor.h \
[License: GPL (v2+)] A +80 -0 \
krita/plugins/extensions/gmic/kis_import_gmic_processing_visitor.cpp [License: \
GPL (v2+)] A +48 -0 \
krita/plugins/extensions/gmic/kis_import_gmic_processing_visitor.h [License: GPL \
(v2+)]
http://commits.kde.org/calligra/223d37e40234950093b0bf7161fcde570a748fa6
diff --git a/krita/plugins/extensions/gmic/CMakeLists.txt \
b/krita/plugins/extensions/gmic/CMakeLists.txt index bc47635..d4c3bc4 100644
--- a/krita/plugins/extensions/gmic/CMakeLists.txt
+++ b/krita/plugins/extensions/gmic/CMakeLists.txt
@@ -58,6 +58,10 @@ set(kritagmic_PART_SRCS
dlg_gmic.cpp
kis_gmic.cpp
kis_gmic_processing_visitor.cpp
+ kis_gmic_simple_convertor.cpp
+ kis_export_gmic_processing_visitor.cpp
+ kis_gmic_command.cpp
+ kis_import_gmic_processing_visitor.cpp
kis_gmic_plugin.cpp ${kritagmic_shared_PART_SRCS}
)
diff --git a/krita/plugins/extensions/gmic/kis_export_gmic_processing_visitor.cpp \
b/krita/plugins/extensions/gmic/kis_export_gmic_processing_visitor.cpp new file mode \
100644 index 0000000..f3f0c97
--- /dev/null
+++ b/krita/plugins/extensions/gmic/kis_export_gmic_processing_visitor.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2013 Dmitry Kazakov <dimula73@gmail.com>
+ * Copyright (c) 2013 Lukáš Tvrdý <lukast.dev@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_export_gmic_processing_visitor.h"
+#include <KoColorSpaceRegistry.h>
+#include <KoColorSpace.h>
+
+#include <kis_gmic_simple_convertor.h>
+#include <kis_node.h>
+
+KisExportGmicProcessingVisitor::KisExportGmicProcessingVisitor(const \
QList<KisNodeSP> &nodes, QSharedPointer<gmic_list<float> > images) + : \
m_nodes(nodes), + m_images(images)
+{
+}
+
+
+void KisExportGmicProcessingVisitor::visitNodeWithPaintDevice(KisNode *node, \
KisUndoAdapter *undoAdapter) +{
+ Q_UNUSED(undoAdapter);
+
+ int index = m_nodes.indexOf(node);
+ if (index >= 0)
+ {
+ qDebug() << "Found the LAYEEEEEEEEEEEEEEEEER!";
+
+ /* fill the image with data here */
+ KisGmicSimpleConvertor convertor;
+
+ KisPaintDeviceSP device = node->paintDevice();
+ gmic_image<float> &gimg = m_images->_data[index];
+
+
+ QRect rc = device->exactBounds();
+ quint32 x = rc.width();
+ quint32 y = rc.height();
+ quint32 z = 1;
+ quint32 colorChannelCount = 4; // RGBA
+ gimg.assign(x,y,z,colorChannelCount);
+
+ convertor.convertToGmicImage(device, gimg);
+ }
+}
+
diff --git a/krita/plugins/extensions/gmic/kis_export_gmic_processing_visitor.h \
b/krita/plugins/extensions/gmic/kis_export_gmic_processing_visitor.h new file mode \
100644 index 0000000..d3cca87
--- /dev/null
+++ b/krita/plugins/extensions/gmic/kis_export_gmic_processing_visitor.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Dmitry Kazakov <dimula73@gmail.com>
+ * Copyright (c) 2013 Lukáš Tvrdý <lukast.dev@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __KIS_EXPORT_GMIC_PROCESSING_VISITOR_H
+#define __KIS_EXPORT_GMIC_PROCESSING_VISITOR_H
+
+#include <gmic.h>
+
+#include <QSharedPointer>
+#include <QList>
+
+#include <processing/kis_simple_processing_visitor.h>
+#include <kis_types.h>
+#include <kis_node.h>
+
+class KisNode;
+class KisUndoAdapter;
+
+#include <kis_paint_device.h>
+
+class KisExportGmicProcessingVisitor : public KisSimpleProcessingVisitor
+{
+public:
+ KisExportGmicProcessingVisitor(const QList<KisNodeSP> &nodes, QSharedPointer< \
gmic_list<float> > images); +
+protected:
+ void visitNodeWithPaintDevice(KisNode *node, KisUndoAdapter *undoAdapter);
+ void visitExternalLayer(KisExternalLayer *layer, KisUndoAdapter *undoAdapter){ \
Q_UNUSED(layer); Q_UNUSED(undoAdapter); } +
+private:
+ void convertToGmicImageOpti(KisPaintDeviceSP dev, gmic_image<float>& gmicImage);
+ void init();
+private:
+
+ QList<KisNodeSP> m_nodes;
+ QSharedPointer<gmic_list<float> > m_images;
+};
+
+#endif /* __KIS_EXPORT_GMIC_PROCESSING_VISITOR_H */
diff --git a/krita/plugins/extensions/gmic/kis_gmic_command.cpp \
b/krita/plugins/extensions/gmic/kis_gmic_command.cpp new file mode 100644
index 0000000..d7159de
--- /dev/null
+++ b/krita/plugins/extensions/gmic/kis_gmic_command.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2013 Dmitry Kazakov <dimula73@gmail.com>
+ * Copyright (c) 2013 Lukáš Tvrdý <lukast.dev@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_gmic_command.h"
+
+#include <QString>
+
+KisGmicCommand::KisGmicCommand(const QString &gmicCommandString, QSharedPointer< \
gmic_list<float> > images): + m_gmicCommandString(gmicCommandString),
+ m_images(images),
+ m_firstRedo(true)
+{
+}
+
+void KisGmicCommand::undo()
+{
+ // do nothing
+}
+
+void KisGmicCommand::redo()
+{
+ if (m_firstRedo)
+ {
+ m_firstRedo = false;
+
+ /* process m_images using GMIC here */
+ // Second step : Call G'MIC API to process input images.
+ //------------------------------------------------------
+ std::fprintf(stderr,"\n- 2st step : Call G'MIC interpreter.\n");
+
+ gmic_list<char> images_names;
+ try
+ {
+ QString gmicCmd = "-+ -n 0,255 ";
+ gmicCmd.append(m_gmicCommandString);
+ qDebug() << m_gmicCommandString;
+ gmic(gmicCmd.toLocal8Bit().constData(), *m_images, images_names);
+ }
+ // Catch exception, if an error occured in the interpreter.
+ catch (gmic_exception &e)
+ {
+ qDebug() << "\n- Error encountered when calling G'MIC : '%s'\n" << \
e.what(); + return;
+ }
+
+ // Third step : get back modified image data.
+ //-------------------------------------------
+ std::fprintf(stderr,"\n- 3st step : Returned %u output \
images.\n",m_images->_width); + for (unsigned int i = 0; i<m_images->_width; \
++i) + {
+ std::fprintf(stderr," Output image %u = %ux%ux%ux%u, buffer : %p\n",i,
+ m_images->_data[i]._width,
+ m_images->_data[i]._height,
+ m_images->_data[i]._depth,
+ m_images->_data[i]._spectrum,
+ m_images->_data[i]._data);
+ }
+ }
+}
+
+/*
+
+KisProcessingApplicator applicator(this, m_d->rootLayer,
+ KisProcessingApplicator::RECURSIVE,
+ emitSignals, actionName);
+
+nodes.append(..);
+nodes.append(..);
+nodes.append(..);
+
+QSharedPointer<gmic_list<float> > m_images(new ...);
+
+KisProcessingVisitorSP visitor;
+
+visitor = new KisExportGmicProcessingVisitor(nodes, images);
+applicator.applyVisitor(visitor, KisStrokeJobData::CONCURRENT);
+
+applicator.applyCommand(new KisGmicCommand(images));
+
+visitor = new KisImportGmicProcessingVisitor(nodes, images);
+applicator.applyVisitor(visitor, KisStrokeJobData::CONCURRENT); // undo information \
is stored in this visitor +
+applicator.applyCommand(new CleanTheData(images));
+
+CleanTheData::redo() {
+ m_images->clear();
+}
+
+
+*/
diff --git a/krita/plugins/extensions/gmic/kis_gmic_plugin.h \
b/krita/plugins/extensions/gmic/kis_gmic_command.h similarity index 54%
copy from krita/plugins/extensions/gmic/kis_gmic_plugin.h
copy to krita/plugins/extensions/gmic/kis_gmic_command.h
index 2e1f44a..4a8f95c 100644
--- a/krita/plugins/extensions/gmic/kis_gmic_plugin.h
+++ b/krita/plugins/extensions/gmic/kis_gmic_command.h
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2013 Lukáš Tvrdý <lukast.dev@gmail.com>
+ * Copyright (c) 2013 Dmitry Kazakov <dimula73@gmail.com>
+ * Copyright (c) 2013 Lukáš Tvrdý <lukast.dev@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,33 +14,33 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. \
*/ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, \
USA. + */
-#ifndef _KIS_GMIC_PLUGIN_H_
-#define _KIS_GMIC_PLUGIN_H_
+#ifndef __KIS_GMIC_COMMAND_H
+#define __KIS_GMIC_COMMAND_H
-#include <QVariant>
+#include <QSharedPointer>
-#include <kis_view_plugin.h>
-#include <kis_gmic_filter_settings.h>
-#include "kis_gmic_parser.h"
+#include <gmic.h>
-class KisGmicWidget;
+#include <kundo2command.h>
+#include "kis_types.h"
-class KisGmicPlugin : public KisViewPlugin
+class QString;
+
+class KisGmicCommand : public KUndo2Command
{
- Q_OBJECT
public:
- KisGmicPlugin(QObject *parent, const QVariantList &);
- virtual ~KisGmicPlugin();
+ KisGmicCommand(const QString &gmicCommandString, QSharedPointer< \
gmic_list<float> > images);
-private:
- KisGmicWidget * m_gmicWidget;
- QString m_gmicDefinitionFilePath;
+ void undo();
+ void redo();
-private slots:
- void slotGmic();
- void slotApplyGmicCommand(KisGmicFilterSetting* setting);
+private:
+ QString m_gmicCommandString;
+ QSharedPointer<gmic_list<float> > m_images;
+ bool m_firstRedo;
};
-#endif
+#endif /* __KIS_GMIC_COMMAND_H */
diff --git a/krita/plugins/extensions/gmic/kis_gmic_plugin.cpp \
b/krita/plugins/extensions/gmic/kis_gmic_plugin.cpp index 304e46f..4c96a0b 100644
--- a/krita/plugins/extensions/gmic/kis_gmic_plugin.cpp
+++ b/krita/plugins/extensions/gmic/kis_gmic_plugin.cpp
@@ -49,9 +49,6 @@
#include "kis_gmic.h"
#include "dlg_gmic.h"
-K_PLUGIN_FACTORY(KisGmicPluginFactory, registerPlugin<KisGmicPlugin>();)
-K_EXPORT_PLUGIN(KisGmicPluginFactory("krita"))
-
#include "gmic.h"
#include "kis_gmic_parser.h"
#include "Component.h"
@@ -59,6 +56,14 @@ K_EXPORT_PLUGIN(KisGmicPluginFactory("krita"))
#include "kis_gmic_widget.h"
#include "kis_gmic_processing_visitor.h"
+#include "kis_export_gmic_processing_visitor.h"
+#include "kis_gmic_command.h"
+#include "kis_import_gmic_processing_visitor.h"
+
+
+K_PLUGIN_FACTORY(KisGmicPluginFactory, registerPlugin<KisGmicPlugin>();)
+K_EXPORT_PLUGIN(KisGmicPluginFactory("krita"))
+
KisGmicPlugin::KisGmicPlugin(QObject *parent, const QVariantList &)
: KisViewPlugin(parent, "kritaplugins/gmic.rc"),m_gmicWidget(0)
{
@@ -102,7 +107,7 @@ void KisGmicPlugin::slotGmic()
}
-void KisGmicPlugin::slotApplyGmicCommand(KisGmicFilterSetting* setting)
+void KisGmicPlugin::slotApplyGmicCommandOld(KisGmicFilterSetting* setting)
{
KisImageWSP image = m_view->image();
@@ -143,4 +148,63 @@ void KisGmicPlugin::slotApplyGmicCommand(KisGmicFilterSetting* \
setting) }
}
+void KisGmicPlugin::slotApplyGmicCommand(KisGmicFilterSetting* setting)
+{
+ QString actionName;
+ KisNodeSP node;
+
+ if (setting->inputLayerMode() == ACTIVE_LAYER)
+ {
+ //TODO: Undo string for gimp plug-in is G'MIC, I would like to use \
G'MIC+filtername + actionName = i18n("Gmic: Active Layer");
+ node = m_view->activeNode();
+ }
+ else
+ {
+ KMessageBox::sorry(m_gmicWidget, i18n("Sorry, this input mode is not \
implemented"), i18n("Krita")); + return;
+ }
+
+ if (setting->outputMode() != IN_PLACE)
+ {
+ KMessageBox::sorry(m_gmicWidget,QString("Sorry, this output mode is not \
implemented"),"Krita"); + return;
+ }
+
+ KisImageSignalVector emitSignals;
+ emitSignals << ModifiedSignal;
+
+
+ KisProcessingApplicator applicator(m_view->image(), node,
+ KisProcessingApplicator::RECURSIVE,
+ emitSignals, actionName);
+
+ QList<KisNodeSP> kritaNodes;
+ kritaNodes.append(m_view->activeNode());
+
+ QSharedPointer< gmic_list<float> > gmicLayers(new gmic_list<float>);
+ gmicLayers->assign(kritaNodes.size());
+
+
+ KisProcessingVisitorSP visitor;
+ visitor = new KisExportGmicProcessingVisitor(kritaNodes, gmicLayers);
+ applicator.applyVisitor(visitor, KisStrokeJobData::CONCURRENT);
+
+ applicator.applyCommand(new KisGmicCommand(setting->gmicCommand(), gmicLayers));
+
+ visitor = new KisImportGmicProcessingVisitor(kritaNodes, gmicLayers);
+ applicator.applyVisitor(visitor, KisStrokeJobData::CONCURRENT); // undo \
information is stored in this visitor + applicator.end();
+
+ // TODO: applicator.applyCommand(new CleanTheData(images));
+
+ /*CleanTheData::redo() {
+ m_images->clear();
+ }/*/
+
+
+
+}
+
+
#include "kis_gmic_plugin.moc"
diff --git a/krita/plugins/extensions/gmic/kis_gmic_plugin.h \
b/krita/plugins/extensions/gmic/kis_gmic_plugin.h index 2e1f44a..8404cf8 100644
--- a/krita/plugins/extensions/gmic/kis_gmic_plugin.h
+++ b/krita/plugins/extensions/gmic/kis_gmic_plugin.h
@@ -39,6 +39,7 @@ private:
private slots:
void slotGmic();
+ void slotApplyGmicCommandOld(KisGmicFilterSetting* setting);
void slotApplyGmicCommand(KisGmicFilterSetting* setting);
};
diff --git a/krita/plugins/extensions/gmic/kis_gmic_simple_convertor.cpp \
b/krita/plugins/extensions/gmic/kis_gmic_simple_convertor.cpp new file mode 100644
index 0000000..3da1fd5
--- /dev/null
+++ b/krita/plugins/extensions/gmic/kis_gmic_simple_convertor.cpp
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2013 Lukáš Tvrdý <lukast.dev@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <QRect>
+
+#include <kis_gmic_simple_convertor.h>
+
+#include <kis_paint_device.h>
+#include <KoColorSpaceRegistry.h>
+#include <KoColorSpace.h>
+#include <KoColorModelStandardIds.h>
+#include <KoColorSpaceTraits.h>
+
+using namespace cimg_library;
+
+
+KisGmicSimpleConvertor::KisGmicSimpleConvertor():m_channelSize(0)
+{
+
+}
+
+
+KisGmicSimpleConvertor::~KisGmicSimpleConvertor()
+{
+ deletePlanes();
+}
+
+
+void KisGmicSimpleConvertor::convertToGmicImage(KisPaintDeviceSP dev, gmic_image< \
float >& gmicImage) +{
+ const KoColorSpace *rgbaFloat32bitcolorSpace = \
KoColorSpaceRegistry::instance()->colorSpace(RGBAColorModelID.id(), + \
Float32BitsColorDepthID.id(), + \
KoColorSpaceRegistry::instance()->rgb8()->profile()); +
+ Q_CHECK_PTR(rgbaFloat32bitcolorSpace);
+ dev->convertTo(rgbaFloat32bitcolorSpace);
+
+ QRect rc = dev->exactBounds();
+ m_planarBytes = dev->readPlanarBytes(rc.x(), rc.y(), rc.width(), rc.height());
+ setChannelSize(rc.width() * rc.height());
+
+ int greenOffset = gmicImage._width * gmicImage._height;
+ int blueOffset = greenOffset * 2;
+ int alphaOffset = greenOffset * 3;
+ quint8 * redChannelBytes = m_planarBytes.at(KoRgbF32Traits::red_pos);
+ quint8 * greenChannelBytes = m_planarBytes.at(KoRgbF32Traits::green_pos);
+ quint8 * blueChannelBytes = m_planarBytes.at(KoRgbF32Traits::blue_pos);
+ quint8 * alphaChannelBytes = m_planarBytes.at(KoRgbF32Traits::alpha_pos);
+
+ unsigned int channelSize = sizeof(float);
+
+ memcpy(gmicImage._data ,redChannelBytes ,gmicImage._width * \
gmicImage._height * channelSize); + memcpy(gmicImage._data + greenOffset \
,greenChannelBytes ,gmicImage._width * gmicImage._height * channelSize); + \
memcpy(gmicImage._data + blueOffset ,blueChannelBytes ,gmicImage._width * \
gmicImage._height * channelSize); + memcpy(gmicImage._data + alphaOffset \
,alphaChannelBytes ,gmicImage._width * gmicImage._height * channelSize); +}
+
+
+KisPaintDeviceSP KisGmicSimpleConvertor::convertFromGmicImage(CImg< float >& \
gmicImage, bool &preserveAlpha) +{
+ const KoColorSpace *rgbaFloat32bitcolorSpace = \
KoColorSpaceRegistry::instance()->colorSpace(RGBAColorModelID.id(), + \
Float32BitsColorDepthID.id(), + \
KoColorSpaceRegistry::instance()->rgb8()->profile()); +
+ KisPaintDeviceSP dev = new KisPaintDevice(rgbaFloat32bitcolorSpace);
+
+
+ unsigned int channelBytes = gmicImage._width * gmicImage._height * \
sizeof(float); + if (channelBytes == channelSize() * sizeof(float))
+ {
+ // ok, we can reuse read plannar bytes here
+ qDebug() << "[krita] Re-using read plannar bytes";
+ if ((gmicImage._spectrum == 1) || (gmicImage._spectrum == 3))
+ {
+ qDebug() << "[krita] Releasing alpha channel";
+ // we can delete alpha channel
+ releaseAlphaChannel();
+ }
+
+ }
+ else
+ {
+ // re-accumullate buffers, output image has different dimension..not sure if \
this ever happens + deletePlanes();
+ bool alphaChannelEnabled = ((gmicImage._spectrum == 2) || \
(gmicImage._spectrum == 4)); + qDebug() << "Accumulating...!";
+ accumulate(gmicImage._width * gmicImage._height, alphaChannelEnabled);
+ }
+
+ switch (gmicImage._spectrum)
+ {
+ case 1:
+ {
+ grayscale2rgb(gmicImage, m_planarBytes);
+ preserveAlpha = true;
+ break;
+ }
+ case 2:
+ {
+ grayscaleAlpha2rgba(gmicImage, m_planarBytes);
+ break;
+ }
+ case 3:
+ {
+ rgb2rgb(gmicImage, m_planarBytes);
+ preserveAlpha = true;
+ break;
+ }
+ case 4:
+ rgba2rgba(gmicImage, m_planarBytes);
+ break;
+ default:
+ {
+ qDebug() << "Unsupported gmic output format : " << gmicImage._width << \
gmicImage._height << gmicImage._depth << gmicImage._spectrum; + }
+ }
+
+ dev->writePlanarBytes(m_planarBytes, 0, 0, gmicImage._width, gmicImage._height);
+
+ // release planes
+ deletePlanes();
+ return dev;
+}
+
+void KisGmicSimpleConvertor::grayscale2rgb(CImg< float >& gmicImage, QVector< quint8 \
* > &planes) +{
+ quint8 * redChannelBytes = planes[0];
+ quint8 * greenChannelBytes = planes[1];
+ quint8 * blueChannelBytes = planes[2];
+ // alphaChannel will be preserved
+
+ int pos = 0;
+ float r,g,b;
+
+ // iterate over gmic image and fill plane buffers
+ for (unsigned int y = 0; y < gmicImage._height; y++)
+ {
+ for (unsigned int x = 0; x < gmicImage._width; x++)
+ {
+ pos = y * gmicImage._width + x;
+ // gmic assumes 0.0 - 255.0, Krita stores 0.0 - 1.0
+ r = g = b = gmicImage._data[pos] / 255.0;
+ memcpy(redChannelBytes, &r, 4); redChannelBytes += 4;
+ memcpy(greenChannelBytes, &g, 4); greenChannelBytes += 4;
+ memcpy(blueChannelBytes, &b, 4); blueChannelBytes += 4;
+ }
+ }
+ // TODO: check performance if memcpy whole channel is faster
+}
+
+
+void KisGmicSimpleConvertor::grayscaleAlpha2rgba(CImg< float >& gmicImage, QVector< \
quint8 * > &planes) +{
+ quint8 * redChannelBytes = planes[0];
+ quint8 * greenChannelBytes = planes[1];
+ quint8 * blueChannelBytes = planes[2];
+ quint8 * alphaChannelBytes = planes[3];
+
+ int pos = 0;
+ int alphaOffset = gmicImage._width * gmicImage._height;
+ float r,g,b,a;
+
+ // iterate over gmic image and fill plane buffers
+ for (unsigned int y = 0; y < gmicImage._height; y++)
+ {
+ for (unsigned int x = 0; x < gmicImage._width; x++){
+ pos = y * gmicImage._width + x;
+
+ // gmic assumes 0.0 - 255.0, Krita stores 0.0 - 1.0
+ r = g = b = gmicImage._data[pos] / 255.0;
+ a = gmicImage._data[pos + alphaOffset] / 255.0;
+
+ memcpy(redChannelBytes, &r, 4); redChannelBytes += 4;
+ memcpy(greenChannelBytes, &g, 4); greenChannelBytes += 4;
+ memcpy(blueChannelBytes, &b, 4); blueChannelBytes += 4;
+ memcpy(alphaChannelBytes, &a, 4); alphaChannelBytes += 4;
+ }
+ }
+}
+
+
+void KisGmicSimpleConvertor::rgb2rgb(CImg< float >& gmicImage, QVector< quint8 * > \
&planes) +{
+ quint8 * redChannelBytes = planes[0];
+ quint8 * greenChannelBytes = planes[1];
+ quint8 * blueChannelBytes = planes[2];
+ // alphaChannel will be preserved
+
+ int pos = 0;
+ int greenOffset = gmicImage._width * gmicImage._height;
+ int blueOffset = greenOffset * 2;
+
+ float r,g,b;
+
+ // iterate over gmic image and fill plane buffers
+ for (unsigned int y = 0; y < gmicImage._height; y++)
+ {
+ for (unsigned int x = 0; x < gmicImage._width; x++)
+ {
+ pos = y * gmicImage._width + x;
+
+ // gmic assumes 0.0 - 255.0, Krita stores 0.0 - 1.0
+ r = gmicImage._data[pos] / 255.0;
+ g = gmicImage._data[pos + greenOffset] / 255.0;
+ b = gmicImage._data[pos + blueOffset] / 255.0;
+
+ memcpy(redChannelBytes, &r, 4); redChannelBytes += 4;
+ memcpy(greenChannelBytes, &g, 4); greenChannelBytes += 4;
+ memcpy(blueChannelBytes, &b, 4); blueChannelBytes += 4;
+ }
+ }
+}
+
+void KisGmicSimpleConvertor::rgba2rgba(CImg< float >& gmicImage, QVector< quint8 * > \
&planes) +{
+ qDebug() <<"planes-size"<< planes.size();
+
+ quint8 * redChannelBytes = planes[0];
+ quint8 * greenChannelBytes = planes[1];
+ quint8 * blueChannelBytes = planes[2];
+ quint8 * alphaChannelBytes = planes[3];
+
+ int pos = 0;
+ int greenOffset = gmicImage._width * gmicImage._height;
+ int blueOffset = greenOffset * 2;
+ int alphaOffset = greenOffset * 3;
+
+ float r,g,b,a;
+
+ // iterate over gmic image and fill plane buffers
+ for (unsigned int y = 0; y < gmicImage._height; y++)
+ {
+ for (unsigned int x = 0; x < gmicImage._width; x++)
+ {
+ pos = y * gmicImage._width + x;
+
+ // gmic assumes 0.0 - 255.0, Krita stores 0.0 - 1.0
+ r = gmicImage._data[pos] / 255.0;
+ g = gmicImage._data[pos + greenOffset] / 255.0;
+ b = gmicImage._data[pos + blueOffset] / 255.0;
+ a = gmicImage._data[pos + alphaOffset] / 255.0;
+
+ memcpy(redChannelBytes, &r, 4); redChannelBytes += 4;
+ memcpy(greenChannelBytes, &g, 4); greenChannelBytes += 4;
+ memcpy(blueChannelBytes, &b, 4); blueChannelBytes += 4;
+ memcpy(alphaChannelBytes, &a, 4); alphaChannelBytes += 4;
+ }
+ }
+}
diff --git a/krita/plugins/extensions/gmic/kis_gmic_simple_convertor.h \
b/krita/plugins/extensions/gmic/kis_gmic_simple_convertor.h new file mode 100644
index 0000000..4bc8830
--- /dev/null
+++ b/krita/plugins/extensions/gmic/kis_gmic_simple_convertor.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013 Lukáš Tvrdý <lukast.dev@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <kis_gmic.h>
+
+#include <QVector>
+
+#ifndef __KIS_GMIC_SIMPLE_CONVERTOR_H
+#define __KIS_GMIC_SIMPLE_CONVERTOR_H
+
+class KisGmicSimpleConvertor
+{
+public:
+ KisGmicSimpleConvertor();
+ ~KisGmicSimpleConvertor();
+
+public:
+ // convert functions
+ void convertToGmicImage(KisPaintDeviceSP dev, gmic_image<float>& gmicImage);
+
+ KisPaintDeviceSP convertFromGmicImage(gmic_image<float>& gmicImage, bool \
&preserveAlpha); + // re-align functions
+ void grayscale2rgb(cimg_library::CImg< float >& gmicImage, QVector< quint8 * > \
&planes); + void grayscaleAlpha2rgba(cimg_library::CImg< float >& gmicImage, \
QVector< quint8 * > &planes); + void rgb2rgb(cimg_library::CImg< float >& \
gmicImage, QVector< quint8 * > &planes); + void rgba2rgba(cimg_library::CImg< \
float >& gmicImage, QVector< quint8 * > &planes); +
+
+ void releaseAlphaChannel()
+ {
+ // alphaPos == 3
+ delete m_planarBytes[3];
+ m_planarBytes[3] = 0;
+ }
+
+ void deletePlanes()
+ {
+ qDeleteAll(m_planarBytes);
+ m_planarBytes.clear();
+ }
+
+ void accumulate(unsigned int channelSize, bool alphaChannelEnabled = true)
+ {
+ setChannelSize(channelSize);
+ m_planarBytes.resize(4);
+
+ int channelCount = 4;
+ if (!alphaChannelEnabled)
+ {
+ m_planarBytes[3] = 0;
+ channelCount = 3;
+ }
+
+ for (int i=0;i<channelCount;i++)
+ {
+ m_planarBytes[i] = new quint8[channelSize * sizeof(float)];
+ }
+ }
+
+ void setChannelSize(unsigned int channelSize) { m_channelSize = channelSize; }
+ // count of float pixels per channel
+ unsigned int channelSize() {return m_channelSize;}
+
+private:
+ unsigned int m_channelSize;
+ QVector<quint8 *> m_planarBytes;
+
+};
+
+#endif
diff --git a/krita/plugins/extensions/gmic/kis_import_gmic_processing_visitor.cpp \
b/krita/plugins/extensions/gmic/kis_import_gmic_processing_visitor.cpp new file mode \
100644 index 0000000..f3a7677
--- /dev/null
+++ b/krita/plugins/extensions/gmic/kis_import_gmic_processing_visitor.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2013 Dmitry Kazakov <dimula73@gmail.com>
+ * Copyright (c) 2013 Lukáš Tvrdý <lukast.dev@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_import_gmic_processing_visitor.h"
+
+#include <kis_transaction.h>
+#include <kis_paint_device.h>
+
+#include <gmic.h>
+#include "kis_gmic_simple_convertor.h"
+#include <kis_node.h>
+#include <kis_painter.h>
+#include <KoCompositeOpRegistry.h>
+
+KisImportGmicProcessingVisitor::KisImportGmicProcessingVisitor(const \
QList<KisNodeSP> &nodes,QSharedPointer<gmic_list<float> > images) + : \
m_nodes(nodes), + m_images(images)
+{
+}
+
+void KisImportGmicProcessingVisitor::visitNodeWithPaintDevice(KisNode *node, \
KisUndoAdapter *undoAdapter) +{
+ int index = m_nodes.indexOf(node);
+ if (index >= 0)
+ {
+ gmic_image<float> &gimg = m_images->_data[index];
+
+ qDebug() << "Importing: " << gimg._width << gimg._height << gimg._spectrum;
+
+
+ KisPaintDeviceSP src = node->paintDevice();
+ KisTransaction transaction("", src);
+
+ bool preserveAlpha = false;
+
+ KisGmicSimpleConvertor convertor;
+ KisPaintDeviceSP dstDev = \
convertor.convertFromGmicImage(m_images->_data[index], preserveAlpha); +
+
+ // to actual layer colorspace
+ dstDev->convertTo(src->colorSpace());
+ // bitBlt back -- we don't write the pixel data back directly, but bitBlt so \
the + // unselected pixels are not overwritten.
+ KisPainter gc(src);
+ gc.setCompositeOp(COMPOSITE_COPY);
+
+ // preserve alpha if grayscale or RGB output
+ QRect rc(0,0,m_images->_data[index]._width, m_images->_data[index]._height);
+ if (preserveAlpha)
+ {
+ gc.setLockAlpha(true);
+ }
+ gc.bitBlt(rc.topLeft(), dstDev, rc);
+ gc.end();
+
+ transaction.commit(undoAdapter);
+ }
+}
+
+void KisImportGmicProcessingVisitor::visitExternalLayer(KisExternalLayer *layer, \
KisUndoAdapter *undoAdapter) +{
+ Q_UNUSED(layer);
+ Q_UNUSED(undoAdapter);
+}
diff --git a/krita/plugins/extensions/gmic/kis_import_gmic_processing_visitor.h \
b/krita/plugins/extensions/gmic/kis_import_gmic_processing_visitor.h new file mode \
100644 index 0000000..61a4fa5
--- /dev/null
+++ b/krita/plugins/extensions/gmic/kis_import_gmic_processing_visitor.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Dmitry Kazakov <dimula73@gmail.com>
+ * Copyright (c) 2013 Lukáš Tvrdý <lukast.dev@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __KIS_IMPORT_GMIC_PROCESSING_VISITOR_H
+#define __KIS_IMPORT_GMIC_PROCESSING_VISITOR_H
+
+#include <processing/kis_simple_processing_visitor.h>
+#include <QList>
+
+#include <QSharedPointer>
+
+#include <gmic.h>
+
+#include <kis_node.h>
+class KisUndoAdapter;
+
+class KisImportGmicProcessingVisitor : public KisSimpleProcessingVisitor
+{
+public:
+ KisImportGmicProcessingVisitor(const QList<KisNodeSP> &nodes,
+ QSharedPointer<gmic_list<float> > images);
+
+protected:
+ void visitNodeWithPaintDevice(KisNode *node, KisUndoAdapter *undoAdapter);
+ void visitExternalLayer(KisExternalLayer *layer, KisUndoAdapter *undoAdapter);
+
+private:
+ QList<KisNodeSP> m_nodes;
+ QSharedPointer<gmic_list<float> > m_images;
+};
+
+#endif /* __KIS_IMPORT_GMIC_PROCESSING_VISITOR_H */
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic