[krita] /: Refactor KisSequentialIterator to use java-style iteration

Dmitry Kazakov null at kde.org
Thu Jan 4 17:20:42 UTC 2018


Git commit f352cc1d4367542ad55d61636927e90c56e92b7d by Dmitry Kazakov.
Committed on 04/01/2018 at 17:20.
Pushed by dkazakov into branch 'master'.

Refactor KisSequentialIterator to use java-style iteration

This patch touches quite a lot of stuff throughout the entire Krita,
please report any crashes you get because of that!

Technical details:

The sequential iterator (alongside the hline and vline) iterators had
an inherent problem: when called with an empty rect it just crashed
with SIGSEGV (hlive and vline iterators just have a hack to read/write
at least one pixel when called with an empty rect). This problem happens
because of the structure of API we use: we call nextPixel() **after** the
first cycle of iteration, that is we will read/write at least one pixel
even when the requested rect is empty(!).

Now the iterator inserts one "virtual" pixel before every iteration that
allows the user to call nextPixel() **before** the the first iteration
and stop the cycle in case the check fails.

See example code snippets in kis_sequential_iterator.h

CC:kimageshop at kde.org
BUG:388272

M  +2    -2    benchmarks/kis_bcontrast_benchmark.cpp
M  +2    -2    benchmarks/kis_blur_benchmark.cpp
M  +2    -2    benchmarks/kis_level_filter_benchmark.cpp
M  +2    -2    libs/global/kis_acs_pixel_cache_renderer.h
M  +4    -4    libs/image/filter/kis_color_transformation_filter.cc
M  +6    -6    libs/image/kis_edge_detection_kernel.cpp
M  +2    -2    libs/image/kis_gradient_painter.cc
M  +2    -2    libs/image/kis_grid_interpolation_tools.h
M  +7    -5    libs/image/kis_histogram.cc
M  +4    -4    libs/image/kis_marker_painter.cpp
M  +6    -5    libs/image/kis_paint_device.cc
M  +8    -6    libs/image/kis_paint_device_data.h
M  +6    -6    libs/image/kis_painter.cc
M  +6    -6    libs/image/kis_pixel_selection.cpp
M  +65   -12   libs/image/kis_sequential_iterator.h
M  +4    -4    libs/image/krita_utils.cpp
M  +6    -6    libs/image/layerstyles/kis_layer_style_filter_environment.cpp
M  +4    -4    libs/image/layerstyles/kis_ls_bevel_emboss_filter.cpp
M  +4    -6    libs/image/layerstyles/kis_ls_satin_filter.cpp
M  +22   -22   libs/image/layerstyles/kis_ls_utils.cpp
M  +26   -24   libs/image/lazybrush/KisWatershedWorker.cpp
M  +6    -6    libs/image/lazybrush/kis_lazy_fill_tools.cpp
M  +2    -2    libs/image/lazybrush/kis_multiway_cut.cpp
M  +14   -14   libs/image/tests/kis_iterator_benchmark.cpp
M  +53   -8    libs/image/tests/kis_iterators_ng_test.cpp
M  +2    -2    libs/image/tests/kis_lazy_brush_test.cpp
M  +2    -2    libs/image/tests/kis_paint_device_test.cpp
M  +2    -2    libs/image/tests/kis_paint_layer_test.cpp
M  +4    -4    libs/image/tests/kis_painter_test.cpp
M  +2    -2    libs/image/tests/kis_projection_test.cpp
M  +18   -18   libs/libkis/Channel.cpp
M  +2    -2    libs/ui/canvas/kis_display_color_converter.cpp
M  +2    -2    libs/ui/flake/kis_shape_selection.cpp
M  +4    -4    libs/ui/kis_node_manager.cpp
M  +2    -2    libs/ui/kis_png_converter.cpp
M  +2    -2    libs/ui/tool/kis_tool_utils.cpp
M  +1    -1    plugins/dockers/channeldocker/channelmodel.cpp
M  +8    -6    plugins/dockers/histogram/histogramdockerwidget.cpp
M  +2    -2    plugins/filters/colors/kis_color_to_alpha.cpp
M  +4    -4    plugins/filters/colors/kis_minmax_filters.cpp
M  +6    -4    plugins/filters/colorsfilters/colorsfilters.cpp
M  +2    -2    plugins/filters/embossfilter/kis_emboss_filter.cpp
M  +2    -2    plugins/filters/fastcolortransfer/fastcolortransfer.cpp
M  +2    -2    plugins/filters/fastcolortransfer/kis_wdg_fastcolortransfer.cpp
M  +2    -2    plugins/filters/gradientmap/krita_filter_gradient_map.cpp
M  +2    -2    plugins/filters/noisefilter/noisefilter.cpp
M  +2    -2    plugins/filters/oilpaintfilter/kis_oilpaint_filter.cpp
M  +4    -4    plugins/filters/pixelizefilter/kis_pixelize_filter.cpp
M  +2    -2    plugins/filters/randompickfilter/randompickfilter.cpp
M  +2    -2    plugins/filters/threshold/threshold.cpp
M  +2    -2    plugins/filters/wavefilter/wavefilter.cpp
M  +2    -2    plugins/impex/csv/csv_saver.cpp
M  +2    -2    plugins/impex/heightmap/kis_heightmap_export.cpp
M  +2    -2    plugins/impex/psd/psd_pixel_utils.cpp
M  +2    -2    plugins/paintops/defaultpaintops/duplicate/kis_duplicateop.cpp
M  +2    -3    plugins/paintops/libpaintop/kis_bidirectional_mixing_option.cpp

https://commits.kde.org/krita/f352cc1d4367542ad55d61636927e90c56e92b7d

diff --git a/benchmarks/kis_bcontrast_benchmark.cpp b/benchmarks/kis_bcontrast_benchmark.cpp
index bc5e8d04fda..889855f4de2 100644
--- a/benchmarks/kis_bcontrast_benchmark.cpp
+++ b/benchmarks/kis_bcontrast_benchmark.cpp
@@ -49,14 +49,14 @@ void KisBContrastBenchmark::initTestCase()
     int r,g,b;
 
     KisSequentialIterator it(m_device, QRect(0, 0, GMP_IMAGE_WIDTH, GMP_IMAGE_HEIGHT));
-    do {
+    while (it.nextPixel()) {
         r = rand() % 255;
         g = rand() % 255;
         b = rand() % 255;
 
         m_color.fromQColor(QColor(r,g,b));
         memcpy(it.rawData(), m_color.data(), m_colorSpace->pixelSize());
-    } while (it.nextPixel());
+    }
 
 }
 
diff --git a/benchmarks/kis_blur_benchmark.cpp b/benchmarks/kis_blur_benchmark.cpp
index 7c7057aaebf..70fe441b521 100644
--- a/benchmarks/kis_blur_benchmark.cpp
+++ b/benchmarks/kis_blur_benchmark.cpp
@@ -49,14 +49,14 @@ void KisBlurBenchmark::initTestCase()
     int r,g,b;
     
     KisSequentialIterator it(m_device, QRect(0,0,GMP_IMAGE_WIDTH, GMP_IMAGE_HEIGHT));
-    do {
+    while (it.nextPixel()) {
         r = rand() % 255;
         g = rand() % 255;
         b = rand() % 255;
         
         m_color.fromQColor(QColor(r,g,b));
         memcpy(it.rawData(), m_color.data(), m_colorSpace->pixelSize());
-    } while (it.nextPixel());
+    }
 }
 
 void KisBlurBenchmark::cleanupTestCase()
diff --git a/benchmarks/kis_level_filter_benchmark.cpp b/benchmarks/kis_level_filter_benchmark.cpp
index 6a9538b8ef5..63a35a10a35 100644
--- a/benchmarks/kis_level_filter_benchmark.cpp
+++ b/benchmarks/kis_level_filter_benchmark.cpp
@@ -50,14 +50,14 @@ void KisLevelFilterBenchmark::initTestCase()
     int r,g,b;
 
     KisSequentialIterator it(m_device, QRect(0,0,GMP_IMAGE_WIDTH, GMP_IMAGE_HEIGHT));
-    do {
+    while (it.nextPixel()) {
         r = rand() % 255;
         g = rand() % 255;
         b = rand() % 255;
 
         m_color.fromQColor(QColor(r,g,b));
         memcpy(it.rawData(), m_color.data(), m_colorSpace->pixelSize());
-    } while (it.nextPixel());
+    }
 }
 
 void KisLevelFilterBenchmark::cleanupTestCase()
