diff options
Diffstat (limited to 'krita/core/kis_convolution_painter.cc')
-rw-r--r-- | krita/core/kis_convolution_painter.cc | 426 |
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; -} |