diff options
Diffstat (limited to 'chalk/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp')
-rw-r--r-- | chalk/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp b/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp new file mode 100644 index 000000000..a6b77df76 --- /dev/null +++ b/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp @@ -0,0 +1,188 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * ported from Gimp, Copyright (C) 1997 Eiichi Takamori <taka@ma1.seikyou.ne.jp> + * original pixelize.c for GIMP 0.54 by Tracy Scott + * + * 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 <vector> + +#include <tqpoint.h> +#include <tqspinbox.h> + +#include <tdelocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <tdemessagebox.h> +#include <kstandarddirs.h> +#include <tdetempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <knuminput.h> + +#include <kis_doc.h> +#include <kis_image.h> +#include <kis_iterators_pixel.h> +#include <kis_layer.h> +#include <kis_filter_registry.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_progress_display_interface.h> + +#include "kis_multi_integer_filter_widget.h" +#include "kis_pixelize_filter.h" + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +KisPixelizeFilter::KisPixelizeFilter() : KisFilter(id(), "artistic", i18n("&Pixelize...")) +{ +} + +void KisPixelizeFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) +{ + Q_ASSERT( src ); + Q_ASSERT( dst ); + Q_ASSERT( configuration ); + Q_ASSERT( rect.isValid() ); + + TQ_INT32 x = rect.x(), y = rect.y(); + TQ_INT32 width = rect.width(); + TQ_INT32 height = rect.height(); + + //read the filter configuration values from the KisFilterConfiguration object + TQ_UINT32 pixelWidth = ((KisPixelizeFilterConfiguration*)configuration)->pixelWidth(); + TQ_UINT32 pixelHeight = ((KisPixelizeFilterConfiguration*)configuration)->pixelHeight(); + + pixelize(src, dst, x, y, width, height, pixelWidth, pixelHeight); +} + +void KisPixelizeFilter::pixelize(KisPaintDeviceSP src, KisPaintDeviceSP dst, int startx, int starty, int width, int height, int pixelWidth, int pixelHeight) +{ + Q_ASSERT(src); + Q_ASSERT(dst); + + if (!src) return; + if (!dst) return; + + TQ_INT32 pixelSize = src->pixelSize(); + TQMemArray<TQ_INT32> average( pixelSize ); + + TQ_INT32 count; + + //calculate the total number of pixels + TQ_INT32 numX=0; + TQ_INT32 numY=0; + + for (TQ_INT32 x = startx; x < startx + width; x += pixelWidth - (x % pixelWidth)) + { + numX++; + } + for (TQ_INT32 y = starty; y < starty + height; y += pixelHeight - (y % pixelHeight)) + { + numY++; + } + + setProgressTotalSteps( numX * numY ); + setProgressStage(i18n("Applying pixelize filter..."),0); + + TQ_INT32 numberOfPixelsProcessed = 0; + + for (TQ_INT32 y = starty; y < starty + height; y += pixelHeight - (y % pixelHeight)) + { + TQ_INT32 h = pixelHeight - (y % pixelHeight); + h = MIN(h, starty + height - y); + + for (TQ_INT32 x = startx; x < startx + width; x += pixelWidth - (x % pixelWidth)) + { + TQ_INT32 w = pixelWidth - (x % pixelWidth); + w = MIN(w, startx + width - x); + + for (TQ_INT32 i = 0; i < pixelSize; i++) + { + average[i] = 0; + } + count = 0; + + //read + KisRectIteratorPixel srcIt = src->createRectIterator(x, y, w, h, false); + while( ! srcIt.isDone() ) { + if(srcIt.isSelected()) + { + for (TQ_INT32 i = 0; i < pixelSize; i++) + { + average[i] += srcIt.oldRawData()[i]; + } + count++; + } + ++srcIt; + } + + //average + if (count > 0) + { + for (TQ_INT32 i = 0; i < pixelSize; i++) + average[i] /= count; + } + //write + srcIt = src->createRectIterator(x, y, w, h, false); + KisRectIteratorPixel dstIt = dst->createRectIterator(x, y, w, h, true ); + while( ! srcIt.isDone() ) + { + if(srcIt.isSelected()) + { + for( int i = 0; i < pixelSize; i++) + { + dstIt.rawData()[i] = average[i]; + } + } + ++srcIt; + ++dstIt; + } + numberOfPixelsProcessed++; + setProgress(numberOfPixelsProcessed); + } + } + + setProgressDone(); +} + +KisFilterConfigWidget * KisPixelizeFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) +{ + vKisIntegerWidgetParam param; + param.push_back( KisIntegerWidgetParam( 2, 40, 10, i18n("Pixel width"), "pixelWidth" ) ); + param.push_back( KisIntegerWidgetParam( 2, 40, 10, i18n("Pixel height"), "pixelHeight" ) ); + return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); +} + +KisFilterConfiguration* KisPixelizeFilter::configuration(TQWidget* nwidget) +{ + KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; + if( widget == 0 ) + { + return new KisPixelizeFilterConfiguration( 10, 10); + } else { + return new KisPixelizeFilterConfiguration( widget->valueAt( 0 ), widget->valueAt( 1 ) ); + } +} + +KisFilterConfiguration * KisPixelizeFilter::configuration() +{ + return new KisPixelizeFilterConfiguration(10, 10); +} |