diff --git a/libs/global/kis_acs_pixel_cache_renderer.h b/libs/global/kis_acs_pixel_cache_renderer.h
index 3b061e5faf5..5b2b1bde8d0 100644
--- a/libs/global/kis_acs_pixel_cache_renderer.h
+++ b/libs/global/kis_acs_pixel_cache_renderer.h
@@ -52,10 +52,10 @@ namespace Acs {
 
                 KisSequentialIterator it(realPixelCache, pickRect);
 
-                do {
+                while (it.nextPixel()) {
                     color = picker->colorAt(it.x(), it.y());
                     memcpy(it.rawData(), color.data(), pixelSize);
-                } while (it.nextPixel());
+                }
 
 
                 // NOTE: toQImage() function of the converter copies exactBounds() only!
diff --git a/libs/image/filter/kis_color_transformation_filter.cc b/libs/image/filter/kis_color_transformation_filter.cc
index 3b5457dec35..cd34cdd2e82 100644
--- a/libs/image/filter/kis_color_transformation_filter.cc
+++ b/libs/image/filter/kis_color_transformation_filter.cc
@@ -67,15 +67,15 @@ void KisColorTransformationFilter::processImpl(KisPaintDeviceSP device,
 
     KisSequentialIterator it(device, applyRect);
     int p = 0;
-    int conseq;
-    do {
-        conseq = it.nConseqPixels();
+    int conseq = it.nConseqPixels();
+    while (it.nextPixels(conseq)) {
 
+        conseq = it.nConseqPixels();
         colorTransformation->transform(it.oldRawData(), it.rawData(), conseq);
 
         if (progressUpdater) progressUpdater->setValue(p += conseq);
+    }
 
-    } while(it.nextPixels(conseq));
     if (!colorTransformationConfiguration) {
         delete colorTransformation;
     }
diff --git a/libs/image/kis_edge_detection_kernel.cpp b/libs/image/kis_edge_detection_kernel.cpp
index f9108d4bff1..dab5194df39 100644
--- a/libs/image/kis_edge_detection_kernel.cpp
+++ b/libs/image/kis_edge_detection_kernel.cpp
@@ -241,7 +241,7 @@ void KisEdgeDetectionKernel::applyEdgeDetection(KisPaintDeviceSP device,
         QVector<float> xNormalised(channels);
         QVector<float> finalNorm(channels);
 
-        do {
+        while(yItterator.nextPixel() && xItterator.nextPixel() && finalIt.nextPixel()) {
             device->colorSpace()->normalisedChannelsValue(yItterator.rawData(), yNormalised);
             device->colorSpace()->normalisedChannelsValue(xItterator.rawData(), xNormalised);
             device->colorSpace()->normalisedChannelsValue(finalIt.rawData(), finalNorm);
@@ -273,7 +273,7 @@ void KisEdgeDetectionKernel::applyEdgeDetection(KisPaintDeviceSP device,
                 memcpy(finalIt.rawData(), f, pixelSize);
             }
 
-        } while(yItterator.nextPixel() && xItterator.nextPixel() && finalIt.nextPixel());
+        }
     } else {
         KisConvolutionKernelSP kernel;
         qreal center = 0;
@@ -306,7 +306,7 @@ void KisEdgeDetectionKernel::applyEdgeDetection(KisPaintDeviceSP device,
             const int pixelSize = device->colorSpace()->pixelSize();
             const int channels = device->colorSpace()->colorChannelCount();
             QVector<float> normalised(channels);
-            do {
+            while (itterator.nextPixel() && finalIt.nextPixel()) {
                 device->colorSpace()->normalisedChannelsValue(itterator.rawData(), normalised);
                 KoColor col(finalIt.rawData(), device->colorSpace());
                 qreal alpha = 0;
@@ -317,7 +317,7 @@ void KisEdgeDetectionKernel::applyEdgeDetection(KisPaintDeviceSP device,
                 col.setOpacity(alpha);
                 memcpy(finalIt.rawData(), col.data(), pixelSize);
 
-            } while(itterator.nextPixel() && finalIt.nextPixel());
+            }
 
         } else {
             KisConvolutionPainter kernelP(device);
@@ -381,7 +381,7 @@ void KisEdgeDetectionKernel::convertToNormalMap(KisPaintDeviceSP device,
     QVector<float> xNormalised(channels);
     QVector<float> finalNorm(channels);
 
-    do {
+    while(yItterator.nextPixel() && xItterator.nextPixel() && finalIt.nextPixel()) {
         device->colorSpace()->normalisedChannelsValue(yItterator.rawData(), yNormalised);
         device->colorSpace()->normalisedChannelsValue(xItterator.rawData(), xNormalised);
 
@@ -400,5 +400,5 @@ void KisEdgeDetectionKernel::convertToNormalMap(KisPaintDeviceSP device,
         device->colorSpace()->fromNormalisedChannelsValue(pixel, finalNorm);
         memcpy(finalIt.rawData(), pixel, pixelSize);
 
-    } while(yItterator.nextPixel() && xItterator.nextPixel() && finalIt.nextPixel());
+    }
 }
diff --git a/libs/image/kis_gradient_painter.cc b/libs/image/kis_gradient_painter.cc
index b06b3c8f4f6..651a609e8fb 100644
--- a/libs/image/kis_gradient_painter.cc
+++ b/libs/image/kis_gradient_painter.cc
@@ -716,7 +716,7 @@ bool KisGradientPainter::paintGradient(const QPointF& gradientVectorStart,
         const int rightCol = processRect.right();
         KisProgressUpdateHelper progressHelper(progressUpdater(), 100, processRect.height());
 
-        do {
+        while (it.nextPixel()) {
             double t = shapeStrategy->valueAt(it.x(), it.y());
             t = repeatStrategy->valueAt(t);
 
@@ -729,7 +729,7 @@ bool KisGradientPainter::paintGradient(const QPointF& gradientVectorStart,
             if (it.x() == rightCol) {
                 progressHelper.step();
             }
-        } while (it.nextPixel());
+        }
 
         bitBlt(processRect.topLeft(), dev, processRect);
     }
diff --git a/libs/image/kis_grid_interpolation_tools.h b/libs/image/kis_grid_interpolation_tools.h
index 353ef49eb52..f6eaeeba452 100644
--- a/libs/image/kis_grid_interpolation_tools.h
+++ b/libs/image/kis_grid_interpolation_tools.h
@@ -195,7 +195,7 @@ struct PaintDevicePolygonOp
         int y = boundRect.top();
         interp.setY(y);
 
-        do {
+        while (dstIt.nextPixel()) {
             int newY = dstIt.y();
 
             if (y != newY) {
@@ -221,7 +221,7 @@ struct PaintDevicePolygonOp
                 srcAcc->sampledOldRawData(dstIt.rawData());
             }
 
-        } while (dstIt.nextPixel());
+        }
 
     }
 
diff --git a/libs/image/kis_histogram.cc b/libs/image/kis_histogram.cc
index 3e6dbcd547f..a0a32dad18c 100644
--- a/libs/image/kis_histogram.cc
+++ b/libs/image/kis_histogram.cc
@@ -90,17 +90,19 @@ void KisHistogram::updateHistogram()
 
     // Let the producer do it's work
     m_producer->clear();
-    int i;
+
 
     // XXX: the original code depended on their being a selection mask in the iterator
     //      if the paint device had a selection. When we changed that to passing an
     //      explicit selection to the createRectIterator call, that broke because
     //      paint devices didn't know about their selections anymore.
     //      updateHistogram should get a selection parameter.
-    do {
-        i = srcIt.nConseqPixels();
-        m_producer->addRegionToBin(srcIt.oldRawData(), 0, i, cs);
-    } while (srcIt.nextPixels(i));
+    int numConseqPixels = srcIt.nConseqPixels();
+    while (srcIt.nextPixels(numConseqPixels)) {
+
+        numConseqPixels = srcIt.nConseqPixels();
+        m_producer->addRegionToBin(srcIt.oldRawData(), 0, numConseqPixels, cs);
+    }
 
     computeHistogram();
 }
diff --git a/libs/image/kis_marker_painter.cpp b/libs/image/kis_marker_painter.cpp
index 68c38973f69..ff2f7565750 100644
--- a/libs/image/kis_marker_painter.cpp
+++ b/libs/image/kis_marker_painter.cpp
@@ -64,7 +64,7 @@ void KisMarkerPainter::fillHalfBrushDiff(const QPointF &p1, const QPointF &p2, c
     boundRect = KisAlgebra2D::cutOffRect(boundRect, plane2);
 
     KisSequentialIterator it(m_d->device, boundRect.toAlignedRect());
-    do {
+    while (it.nextPixel()) {
         QPoint pt(it.x(), it.y());
 
         qreal value1 = plane1.value(pt);
@@ -88,7 +88,7 @@ void KisMarkerPainter::fillHalfBrushDiff(const QPointF &p1, const QPointF &p2, c
             currentColor.setOpacity(srcAlpha);
             memcpy(it.rawData(), currentColor.data(), pixelSize);
         }
-    } while(it.nextPixel());
+    }
 }
 
 void KisMarkerPainter::fillFullCircle(const QPointF &center, qreal radius)
@@ -105,7 +105,7 @@ void KisMarkerPainter::fillFullCircle(const QPointF &center, qreal radius)
     KisAlgebra2D::OuterCircle outer(center, radius);
 
     KisSequentialIterator it(m_d->device, boundRect.toAlignedRect());
-    do {
+    while (it.nextPixel()) {
         QPoint pt(it.x(), it.y());
 
         qreal value3 = outer.fadeSq(pt);
@@ -118,7 +118,7 @@ void KisMarkerPainter::fillFullCircle(const QPointF &center, qreal radius)
             currentColor.setOpacity(srcAlpha);
             memcpy(it.rawData(), currentColor.data(), pixelSize);
         }
-    } while(it.nextPixel());
+    }
 }
 
 void KisMarkerPainter::fillCirclesDiff(const QPointF &c1, qreal r1,
diff --git a/libs/image/kis_paint_device.cc b/libs/image/kis_paint_device.cc
index 73b9a1e368e..8c9a8e52703 100644
--- a/libs/image/kis_paint_device.cc
+++ b/libs/image/kis_paint_device.cc
@@ -742,7 +742,7 @@ void KisPaintDevice::Private::updateLodDataStruct(LodDataStruct *_dst, const QRe
     while (rowsRemaining > 0) {
 
         int colsRemaining = srcRect.width();
-        while (colsRemaining > 0) {
+        while (colsRemaining > 0 && srcIntIt.nextPixel()) {
 
             memcpy(blendDataPtr, srcIntIt.rawDataConst(), pixelSize);
             blendDataPtr += pixelSize;
@@ -753,7 +753,6 @@ void KisPaintDevice::Private::updateLodDataStruct(LodDataStruct *_dst, const QRe
                 columnsAccumulated = 0;
             }
 
-            srcIntIt.nextPixel();
             colsRemaining--;
         }
 
@@ -763,11 +762,13 @@ void KisPaintDevice::Private::updateLodDataStruct(LodDataStruct *_dst, const QRe
 
             // blend and write the final data
             blendDataPtr = blendData.data();
-            for (int i = 0; i < dstRect.width(); i++) {
-                mixOp->mixColors(blendDataPtr, weights.data(), srcCellSize, dstIntIt.rawData());
 
+            int colsRemaining = dstRect.width();
+            while (colsRemaining > 0 && dstIntIt.nextPixel()) {
+                mixOp->mixColors(blendDataPtr, weights.data(), srcCellSize, dstIntIt.rawData());
                 blendDataPtr += srcCellStride;
-                dstIntIt.nextPixel();
+
+                colsRemaining--;
             }
 
             // reset counters
diff --git a/libs/image/kis_paint_device_data.h b/libs/image/kis_paint_device_data.h
index a12a14fb950..6071043f4fc 100644
--- a/libs/image/kis_paint_device_data.h
+++ b/libs/image/kis_paint_device_data.h
@@ -161,9 +161,14 @@ public:
             InternalSequentialConstIterator srcIt(DirectDataAccessPolicy(m_dataManager.data(), cacheInvalidator()), rc);
             InternalSequentialIterator dstIt(DirectDataAccessPolicy(dstDataManager.data(), cacheInvalidator()), rc);
 
-            int nConseqPixels = 0;
+            int nConseqPixels = srcIt.nConseqPixels();
+
+            // since we are accessing data managers directly, the colums are always aligned
+            KIS_SAFE_ASSERT_RECOVER_NOOP(srcIt.nConseqPixels() == dstIt.nConseqPixels());
+
+            while(srcIt.nextPixels(nConseqPixels) &&
+                  dstIt.nextPixels(nConseqPixels)) {
 
-            do {
                 nConseqPixels = srcIt.nConseqPixels();
 
                 const quint8 *srcData = srcIt.rawDataConst();
@@ -173,10 +178,7 @@ public:
                                               dstColorSpace,
                                               nConseqPixels,
                                               renderingIntent, conversionFlags);
-
-
-            } while(srcIt.nextPixels(nConseqPixels) &&
-                    dstIt.nextPixels(nConseqPixels));
+            }
         }
 
         // becomes owned by the parent
diff --git a/libs/image/kis_painter.cc b/libs/image/kis_painter.cc
index cc7dbddd75b..12e21b9f550 100644
--- a/libs/image/kis_painter.cc
+++ b/libs/image/kis_painter.cc
@@ -217,7 +217,7 @@ KisPaintDeviceSP KisPainter::convertToAlphaAsAlpha(KisPaintDeviceSP src)
     KisSequentialConstIterator srcIt(src, processRect);
     KisSequentialIterator dstIt(dst, processRect);
 
-    do {
+    while (srcIt.nextPixel() && dstIt.nextPixel()) {
         const quint8 *srcPtr = srcIt.rawDataConst();
         quint8 *alpha8Ptr = dstIt.rawData();
 
@@ -225,7 +225,7 @@ KisPaintDeviceSP KisPainter::convertToAlphaAsAlpha(KisPaintDeviceSP src)
         const quint8 alpha = srcCS->opacityU8(srcPtr);
 
         *alpha8Ptr = KoColorSpaceMaths<quint8>::multiply(alpha, KoColorSpaceMathsTraits<quint8>::unitValue - white);
-    } while (srcIt.nextPixel() && dstIt.nextPixel());
+    }
 
     return dst;
 }
@@ -241,12 +241,12 @@ KisPaintDeviceSP KisPainter::convertToAlphaAsGray(KisPaintDeviceSP src)
     KisSequentialConstIterator srcIt(src, processRect);
     KisSequentialIterator dstIt(dst, processRect);
 
-    do {
+    while (srcIt.nextPixel() && dstIt.nextPixel()) {
         const quint8 *srcPtr = srcIt.rawDataConst();
         quint8 *alpha8Ptr = dstIt.rawData();
 
         *alpha8Ptr = srcCS->intensity8(srcPtr);
-    } while (srcIt.nextPixel() && dstIt.nextPixel());
+    }
 
     return dst;
 }
@@ -265,11 +265,11 @@ bool KisPainter::checkDeviceHasTransparency(KisPaintDeviceSP dev)
     const KoColorSpace *cs = dev->colorSpace();
     KisSequentialConstIterator it(dev, deviceBounds);
 
-    do {
+    while(it.nextPixel()) {
         if (cs->opacityU8(it.rawDataConst()) != OPACITY_OPAQUE_U8) {
             return true;
         }
-    } while(it.nextPixel());
+    }
 
     return false;
 }
diff --git a/libs/image/kis_pixel_selection.cpp b/libs/image/kis_pixel_selection.cpp
index 44677cb4bff..0d123fba32a 100644
--- a/libs/image/kis_pixel_selection.cpp
+++ b/libs/image/kis_pixel_selection.cpp
@@ -162,12 +162,12 @@ void KisPixelSelection::copyAlphaFrom(KisPaintDeviceSP src, const QRect &process
     KisSequentialConstIterator srcIt(src, processRect);
     KisSequentialIterator dstIt(this, processRect);
 
-    do {
+    while (srcIt.nextPixel() && dstIt.nextPixel()) {
         const quint8 *srcPtr = srcIt.rawDataConst();
         quint8 *alpha8Ptr = dstIt.rawData();
 
         *alpha8Ptr = srcCS->opacityU8(srcPtr);
-    } while (srcIt.nextPixel() && dstIt.nextPixel());
+    }
 
     m_d->outlineCacheValid = false;
     m_d->outlineCache = QPainterPath();
@@ -296,9 +296,9 @@ void KisPixelSelection::invert()
 
     if (!rc.isEmpty()) {
         KisSequentialIterator it(this, rc);
-        do {
+        while(it.nextPixel()) {
             *(it.rawData()) = MAX_SELECTED - *(it.rawData());
-        } while (it.nextPixel());
+        }
     }
     quint8 defPixel = MAX_SELECTED - *defaultPixel().data();
     setDefaultPixel(KoColor(&defPixel, colorSpace()));
@@ -473,7 +473,7 @@ QImage deviceToQImage(KisPaintDeviceSP device,
     const qreal alphaScale = maskColor.alphaF();
 
     KisSequentialIterator it(device, rc);
-    do {
+    while(it.nextPixel()) {
         quint8 value = (MAX_SELECTED - *(it.rawData())) * alphaScale;
         color.setAlpha(value);
 
@@ -481,7 +481,7 @@ QImage deviceToQImage(KisPaintDeviceSP device,
         pt -= rc.topLeft();
 
         image.setPixel(pt.x(), pt.y(), color.rgba());
-    } while (it.nextPixel());
+    }
 
     return image;
 }
diff --git a/libs/image/kis_sequential_iterator.h b/libs/image/kis_sequential_iterator.h
index 99d778edcc2..5f732d5896b 100644
--- a/libs/image/kis_sequential_iterator.h
+++ b/libs/image/kis_sequential_iterator.h
@@ -52,12 +52,12 @@ struct ReadOnlyIteratorPolicy {
     typedef KisHLineConstIteratorSP IteratorTypeSP;
 
     ReadOnlyIteratorPolicy(SourcePolicy source, const QRect &rect) {
-        m_iter = source.createConstIterator(rect);
+        m_iter = !rect.isEmpty() ? source.createConstIterator(rect) : 0;
     }
 
     ALWAYS_INLINE void updatePointersCache() {
-        m_rawDataConst = m_iter->rawDataConst();
-        m_oldRawData = m_iter->oldRawData();
+        m_rawDataConst = m_iter ? m_iter->rawDataConst() : 0;
+        m_oldRawData = m_iter ? m_iter->oldRawData() : 0;
     }
 
     ALWAYS_INLINE const quint8* rawDataConst() const {
@@ -80,12 +80,12 @@ struct WritableIteratorPolicy {
     typedef KisHLineIteratorSP IteratorTypeSP;
 
     WritableIteratorPolicy(SourcePolicy source, const QRect &rect) {
-        m_iter = source.createIterator(rect);
+        m_iter = !rect.isEmpty() ? source.createIterator(rect) : 0;
     }
 
     ALWAYS_INLINE void updatePointersCache() {
-        m_rawData = m_iter->rawData();
-        m_oldRawData = m_iter->oldRawData();
+        m_rawData = m_iter ? m_iter->rawData() : 0;
+        m_oldRawData = m_iter ? m_iter->oldRawData() : 0;
     }
 
     ALWAYS_INLINE quint8* rawData() {
@@ -117,6 +117,49 @@ private:
  * pixel-by-pixel processing it is about twice faster(!)  than a usual
  * hline iterator.
  *
+ * The follows the "java-style" iterators rules. Before requesting the
+ * first pixel from the iterator you should call nextPixel() to "jump over"
+ * this first pixel. After the jump is accomplished, you can easily request
+ * the "jumped over" pixel data.
+ *
+ * The modified rules apply when the user wants accesses censequent pixels
+ * in one go. The user first asks the iterator for the number of available
+ * consequent pixels, and then calls nextPixels(numConseqPixels). In this
+ * case, iterator inserts a "virtual" pixel that one should jump over before
+ * doing any real iteration.
+ *
+ * Iteration in pixel-by-pixel manner:
+ *
+ * \code{.cpp}
+ * KisSequentialConstIterator it(dev, rect);
+ * while (it.nextPixel()) {
+ *     quint *ptr = it.rawDataConst();
+ *     // work with ptr...
+ * }
+ * \endcode
+ *
+ * Iteration with strides:
+ *
+ * \code{.cpp}
+ * KisSequentialConstIterator it(dev, rect);
+ *
+ * // Here we jump over the first "virtual" pixel,
+ * // which helps us to avoid an empty rect problem
+ *
+ * int numConseqPixels = it.nConseqPixels();
+ * while (it.nextPixels(numConseqPixels)) {
+ *
+ *     // get real number of conseq pixels
+ *
+ *     numConseqPixels = it.nConseqPixels();
+ *     quint *ptr = it.rawDataConst();
+ *
+ *     // process the data
+ *     processPixelData(tr, numConseqPixels);
+ * }
+ * \endcode
+ *
+ *
  * Implementation:
  *
  * The iterator is implemented using a policy pattern. The class
@@ -137,16 +180,19 @@ public:
           m_rowsLeft(rect.height() - 1),
           m_columnOffset(0),
           m_iteratorX(0),
-          m_iteratorY(0)
+          m_iteratorY(0),
+          m_isStarted(false)
     {
-        m_columnsLeft = m_numConseqPixels = m_policy.m_iter->nConseqPixels();
+        m_columnsLeft = m_numConseqPixels =
+            m_policy.m_iter ? m_policy.m_iter->nConseqPixels() : 0;
+
         m_policy.updatePointersCache();
-        m_iteratorX = m_policy.m_iter->x();
-        m_iteratorY = m_policy.m_iter->y();
+        m_iteratorX = m_policy.m_iter ? m_policy.m_iter->x() : 0;
+        m_iteratorY = m_policy.m_iter ? m_policy.m_iter->y() : 0;
     }
 
     inline int nConseqPixels() const {
-        return m_columnsLeft;
+        return m_isStarted ? m_columnsLeft : 1;
     }
 
     inline bool nextPixels(int numPixels) {
@@ -160,9 +206,14 @@ public:
     }
 
     inline bool nextPixel() {
+        if (!m_isStarted) {
+            m_isStarted = true;
+            return m_policy.m_iter;
+        }
+
         m_columnsLeft--;
 
-        if (m_columnsLeft) {
+        if (m_columnsLeft > 0) {
             m_columnOffset += m_pixelSize;
             return true;
         } else {
@@ -219,6 +270,8 @@ private:
     int m_columnOffset;
     int m_iteratorX;
     int m_iteratorY;
+
+    bool m_isStarted;
 };
 
 typedef KisSequentialIteratorBase<ReadOnlyIteratorPolicy<> > KisSequentialConstIterator;
diff --git a/libs/image/krita_utils.cpp b/libs/image/krita_utils.cpp
index 54ee2e43ae7..864fe0857f3 100644
--- a/libs/image/krita_utils.cpp
+++ b/libs/image/krita_utils.cpp
@@ -402,18 +402,18 @@ namespace KritaUtils
 
     void applyToAlpha8Device(KisPaintDeviceSP dev, const QRect &rc, std::function<void(quint8)> func) {
         KisSequentialConstIterator dstIt(dev, rc);
-        do {
+        while (dstIt.nextPixel()) {
             const quint8 *dstPtr = dstIt.rawDataConst();
             func(*dstPtr);
-        } while (dstIt.nextPixel());
+        }
     }
 
     void filterAlpha8Device(KisPaintDeviceSP dev, const QRect &rc, std::function<quint8(quint8)> func) {
         KisSequentialIterator dstIt(dev, rc);
-        do {
+        while (dstIt.nextPixel()) {
             quint8 *dstPtr = dstIt.rawData();
             *dstPtr = func(*dstPtr);
-        } while (dstIt.nextPixel());
+        }
     }
 
     qreal estimatePortionOfTransparentPixels(KisPaintDeviceSP dev, const QRect &rect, qreal samplePortion) {
diff --git a/libs/image/layerstyles/kis_layer_style_filter_environment.cpp b/libs/image/layerstyles/kis_layer_style_filter_environment.cpp
index fd252974d53..4ba2d485974 100644
--- a/libs/image/layerstyles/kis_layer_style_filter_environment.cpp
+++ b/libs/image/layerstyles/kis_layer_style_filter_environment.cpp
@@ -55,23 +55,23 @@ generateRandomSelection(const QRect &rc)
     boost::mt11213b uniformSource;
 
     if (uniformSource.max() >= 0x00FFFFFF) {
-        do {
+        while (dstIt.nextPixel()) {
             int randValue = uniformSource();
             *dstIt.rawData() = (quint8) randValue;
-            if (!dstIt.nextPixel()) break;
 
+            if (!dstIt.nextPixel()) break;
             randValue >>= 8;
             *dstIt.rawData() = (quint8) randValue;
-            if (!dstIt.nextPixel()) break;
 
+            if (!dstIt.nextPixel()) break;
             randValue >>= 8;
             *dstIt.rawData() = (quint8) randValue;
-        } while(dstIt.nextPixel());
+        }
 
     } else {
-        do {
+        while (dstIt.nextPixel()) {
             *dstIt.rawData() = (quint8) uniformSource();
-        } while(dstIt.nextPixel());
+        }
     }
 
     return selection;
diff --git a/libs/image/layerstyles/kis_ls_bevel_emboss_filter.cpp b/libs/image/layerstyles/kis_ls_bevel_emboss_filter.cpp
index 0f2a2acd18a..08432cd9759 100644
--- a/libs/image/layerstyles/kis_ls_bevel_emboss_filter.cpp
+++ b/libs/image/layerstyles/kis_ls_bevel_emboss_filter.cpp
@@ -148,11 +148,11 @@ void mapPixelValues(KisPixelSelectionSP srcSelection,
     KisSequentialConstIterator srcIt(srcSelection, applyRect);
     KisSequentialIterator dstIt(dstSelection, applyRect);
 
-    do {
+    while (srcIt.nextPixel() && dstIt.nextPixel()) {
         const quint8 *srcPtr = srcIt.rawDataConst();
         quint8 *dstPtr = dstIt.rawData();
         *dstPtr = mapTable[*srcPtr];
-    } while(srcIt.nextPixel() && dstIt.nextPixel());
+    }
 }
 
 template <class MapOp>
@@ -173,10 +173,10 @@ void mapPixelValues(KisPixelSelectionSP dstSelection,
 
     KisSequentialIterator dstIt(dstSelection, applyRect);
 
-    do {
+    while (dstIt.nextPixel()) {
         quint8 *dstPtr = dstIt.rawData();
         *dstPtr = mapTable[*dstPtr];
-    } while(dstIt.nextPixel());
+    }
 }
 
 struct BevelEmbossRectCalculator
diff --git a/libs/image/layerstyles/kis_ls_satin_filter.cpp b/libs/image/layerstyles/kis_ls_satin_filter.cpp
index 893b726433c..5a5603f2e9e 100644
--- a/libs/image/layerstyles/kis_ls_satin_filter.cpp
+++ b/libs/image/layerstyles/kis_ls_satin_filter.cpp
@@ -104,21 +104,19 @@ void blendAndOffsetSatinSelection(KisPixelSelectionSP dstSelection,
     KisSequentialIterator srcIt1(srcSelection, applyRect.translated(offset));
     KisSequentialIterator srcIt2(srcSelection, applyRect.translated(-offset));
     KisSequentialIterator dstIt(dstSelection, applyRect);
-    do {
+
+    while(dstIt.nextPixel() && srcIt1.nextPixel() && srcIt2.nextPixel()) {
+
         quint8 *dstPixelPtr = dstIt.rawData();
         quint8 *src1PixelPtr = srcIt1.rawData();
         quint8 *src2PixelPtr = srcIt2.rawData();
 
-
         if (!invert) {
             *dstPixelPtr = *dstPixelPtr * qAbs(*src1PixelPtr - *src2PixelPtr) >> 8;
         } else {
             *dstPixelPtr = *dstPixelPtr * (255 - qAbs(*src1PixelPtr - *src2PixelPtr)) >> 8;
         }
-    } while(dstIt.nextPixel() &&
-            srcIt1.nextPixel() &&
-            srcIt2.nextPixel());
-
+    }
 }
 
 void applySatin(KisPaintDeviceSP srcDevice,
diff --git a/libs/image/layerstyles/kis_ls_utils.cpp b/libs/image/layerstyles/kis_ls_utils.cpp
index 428e15af82f..0e0d0ca3a04 100644
--- a/libs/image/layerstyles/kis_ls_utils.cpp
+++ b/libs/image/layerstyles/kis_ls_utils.cpp
@@ -72,11 +72,11 @@ namespace KisLsUtils
         KisSequentialConstIterator srcIt(device, srcRect);
         KisSequentialIterator dstIt(selection, srcRect);
 
-        do {
+        while (srcIt.nextPixel() && dstIt.nextPixel()) {
             quint8 *dstPtr = dstIt.rawData();
             const quint8* srcPtr = srcIt.rawDataConst();
             *dstPtr = cs->opacityU8(srcPtr);
-        } while(srcIt.nextPixel() && dstIt.nextPixel());
+        }
 
         return baseSelection;
     }
@@ -86,20 +86,20 @@ namespace KisLsUtils
         KisSequentialIterator dstIt(selection, applyRect);
 
         if (edgeHidden) {
-            do {
+            while(dstIt.nextPixel()) {
                 quint8 *pixelPtr = dstIt.rawData();
 
                 *pixelPtr =
                     (*pixelPtr < 24) ?
                     *pixelPtr * 10 : 0xFF;
 
-            } while(dstIt.nextPixel());
+            }
         } else {
-            do {
+            while(dstIt.nextPixel()) {
                 quint8 *pixelPtr = dstIt.rawData();
                 *pixelPtr = 0xFF;
 
-            } while(dstIt.nextPixel());
+            }
         }
     }
 
@@ -190,7 +190,10 @@ namespace KisLsUtils
 
             if (edgeHidden) {
 
-                do {
+                while (selIt.nextPixel() &&
+                       dstIt.nextPixel() &&
+                       indexFetcher.nextPixel()) {
+
                     quint8 selAlpha = *selIt.rawDataConst();
                     int gradientIndex = indexFetcher.popOneIndex(selAlpha);
                     const KoColor &color = table[gradientIndex];
@@ -203,20 +206,18 @@ namespace KisLsUtils
                         cs->setOpacity(dstIt.rawData(), tableAlpha, 1);
                     }
 
-                } while(selIt.nextPixel() &&
-                        dstIt.nextPixel() &&
-                        indexFetcher.nextPixel());
+                }
 
             } else {
 
-                do {
+                while (selIt.nextPixel() &&
+                       dstIt.nextPixel() &&
+                       indexFetcher.nextPixel()) {
+
                     int gradientIndex = indexFetcher.popOneIndex(*selIt.rawDataConst());
                     const KoColor &color = table[gradientIndex];
                     memcpy(dstIt.rawData(), color.data(), pixelSize);
-                } while(selIt.nextPixel() &&
-                        dstIt.nextPixel() &&
-                        indexFetcher.nextPixel());
-
+                }
             }
         }
 
@@ -257,7 +258,7 @@ namespace KisLsUtils
         KisSequentialConstIterator srcIt(selection, overlayRect);
         KisRandomAccessorSP dstIt = randomOverlay->createRandomAccessorNG(overlayRect.x(), overlayRect.y());
 
-        do {
+        while (noiseIt.nextPixel() && srcIt.nextPixel()) {
             int itX = noiseIt.x();
             int itY = noiseIt.y();
 
@@ -274,8 +275,7 @@ namespace KisLsUtils
             int value = qMin(255, dstAlpha + srcAlpha);
 
             *dstIt->rawData() = value;
-
-        } while(noiseIt.nextPixel() && srcIt.nextPixel());
+        }
 
         noise = noise * 255 / 100;
 
@@ -299,10 +299,10 @@ namespace KisLsUtils
 
         KisSequentialIterator dstIt(selection, applyRect);
 
-        do {
+        while (dstIt.nextPixel()) {
             quint8 *pixelPtr = dstIt.rawData();
             *pixelPtr = rangeTable[*pixelPtr];
-        } while(dstIt.nextPixel());
+        }
     }
 
     void applyContourCorrection(KisPixelSelectionSP selection,
@@ -352,10 +352,10 @@ namespace KisLsUtils
         }
 
         KisSequentialIterator dstIt(selection, applyRect);
-        do {
+        while (dstIt.nextPixel()) {
             quint8 *pixelPtr = dstIt.rawData();
             *pixelPtr = contour[*pixelPtr];
-        } while(dstIt.nextPixel());
+        }
     }
 
     void knockOutSelection(KisPixelSelectionSP selection,
diff --git a/libs/image/lazybrush/KisWatershedWorker.cpp b/libs/image/lazybrush/KisWatershedWorker.cpp
index 0e827cbf352..749c680d55c 100644
--- a/libs/image/lazybrush/KisWatershedWorker.cpp
+++ b/libs/image/lazybrush/KisWatershedWorker.cpp
@@ -151,7 +151,7 @@ void mergeHeightmapOntoStroke(KisPaintDeviceSP stroke, KisPaintDeviceSP heightMa
     KisSequentialIterator dstIt(stroke, rc);
     KisSequentialConstIterator mapIt(heightMap, rc);
 
-    do {
+    while (dstIt.nextPixel() && mapIt.nextPixel()) {
         quint8 *dstPtr = dstIt.rawData();
 
         if (*dstPtr > 0) {
@@ -161,7 +161,7 @@ void mergeHeightmapOntoStroke(KisPaintDeviceSP stroke, KisPaintDeviceSP heightMa
             *dstPtr = 0;
         }
 
-    } while (dstIt.nextPixel() && mapIt.nextPixel());
+    }
 }
 
 void parseColorIntoGroups(QVector<FillGroup> &groups,
@@ -176,7 +176,7 @@ void parseColorIntoGroups(QVector<FillGroup> &groups,
 
     KisSequentialIterator dstIt(stroke, strokeRect);
 
-    do {
+    while (dstIt.nextPixel()) {
         quint8 *dstPtr = dstIt.rawData();
 
         if (*dstPtr > 0) {
@@ -193,7 +193,7 @@ void parseColorIntoGroups(QVector<FillGroup> &groups,
             groups << FillGroup(colorIndex);
         }
 
-    } while (dstIt.nextPixel());
+    }
 }
 
 using PointsPriorityQueue = boost::heap::fibonacci_heap<TaskPoint, boost::heap::compare<CompareTaskPoints>>;
@@ -292,7 +292,9 @@ void KisWatershedWorker::addKeyStroke(KisPaintDeviceSP dev, const KoColor &color
         KisSequentialIterator devIt(dev, rc);
         KisSequentialConstIterator lastDevIt(lastDev, rc);
 
-        do {
+        while (devIt.nextPixel() &&
+               lastDevIt.nextPixel()) {
+
             quint8 *devPtr = devIt.rawData();
             const quint8 *lastDevPtr = lastDevIt.rawDataConst();
 
@@ -300,8 +302,7 @@ void KisWatershedWorker::addKeyStroke(KisPaintDeviceSP dev, const KoColor &color
                 *devPtr = 0;
             }
 
-        } while (devIt.nextPixel() &&
-                 lastDevIt.nextPixel());
+        }
     }
 }
 
@@ -385,7 +386,9 @@ void KisWatershedWorker::Private::initializeQueueFromGroupMap(const QRect &rc)
     KisSequentialIterator groupMapIt(groupsMap, rc);
     KisSequentialConstIterator heightMapIt(heightMap, rc);
 
-    do {
+    while (groupMapIt.nextPixel() &&
+           heightMapIt.nextPixel()) {
+
         qint32 *groupPtr = reinterpret_cast<qint32*>(groupMapIt.rawData());
         const quint8 *heightPtr = heightMapIt.rawDataConst();
 
@@ -402,8 +405,7 @@ void KisWatershedWorker::Private::initializeQueueFromGroupMap(const QRect &rc)
             *groupPtr = 0;
         }
 
-    } while (groupMapIt.nextPixel() &&
-             heightMapIt.nextPixel());
+    }
 }
 
 ALWAYS_INLINE void addForeignAlly(qint32 currGroupId,
@@ -728,7 +730,7 @@ void KisWatershedWorker::Private::writeColoring()
     const int colorPixelSize = dstDevice->pixelSize();
 
 
-    do {
+    while (srcIt.nextPixel() && dstIt.nextPixel()) {
         const qint32 *srcPtr = reinterpret_cast<const qint32*>(srcIt.rawDataConst());
 
         const int colorIndex = groups[*srcPtr].colorIndex;
@@ -736,7 +738,7 @@ void KisWatershedWorker::Private::writeColoring()
             memcpy(dstIt.rawData(), colors[colorIndex].data(), colorPixelSize);
         }
 
-    } while (srcIt.nextPixel() && dstIt.nextPixel());
+    }
 }
 
 QVector<TaskPoint> KisWatershedWorker::Private::tryRemoveConflictingPlane(qint32 group, quint8 level)
@@ -921,7 +923,14 @@ void KisWatershedWorker::Private::dumpGroupMaps()
 
 
 
-    do {
+    while (dstGroupIt.nextPixel() &&
+           heightIt.nextPixel() &&
+           srcIt.nextPixel() &&
+           dstColorIt.nextPixel() &&
+           dstPedgeIt.nextPixel() &&
+           dstNedgeIt.nextPixel() &&
+           dstFedgeIt.nextPixel()) {
+
         const qint32 *srcPtr = reinterpret_cast<const qint32*>(srcIt.rawDataConst());
 
         *dstGroupIt.rawData() = quint8(*srcPtr);
@@ -942,14 +951,7 @@ void KisWatershedWorker::Private::dumpGroupMaps()
             *dstNedgeIt.rawData() = 0;
             *dstFedgeIt.rawData() = 0;
         }
-
-    } while (dstGroupIt.nextPixel() &&
-             heightIt.nextPixel() &&
-             srcIt.nextPixel() &&
-             dstColorIt.nextPixel() &&
-             dstPedgeIt.nextPixel() &&
-             dstNedgeIt.nextPixel() &&
-             dstFedgeIt.nextPixel());
+    }
 
 
     KIS_DUMP_DEVICE_2(groupDevice, boundingRect, "01_groupMap", "dd");
@@ -966,13 +968,13 @@ void KisWatershedWorker::Private::calcNumGroupMaps()
 
     QSet<QPair<qint32, quint8>> groups;
 
-    do {
+    while (groupIt.nextPixel() && levelIt.nextPixel()) {
+
         const qint32 group = *reinterpret_cast<const qint32*>(groupIt.rawDataConst());
         const quint8 level = *reinterpret_cast<const quint8*>(levelIt.rawDataConst());
 
         groups.insert(qMakePair(group, level));
-
-    } while (groupIt.nextPixel() && levelIt.nextPixel());
+    }
 
     for (auto it = groups.begin(); it != groups.end(); ++it) {
         dumpGroupInfo(it->first, it->second);
diff --git a/libs/image/lazybrush/kis_lazy_fill_tools.cpp b/libs/image/lazybrush/kis_lazy_fill_tools.cpp
index 0cce32de852..bdc365ed82c 100644
--- a/libs/image/lazybrush/kis_lazy_fill_tools.cpp
+++ b/libs/image/lazybrush/kis_lazy_fill_tools.cpp
@@ -138,7 +138,7 @@ void cutOneWay(const KoColor &color,
 
     const int pixelSize = resultDevice->pixelSize();
 
-    do {
+    while (dstIt.nextPixel() && mskIt.nextPixel()) {
         KisLazyFillGraph::vertex_descriptor v(dstIt.x(), dstIt.y());
         long vertex_idx = get(boost::vertex_index, graph, v);
         default_color_type label = groups[vertex_idx];
@@ -147,11 +147,11 @@ void cutOneWay(const KoColor &color,
             memcpy(dstIt.rawData(), color.data(), pixelSize);
             *mskIt.rawData() = 10 + (int(label) << 4);
         }
-    } while (dstIt.nextPixel() && mskIt.nextPixel());
+    }
 }
 
-    QVector<QPoint> splitIntoConnectedComponents(KisPaintDeviceSP dev,
-                                                 const QRect &boundingRect)
+QVector<QPoint> splitIntoConnectedComponents(KisPaintDeviceSP dev,
+                                             const QRect &boundingRect)
 {
     QVector<QPoint> points;
     const KoColorSpace *cs = dev->colorSpace();
@@ -167,7 +167,7 @@ void cutOneWay(const KoColor &color,
      */
     KisSequentialIterator dstIt(dev, rect);
 
-    do {
+    while (dstIt.nextPixel()) {
         if (cs->opacityU8(dstIt.rawData()) > 0) {
             const QPoint pt(dstIt.x(), dstIt.y());
             points << pt;
@@ -175,7 +175,7 @@ void cutOneWay(const KoColor &color,
             KisScanlineFill fill(dev, pt, rect);
             fill.clearNonZeroComponent();
         }
-    } while (dstIt.nextPixel());
+    }
 
     return points;
 }
diff --git a/libs/image/lazybrush/kis_multiway_cut.cpp b/libs/image/lazybrush/kis_multiway_cut.cpp
index bd750fb2f8d..b0d6c3dd132 100644
--- a/libs/image/lazybrush/kis_multiway_cut.cpp
+++ b/libs/image/lazybrush/kis_multiway_cut.cpp
@@ -77,11 +77,11 @@ void KisMultiwayCut::Private::maskOutKeyStroke(KisPaintDeviceSP keyStrokeDevice,
         KisSequentialIterator dstIt(keyStrokeDevice, rc);
         KisSequentialConstIterator mskIt(mask, rc);
 
-        do {
+        while (dstIt.nextPixel() && mskIt.nextPixel()) {
             if (*mskIt.rawDataConst() > 0) {
                 *dstIt.rawData() = 0;
             }
-        } while (dstIt.nextPixel() && mskIt.nextPixel());
+        }
     }
 }
 
diff --git a/libs/image/tests/kis_iterator_benchmark.cpp b/libs/image/tests/kis_iterator_benchmark.cpp
index 0ce2064cbae..963f2dd1e13 100644
--- a/libs/image/tests/kis_iterator_benchmark.cpp
+++ b/libs/image/tests/kis_iterator_benchmark.cpp
@@ -51,15 +51,15 @@ void KisIteratorBenchmark::sequentialIter(const KoColorSpace * colorSpace)
     for (int i = 0; i < 3; i++) {
         KisSequentialIterator it(dev, QRect(0, 0, TEST_WIDTH, TEST_HEIGHT));
         int sum = 0;
-        do {
+        while (it.nextPixel()) {
             if (useXY) {
                 sum = it.x() + it.y();
             }
 
             memcpy(it.rawData(), bytes, colorSpace->pixelSize());
-        } while (it.nextPixel());
+        }
 
-        dbgKrita << ppVar(useXY) << "SequentialIterator run " << i  << "took" << t.elapsed();
+        qDebug() << ppVar(useXY) << "SequentialIterator run " << i  << "took" << t.elapsed();
         Q_UNUSED(sum);
         t.restart();
     }
@@ -69,14 +69,14 @@ void KisIteratorBenchmark::sequentialIter(const KoColorSpace * colorSpace)
     for (int i = 0; i < 3; i++) {
         KisSequentialConstIterator it(dev, QRect(0, 0, TEST_WIDTH, TEST_HEIGHT));
         int sum = 0;
-        do {
+        while (it.nextPixel()) {
             if (useXY) {
                 sum = it.x() + it.y();
             }
             //memcpy(it.rawData(), bytes, colorSpace->pixelSize());
-        } while (it.nextPixel());
+        }
 
-        dbgKrita << ppVar(useXY) << "SequentialConstIterator run " << i  << "took" << t.elapsed();
+        qDebug() << ppVar(useXY) << "SequentialConstIterator run " << i  << "took" << t.elapsed();
         Q_UNUSED(sum);
         t.restart();
     }
@@ -105,7 +105,7 @@ void KisIteratorBenchmark::hLineIterNG(const KoColorSpace * colorSpace)
             it->nextRow();
         }
 
-        dbgKrita << "HLineIteratorNG run " << i  << "took" << t.elapsed();
+        qDebug() << "HLineIteratorNG run " << i  << "took" << t.elapsed();
         t.restart();
     }
 
@@ -120,7 +120,7 @@ void KisIteratorBenchmark::hLineIterNG(const KoColorSpace * colorSpace)
             it->nextRow();
         }
 
-        dbgKrita << "HLineIteratorNG with nConseqHPixels run " << i  << "took" << t.elapsed();
+        qDebug() << "HLineIteratorNG with nConseqHPixels run " << i  << "took" << t.elapsed();
         t.restart();
     }
 
@@ -132,7 +132,7 @@ void KisIteratorBenchmark::hLineIterNG(const KoColorSpace * colorSpace)
         cit->nextRow();
     }
 
-    dbgKrita << "const HLineIteratorNG took" << t.elapsed();
+    qDebug() << "const HLineIteratorNG took" << t.elapsed();
 
     delete[] bytes;
 }
@@ -156,7 +156,7 @@ void KisIteratorBenchmark::vLineIterNG(const KoColorSpace * colorSpace)
             it->nextColumn();
         }
 
-        dbgKrita << "VLineIteratorNG run " << i  << " took" << t.elapsed();
+        qDebug() << "VLineIteratorNG run " << i  << " took" << t.elapsed();
         t.restart();
     }
 
@@ -165,7 +165,7 @@ void KisIteratorBenchmark::vLineIterNG(const KoColorSpace * colorSpace)
         do {} while(cit->nextPixel());
         cit->nextColumn();
     }
