Commit 8386879b authored by Cyrille Berger's avatar Cyrille Berger

add a const paint device, usefull for filters

svn path=/trunk/koffice/; revision=664008
parent 70ec9683
include_directories(${KOKROSS_INCLUDES})
set(krossmodulekrita_LIB_SRCS
krs_brush.cpp
krs_color.cpp
krs_const_paint_device.cpp
krs_filter.cpp
krs_histogram.cpp
krs_image.cpp
krs_module.cpp
krs_progress.cpp
krs_paint_layer.cpp
krs_paint_device.cpp
krs_image.cpp
krs_histogram.cpp
krs_painter.cpp
krs_color.cpp
krs_brush.cpp
krs_paint_layer.cpp
krs_pattern.cpp
krs_filter.cpp
krs_painter.cpp
krs_progress.cpp
krs_wavelet.cpp
)
kde4_automoc(${krossmodulekrita_LIB_SRCS})
qt4_wrap_cpp(krossmodulekrita_LIB_SRCS krs_iterator.h)
qt4_wrap_cpp(krossmodulekrita_LIB_SRCS krs_iterator.h krs_const_iterator.h)
kde4_add_library(krossmodulekrita SHARED ${krossmodulekrita_LIB_SRCS})
##add_definitions(${KDE4_ENABLE_EXCEPTIONS})
target_link_libraries(krossmodulekrita kokross kritaui)
......
/*
* Copyright (c) 2005 Cyrille Berger <cberger@cberger.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library 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 Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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 KROSS_KRITACOREKRS_ITERATOR_H
#define KROSS_KRITACOREKRS_ITERATOR_H
#include <QObject>
#include <QList>
#include <QListIterator>
#include <klocale.h>
#include <KoColorTransformation.h>
#include "krs_paint_device.h"
#include <kis_paint_device.h>
#include <kis_types.h>
//#include "../scriptingmonitor.h"
namespace Scripting {
/**
* This object allow to read the value of pixel one by one.
*/
class ConstIteratorBase : public QObject
{
Q_OBJECT
public:
ConstIteratorBase(QObject* parent) : QObject(parent) {
setObjectName("KritaIterator");
// Connect the Monitor to know when the invalidating of iterator is needed
//connect(ScriptingMonitor::instance(), SIGNAL(executionFinished(const Kross::Api::ScriptAction* )), this, SLOT(invalidate()));
}
virtual ~ConstIteratorBase() {}
public slots:
/**
* Increment the position, and go to the next pixel. The
* returned value is true if the iterator reached the
* end (so, it's like calling next() and after that asking
* what isDone() returns).
*/
virtual bool next() = 0;
/**
* Return true if the iterator is at the end, what means, that
* there are no more pixels available.
*/
virtual bool isDone() = 0;
/**
* Return the current column the iterator is on. The value will
* be always smaller then the width of the image/layer.
*/
virtual int x() = 0;
/**
* Return the current row the iterator is on. The value will
* be always smaller then the height of the image/layer.
*/
virtual int y() = 0;
/**
* Return the value the current pixel has in the channel
* number \p channelnr . If the channelnr is out of range
* (as in >= what \p channelCount() returns) a invalid
* QVariant is returned.
*/
virtual QVariant channel(uint channelnr) = 0;
/**
* Return the number of channels the current pixmap has. As
* example for RGBA-images 4 is returned cause R is one channel,
* while G, B and A are other channels what makes 4 total.
*/
virtual uint channelCount() = 0;
/**
* Return the current pixel. The pixel itself may have depending
* on the used colorspace n colors where each color has it's own
* channel. So, as example if the colorspace is RGBA, the returned
* list has exact 4 items. The first one is a value 0-255 for the
* color red, the second for green and the theird for blue while
* the forth is the alpha-channel.
*/
virtual QVariantList pixel() = 0;
private slots:
virtual void invalidateIterator() = 0;
};
/**
* \internal template class that implements \a IteratorBase to provide
* iterators for walking over the pixels of an image or a layer.
*/
template<class _T_It>
class ConstIterator : public ConstIteratorBase
{
public:
ConstIterator(ConstPaintDevice* layer, _T_It it)
: ConstIteratorBase(layer)
, m_it(new _T_It(it))
, m_layer(layer->paintDevice())
{
}
virtual ~ConstIterator()
{
invalidateIterator();
}
private:
bool isDone()
{
return m_it->isDone();
}
bool next()
{
++(*m_it);
return m_it->isDone();
}
int x()
{
return m_it->x();
}
int y()
{
return m_it->y();
}
QVariant channel(uint channelnr)
{
QList<KoChannelInfo*> channels = m_layer->colorSpace()->channels();
return channelnr < uint(channels.count()) ? channelValue(channels[channelnr]) : QVariant();
}
uint channelCount()
{
return m_layer->colorSpace()->channels().count();
}
QVariantList pixel()
{
QVariantList pixel;
QList<KoChannelInfo*> channels = m_layer->colorSpace()->channels();
for(QList<KoChannelInfo*>::iterator itC = channels.begin(); itC != channels.end(); ++itC)
pixel.push_back( channelValue(*itC) );
return pixel;
}
private:
virtual void invalidateIterator()
{
delete m_it; m_it = 0;
}
inline QVariant channelValue(KoChannelInfo* ci)
{
quint8* data = (quint8*)(m_it->rawData() + ci->pos());
switch(ci->channelValueType()) {
case KoChannelInfo::UINT8:
return *data;
case KoChannelInfo::UINT16:
return *((quint16*) data);
case KoChannelInfo::FLOAT32:
return *((float*) data);
default:
kDebug(41011) << "Unsupported data format in script" << endl;
return QVariant();
}
}
private:
_T_It* m_it;
const KisPaintDeviceSP m_layer;
};
}
#endif
/*
* Copyright (c) 2005,2007 Cyrille Berger <cberger@cberger.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library 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 Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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 "krs_const_paint_device.h"
#include <QBuffer>
#include <klocale.h>
#include <KoColorSpaceRegistry.h>
#include <kis_doc2.h>
#include <kis_layer.h>
#include <kis_meta_registry.h>
#include <kis_iterators_pixel.h>
#include <kis_transaction.h>
#include <kis_math_toolbox.h>
#include "krs_image.h"
#include "krs_const_iterator.h"
#include "krs_histogram.h"
#include "krs_painter.h"
#include "krs_wavelet.h"
using namespace Scripting;
ConstPaintDevice::ConstPaintDevice(Image* image, KisPaintDeviceSP device, KisDoc2* doc)
: QObject(image)
, m_device(device)
, m_doc(doc)
{
setObjectName("KritaLayer");
}
ConstPaintDevice::~ConstPaintDevice()
{
}
int ConstPaintDevice::width()
{
QRect r1 = paintDevice()->extent();
QRect r2 = paintDevice()->image()->bounds();
QRect rect = r1.intersect(r2);
return rect.width();
}
int ConstPaintDevice::height()
{
QRect r1 = paintDevice()->extent();
QRect r2 = paintDevice()->image()->bounds();
QRect rect = r1.intersect(r2);
return rect.height();
}
QString ConstPaintDevice::colorSpaceId()
{
return paintDevice()->colorSpace()->id();
}
QObject* ConstPaintDevice::createRectConstIterator(uint x, uint y, uint width, uint height)
{
return new ConstIterator<KisRectConstIteratorPixel>(this,
paintDevice()->createRectConstIterator(x, y, width, height));
}
QObject* ConstPaintDevice::createHLineConstIterator(uint x, uint y, uint width)
{
return new ConstIterator<KisHLineConstIteratorPixel>(this,
paintDevice()->createHLineConstIterator(x, y, width));
}
QObject* ConstPaintDevice::createVLineConstIterator(uint x, uint y, uint height)
{
return new ConstIterator<KisVLineConstIteratorPixel>(this,
paintDevice()->createVLineConstIterator(x, y, height));
}
QObject* ConstPaintDevice::createHistogram(const QString& histoname, uint typenr)
{
KoHistogramProducerFactory* factory = KoHistogramProducerFactoryRegistry::instance()->value(histoname);
/*
QList<KoID> listID = KisHistogramProducerFactoryRegistry::instance()->listKeys();
for(QList<KoID>::iterator it = listID.begin(); it != listID.end(); it++)
kDebug(41011) << (*it).name() << " " << (*it).id() << endl;
*/
enumHistogramType type ;
switch(typenr)
{
case 1:
type = LOGARITHMIC;
break;
case 0:
default:
type = LINEAR;
break;
}
if(factory && factory->isCompatibleWith( paintDevice()->colorSpace() ))
return new Histogram(this, factory->generate() , type);
kWarning() << QString("An error has occurred in %1\n%2").arg("createHistogram").arg( QString("The histogram %1 is not available").arg(histoname) );
return 0;
}
QObject* ConstPaintDevice::fastWaveletTransformation()
{
KisMathToolbox* mathToolbox = KisMetaRegistry::instance()->mtRegistry()->value( paintDevice()->colorSpace()->mathToolboxId().id() );
QRect rect = paintDevice()->exactBounds();
KisMathToolbox::KisWavelet* wav = mathToolbox->fastWaveletTransformation(paintDevice(), rect);
return new Wavelet(wav);
}
QObject* ConstPaintDevice::clone()
{
KisPaintDeviceSP pl = new KisPaintDevice(*paintDevice());
return new ConstPaintDevice(0, pl);
}
#if 0
QByteArray ConstPaintDevice::bytes()
{
qint32 pixelsize = paintDevice()->colorSpace()->pixelSize();
const int w = width();
const int h = height();
const int size = w * h * pixelsize;
Q_ASSERT(size >= 0);
QByteArray bytearray;
QBuffer buffer(&bytearray);
buffer.open(QIODevice::WriteOnly);
QDataStream out(&buffer);
quint8* data = new quint8[size];
Q_CHECK_PTR(data);
paintDevice()->readBytes(data, 0, 0, w, h);
for(int i = 0; i < size; ++i)
out << data[i];
delete [] data;
// kDebug()<<"ConstPaintDevice::bytes width="<<w<<" height="<<h<<" pixelsize="<<pixelsize<<" size="<<size<<endl;
return bytearray;
}
bool ConstPaintDevice::setBytes(const QByteArray& bytearray)
{
qint32 pixelsize = paintDevice()->colorSpace()->pixelSize();
const int w = width();
const int h = height();
const int size = w * h * pixelsize;
if(size < 0 || bytearray.size() < size)
return false;
QBuffer buffer(&bytearray);
buffer.open(QIODevice::ReadOnly);
QDataStream in(&buffer);
quint8* data = new quint8[size];
Q_CHECK_PTR(data);
for(int i = 0; i < size; ++i)
in >> data[i];
paintDevice()->writeBytes(data, 0, 0, w, h);
delete [] data;
return true;
}
#endif
#include "krs_const_paint_device.moc"
/*
* Copyright (c) 2005,2007 Cyrille Berger <cberger@cberger.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library 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 Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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 KROSS_KRITACOREKRSCONSTPAINTDEVICE_H
#define KROSS_KRITACOREKRSCONSTPAINTDEVICE_H
#include <QObject>
#include <kis_types.h>
#include <kis_paint_layer.h>
class KisDoc2;
class KisTransaction;
namespace Scripting {
class Image;
/**
* A PaintDevice is a layer within a \a Image where you are able
* to perform paint-operations on.
*/
class ConstPaintDevice : public QObject
{
Q_OBJECT
public:
explicit ConstPaintDevice(Image* image, const KisPaintDeviceSP layer, KisDoc2* doc = 0);
virtual ~ConstPaintDevice();
public slots:
/**
* Return the width of the layer.
*/
int width();
/**
* Return the height of the layer.
*/
int height();
/**
* Return the id of the colorspace of this image (e.g. "RGBA" or "CMYK").
*/
QString colorSpaceId();
/**
* Create an iterator over a layer, it will iterate on a rectangle area.
* This function takes four arguments :
* - x
* - y
* - width of the rectangle
* - height of the rectangle
*/
QObject* createRectConstIterator(uint x, uint y, uint width, uint height);
/**
* Create an iterator over a layer, it will iterate on a row.
* This function takes three arguments :
* - x start in the row
* - y vertical position of the row
* - width of the row
*/
QObject* createHLineConstIterator(uint x, uint y, uint width);
/**
* Create an iterator over a layer, it will iterate on a column.
* This function takes three arguments :
* - x horizontal position of the column
* - y start in the column
* - height of the column
*/
QObject* createVLineConstIterator(uint x, uint y, uint height);
/**
* This function creates an Histogram for this layer.
* It takes two arguments :
* - the type of the histogram ("RGB8HISTO")
* - 0 if the histogram is linear, or 1 if it is logarithmic
*/
QObject* createHistogram(const QString& histoname, uint typenr);
/**
* Return the fast \a Wavelet transformed of the layer.
*/
QObject* fastWaveletTransformation();
/**
* clone this paint layer, making a deep copy.
*/
QObject* clone();
public:
inline const KisPaintDeviceSP paintDevice() const { return m_device; }
inline KisDoc2* doc() { return m_doc; }
private:
const KisPaintDeviceSP m_device;
KisDoc2* m_doc;
};
}
#endif
......@@ -17,13 +17,13 @@
*/
#include "krs_histogram.h"
#include "krs_paint_device.h"
#include "krs_const_paint_device.h"
#include <kis_paint_layer.h>
using namespace Scripting;
Histogram::Histogram(PaintDevice* layer, KoHistogramProducerSP producer, const enumHistogramType type)
Histogram::Histogram(ConstPaintDevice* layer, KoHistogramProducerSP producer, const enumHistogramType type)
: QObject(layer)
{
setObjectName("KritaHistogram");
......
......@@ -26,7 +26,7 @@
namespace Scripting {
class PaintDevice;
class ConstPaintDevice;
/**
* This class allow to access the histogram of a \a PaintDevice object.
......@@ -48,7 +48,7 @@ class Histogram : public QObject
{
Q_OBJECT
public:
Histogram(PaintDevice* layer, KoHistogramProducerSP producer, const enumHistogramType type);
Histogram(ConstPaintDevice* layer, KoHistogramProducerSP producer, const enumHistogramType type);
~Histogram();
public slots:
......
......@@ -39,9 +39,8 @@
using namespace Scripting;
PaintDevice::PaintDevice(Image* image, KisPaintDeviceSP device, KisDoc2* doc)
: QObject(image)
: ConstPaintDevice(image, device, doc)
, m_device(device)
, m_doc(doc)
, m_cmd(0)
{
setObjectName("KritaLayer");
......@@ -52,27 +51,6 @@ PaintDevice::~PaintDevice()
{
}
int PaintDevice::width()
{
QRect r1 = paintDevice()->extent();
QRect r2 = paintDevice()->image()->bounds();
QRect rect = r1.intersect(r2);
return rect.width();
}
int PaintDevice::height()
{
QRect r1 = paintDevice()->extent();
QRect r2 = paintDevice()->image()->bounds();
QRect rect = r1.intersect(r2);
return rect.height();
}
QString PaintDevice::colorSpaceId()
{
return paintDevice()->colorSpace()->id();
}
bool PaintDevice::convertToColorspace(const QString& colorspacename)
{
KoColorSpace * dstCS = KoColorSpaceRegistry::instance()->colorSpace(colorspacename, 0);
......@@ -103,35 +81,6 @@ QObject* PaintDevice::createVLineIterator(uint x, uint y, uint height)
paintDevice()->createVLineIterator(x, y, height));
}
QObject* PaintDevice::createHistogram(const QString& histoname, uint typenr)
{
KoHistogramProducerFactory* factory = KoHistogramProducerFactoryRegistry::instance()->value(histoname);
/*
QList<KoID> listID = KisHistogramProducerFactoryRegistry::instance()->listKeys();
for(QList<KoID>::iterator it = listID.begin(); it != listID.end(); it++)
kDebug(41011) << (*it).name() << " " << (*it).id() << endl;
*/
enumHistogramType type ;
switch(typenr)
{
case 1:
type = LOGARITHMIC;
break;
case 0:
default:
type = LINEAR;
break;
}
if(factory && factory->isCompatibleWith( paintDevice()->colorSpace() ))
return new Histogram(this, factory->generate() , type);
kWarning() << QString("An error has occurred in %1\n%2").arg("createHistogram").arg( QString("The histogram %1 is not available").arg(histoname) );
return 0;
}
QObject* PaintDevice::createPainter()
{
return new Painter(this);
......@@ -160,14 +109,6 @@ void PaintDevice::endPainting()
}
}
QObject* PaintDevice::fastWaveletTransformation()
{
KisMathToolbox* mathToolbox = KisMetaRegistry::instance()->mtRegistry()->value( paintDevice()->colorSpace()->mathToolboxId().id() );
QRect rect = paintDevice()->exactBounds();
KisMathToolbox::KisWavelet* wav = mathToolbox->fastWaveletTransformation(paintDevice(), rect);
return new Wavelet(wav);
}