Histogram white spike bug

William Steidtmann billstei at hbci.com
Mon Nov 22 17:33:23 CET 2010


This patch limits the bounds of the Levels Adjust Filter histogram to 
that of the image, rather than the paint device "exactBounds", because 
exactBounds includes pixel data outside the bounds of the image which is 
not relevant to the user.  This fixes the typically predominant spike on 
the highest (whitest) bin of the histogram, which was counting white 
pixels outside the image bounds.  This same fix can (and will hopefully) 
be applied to other filters that use histograms, but this patch does not 
include them.

Bill Steidtmann

-------------------

Index: krita/plugins/extensions/histogram/histogram.cc
===================================================================
--- krita/plugins/extensions/histogram/histogram.cc    (revision 1199730)
+++ krita/plugins/extensions/histogram/histogram.cc    (working copy)
@@ -99,7 +99,7 @@
          KisPaintDeviceSP dev = layer->paintDevice();

          if (dev)
-            dlgHistogram->setPaintDevice(dev);
+            dlgHistogram->setPaintDevice(dev, layer->image()->bounds());

          if (dlgHistogram->exec() == QDialog::Accepted) {
              // Do nothing; this is an informational dialog
Index: krita/plugins/extensions/histogram/dlg_histogram.cc
===================================================================
--- krita/plugins/extensions/histogram/dlg_histogram.cc    (revision 
1199730)
+++ krita/plugins/extensions/histogram/dlg_histogram.cc    (working copy)
@@ -61,9 +61,9 @@
      delete m_page;
  }

-void DlgHistogram::setPaintDevice(KisPaintDeviceSP dev)
+void DlgHistogram::setPaintDevice(KisPaintDeviceSP dev, const QRect 
&bounds)
  {
-    m_page->setPaintDevice(dev);
+    m_page->setPaintDevice(dev, bounds);
  }

  void DlgHistogram::okClicked()
Index: krita/plugins/extensions/histogram/dlg_histogram.h
===================================================================
--- krita/plugins/extensions/histogram/dlg_histogram.h    (revision 1199730)
+++ krita/plugins/extensions/histogram/dlg_histogram.h    (working copy)
@@ -42,7 +42,7 @@
                   const char* name = 0);
      ~DlgHistogram();

-    void setPaintDevice(KisPaintDeviceSP dev);
+    void setPaintDevice(KisPaintDeviceSP dev, const QRect &bounds);

  private slots:
      void okClicked();
Index: krita/plugins/extensions/histogram/kis_histogram_widget.cc
===================================================================
--- krita/plugins/extensions/histogram/kis_histogram_widget.cc   
  (revision 1199730)
+++ krita/plugins/extensions/histogram/kis_histogram_widget.cc   
  (working copy)
@@ -51,12 +51,12 @@
  {
  }

-void KisHistogramWidget::setPaintDevice(KisPaintDeviceSP dev)
+void KisHistogramWidget::setPaintDevice(KisPaintDeviceSP dev, const 
QRect &bounds)
  {
      grpType->disconnect(this);
      cmbChannel->disconnect(this);

-    m_histogramView->setPaintDevice(dev);
+    m_histogramView->setPaintDevice(dev, bounds);
      setActiveChannel(0); // So we have the colored one if there are colors

      // The channels
Index: krita/plugins/extensions/histogram/kis_histogram_widget.h
===================================================================
--- krita/plugins/extensions/histogram/kis_histogram_widget.h   
  (revision 1199730)
+++ krita/plugins/extensions/histogram/kis_histogram_widget.h   
  (working copy)
@@ -45,7 +45,7 @@
      KisHistogramWidget(QWidget *parent, const char *name);
      virtual ~KisHistogramWidget();

-    void setPaintDevice(KisPaintDeviceSP dev);
+    void setPaintDevice(KisPaintDeviceSP dev, const QRect &bounds);

  private slots:
      void setActiveChannel(int channel);
Index: krita/plugins/filters/levelfilter/kis_level_filter.cpp
===================================================================
--- krita/plugins/filters/levelfilter/kis_level_filter.cpp    (revision 
1199730)
+++ krita/plugins/filters/levelfilter/kis_level_filter.cpp    (working copy)
@@ -59,8 +59,7 @@

  KisConfigWidget * KisLevelFilter::createConfigurationWidget(QWidget* 
parent, const KisPaintDeviceSP dev, const KisImageWSP image) const
  {
-    Q_UNUSED(image);
-    return new KisLevelConfigWidget(parent, dev);
+    return new KisLevelConfigWidget(parent, dev, image->bounds());
  }

  bool KisLevelFilter::workWith(KoColorSpace* cs) const
@@ -100,7 +99,7 @@
      return cs->createBrightnessContrastAdjustment(transfer);
  }