-    dbgKrita << "const VLineIteratorNG took" << t.elapsed();
+    qDebug() << "const VLineIteratorNG took" << t.elapsed();
 
     delete[] bytes;
 
@@ -190,7 +190,7 @@ void KisIteratorBenchmark::randomAccessor(const KoColorSpace * colorSpace)
             }
         }
 
-        dbgKrita << "RandomIterator run " << i  << " took" << t.elapsed();
+        qDebug() << "RandomIterator run " << i  << " took" << t.elapsed();
         t.restart();
     }
 
@@ -217,7 +217,7 @@ void KisIteratorBenchmark::randomAccessor(const KoColorSpace * colorSpace)
             y += numContiguousRows;
         }
 
-        dbgKrita << "RandomIterator run (with strides)" << i  << " took" << t.elapsed();
+        qDebug() << "RandomIterator run (with strides)" << i  << " took" << t.elapsed();
         t.restart();
     }
 
@@ -228,7 +228,7 @@ void KisIteratorBenchmark::randomAccessor(const KoColorSpace * colorSpace)
         }
     }
 
-    dbgKrita << "const RandomIterator took" << t.elapsed();
+    qDebug() << "const RandomIterator took" << t.elapsed();
 
     delete[] bytes;
 }
diff --git a/libs/image/tests/kis_iterators_ng_test.cpp b/libs/image/tests/kis_iterators_ng_test.cpp
index 6fcbeafa26b..e3e086e30c2 100644
--- a/libs/image/tests/kis_iterators_ng_test.cpp
+++ b/libs/image/tests/kis_iterators_ng_test.cpp
@@ -149,14 +149,14 @@ void KisIteratorTest::sequentialIter(const KoColorSpace * colorSpace)
         KisSequentialIterator it(dev, QRect(0, 0, 128, 128));
         int i = -1;
 
