Commit d427cade authored by Edward Apap's avatar Edward Apap

* Added a preliminarily version of FFT based convolution (requires the

  FFTW3 library)
* Added an abstract class KisConvolutionWorker
* Spatial and FFT based convolution now inherit from the worker base
* Both workers perform convolution outside the colorspace classes to
  ensure that the code is only in a single place and works correctly under
  all circumstances
* Convolution offset is now a relative value [0..1]
* Channel flags are now adhered to

svn path=/trunk/koffice/; revision=1088315
parent c817e497
......@@ -13,16 +13,16 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-tiles.h.cmake ${CMAKE_CURRENT_
if(USE_TILESYSTEM EQUAL 1)
set(libkritatile_SRCS
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tiled_random_accessor.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tiledvlineiterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tiledhlineiterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tileddatamanager.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tile.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tilediterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tiledrectiterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_memento.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tilemanager.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tile_compressor.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tiled_random_accessor.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tiledvlineiterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tiledhlineiterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tileddatamanager.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tile.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tilediterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tiledrectiterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_memento.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tilemanager.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles/kis_tile_compressor.cc
)
add_subdirectory( tiles )
elseif(USE_TILESYSTEM EQUAL 3)
......@@ -31,13 +31,13 @@ set(libkritatile_SRCS
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tile_data.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tile_data_store.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tile_data_pooler.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiled_data_manager.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_memento_manager.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tilediterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiledrectiterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiledvlineiterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiledhlineiterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiled_random_accessor.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiled_data_manager.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_memento_manager.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tilediterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiledrectiterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiledvlineiterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiledhlineiterator.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiled_random_accessor.cc
)
add_subdirectory( tiles3 )
endif(USE_TILESYSTEM EQUAL 1)
......@@ -46,6 +46,11 @@ option(HAVE_MEMORY_LEAK_TRACKER "Enable memory leak tracker (always disabled in
option(HAVE_BACKTRACE_SUPPORT "Enable recording of backtrace in memory leak tracker" OFF)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-memory-leak-tracker.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-memory-leak-tracker.h) ### WRONG PLACE???
macro_optional_find_package(FFTW3)
macro_log_feature(FFTW3_FOUND "FFTW3" "A fast, free C FFT library" "http://www.fftw.org/" FALSE "" "Required by the Krita for fast convolution operators")
macro_bool_to_01(FFTW3_FOUND HAVE_FFTW3)
configure_file(config_convolution.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config_convolution.h)
include_directories( ${KDE4_INCLUDE_DIR}/threadweaver/
${CMAKE_SOURCE_DIR}/krita/image/metadata
${KOMAIN_INCLUDES}
......@@ -198,6 +203,10 @@ if(OPENEXR_FOUND)
target_link_libraries(kritaimage ${OPENEXR_LIBRARIES})
endif(OPENEXR_FOUND)
if(FFTW3_FOUND)
target_link_libraries(kritaimage ${FFTW3_LIBRARIES})
endif(FFTW3_FOUND)
set_target_properties(kritaimage PROPERTIES
VERSION ${GENERIC_KOFFICE_LIB_VERSION} SOVERSION ${GENERIC_KOFFICE_LIB_SOVERSION}
......@@ -223,6 +232,7 @@ install( FILES
kis_config_widget.h
kis_convolution_kernel.h
kis_convolution_painter.h
kis_convolution_worker.h
kis_debug.h
kis_filter_strategy.h
kis_generic_colorspace.h
......
/* Defines if your system has the FFTW3 library */
#cmakedefine HAVE_FFTW3 1
......@@ -56,7 +56,14 @@
#include "kis_selection.h"
#include "kis_convolution_painter_impl.h"
#include "kis_convolution_worker.h"
#include "kis_convolution_worker_spatial.h"
#include "config_convolution.h"
#ifdef HAVE_FFTW3
#include "kis_convolution_worker_fft.h"
#endif
KisConvolutionPainter::KisConvolutionPainter()
......@@ -93,13 +100,29 @@ void KisConvolutionPainter::applyMatrix(const KisConvolutionKernelSP kernel, con
* o check other cases of the switch for the vulnerability
*/
if(dataRect.isValid())
applyMatrixImpl<RepeatIteratorFactory>(kernel, src, srcPos, dstPos, areaSize, dataRect);
if(dataRect.isValid()) {
KisConvolutionWorker<RepeatIteratorFactory> *worker;
#ifdef HAVE_FFTW3
worker = new KisConvolutionWorkerFFT<RepeatIteratorFactory>(this, progressUpdater());
#else
worker = new KisConvolutionWorkerSpatial<RepeatIteratorFactory>(this, progressUpdater());
#endif
worker->execute(kernel, src, srcPos, dstPos, areaSize, dataRect);
delete worker;
}
break;
}
return;
case BORDER_DEFAULT_FILL : {
applyMatrixImpl<StandardIteratorFactory>(kernel, src, srcPos, dstPos, areaSize, QRect());
return;
KisConvolutionWorker<StandardIteratorFactory> *worker;
#ifdef HAVE_FFTW3
worker = new KisConvolutionWorkerFFT<StandardIteratorFactory>(this, progressUpdater());
#else
worker = new KisConvolutionWorkerSpatial<StandardIteratorFactory>(this, progressUpdater());
#endif
worker->execute(kernel, src, srcPos, dstPos, areaSize, QRect());
delete worker;
break;
}
case BORDER_WRAP: {
qFatal("Not implemented");
......@@ -113,7 +136,15 @@ void KisConvolutionPainter::applyMatrix(const KisConvolutionKernelSP kernel, con
srcPos += tr;
dstPos += tr;
areaSize -= QSize(kw - 1, kh - 1);
applyMatrixImpl<StandardIteratorFactory>(kernel, src, srcPos, dstPos, areaSize, QRect());
KisConvolutionWorker<StandardIteratorFactory> *worker;
#ifdef HAVE_FFTW3
worker = new KisConvolutionWorkerFFT<StandardIteratorFactory>(this, progressUpdater());
#else
worker = new KisConvolutionWorkerSpatial<StandardIteratorFactory>(this, progressUpdater());
#endif
worker->execute(kernel, src, srcPos, dstPos, areaSize, QRect());
delete worker;
}
}
}
......@@ -63,20 +63,5 @@ public:
*/
void applyMatrix(const KisConvolutionKernelSP kernel, const KisPaintDeviceSP src, QPoint srcPos, QPoint dstPos, QSize areaSize,
KisConvolutionBorderOp borderOp = BORDER_AVOID);
private:
/**
* This function is called by applyMatrix when borderOp == BORDER_REPEAT
*/
template< class _IteratorFactory_>
void applyMatrixImpl(const KisConvolutionKernelSP kernel, const KisPaintDeviceSP src, QPoint srcPos, QPoint dstPos, QSize areaSize, const QRect& _dataRect);
template< class _IteratorFactory_>
inline void moveKernelRight(const KisPaintDeviceSP, const QRect&, quint8 **, quint32, quint32);
template< class _IteratorFactory_>
inline void moveKernelDown(const KisPaintDeviceSP, const QRect&, quint8 **, quint32, quint32);
void cleanUp(quint8**, quint8**);
quint32 m_kw, m_kh, m_khalfWidth, m_khalfHeight, m_cacheSize, m_cdepth;
};
#endif //KIS_CONVOLUTION_PAINTER_H_
This diff is collapsed.
/*
* Copyright (c) 2005, 2008 Cyrille Berger <cberger@cberger.net>
* Copyright (c) 2010 Edward Apap <schumifer@hotmail.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_CONVOLUTION_WORKER_H
#define KIS_CONVOLUTION_WORKER_H
#include <KoUpdater.h>
#include "kis_repeat_iterators_pixel.h"
#include "kis_painter.h"
struct StandardIteratorFactory {
typedef KisHLineIteratorPixel HLineIterator;
typedef KisVLineIteratorPixel VLineIterator;
typedef KisHLineConstIteratorPixel HLineConstIterator;
typedef KisVLineConstIteratorPixel VLineConstIterator;
inline static KisHLineIteratorPixel createHLineIterator(KisPaintDeviceSP src, qint32 x, qint32 y, qint32 w, const QRect&) {
return src->createHLineIterator(x, y, w);
}
inline static KisVLineIteratorPixel createVLineIterator(KisPaintDeviceSP src, qint32 x, qint32 y, qint32 h, const QRect&) {
return src->createVLineIterator(x, y, h);
}
inline static KisHLineConstIteratorPixel createHLineConstIterator(KisPaintDeviceSP src, qint32 x, qint32 y, qint32 w, const QRect&) {
return src->createHLineConstIterator(x, y, w);
}
inline static KisVLineConstIteratorPixel createVLineConstIterator(KisPaintDeviceSP src, qint32 x, qint32 y, qint32 h, const QRect&) {
return src->createVLineConstIterator(x, y, h);
}
};
struct RepeatIteratorFactory {
typedef KisHLineIteratorPixel HLineIterator;
typedef KisVLineIteratorPixel VLineIterator;
typedef KisRepeatHLineConstIteratorPixel HLineConstIterator;
typedef KisRepeatVLineConstIteratorPixel VLineConstIterator;
inline static KisHLineIteratorPixel createHLineIterator(KisPaintDeviceSP src, qint32 x, qint32 y, qint32 w, const QRect&) {
return src->createHLineIterator(x, y, w);
}
inline static KisVLineIteratorPixel createVLineIterator(KisPaintDeviceSP src, qint32 x, qint32 y, qint32 h, const QRect&) {
return src->createVLineIterator(x, y, h);
}
inline static KisRepeatHLineConstIteratorPixel createHLineConstIterator(KisPaintDeviceSP src, qint32 x, qint32 y, qint32 w, const QRect& _dataRect) {
return src->createRepeatHLineConstIterator(x, y, w, _dataRect);
}
inline static KisRepeatVLineConstIteratorPixel createVLineConstIterator(KisPaintDeviceSP src, qint32 x, qint32 y, qint32 h, const QRect& _dataRect) {
return src->createRepeatVLineConstIterator(x, y, h, _dataRect);
}
};
template <class _IteratorFactory_>
class KisConvolutionWorker
{
public:
KisConvolutionWorker(KisPainter *painter, KoUpdater *progress)
{
m_painter = painter;
m_progress = progress;
}
virtual ~KisConvolutionWorker()
{
}
virtual void execute(const KisConvolutionKernelSP kernel, const KisPaintDeviceSP src, QPoint srcPos, QPoint dstPos, QSize areaSize, const QRect& dataRect) = 0;
protected:
QList<KoChannelInfo *> convolvableChannelList(const KisPaintDeviceSP src)
{
QBitArray painterChannelFlags = m_painter->channelFlags();
QList<KoChannelInfo *> channelInfo = src->colorSpace()->channels();
QList<KoChannelInfo *> convChannelList;
for (qint32 c = 0; c < channelInfo.count(); ++c) {
if (painterChannelFlags.testBit(channelInfo[c]->channelType())) {
convChannelList.append(channelInfo[c]);
}
}
return convChannelList;
}
protected:
KisPainter* m_painter;
KoUpdater* m_progress;
};
#endif
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment