"kernel longer than line" because user chose large sigma
Related to #64 
Related to #53

A single 8bit .tif stack file (containing two image slices) was loaded through 'Add File' option, then at the stage of 'Feature Selection', after selected a number of features (i.e. clicked OK button), the program crashed. The printed error message is as follows (repeated in multiple times):

RuntimeError: 
Precondition violation!
convolveLine(): kernel longer than line.

(/home/czhang/softwares/vigra/include/vigra/separableconvolution.hxx:914)

```
ERROR: volumina tiling layer rendering worker thread caught an unhandled exception:Traceback (most recent call last):
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/volumina-0.6a-py2.7.egg/volumina/tiling.py", line 548, in _dirtyLayersWorker
    img = image_req.wait()
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/volumina-0.6a-py2.7.egg/volumina/pixelpipeline/imagesources.py", line 116, in wait
    self._arrayreq.wait()
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/volumina-0.6a-py2.7.egg/volumina/pixelpipeline/slicesources.py", line 22, in wait
    return self._sp(self._ar.wait())
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/volumina-0.6a-py2.7.egg/volumina/pixelpipeline/datasources.py", line 387, in wait
    rawData = self._rawRequest.wait()
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/volumina-0.6a-py2.7.egg/volumina/pixelpipeline/datasources.py", line 188, in wait
    a = self._req[0].wait()
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/request/request_rewrite.py", line 293, in wait
    return self._wait(timeout)
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/request/request_rewrite.py", line 316, in _wait
    self._wait_within_foreign_thread( timeout )
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/request/request_rewrite.py", line 198, in _execute
    self._result = self.fn()
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/graph.py", line 788, in __call__
    result_op = self.operator.execute(self.slot, (), self.roi, destination)
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/volumina-0.6a-py2.7.egg/volumina/adaptors.py", line 86, in execute
    tmpres = self.inputs["input"][inSlice].wait()
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/request/request_rewrite.py", line 293, in wait
    return self._wait(timeout)
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/request/request_rewrite.py", line 316, in _wait
    self._wait_within_foreign_thread( timeout )
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/request/request_rewrite.py", line 198, in _execute
    self._result = self.fn()
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/graph.py", line 788, in __call__
    result_op = self.operator.execute(self.slot, (), self.roi, destination)
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/operators/generic.py", line 503, in execute
    res = self.inputs["Input"][newKey].allocate().wait()
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/request/request_rewrite.py", line 293, in wait
    return self._wait(timeout)
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/request/request_rewrite.py", line 316, in _wait
    self._wait_within_foreign_thread( timeout )
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/request/request_rewrite.py", line 198, in _execute
    self._result = self.fn()
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/graph.py", line 788, in __call__
    result_op = self.operator.execute(self.slot, (), self.roi, destination)
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/graph.py", line 1360, in execute
    return self.operator.execute(self, totalIndex, roi, result)
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/operators/vigraOperators.py", line 359, in execute
    return self.execute(self.Output, (), rroi, result)
  File "/home/czhang/ilastikenv/local/lib/python2.7/site-packages/lazyflow-0.0.0-py2.7.egg/lazyflow/operators/vigraOperators.py", line 483, in execute
    sourceArraysForSigmas[j] = vigra.filters.gaussianSmoothing(sourceArrayV, sigma = tempSigma, roi = droi, window_size = 3.5)
RuntimeError: 
Precondition violation!
convolveLine(): kernel longer than line.

(/home/czhang/softwares/vigra/include/vigra/separableconvolution.hxx:914)
```

diff --git a/ilastik/applets/labeling/icons/threshold.png b/ilastik/applets/labeling/icons/threshold.png
new file mode 100644
index 000000000..2e24f05a5
Binary files /dev/null and b/ilastik/applets/labeling/icons/threshold.png differ
diff --git a/ilastik/applets/labeling/labelingGui.py b/ilastik/applets/labeling/labelingGui.py
index 1134caaf4..b28d743b1 100644
--- a/ilastik/applets/labeling/labelingGui.py
+++ b/ilastik/applets/labeling/labelingGui.py
@@ -49,6 +49,7 @@ class Tool():
     Navigation = 0 # Arrow
     Paint      = 1
     Erase      = 2
