summaryrefslogtreecommitdiffstats
path: root/krita/core/kis_convolution_painter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'krita/core/kis_convolution_painter.cc')
-rw-r--r--krita/core/kis_convolution_painter.cc426
1 files changed, 0 insertions, 426 deletions
diff --git a/krita/core/kis_convolution_painter.cc b/krita/core/kis_convolution_painter.cc
deleted file mode 100644
index c9146527..00000000
--- a/krita/core/kis_convolution_painter.cc
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- * Copyright (c) 2005 Cyrille Berger <[email protected]>
- *
- * 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 <stdlib.h>
-#include <string.h>
-#include <cfloat>
-
-#include "tqbrush.h"
-#include "tqcolor.h"
-#include "tqfontinfo.h"
-#include "tqfontmetrics.h"
-#include "tqpen.h"
-#include "tqregion.h"
-#include "tqwmatrix.h"
-#include <tqimage.h>
-#include <tqmap.h>
-#include <tqpainter.h>
-#include <tqpixmap.h>
-#include <tqpointarray.h>
-#include <tqrect.h>
-#include <tqstring.h>
-
-#include <kdebug.h>
-#include <klocale.h>
-
-#include <tqcolor.h>
-
-#include "kis_brush.h"
-#include "kis_global.h"
-#include "kis_image.h"
-#include "kis_iterators_pixel.h"
-#include "kis_layer.h"
-#include "kis_paint_device.h"
-#include "kis_painter.h"
-#include "kis_pattern.h"
-#include "kis_rect.h"
-#include "kis_colorspace.h"
-#include "kis_types.h"
-#include "kis_vec.h"
-#include "kis_selection.h"
-#include "kis_convolution_painter.h"
-
-
-KisKernelSP KisKernel::fromTQImage(const TQImage& img)
-{
- KisKernelSP k = new KisKernel;
- k->width = img.width();
- k->height = img.height();
- k->offset = 0;
- uint count = k->width * k->height;
- k->data = new TQ_INT32[count];
- TQ_INT32* itData = k->data;
- TQ_UINT8* itImg = img.bits();
- k->factor = 0;
- for(uint i = 0; i < count; ++i , ++itData, itImg+=4)
- {
- *itData = 255 - ( *itImg + *(itImg+1) + *(itImg+2) ) / 3;
- k->factor += *itData;
- }
- return k;
-}
-
-
-KisConvolutionPainter::KisConvolutionPainter()
- : super()
-{
-}
-
-KisConvolutionPainter::KisConvolutionPainter(KisPaintDeviceSP device) : super(device)
-{
-}
-
-void KisConvolutionPainter::applyMatrix(KisKernelSP kernel, TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h,
- KisConvolutionBorderOp borderOp,
- KisChannelInfo::enumChannelFlags channelFlags )
-{
- // Make the area we cover as small as possible
- if (m_device->hasSelection()) {
-
- TQRect r = m_device->selection()->selectedRect().intersect(TQRect(x, y, w, h));
- x = r.x();
- y = r.y();
- w = r.width();
- h = r.height();
-
- }
-
- if ( w == 0 && h == 0 ) return;
-
- // Determine the kernel's extent from the center pixel
- TQ_INT32 kw, kh, khalfWidth, khalfHeight, xLastMinuskhw, yLastMinuskhh;
- kw = kernel->width;
- kh = kernel->height;
- khalfWidth = (kw - 1) / 2;
- khalfHeight = (kh - 1) / 2;
-
- xLastMinuskhw = x + (w - khalfWidth);
- yLastMinuskhh = y + (h - khalfHeight);
-
- // Don't try to convolve on an area smaller than the kernel, or with a kernel that is not square or has no center pixel.
- if (w < kw || h < kh || (kw&1) == 0 || (kh&1) == 0 || kernel->factor == 0 ) return;
-
- m_cancelRequested = false;
- int lastProgressPercent = 0;
- emit notifyProgress(0);
-
- KisColorSpace * cs = m_device->colorSpace();
-
- // Determine whether we convolve border pixels, or not.
- switch (borderOp) {
- case BORDER_DEFAULT_FILL :
- break;
- case BORDER_REPEAT:
- applyMatrixRepeat(kernel, x, y, w, h, channelFlags);
- return;
- case BORDER_WRAP:
- case BORDER_AVOID:
- default :
- x += khalfWidth;
- y += khalfHeight;
- w -= kw - 1;
- h -= kh - 1;
- }
-
- // Iterate over all pixels in our rect, create a cache of pixels around the current pixel and convolve them in the colorstrategy.
-
- int cacheSize = kw * kh;
- int cdepth = cs -> pixelSize();
- TQ_UINT8** pixelPtrCache = new TQ_UINT8*[cacheSize];
- for (int i = 0; i < cacheSize; i++)
- pixelPtrCache[i] = new TQ_UINT8[cdepth];
-// pixelPtrCache.fill(0);
-
- // row == the y position of the pixel we want to change in the paint device
- int row = y;
-
- for (; row < y + h; ++row) {
-
- // col = the x position of the pixel we want to change
- int col = x;
-
- KisHLineIteratorPixel hit = m_device->createHLineIterator(x, row, w, true);
- bool needFull = true;
- while (!hit.isDone()) {
-
- // Iterate over all contributing pixels that are covered by the kernel
- // krow = the y position in the kernel matrix
- if(needFull)
- {
- TQ_INT32 i = 0;
- for (TQ_INT32 krow = 0; krow < kh; ++krow) {
-
- // col - khalfWidth = the left starting point of the kernel as centered on our pixel
- // krow - khalfHeight = the offset for the top of the kernel as centered on our pixel
- // kw = the width of the kernel
-
- // Fill the cache with pointers to the pixels under the kernel
- KisHLineIteratorPixel kit = m_device->createHLineIterator(col - khalfWidth, (row - khalfHeight) + krow, kw, false);
- while (!kit.isDone()) {
- memcpy(pixelPtrCache[i], kit.oldRawData(), cdepth);
- ++kit;
- ++i;
- }
- }
- needFull = false;
- Q_ASSERT (i==kw*kh);
- } else {
- for (TQ_INT32 krow = 0; krow < kh; ++krow) { // shift the cache to the left
- TQ_UINT8** d = pixelPtrCache + krow * kw;
- //memmove( d, d + 1, (kw-1)*sizeof(TQ_UINT8*));
- for (int i = 0; i < (kw-1); i++) {
- memcpy(d[i], d[i+1], cdepth);
- }
- }
- TQ_INT32 i = kw - 1;
- KisVLineIteratorPixel kit = m_device->createVLineIterator(col + khalfWidth, row - khalfHeight, kh, false);
- while (!kit.isDone()) {
- memcpy(pixelPtrCache[i], kit.oldRawData(), cdepth);
- ++kit;
- i += kw;
- }
- }
- if (hit.isSelected()) {
- cs->convolveColors(pixelPtrCache, kernel->data, channelFlags, hit.rawData(), kernel->factor, kernel->offset, kw * kh);
-// pixelPtrCache.fill(0);
- }
- ++col;
- ++hit;
- }
-
- int progressPercent = 100 - ((((y + h) - row) * 100) / h);
-
- if (progressPercent > lastProgressPercent) {
- emit notifyProgress(progressPercent);
- lastProgressPercent = progressPercent;
-
- if (m_cancelRequested) {
- for (int i = 0; i < cacheSize; i++)
- delete[] pixelPtrCache[i];
- delete[] pixelPtrCache;
-
- return;
- }
- }
-
- }
-
- addDirtyRect(TQRect(x, y, w, h));
-
- emit notifyProgressDone();
-
- for (int i = 0; i < cacheSize; i++)
- delete[] pixelPtrCache[i];
- delete[] pixelPtrCache;
-}
-
-void KisConvolutionPainter::applyMatrixRepeat(KisKernelSP kernel, TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h,
- KisChannelInfo::enumChannelFlags channelFlags)
-{
- int lastProgressPercent = 0;
- // Determine the kernel's extent from the center pixel
- TQ_INT32 kw, kh, khalfWidth, khalfHeight, xLastMinuskhw, yLastMinuskhh;
- kw = kernel->width;
- kh = kernel->height;
- khalfWidth = (kw - 1) / 2;
- khalfHeight = (kh - 1) / 2;
-
- xLastMinuskhw = x + (w - khalfWidth);
- yLastMinuskhh = y + (h - khalfHeight);
-
- KisColorSpace * cs = m_device->colorSpace();
-
- // Iterate over all pixels in our rect, create a cache of pixels around the current pixel and convolve them in the colorstrategy.
-
- int cacheSize = kw * kh;
- int cdepth = cs -> pixelSize();
- TQ_UINT8** pixelPtrCache = new TQ_UINT8*[cacheSize];
- for (int i = 0; i < cacheSize; i++)
- pixelPtrCache[i] = new TQ_UINT8[cdepth];
-
- // row == the y position of the pixel we want to change in the paint device
- int row = y;
-
- for (; row < y + h; ++row) {
-
- // col = the x position of the pixel we want to change
- int col = x;
-
- KisHLineIteratorPixel hit = m_device->createHLineIterator(x, row, w, true);
- bool needFull = true;
-
- TQ_INT32 itStart = row - khalfHeight;
- TQ_INT32 itH = kh;
- if(itStart < 0)
- {
- itH += itStart;
- itStart = 0;
- } else if(itStart + kh > yLastMinuskhh)
- {
- itH -= itStart + kh - yLastMinuskhh;
- }
- KisVLineIteratorPixel kit = m_device->createVLineIterator(col + khalfWidth, itStart, itH, false);
- while (!hit.isDone()) {
-
- // Iterate over all contributing pixels that are covered by the kernel
- // krow = the y position in the kernel matrix
- if(needFull) // The cache has not been fill, so we need to fill it
- {
- TQ_INT32 i = 0;
- TQ_INT32 krow = 0;
- if( row < khalfHeight )
- {
- // We are just outside the layer, all the row in the cache will be identical
- // so we need to create them only once, and then to copy them
- if( x < khalfWidth)
- { // the left pixels are outside of the layer, in the corner
- TQ_INT32 kcol = 0;
- KisHLineIteratorPixel kit = m_device->createHLineIterator(0, 0, kw, false);
- for(; kcol < (khalfWidth - x) + 1; ++kcol)
- { // First copy the address of the topleft pixel
- memcpy(pixelPtrCache[kcol], kit.oldRawData(), cdepth);
- }
- for(; kcol < kw; ++kcol)
- { // Then copy the address of the rest of the line
- ++kit;
- memcpy(pixelPtrCache[kcol], kit.oldRawData(), cdepth);
- }
- } else {
- uint kcol = 0;
- KisHLineIteratorPixel kit = m_device->createHLineIterator(col - khalfWidth, 0, kw, false);
- while (!kit.isDone()) {
- memcpy(pixelPtrCache[kcol], kit.oldRawData(), cdepth);
- ++kit;
- ++kcol;
- }
- }
- krow = 1; // we have allready done the first krow
- for(;krow < (khalfHeight - row); ++krow)
- {
- // Copy the first line in the current line
- for (int i = 0; i < kw; i++)
- memcpy(pixelPtrCache[krow * kw + i], pixelPtrCache[i], cdepth);
- }
- i = krow * kw;
- }
- TQ_INT32 itH = kh;
- if(row + khalfHeight > yLastMinuskhh)
- {
- itH += yLastMinuskhh - row - khalfHeight;
- }
- for (; krow < itH; ++krow) {
-
- // col - khalfWidth = the left starting point of the kernel as centered on our pixel
- // krow - khalfHeight = the offset for the top of the kernel as centered on our pixel
- // kw = the width of the kernel
-
- // Fill the cache with pointers to the pixels under the kernel
- TQ_INT32 itHStart = col - khalfWidth;
- TQ_INT32 itW = kw;
- if(itHStart < 0)
- {
- itW += itHStart;
- itHStart = 0;
- }
- KisHLineIteratorPixel kit = m_device->createHLineIterator(itHStart, (row - khalfHeight) + krow, itW, false);
- if( col < khalfWidth )
- {
- for(; i < krow * kw + ( kw - itW ); i+= 1)
- {
- memcpy(pixelPtrCache[i], kit.oldRawData(), cdepth);
- }
- }
- while (!kit.isDone()) {
- memcpy(pixelPtrCache[i], kit.oldRawData(), cdepth);
- ++kit;
- ++i;
- }
- }
- TQ_INT32 lastvalid = i - kw;
- for(; krow < kh; ++krow) {
- // Copy the last valid line in the current line
- for (int i = 0; i < kw; i++)
- memcpy(pixelPtrCache[krow * kw + i], pixelPtrCache[lastvalid + i],
- cdepth);
- }
- needFull = false;
- } else {
-/* for (TQ_INT32 krow = 0; krow < kh; ++krow) { // shift the cache to the left
- TQ_UINT8** d = pixelPtrCache + krow * kw;
-// memmove( d, d + 1, (kw-1)*sizeof(TQ_UINT8*));
- for (int i = 0; i < (kw-1); i++) {
- memcpy(d[i], d[i+1], cdepth);
- }
- }*/
- TQ_UINT8* firstincache = pixelPtrCache[0];
- memmove(pixelPtrCache, pixelPtrCache + 1, (cacheSize - 1) * sizeof(TQ_UINT8*) );
- pixelPtrCache[cacheSize - 1] = firstincache;
- if(col < xLastMinuskhw)
- {
- TQ_INT32 i = kw - 1;
-// KisVLineIteratorPixel kit = m_device->createVLineIterator(col + khalfWidth, itStart, itH, false);
- kit.nextCol();
- if( row < khalfHeight )
- {
- for(; i < (khalfHeight- row ) * kw; i+=kw)
- {
- memcpy(pixelPtrCache[i], kit.oldRawData(), cdepth);
- }
- }
- while (!kit.isDone()) {
- memcpy(pixelPtrCache[i], kit.oldRawData(), cdepth);
- ++kit;
- i += kw;
- }
- TQ_INT32 lastvalid = i - kw;
- for(;i < kw*kh; i+=kw)
- {
- memcpy(pixelPtrCache[i], pixelPtrCache[lastvalid], cdepth);
- }
- }
- }
- if (hit.isSelected()) {
- cs->convolveColors(pixelPtrCache, kernel->data, channelFlags, hit.rawData(), kernel->factor, kernel->offset, kw * kh);
- }
- ++col;
- ++hit;
- }
-
- int progressPercent = 100 - ((((y + h) - row) * 100) / h);
-
- if (progressPercent > lastProgressPercent) {
- emit notifyProgress(progressPercent);
- lastProgressPercent = progressPercent;
-
- if (m_cancelRequested) {
- for (int i = 0; i < cacheSize; i++)
- delete[] pixelPtrCache[i];
- delete[] pixelPtrCache;
- return;
- }
- }
-
- }
-
- addDirtyRect(TQRect(x, y, w, h));
-
- emit notifyProgressDone();
- for (int i = 0; i < cacheSize; i++)
- delete[] pixelPtrCache[i];
- delete[] pixelPtrCache;
-}