-        do {
+        while (it.nextPixel()) {
             i++;
             KoColor c(QColor(i % 255, i / 255, 0), colorSpace);
             memcpy(it.rawData(), c.data(), colorSpace->pixelSize());
 
             QCOMPARE(it.x(), i % 128);
             QCOMPARE(it.y(), i / 128);
-        } while (it.nextPixel());
+        }
 
         QCOMPARE(dev->extent(), QRect(0, 0, 128, 128));
         QCOMPARE(dev->exactBounds(), QRect(0, 0, 128, 128));
@@ -166,28 +166,73 @@ void KisIteratorTest::sequentialIter(const KoColorSpace * colorSpace)
         KisSequentialConstIterator it(dev, QRect(0, 0, 128, 128));
         int i = -1;
 
-        do {
+        while (it.nextPixel()) {
             i++;
             KoColor c(QColor(i % 255, i / 255, 0), colorSpace);
             QVERIFY(memcmp(it.rawDataConst(), c.data(), colorSpace->pixelSize()) == 0);
-        } while (it.nextPixel());
+        }
 
         QCOMPARE(dev->extent(), QRect(0, 0, 128, 128));
         QCOMPARE(dev->exactBounds(), QRect(0, 0, 128, 128));
     }
 
+    { // check const iterator with **empty** area! It should neither crash nor enter the loop
+        KisSequentialConstIterator it(dev, QRect());
+
+        QVERIFY(!it.rawDataConst());
+        QVERIFY(!it.oldRawData());
+
+        while (it.nextPixel()) {
+            QVERIFY(0 && "we should never enter the loop");
+        }
+    }
+
+    { // check const iterator with strides
+        KisSequentialConstIterator it(dev, QRect(0, 0, 128, 128));
+        int i = -1;
+
+        int numConseqPixels = it.nConseqPixels();
+        while (it.nextPixels(numConseqPixels)) {
+
+            numConseqPixels = it.nConseqPixels();
+
+            for (int j = 0; j < numConseqPixels; j++) {
+                i++;
+                KoColor c(QColor(i % 255, i / 255, 0), colorSpace);
+                QVERIFY(memcmp(it.rawDataConst() + j * colorSpace->pixelSize(),
+                               c.data(),
+                               colorSpace->pixelSize()) == 0);
+            }
+        }
+
+        QCOMPARE(dev->extent(), QRect(0, 0, 128, 128));
+        QCOMPARE(dev->exactBounds(), QRect(0, 0, 128, 128));
+    }
+
+    { // check const iterator with strides and **empty** area
+        KisSequentialConstIterator it(dev, QRect());
+
+        QVERIFY(!it.rawDataConst());
+        QVERIFY(!it.oldRawData());
+
+        int numConseqPixels = it.nConseqPixels();
+        while (it.nextPixels(numConseqPixels)) {
+            QVERIFY(0 && "we should never enter the loop");
+        }
+    }
+
     dev->clear();
 
     {
         KisSequentialIterator it(dev, QRect(10, 10, 128, 128));
         int i = -1;
 
-        do {
+        while (it.nextPixel()) {
             i++;
             KoColor c(QColor(i % 255, i / 255, 0), colorSpace);
 
             memcpy(it.rawData(), c.data(), colorSpace->pixelSize());
-        } while (it.nextPixel());
+        }
 
         QCOMPARE(dev->extent(), QRect(0, 0, 3 * 64, 3 * 64));
         QCOMPARE(dev->exactBounds(), QRect(10, 10, 128, 128));
@@ -201,12 +246,12 @@ void KisIteratorTest::sequentialIter(const KoColorSpace * colorSpace)
         KisSequentialIterator it(dev, QRect(10, 10, 128, 128));
         int i = -1;
 
-        do {
+        while (it.nextPixel()) {
             i++;
             KoColor c(QColor(i % 255, i / 255, 0), colorSpace);
 
             memcpy(it.rawData(), c.data(), colorSpace->pixelSize());
-        } while (it.nextPixel());
+        }
         QCOMPARE(dev->extent(), QRect(10, -15, 128, 192));
         QCOMPARE(dev->exactBounds(), QRect(10, 10, 128, 128));
     }