+    Threshold  = 3
 
 class LabelingGui(LayerViewerGui):
     """
@@ -218,11 +219,27 @@ class LabelingGui(LayerViewerGui):
         _labelControlUi.eraserToolButton.setCheckable(True)
         _labelControlUi.eraserToolButton.clicked.connect( lambda checked: self._handleToolButtonClicked(checked, Tool.Erase) )
 
-        # This maps tool types to the buttons that enable them
-        self.toolButtons = { Tool.Navigation : _labelControlUi.arrowToolButton,
-                             Tool.Paint      : _labelControlUi.paintToolButton,
-                             Tool.Erase      : _labelControlUi.eraserToolButton }
+        # Initialize the thresholding tool
+        if hasattr(_labelControlUi, "thresToolButton"):
+            thresholdIconPath = os.path.split(__file__)[0] \
+              + "/icons/threshold.png"
+            thresholdIcon = QIcon(thresholdIconPath)
+            _labelControlUi.thresToolButton.setIcon(thresholdIcon)
+            _labelControlUi.thresToolButton.setCheckable(True)
+            _labelControlUi.thresToolButton.clicked.connect( lambda checked: self._handleToolButtonClicked(checked, Tool.Threshold) )
+
 
+        # This maps tool types to the buttons that enable them
+        if hasattr(_labelControlUi, "thresToolButton"):
+            self.toolButtons = { Tool.Navigation : _labelControlUi.arrowToolButton,
+                                 Tool.Paint      : _labelControlUi.paintToolButton,
+                                 Tool.Erase      : _labelControlUi.eraserToolButton,
+                                 Tool.Threshold  : _labelControlUi.thresToolButton}
+        else:
+            self.toolButtons = { Tool.Navigation : _labelControlUi.arrowToolButton,
+                                 Tool.Paint      : _labelControlUi.paintToolButton,
+                                 Tool.Erase      : _labelControlUi.eraserToolButton}
+            
         self.brushSizes = [ 1, 3, 5, 7, 11, 23, 31, 61 ]
 
         for size in self.brushSizes:
@@ -261,6 +278,7 @@ class LabelingGui(LayerViewerGui):
         shortcutGroupName = "Labeling"
 
         if hasattr(self.labelingDrawerUi, "AddLabelButton"):
+
             mgr.register("a", ActionInfo( shortcutGroupName,
                                           "New Label",
                                           "Add New Label Class",
@@ -288,6 +306,14 @@ class LabelingGui(LayerViewerGui):
                                        self.labelingDrawerUi.eraserToolButton.click,
                                        self.labelingDrawerUi.eraserToolButton,
                                        self.labelingDrawerUi.eraserToolButton ) )
+        if hasattr(self.labelingDrawerUi, "thresToolButton"):
+            mgr.register( "t", ActionInfo( shortcutGroupName,
+                                           "Window Leveling",
+                                           "<p>Window Leveling can be used to adjust the data range used for visualization. Pressing the left mouse button while moving the mouse back and forth changes the window width (data range). Moving the mouse in the left-right plane changes the window mean. Pressing the right mouse button leads to an automatic range adjustment.",
+                                           self.labelingDrawerUi.thresToolButton.click,
+                                           self.labelingDrawerUi.thresToolButton,
+                                           self.labelingDrawerUi.thresToolButton ) )
+        
 
         self._labelShortcuts = []
 
@@ -354,9 +380,15 @@ class LabelingGui(LayerViewerGui):
             return
 
         # The volume editor expects one of two specific names
-        modeNames = { Tool.Navigation   : "navigation",
-                      Tool.Paint        : "brushing",
-                      Tool.Erase        : "brushing" }
+        if hasattr(self.labelingDrawerUi, "thresToolButton"):
+            modeNames = { Tool.Navigation   : "navigation",
+                          Tool.Paint        : "brushing",
+                          Tool.Erase        : "brushing" ,
+                          Tool.Threshold    : "thresholding"}
+        else:
+            modeNames = { Tool.Navigation   : "navigation",
+                          Tool.Paint        : "brushing",
+                          Tool.Erase        : "brushing" }
 
         # If the user can't label this image, disable the button and say why its disabled
         labelsAllowed = False
@@ -401,10 +433,17 @@ class LabelingGui(LayerViewerGui):
                 self.editor.brushingModel.setBrushSize(eraserSize)
                 # update GUI 
                 self._gui_setErasing()
+            elif toolId == Tool.Threshold:
+                self._gui_setThresholding()
 
         self.editor.setInteractionMode( modeNames[toolId] )
         self._toolId = toolId
         
+    def _gui_setThresholding(self):
+        self._labelControlUi.brushSizeComboBox.setEnabled(False)
+        self._labelControlUi.brushSizeCaption.setEnabled(False)
+        self._labelControlUi.thresToolButton.setChecked(True)
+
     def _gui_setErasing(self):
         self._labelControlUi.brushSizeComboBox.setEnabled(True)
         self._labelControlUi.brushSizeCaption.setEnabled(True)
@@ -415,7 +454,7 @@ class LabelingGui(LayerViewerGui):
         self._labelControlUi.brushSizeComboBox.setEnabled(False)
         self._labelControlUi.brushSizeCaption.setEnabled(False)
         self._labelControlUi.arrowToolButton.setChecked(True)
-        self._labelControlUi.arrowToolButton.setChecked(True)
+        # self._labelControlUi.arrowToolButton.setChecked(True) # why twice?
     def _gui_setBrushing(self):
         self._labelControlUi.brushSizeComboBox.setEnabled(True)
         self._labelControlUi.brushSizeCaption.setEnabled(True)
@@ -430,7 +469,6 @@ class LabelingGui(LayerViewerGui):
         self._labelControlUi.eraserToolButton.setEnabled(enable)
         self._labelControlUi.brushSizeCaption.setEnabled(enable)
         self._labelControlUi.brushSizeComboBox.setEnabled(enable)
-    
 
 
     def _onBrushSizeChange(self, index):
diff --git a/ilastik/applets/pixelClassification/labelingDrawer.ui b/ilastik/applets/pixelClassification/labelingDrawer.ui
index 8637e0618..c39637465 100644
--- a/ilastik/applets/pixelClassification/labelingDrawer.ui
+++ b/ilastik/applets/pixelClassification/labelingDrawer.ui
@@ -103,6 +103,13 @@
        </property>
       </widget>
      </item>
+     <item>
+      <widget class="QToolButton" name="thresToolButton">
+       <property name="text">
+        <string>...</string>
+       </property>
+      </widget>
+     </item>
      <item>
       <spacer name="horizontalSpacer_3">
        <property name="orientation">
diff --git a/ilastik/applets/pixelClassification/pixelClassificationGui.py b/ilastik/applets/pixelClassification/pixelClassificationGui.py
index 10a78f36d..b0d184ad6 100644
--- a/ilastik/applets/pixelClassification/pixelClassificationGui.py
+++ b/ilastik/applets/pixelClassification/pixelClassificationGui.py
@@ -26,7 +26,7 @@ from PyQt4.QtCore import Qt, pyqtSlot
 from PyQt4.QtGui import QMessageBox, QColor, QShortcut, QKeySequence, QIcon
 
 # HCI
-from volumina.api import LazyflowSource, AlphaModulatedLayer
+from volumina.api import LazyflowSource, AlphaModulatedLayer, GrayscaleLayer
 from volumina.utility import ShortcutManager
 
 # ilastik
@@ -303,6 +303,12 @@ class PixelClassificationGui(LabelingGui):
             inputLayer.name = "Input Data"
             inputLayer.visible = True
             inputLayer.opacity = 1.0
+            # the flag window_leveling is used to determine if the contrast 
+            # of the layer is adjustable
+            if isinstance( inputLayer, GrayscaleLayer ):
+                inputLayer.window_leveling = True
+            else:
+                inputLayer.window_leveling = False
 
             def toggleTopToBottom():
                 index = self.layerstack.layerIndex( inputLayer )
@@ -319,6 +325,12 @@ class PixelClassificationGui(LabelingGui):
                                                                  self.viewerControlWidget(),
                                                                  inputLayer ) )
             layers.append(inputLayer)
+            
+            # The thresholding button can only be used if the data is displayed as grayscale.
+            if inputLayer.window_leveling:
+                self.labelingDrawerUi.thresToolButton.show()
+            else:
+                self.labelingDrawerUi.thresToolButton.hide()
         
         self.handleLabelSelectionChange()
         return layers
diff --git a/ilastik/workflows/carving/carvingDrawer.ui b/ilastik/workflows/carving/carvingDrawer.ui
index 2f3ceec9e..90d383eab 100644
--- a/ilastik/workflows/carving/carvingDrawer.ui
+++ b/ilastik/workflows/carving/carvingDrawer.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>338</width>
-    <height>732</height>
+    <height>766</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -126,9 +126,22 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="1" colspan="3">
+     <item row="1" column="1" colspan="4">
       <widget class="QComboBox" name="brushSizeComboBox"/>
      </item>
+     <item row="0" column="4">
+      <widget class="QToolButton" name="thresToolButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>...</string>
+       </property>
+      </widget>
+     </item>
     </layout>
    </item>
    <item>
diff --git a/ilastik/workflows/carving/carvingGui.py b/ilastik/workflows/carving/carvingGui.py
index 0bb1b478b..bc3de4871 100644
--- a/ilastik/workflows/carving/carvingGui.py
+++ b/ilastik/workflows/carving/carvingGui.py
@@ -758,8 +758,16 @@ class CarvingGui(LabelingGui):
             #layer.visible = not rawSlot.ready()
             layer.visible = True
             layer.opacity = 1.0
+            # if the flag window_leveling is set the contrast 
+            # of the layer is adjustable
+            layer.window_leveling = True
             layers.append(layer)
 
+            if layer.window_leveling:
+                self.labelingDrawerUi.thresToolButton.show()
+            else:
+                self.labelingDrawerUi.thresToolButton.hide()
+
         filteredSlot = self.topLevelOperatorView.FilteredInputData
         if filteredSlot.ready():
             layer = GrayscaleLayer( LazyflowSource(filteredSlot) )
['ilastik/workflows/carving/carvingDrawer.ui', 'ilastik/workflows/carving/carvingGui.py', 'ilastik/applets/labeling/labelingGui.py', 'ilastik/applets/pixelClassification/labelingDrawer.ui', 'ilastik/applets/pixelClassification/pixelClassificationGui.py']