-KisLevelConfigWidget::KisLevelConfigWidget(QWidget * parent, 
KisPaintDeviceSP dev)
+KisLevelConfigWidget::KisLevelConfigWidget(QWidget * parent, 
KisPaintDeviceSP dev, const QRect &bounds)
          : KisConfigWidget(parent)
  {
      m_page.setupUi(this);
@@ -145,7 +144,7 @@
      connect((QObject*)(m_page.chkLogarithmic), SIGNAL(toggled(bool)), 
this, SLOT(slotDrawHistogram(bool)));

      KoHistogramProducerSP producer = KoHistogramProducerSP(new 
KoGenericLabHistogramProducer());
-    histogram = new KisHistogram(dev, producer, LINEAR);
+    histogram = new KisHistogram(dev, bounds, producer, LINEAR);
      m_histlog = false;
      slotDrawHistogram();

Index: krita/plugins/filters/levelfilter/kis_level_filter.h
===================================================================
--- krita/plugins/filters/levelfilter/kis_level_filter.h    (revision 
1199730)
+++ krita/plugins/filters/levelfilter/kis_level_filter.h    (working copy)
@@ -62,7 +62,7 @@
  {
      Q_OBJECT
  public:
-    KisLevelConfigWidget(QWidget * parent, KisPaintDeviceSP dev);
+    KisLevelConfigWidget(QWidget * parent, KisPaintDeviceSP dev, const 
QRect &bounds);
      virtual ~KisLevelConfigWidget();

      virtual KisPropertiesConfiguration* configuration() const;
Index: krita/image/kis_histogram.cc
===================================================================
--- krita/image/kis_histogram.cc    (revision 1199730)
+++ krita/image/kis_histogram.cc    (working copy)
@@ -33,8 +33,8 @@
                             KoHistogramProducerSP producer,
                             const enumHistogramType type)
  {
-    KisPaintDeviceSP pd = layer->projection();
-    m_dev = pd;
+    m_paintDevice = layer->projection();
+    m_bounds = layer->image()->bounds();
      m_type = type;
      m_producer = producer;
      m_selection = false;
@@ -43,11 +43,13 @@
      updateHistogram();
  }

+// TODO: get rid of this, make all Histogram clients pass bounds (they 
can pass paintdev->exactBounds() if they want)
  KisHistogram::KisHistogram(const KisPaintDeviceSP paintdev,
                             KoHistogramProducerSP producer,
                             const enumHistogramType type)
  {
-    m_dev = paintdev;
+    m_paintDevice = paintdev;
+    m_bounds = m_paintDevice->exactBounds();
      m_type = type;
      m_producer = producer;
      m_selection = false;
@@ -56,6 +58,23 @@
      updateHistogram();
  }

+KisHistogram::KisHistogram(const KisPaintDeviceSP paintdev,
+                           const QRect &bounds,
+                           KoHistogramProducerSP producer,
+                           const enumHistogramType type)
+{
+    m_paintDevice = paintdev;
+    m_bounds = bounds;
+    m_producer = producer;
+    m_type = type;
+
+    m_selection = false;
+    m_channel = 0;
+
+    // TODO: Why does Krita crash when updateHistogram() is *not* 
called here?
+    updateHistogram();
+}
+
  KisHistogram::~KisHistogram()
  {
  }
@@ -64,10 +83,8 @@
  {
      if (!m_producer) return;

-    QRect r;
-    r = m_dev->exactBounds();
-    KisRectConstIteratorPixel srcIt = 
m_dev->createRectConstIterator(r.x(), r.y(), r.width(), r.height());
-    const KoColorSpace* cs = m_dev->colorSpace();
+    KisRectConstIteratorPixel srcIt = 
m_paintDevice->createRectConstIterator(m_bounds.left(), m_bounds.top(), 
m_bounds.width(), m_bounds.height());
+    const KoColorSpace* cs = m_paintDevice->colorSpace();

      // Let the producer do it's work
      m_producer->clear();
Index: krita/image/kis_histogram.h
===================================================================
--- krita/image/kis_histogram.h    (revision 1199730)
+++ krita/image/kis_histogram.h    (working copy)
@@ -20,6 +20,7 @@
  #define KIS_HISTOGRAM_

  #include <QVector>
+#include <QRect>

  #include "KoHistogramProducer.h"

@@ -111,6 +112,11 @@
                   KoHistogramProducerSP producer,
                   const enumHistogramType type);

+    KisHistogram(KisPaintDeviceSP paintdev,
+                 const QRect &bounds,
+                 KoHistogramProducerSP producer,
+                 const enumHistogramType type);
+
      virtual ~KisHistogram();

      /** Updates the information in the producer */
@@ -176,17 +182,15 @@
      QVector<Calculations> calculateForRange(double from, double to);
      Calculations calculateSingleRange(int channel, double from, double 
to);

-    KisPaintDeviceSP m_device;
+    const KisPaintDeviceSP m_paintDevice;
+    QRect m_bounds;
      KoHistogramProducerSP m_producer;
-
      enumHistogramType m_type;

      qint32 m_channel;
      double m_selFrom, m_selTo;
      bool m_selection;

-    const KisPaintDeviceSP m_dev;
-
      QVector<Calculations> m_completeCalculations, m_selectionCalculations;
  };

Index: krita/ui/kis_histogram_view.cc
===================================================================
--- krita/ui/kis_histogram_view.cc    (revision 1199730)
+++ krita/ui/kis_histogram_view.cc    (working copy)
@@ -60,7 +60,7 @@
  {
  }

-void KisHistogramView::setPaintDevice(KisPaintDeviceSP dev)
+void KisHistogramView::setPaintDevice(KisPaintDeviceSP dev, const QRect 
&bounds)
  {
      m_cs = dev->colorSpace();

@@ -72,7 +72,7 @@
      m_from = m_currentProducer->viewFrom();
      m_width = m_currentProducer->viewWidth();

-    m_histogram = new KisHistogram(dev, m_currentProducer, LINEAR);
+    m_histogram = new KisHistogram(dev, bounds, m_currentProducer, LINEAR);

      updateHistogram();
  }
Index: krita/ui/kis_histogram_view.h
===================================================================
--- krita/ui/kis_histogram_view.h    (revision 1199730)
+++ krita/ui/kis_histogram_view.h    (working copy)
@@ -63,7 +63,7 @@

      virtual ~KisHistogramView();

-    void setPaintDevice(KisPaintDeviceSP dev);
+    void setPaintDevice(KisPaintDeviceSP dev, const QRect &bounds);

      void setHistogram(KisHistogramSP histogram);


More information about the kimageshop mailing list