diff --git a/libs/image/tests/kis_lazy_brush_test.cpp b/libs/image/tests/kis_lazy_brush_test.cpp
index d7fc5281352..226b1f53ef0 100644
--- a/libs/image/tests/kis_lazy_brush_test.cpp
+++ b/libs/image/tests/kis_lazy_brush_test.cpp
@@ -976,7 +976,7 @@ void writeColors(KisLazyFillGraph &graph, const std::vector<int> &groups, KisPai
     KoColor gray(Qt::gray, dst->colorSpace());
     const int pixelSize = dst->colorSpace()->pixelSize();
 
-    do {
+    while (dstIt.nextPixel()) {
         KisLazyFillGraph::vertex_descriptor v(dstIt.x(), dstIt.y());
         long vertex_idx = get(boost::vertex_index, graph, v);
         int label = groups[vertex_idx];
@@ -989,7 +989,7 @@ void writeColors(KisLazyFillGraph &graph, const std::vector<int> &groups, KisPai
 
         quint8 *dstPtr = dstIt.rawData();
         memcpy(dstPtr, color.data(), pixelSize);
-    } while (dstIt.nextPixel());
+    }
 }
 
 void writeStat(KisLazyFillGraph &graph,
diff --git a/libs/image/tests/kis_paint_device_test.cpp b/libs/image/tests/kis_paint_device_test.cpp
index e4922b39400..48155455d77 100644
--- a/libs/image/tests/kis_paint_device_test.cpp
+++ b/libs/image/tests/kis_paint_device_test.cpp
@@ -1420,11 +1420,11 @@ void fillGradientDevice(KisPaintDeviceSP dev, const QRect &rect, bool flat = fal
     } else {
         // fill device with a gradient
         KisSequentialIterator it(dev, rect);
-        do {
+        while (it.nextPixel()) {
             QColor c((10 * it.x()) & 0xFF, (10 * it.y()) & 0xFF, 0, 255);
             KoColor color(c, dev->colorSpace());
             memcpy(it.rawData(), color.data(), dev->pixelSize());
-        } while (it.nextPixel());
+        }
     }
 }
 #include "kis_lod_transform.h"
diff --git a/libs/image/tests/kis_paint_layer_test.cpp b/libs/image/tests/kis_paint_layer_test.cpp
index b56149c9505..55c7eb75adf 100644
--- a/libs/image/tests/kis_paint_layer_test.cpp
+++ b/libs/image/tests/kis_paint_layer_test.cpp
@@ -89,9 +89,9 @@ void KisPaintLayerTest::testProjection()
 
     // We've inverted the mask, so now nothing is seen
     KisSequentialConstIterator it(layer->projection(), qimage.rect());
-    do {
+    while (it.nextPixel()) {
         QVERIFY(cs->opacityU8(it.oldRawData()) == OPACITY_TRANSPARENT_U8);
-    } while (it.nextPixel());
+    };
 
     // Now fill the layer with some opaque pixels
     transparencyMask->select(qimage.rect());
diff --git a/libs/image/tests/kis_painter_test.cpp b/libs/image/tests/kis_painter_test.cpp
index 68f963cf966..adf879b35c3 100644
--- a/libs/image/tests/kis_painter_test.cpp
+++ b/libs/image/tests/kis_painter_test.cpp
@@ -267,11 +267,11 @@ void KisPainterTest::testSelectionBltSelection()
     QCOMPARE(dst->selectedExactRect(), QRect(10, 10, 10, 10));
 
     KisSequentialConstIterator it(dst, QRect(10, 10, 10, 10));
-    do {
+    while (it.nextPixel()) {
         // These are selections, so only one channel and it should
         // be totally selected
         QCOMPARE(it.oldRawData()[0], MAX_SELECTED);
-    } while (it.nextPixel());
+    }
 }
 
 /*
@@ -400,11 +400,11 @@ void KisPainterTest::testSelectionBitBltEraseCompositeOp()
 
     QRect erasedRect(50, 50, 50, 50);
     KisSequentialConstIterator it(dst, QRect(0, 0, 150, 150));
-    do {
+    while (it.nextPixel()) {
         if(!erasedRect.contains(it.x(), it.y())) {
              QVERIFY(memcmp(it.oldRawData(), c.data(), cs->pixelSize()) == 0);
         }
-    } while (it.nextPixel());
+    }
 
 }
 
diff --git a/libs/image/tests/kis_projection_test.cpp b/libs/image/tests/kis_projection_test.cpp
index 5e80ad2e8db..23d834e7686 100644
--- a/libs/image/tests/kis_projection_test.cpp
+++ b/libs/image/tests/kis_projection_test.cpp
@@ -49,11 +49,11 @@ void KisProjectionTest::testDirty()
 
     // Check that the projection is totally redistribute
     KisSequentialConstIterator it(image->projection(), QRect(0, 0, 1000, 1000));
-    do {
+    while (it.nextPixel()) {
         QColor c;
         image->colorSpace()->toQColor(it.oldRawData(), &c, image->profile());
         QVERIFY(c == Qt::red);
-    } while (it.nextPixel());
+    }
 }
 
 QTEST_MAIN(KisProjectionTest)
diff --git a/libs/libkis/Channel.cpp b/libs/libkis/Channel.cpp
index 93518e85c86..609176622f4 100644
--- a/libs/libkis/Channel.cpp
+++ b/libs/libkis/Channel.cpp
@@ -136,11 +136,11 @@ QRect Channel::bounds() const
     KisSequentialConstIterator srcIt(d->node->projection(), rect);
     KisSequentialIterator dstIt(dev, rect);
 
-    do {
+    while(srcIt.nextPixel() && dstIt.nextPixel()) {
         const quint8 *srcPtr = srcIt.rawDataConst();
         memcpy(dstIt.rawData(), srcPtr + d->channel->pos(), d->channel->size());
 
-    } while(srcIt.nextPixel() && dstIt.nextPixel());
+    }
 
     if (dev) {
         return dev->exactBounds();
@@ -159,27 +159,27 @@ QByteArray Channel::pixelData(const QRect &rect) const
     KisSequentialConstIterator srcIt(d->node->projection(), rect);
 
     if (d->node->colorSpace()->colorDepthId() == Integer8BitsColorDepthID) {
-        do {
+        while(srcIt.nextPixel()) {
             stream << (quint8) *srcIt.rawDataConst();
-        } while(srcIt.nextPixel());
+        }
     }
     else if (d->node->colorSpace()->colorDepthId() ==  Integer16BitsColorDepthID) {
-        do {
+        while(srcIt.nextPixel()) {
             stream << (quint16) *srcIt.rawDataConst();
-        } while(srcIt.nextPixel());
+        }
     }
 #ifdef HAVE_OPENEXR
     else if (d->node->colorSpace()->colorDepthId() == Float16BitsColorDepthID) {
-        do {
+        while(srcIt.nextPixel()) {
             half h = (half)*srcIt.rawDataConst();
             stream << (float)h;
-        } while(srcIt.nextPixel());
+        }
     }
 #endif
     else if (d->node->colorSpace()->colorDepthId() == Float32BitsColorDepthID) {
-        do {
+        while(srcIt.nextPixel()) {
             stream << (float) *srcIt.rawDataConst();
-        } while(srcIt.nextPixel());
+        }
 
     }
 
@@ -194,36 +194,36 @@ void Channel::setPixelData(QByteArray value, const QRect &rect)
     KisSequentialIterator dstIt(d->node->paintDevice(), rect);
 
     if (d->node->colorSpace()->colorDepthId() == Integer8BitsColorDepthID) {
-        do {
+        while (dstIt.nextPixel()) {
             quint8 v;
             stream >> v;
             *dstIt.rawData() = v ;
-        } while(dstIt.nextPixel());
+        }
     }
     else if (d->node->colorSpace()->colorDepthId() ==  Integer16BitsColorDepthID) {
-        do {
+        while (dstIt.nextPixel()) {
             quint16 v;
             stream >> v;
             *dstIt.rawData() = v ;
-        } while(dstIt.nextPixel());
+        }
     }
 #ifdef HAVE_OPENEXR
     else if (d->node->colorSpace()->colorDepthId() == Float16BitsColorDepthID) {
-        do {
+        while (dstIt.nextPixel()) {
             float f;
             stream >> f;
             half v = f;
             *dstIt.rawData() = v ;
-        } while(dstIt.nextPixel());
+        }
 
     }
 #endif
     else if (d->node->colorSpace()->colorDepthId() == Float32BitsColorDepthID) {
-        do {
+        while (dstIt.nextPixel()) {
             float v;
             stream >> v;
             *dstIt.rawData() = v ;
-        } while(dstIt.nextPixel());
+        }
     }
 }
 
diff --git a/libs/ui/canvas/kis_display_color_converter.cpp b/libs/ui/canvas/kis_display_color_converter.cpp
index 2c69d0ba242..ba1ec8aef15 100644
--- a/libs/ui/canvas/kis_display_color_converter.cpp
+++ b/libs/ui/canvas/kis_display_color_converter.cpp
@@ -454,7 +454,7 @@ KisDisplayColorConverter::Private::convertToQImageDirect(KisPaintDeviceSP device
     int numChannels = cs->channelCount();
     QVector<float> normalizedChannels(numChannels);
 
-    do {
+    while (it.nextPixel()) {
         cs->normalisedChannelsValue(it.rawDataConst(), normalizedChannels);
         displayFilter->filter((quint8*)normalizedChannels.data(), 1);
 
@@ -473,7 +473,7 @@ KisDisplayColorConverter::Private::convertToQImageDirect(KisPaintDeviceSP device
         }
 
         dstPtr += 4;
-    } while (it.nextPixel());
+    }
 
     return image;
 }
diff --git a/libs/ui/flake/kis_shape_selection.cpp b/libs/ui/flake/kis_shape_selection.cpp
index ce7c337328e..f396c49e392 100644
--- a/libs/ui/flake/kis_shape_selection.cpp
+++ b/libs/ui/flake/kis_shape_selection.cpp
@@ -319,9 +319,9 @@ void KisShapeSelection::renderSelection(KisPaintDeviceSP projection, const QRect
             qint32 rectHeight = qMin(r.y() + r.height() - y, MASK_IMAGE_HEIGHT);
 
             KisSequentialIterator it(projection, QRect(x, y, rectWidth, rectHeight));
-            do {
+            while (it.nextPixel()) {
                 (*it.rawData()) = qRed(polygonMaskImage.pixel(it.x() - x, it.y() - y));
-            } while (it.nextPixel());
+            }
         }
     }
 }
diff --git a/libs/ui/kis_node_manager.cpp b/libs/ui/kis_node_manager.cpp
index 4e3585a9d48..317eb93273a 100644
--- a/libs/ui/kis_node_manager.cpp
+++ b/libs/ui/kis_node_manager.cpp
@@ -1112,13 +1112,13 @@ void KisNodeManager::slotSplitAlphaIntoMask()
     KisSequentialIterator srcIt(srcDevice, processRect);
     KisSequentialIterator dstIt(selectionDevice, processRect);
 
-    do {
+    while (srcIt.nextPixel() && dstIt.nextPixel()) {
         quint8 *srcPtr = srcIt.rawData();
         quint8 *alpha8Ptr = dstIt.rawData();
 
         *alpha8Ptr = srcCS->opacityU8(srcPtr);
         srcCS->setOpacity(srcPtr, OPACITY_OPAQUE_U8, 1);
-    } while (srcIt.nextPixel() && dstIt.nextPixel());
+    }
 
     m_d->commandsAdapter.addExtraCommand(transaction.endAndTake());
 
@@ -1175,12 +1175,12 @@ void KisNodeManager::Private::mergeTransparencyMaskAsAlpha(bool writeToLayers)
     KisSequentialIterator srcIt(selectionDevice, processRect);
     KisSequentialIterator dstIt(dstDevice, processRect);
 
-    do {
+    while (srcIt.nextPixel() && dstIt.nextPixel()) {
         quint8 *alpha8Ptr = srcIt.rawData();
         quint8 *dstPtr = dstIt.rawData();
 
         dstCS->setOpacity(dstPtr, *alpha8Ptr, 1);
-    } while (srcIt.nextPixel() && dstIt.nextPixel());
+    }
 
     if (writeToLayers) {
         commandsAdapter.addExtraCommand(transaction->endAndTake());
diff --git a/libs/ui/kis_png_converter.cpp b/libs/ui/kis_png_converter.cpp
index 736adbb7a8e..c39ddefc94d 100644
--- a/libs/ui/kis_png_converter.cpp
+++ b/libs/ui/kis_png_converter.cpp
@@ -975,7 +975,7 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe
         KisSequentialIterator it(device, imageRect);
 
         bool toomuchcolor = false;
-        do {
+        while (it.nextPixel()) {
             const quint8* c = it.oldRawData();
             bool findit = false;
             for (int i = 0; i < num_palette; i++) {
@@ -996,7 +996,7 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe
                 palette[num_palette].blue = c[0];
                 num_palette++;
             }
-        }  while (it.nextPixel());
+        }
 
         if (!toomuchcolor) {
             dbgFile << "Found a palette of " << num_palette << " colors";
diff --git a/libs/ui/tool/kis_tool_utils.cpp b/libs/ui/tool/kis_tool_utils.cpp
index 489fe8de1b1..00598e993ef 100644
--- a/libs/ui/tool/kis_tool_utils.cpp
+++ b/libs/ui/tool/kis_tool_utils.cpp
@@ -53,13 +53,13 @@ namespace KisToolUtils {
 
             const int radiusSq = pow2(effectiveRadius);
 
-            do {
+            while (it.nextPixel()) {
                 const QPoint realPos(it.x(),  it.y());
                 const QPoint pt = realPos - pos;
                 if (pow2(pt.x()) + pow2(pt.y()) < radiusSq) {
                     pixels << it.oldRawData();
                 }
-            } while (it.nextPixel());
+            }
 
             const quint8** cpixels = const_cast<const quint8**>(pixels.constData());
             cs->mixColorsOp()->mixColors(cpixels, pixels.size(), pickedColor.data());
diff --git a/plugins/dockers/channeldocker/channelmodel.cpp b/plugins/dockers/channeldocker/channelmodel.cpp
index cc761771bea..9b0f9b4f0b8 100644
--- a/plugins/dockers/channeldocker/channelmodel.cpp
+++ b/plugins/dockers/channeldocker/channelmodel.cpp
@@ -242,6 +242,7 @@ void ChannelModel::updateThumbnails(void)
 
         for (int y = 0; y < thumbnailSize.height(); y++) {
             for (int x = 0; x < thumbnailSize.width(); x++) {
+                it.nextPixel();
                 const quint8* pixel = it.rawDataConst();
                 for (int chan = 0; chan < m_channelCount; ++chan) {
                     QImage &img = m_thumbnails[chan];
@@ -252,7 +253,6 @@ void ChannelModel::updateThumbnails(void)
                     img.setPixel(x, y, qRgb(v, v, v));
 #endif
                 }
-                it.nextPixel();
             }
         }
     } else {
diff --git a/plugins/dockers/histogram/histogramdockerwidget.cpp b/plugins/dockers/histogram/histogramdockerwidget.cpp
index 411908a2799..3e2d5879a74 100644
--- a/plugins/dockers/histogram/histogramdockerwidget.cpp
+++ b/plugins/dockers/histogram/histogramdockerwidget.cpp
@@ -173,14 +173,16 @@ void HistogramComputationThread::run()
     if (bounds.isEmpty())
         return;
 
-    KisSequentialConstIterator it(m_dev, m_dev->exactBounds());
-    int i;
     quint32 toSkip = nSkip;
 
-    do {
-        i = it.nConseqPixels();
+    KisSequentialConstIterator it(m_dev, m_dev->exactBounds());
+
+    int numConseqPixels = it.nConseqPixels();
+    while (it.nextPixels(numConseqPixels)) {
+
+        numConseqPixels = it.nConseqPixels();
         const quint8* pixel = it.rawDataConst();
-        for (int k = 0; k < i; ++k) {
+        for (int k = 0; k < numConseqPixels; ++k) {
             if (--toSkip == 0) {
                 for (int chan = 0; chan < (int)channelCount; ++chan) {
                     bins[chan][cs->scaleToU8(pixel, chan)]++;
@@ -189,7 +191,7 @@ void HistogramComputationThread::run()
             }
             pixel += pixelSize;
         }
-    } while (it.nextPixels(i));
+    }
 
     emit resultReady(&bins);
 }
diff --git a/plugins/filters/colors/kis_color_to_alpha.cpp b/plugins/filters/colors/kis_color_to_alpha.cpp
index fb48d46adee..be04f2c3a52 100644
--- a/plugins/filters/colors/kis_color_to_alpha.cpp
+++ b/plugins/filters/colors/kis_color_to_alpha.cpp
@@ -80,7 +80,7 @@ void applyToIterator(const int numChannels, const int *channelIndex,
     quint8 *baseColorData_uint8 = baseColor.data();
     channel_type *baseColorData = reinterpret_cast<channel_type*>(baseColorData_uint8);
 
-    do {
+    while (it.nextPixel()) {
         channel_type *dst = reinterpret_cast<channel_type*>(it.rawData());
         quint8 *dst_uint8 = it.rawData();
 
@@ -97,7 +97,7 @@ void applyToIterator(const int numChannels, const int *channelIndex,
                                                   newOpacity);
 
         progressHelper.step();
-    } while(it.nextPixel());
+    }
 }
 
 void KisFilterColorToAlpha::processImpl(KisPaintDeviceSP device,
diff --git a/plugins/filters/colors/kis_minmax_filters.cpp b/plugins/filters/colors/kis_minmax_filters.cpp
index 8f1380a0ad6..96a02aef43b 100644
--- a/plugins/filters/colors/kis_minmax_filters.cpp
+++ b/plugins/filters/colors/kis_minmax_filters.cpp
@@ -102,10 +102,10 @@ void KisFilterMax::processImpl(KisPaintDeviceSP device,
 
     KisSequentialIterator it(device, rect);
 
-    do {
+    while (it.nextPixel()) {
         F(it.oldRawData(), it.rawData(), nC);
         if (progressUpdater) progressUpdater->setProgress((++pixelsProcessed) / totalCost);
-    } while(it.nextPixel());
+    }
 }
 
 KisFilterMin::KisFilterMin() : KisFilter(id(), categoryColors(), i18n("M&inimize Channel"))
@@ -144,9 +144,9 @@ void KisFilterMin::processImpl(KisPaintDeviceSP device,
     }
 
     KisSequentialIterator it(device, rect);
-    do {
+    while (it.nextPixel()) {
         F(it.oldRawData(), it.rawData(), nC);
         if (progressUpdater) progressUpdater->setProgress((++pixelsProcessed) / totalCost);
-    } while(it.nextPixel());
+    }
 }
 
diff --git a/plugins/filters/colorsfilters/colorsfilters.cpp b/plugins/filters/colorsfilters/colorsfilters.cpp
index 67c476eda41..36c11ef7b5b 100644
--- a/plugins/filters/colorsfilters/colorsfilters.cpp
+++ b/plugins/filters/colorsfilters/colorsfilters.cpp
@@ -162,14 +162,16 @@ void KisAutoContrast::processImpl(KisPaintDeviceSP device,
     if (totalCost == 0) totalCost = 1;
     qint32 pixelsProcessed = 0;
 
-    quint32 npix;
-    do {
-        npix = it.nConseqPixels();
+    quint32 npix = it.nConseqPixels();
+    while(it.nextPixels(npix)  && !(progressUpdater && progressUpdater->interrupted())) {
+
         // adjust
+        npix = it.nConseqPixels();
         adj->transform(it.oldRawData(), it.rawData(), npix);
         pixelsProcessed += npix;
         if (progressUpdater) progressUpdater->setProgress(pixelsProcessed / totalCost);
-    } while(it.nextPixels(npix)  && !(progressUpdater && progressUpdater->interrupted()));
+    }
+
     delete[] transfer;
     delete adj;
 }
diff --git a/plugins/filters/embossfilter/kis_emboss_filter.cpp b/plugins/filters/embossfilter/kis_emboss_filter.cpp
index 0eed8d49ea9..c388b7f4716 100644
--- a/plugins/filters/embossfilter/kis_emboss_filter.cpp
+++ b/plugins/filters/embossfilter/kis_emboss_filter.cpp
@@ -107,7 +107,7 @@ void KisEmbossFilter::processImpl(KisPaintDeviceSP device,
     QColor color1;
     QColor color2;
     KisRandomConstAccessorSP acc = device->createRandomAccessorNG(srcTopLeft.x(), srcTopLeft.y());
-    do {
+    while (it.nextPixel()) {
     
         // XXX: COLORSPACE_INDEPENDENCE or at least work IN RGB16A
         device->colorSpace()->toQColor(it.oldRawData(), &color1);
@@ -123,7 +123,7 @@ void KisEmbossFilter::processImpl(KisPaintDeviceSP device,
 
         device->colorSpace()->fromQColor(QColor(Gray, Gray, Gray, color1.alpha()), it.rawData());
         if (progressUpdater) { progressUpdater->setValue(it.y()); if(progressUpdater->interrupted()) return; }
-    } while(it.nextPixel());
+    }
 }
 
 // This method have been ported from Pieter Z. Voloshyn algorithm code.
diff --git a/plugins/filters/fastcolortransfer/fastcolortransfer.cpp b/plugins/filters/fastcolortransfer/fastcolortransfer.cpp
index df9b6833545..e751d8763c6 100644
--- a/plugins/filters/fastcolortransfer/fastcolortransfer.cpp
+++ b/plugins/filters/fastcolortransfer/fastcolortransfer.cpp
@@ -113,7 +113,7 @@ void KisFilterFastColorTransfer::processImpl(KisPaintDeviceSP device,
 
     KisSequentialConstIterator srcIt(srcLAB, applyRect);
 
-    do {
+    while (srcIt.nextPixel() && !(progressUpdater && progressUpdater->interrupted())) {
         const quint16* data = reinterpret_cast<const quint16*>(srcIt.oldRawData());
         quint32 L = data[0];
         quint32 A = data[1];
@@ -125,7 +125,7 @@ void KisFilterFastColorTransfer::processImpl(KisPaintDeviceSP device,
         sigmaA_src += A * A;
         sigmaB_src += B * B;
         if (progressUpdater) progressUpdater->setValue(++count);
-    } while (srcIt.nextPixel() && !(progressUpdater && progressUpdater->interrupted()));
+    }
     
     double totalSize = 1. / (applyRect.width() * applyRect.height());
     meanL_src *= totalSize;
diff --git a/plugins/filters/fastcolortransfer/kis_wdg_fastcolortransfer.cpp b/plugins/filters/fastcolortransfer/kis_wdg_fastcolortransfer.cpp
index 8da8bcfeaec..f4d3cbfb6c6 100644
--- a/plugins/filters/fastcolortransfer/kis_wdg_fastcolortransfer.cpp
+++ b/plugins/filters/fastcolortransfer/kis_wdg_fastcolortransfer.cpp
@@ -104,7 +104,7 @@ KisPropertiesConfigurationSP KisWdgFastColorTransfer::configuration() const
     double sigmaL_ref = 0., sigmaA_ref = 0., sigmaB_ref = 0.;
 
     KisSequentialConstIterator refIt(ref, importedImage->bounds());
-    do {
+    while (refIt.nextPixel()) {
         const quint16* data = reinterpret_cast<const quint16*>(refIt.oldRawData());
 
         quint32 L = data[0];
@@ -119,7 +119,7 @@ KisPropertiesConfigurationSP KisWdgFastColorTransfer::configuration() const
         sigmaA_ref += A * A;
         sigmaB_ref += B * B;
 
-    } while (refIt.nextPixel());
+    }
 
     double totalSize = 1. / (importedImage->width() * importedImage->height());
 
diff --git a/plugins/filters/gradientmap/krita_filter_gradient_map.cpp b/plugins/filters/gradientmap/krita_filter_gradient_map.cpp
index a1ae4bef6cf..c9c29c855b8 100644
--- a/plugins/filters/gradientmap/krita_filter_gradient_map.cpp
+++ b/plugins/filters/gradientmap/krita_filter_gradient_map.cpp
@@ -79,7 +79,7 @@ void KritaFilterGradientMap::processImpl(KisPaintDeviceSP device,
     int p = 0;
     quint8 grey;
     const int pixelSize = device->colorSpace()->pixelSize();
-    do {
+    while (it.nextPixel()) {
         grey = device->colorSpace()->intensity8(it.oldRawData());
         gradient.colorAt(outColor,(qreal)grey/255);
         outColor.setOpacity(qMin(KoColor(it.oldRawData(), device->colorSpace()).opacityF(), outColor.opacityF()));
@@ -87,7 +87,7 @@ void KritaFilterGradientMap::processImpl(KisPaintDeviceSP device,
         memcpy(it.rawData(), outColor.data(), pixelSize);
         if (progressUpdater) progressUpdater->setValue(p++);
 
-    } while (it.nextPixel());
+    }
 
 }
 
diff --git a/plugins/filters/noisefilter/noisefilter.cpp b/plugins/filters/noisefilter/noisefilter.cpp
index c3e192b31d4..cd2c9525ab1 100644
--- a/plugins/filters/noisefilter/noisefilter.cpp
+++ b/plugins/filters/noisefilter/noisefilter.cpp
@@ -134,7 +134,7 @@ void KisFilterNoise::processImpl(KisPaintDeviceSP device,
     KisRandomGenerator randg(seedGreen);
     KisRandomGenerator randb(seedBlue);
 
-    do {
+    while (it.nextPixel() && !(progressUpdater && progressUpdater->interrupted())) {
         if (randt.doubleRandomAt(it.x(), it.y()) > threshold) {
             // XXX: Added static_cast to get rid of warnings
             QColor c = qRgb(static_cast<int>((double)randr.doubleRandomAt(it.x(), it.y()) * 255),
@@ -145,7 +145,7 @@ void KisFilterNoise::processImpl(KisPaintDeviceSP device,
             mixOp->mixColors(pixels, weights, 2, it.rawData());
         }
         if (progressUpdater) progressUpdater->setValue(++count);
-    } while (it.nextPixel() && !(progressUpdater && progressUpdater->interrupted()));
+    }
 
     delete [] interm;
 }
diff --git a/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cpp b/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cpp
index cb4e9eb8dea..96f862ab580 100644
--- a/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cpp
+++ b/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cpp
@@ -157,7 +157,7 @@ void KisOilPaintFilter::MostFrequentColor(KisPaintDeviceSP src, quint8* dst, con
     if ((starty + height) > bounds.bottom()) height = bounds.bottom() - starty + 1;
     Q_ASSERT((starty + height - 1) <= bounds.bottom());
     KisSequentialConstIterator srcIt(src, QRect(startx, starty, width, height));
-    do {
+    while (srcIt.nextPixel()) {
 
         cs->normalisedChannelsValue(srcIt.rawDataConst(), channel);
 
@@ -171,7 +171,7 @@ void KisOilPaintFilter::MostFrequentColor(KisPaintDeviceSP src, quint8* dst, con
                 AverageChannels[I][i] += channel[i];
             }
         }
-    } while (srcIt.nextPixel());
+    }
 
     I = 0;
     int MaxInstance = 0;
diff --git a/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp b/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp
index f913f493570..46c64759c6b 100644
--- a/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp
+++ b/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp
@@ -100,12 +100,12 @@ void KisPixelizeFilter::processImpl(KisPaintDeviceSP device,
 
             //read
             KisSequentialConstIterator srcIt(device, QRect(srcTopLeft.x() + x, srcTopLeft.y() + y, w, h));
-            do {
+            while (srcIt.nextPixel()) {
                 for (qint32 i = 0; i < pixelSize; i++) {
                     average[i] += srcIt.oldRawData()[i];
                 }
                 count++;
-            } while (srcIt.nextPixel());
+            }
 
             //average
             if (count > 0) {
@@ -114,11 +114,11 @@ void KisPixelizeFilter::processImpl(KisPaintDeviceSP device,
             }
             //write
             KisSequentialIterator dstIt(device, QRect(srcTopLeft.x() + x, srcTopLeft.y() + y, w, h));
-            do {
+            while (srcIt.nextPixel()) {
                 for (int i = 0; i < pixelSize; i++) {
                     dstIt.rawData()[i] = average[i];
                 }
-            } while (dstIt.nextPixel());
+            }
             if (progressUpdater) progressUpdater->setValue(++numberOfPixelsProcessed);
         }
     }
diff --git a/plugins/filters/randompickfilter/randompickfilter.cpp b/plugins/filters/randompickfilter/randompickfilter.cpp
index d88c3f7a9a4..576b425139e 100644
--- a/plugins/filters/randompickfilter/randompickfilter.cpp
+++ b/plugins/filters/randompickfilter/randompickfilter.cpp
@@ -111,7 +111,7 @@ void KisFilterRandomPick::processImpl(KisPaintDeviceSP device,
     weights[0] = (255 * opacity) / 100; weights[1] = 255 - weights[0];
     const quint8* pixels[2];
     KoMixColorsOp * mixOp = cs->mixColorsOp();
-    do{
+    while (dstIt.nextPixel()) {
         if (randT.doubleRandomAt(dstIt.x(), dstIt.y()) > threshold) {
             int x = static_cast<int>(dstIt.x() + windowsize * (randH.doubleRandomAt(dstIt.x(), dstIt.y()) - 0.5));
             int y = static_cast<int>(dstIt.y() +  windowsize * (randV.doubleRandomAt(dstIt.x(), dstIt.y()) -0.5));
@@ -121,7 +121,7 @@ void KisFilterRandomPick::processImpl(KisPaintDeviceSP device,
             mixOp->mixColors(pixels, weights, 2, dstIt.rawData());
         }
         if (progressUpdater) progressUpdater->setValue(++count);
-    } while(dstIt.nextPixel());
+    }
 
 }
 
diff --git a/plugins/filters/threshold/threshold.cpp b/plugins/filters/threshold/threshold.cpp
index 7d23faea0ba..c54b3028304 100644
--- a/plugins/filters/threshold/threshold.cpp
+++ b/plugins/filters/threshold/threshold.cpp
@@ -91,7 +91,7 @@ void KisFilterThreshold::processImpl(KisPaintDeviceSP device,
     KisSequentialIterator it(device, applyRect);
     int p = 0;
     const int pixelSize = device->colorSpace()->pixelSize();
-    do {
+    while (it.nextPixel()) {
         if (device->colorSpace()->intensity8(it.oldRawData()) > threshold) {
             memcpy(it.rawData(), white.data(), pixelSize);
         }
@@ -101,7 +101,7 @@ void KisFilterThreshold::processImpl(KisPaintDeviceSP device,
 
         if (progressUpdater) progressUpdater->setValue(p++);
 
-    } while (it.nextPixel());
+    }
 
 }
 
diff --git a/plugins/filters/wavefilter/wavefilter.cpp b/plugins/filters/wavefilter/wavefilter.cpp
index a711983e5cf..13533dbcaa6 100644
--- a/plugins/filters/wavefilter/wavefilter.cpp
+++ b/plugins/filters/wavefilter/wavefilter.cpp
@@ -155,13 +155,13 @@ void KisFilterWave::processImpl(KisPaintDeviceSP device,
         horizontalcurve = new KisSinusoidalWaveCurve(horizontalamplitude, horizontalwavelength, horizontalshift);
     
     KisRandomSubAccessorSP srcRSA = device->createRandomSubAccessor();
-    do {
+    while (dstIt.nextPixel()) {
         double xv = horizontalcurve->valueAt(dstIt.y(), dstIt.x());
         double yv = verticalcurve->valueAt(dstIt.x(), dstIt.y());
         srcRSA->moveTo(QPointF(xv, yv));
         srcRSA->sampledOldRawData(dstIt.rawData());
         if (progressUpdater) progressUpdater->setProgress((++count) / cost);
-    } while (dstIt.nextPixel());
+    }
     delete horizontalcurve;
     delete verticalcurve;
 }
diff --git a/plugins/impex/csv/csv_saver.cpp b/plugins/impex/csv/csv_saver.cpp
index 1e8ea24d28c..9db56249b08 100644
--- a/plugins/impex/csv/csv_saver.cpp
+++ b/plugins/impex/csv/csv_saver.cpp
@@ -415,12 +415,12 @@ KisImageBuilder_Result CSVSaver::getLayer(CSVLayerRecord* layer, KisDocument* ex
     const KoColorSpace* cs = device->colorSpace();
 
     bool isThereAlpha = false;
-    do {
+    while (it.nextPixel()) {
         if (cs->opacityU8(it.oldRawData()) != OPACITY_OPAQUE_U8) {
             isThereAlpha = true;
             break;
         }
-    } while (it.nextPixel());
+    }
 
     if (!KisPNGConverter::isColorSpaceSupported(cs)) {
         device = new KisPaintDevice(*device.data());
diff --git a/plugins/impex/heightmap/kis_heightmap_export.cpp b/plugins/impex/heightmap/kis_heightmap_export.cpp
index 90af136a804..3bab487f393 100644
--- a/plugins/impex/heightmap/kis_heightmap_export.cpp
+++ b/plugins/impex/heightmap/kis_heightmap_export.cpp
@@ -54,9 +54,9 @@ static void writeData(KisPaintDeviceSP pd, const QRect &bounds, QDataStream &out
     KIS_ASSERT_RECOVER_RETURN(pd);
 
     KisSequentialConstIterator it(pd, bounds);
-    do {
+    while (it.nextPixel()) {
         out_stream << KoGrayTraits<T>::gray(const_cast<quint8*>(it.rawDataConst()));
-    } while(it.nextPixel());
+    }
 }
 
 KisHeightMapExport::KisHeightMapExport(QObject *parent, const QVariantList &) : KisImportExportFilter(parent)
diff --git a/plugins/impex/psd/psd_pixel_utils.cpp b/plugins/impex/psd/psd_pixel_utils.cpp
index d171c3ee46f..b926d00ae93 100644
--- a/plugins/impex/psd/psd_pixel_utils.cpp
+++ b/plugins/impex/psd/psd_pixel_utils.cpp
@@ -479,10 +479,10 @@ void readCommon(KisPaintDeviceSP dev,
 
         KisSequentialIterator it(dev, layerRect);
         int col = 0;
-        do {
+        while (it.nextPixel()) {
             pixelFunc(channelSize, channelBytes, col, it.rawData());
             col++;
-        } while(it.nextPixel());
+        }
 
     } else {
         KisHLineIteratorSP it = dev->createHLineIteratorNG(layerRect.left(), layerRect.top(), layerRect.width());
diff --git a/plugins/paintops/defaultpaintops/duplicate/kis_duplicateop.cpp b/plugins/paintops/defaultpaintops/duplicate/kis_duplicateop.cpp
index 5ad5888b6b5..41271657da2 100644
--- a/plugins/paintops/defaultpaintops/duplicate/kis_duplicateop.cpp
+++ b/plugins/paintops/defaultpaintops/duplicate/kis_duplicateop.cpp
@@ -195,11 +195,11 @@ KisSpacingInformation KisDuplicateOp::paintAt(const KisPaintInformation& info)
     //     KisRandomSubAccessorSP srcAcc = realSourceDevice->createRandomSubAccessor();
 
     //     //Action
-    //     do {
+    //     while (dstIt.nextPixel()) {
     //         QPointF p =  KisPerspectiveMath::matProd(startM, KisPerspectiveMath::matProd(endM, QPointF(dstIt.x() + dstRect.x(), dstIt.y() + dstRect.y())) + translat);
     //         srcAcc->moveTo(p);
     //         srcAcc->sampledOldRawData(dstIt.rawData());
-    //     } while (dstIt.nextPixel());
+    //     }
 
 
     // }
diff --git a/plugins/paintops/libpaintop/kis_bidirectional_mixing_option.cpp b/plugins/paintops/libpaintop/kis_bidirectional_mixing_option.cpp
index 10d2b7aef72..39dfb833cd3 100644
--- a/plugins/paintops/libpaintop/kis_bidirectional_mixing_option.cpp
+++ b/plugins/paintops/libpaintop/kis_bidirectional_mixing_option.cpp
@@ -59,7 +59,7 @@ void KisBidirectionalMixingOption::apply(KisPaintDeviceSP dab, KisPaintDeviceSP
     KisSequentialConstIterator cit(canvas, srcRect);
     KisSequentialIterator dit(dab, srcRect);
     QVector<float> cc(count), dc(count);
-    do {
+    while (cit.nextPixel() && dit.nextPixel()) {
         if (cs->opacityU8(dit.rawData()) > 10 && cs->opacityU8(cit.rawDataConst()) > 10) {
 
             cs->normalisedChannelsValue(cit.rawDataConst(), cc);
@@ -75,8 +75,7 @@ void KisBidirectionalMixingOption::apply(KisPaintDeviceSP dab, KisPaintDeviceSP
                 painter->setPaintColor(KoColor(dit.rawData(), cs));
             }
         }
-        dit.nextPixel();
-    } while(cit.nextPixel());
+    }
 }
 
 void KisBidirectionalMixingOption::applyFixed(KisFixedPaintDeviceSP dab, KisPaintDeviceSP device, KisPainter* painter, qint32 sx, qint32 sy, qint32 sw, qint32 sh, quint8 pressure, const QRect& dstRect)


More information about the kimageshop mailing list