public void compute95Percent() {
   final Histogram histogram =
       new Histogram(
           getModel().getHistogramBins(),
           scaleInverse(getModel().getMinSample()),
           scaleInverse(getModel().getMaxSample()));
   final Range autoStretchRange = histogram.findRangeFor95Percent();
   computeFactors();
   setFirstSliderSample(scale(autoStretchRange.getMin()));
   setLastSliderSample(scale(autoStretchRange.getMax()));
   partitionSliders(false);
   computeZoomInToSliderLimits();
 }
  /**
   * Called by the framework in order to compute a tile for the given target band.
   *
   * <p>The default implementation throws a runtime exception with the message "not implemented".
   *
   * @param targetBand The target band.
   * @param targetTile The current tile associated with the target band to be computed.
   * @param pm A progress monitor which should be used to determine computation cancelation
   *     requests.
   * @throws OperatorException If an error occurs during computation of the target raster.
   */
  @Override
  public void computeTile(Band targetBand, Tile targetTile, ProgressMonitor pm)
      throws OperatorException {

    try {
      final Band sourceBand = sourceProduct.getBand(targetBand.getName());
      final Tile srcTile = getSourceTile(sourceBand, targetTile.getRectangle());

      final Stx stx = sourceBand.getStx();
      double origMin = stx.getMinimum();
      double origMax = stx.getMaximum();
      ScalingType scaling = verifyScaling(targetScaling, dataType);

      final double newMin = getMin(dataType);
      final double newMax = getMax(dataType);
      final double newRange = newMax - newMin;

      if (origMax <= newMax
          && origMin >= newMin
          && sourceBand.getDataType() < ProductData.TYPE_FLOAT32) scaling = ScalingType.NONE;

      final ProductData srcData = srcTile.getRawSamples();
      final ProductData dstData = targetTile.getRawSamples();

      final double srcNoDataValue = sourceBand.getNoDataValue();
      final double destNoDataValue = targetBand.getNoDataValue();

      if (scaling == ScalingType.LINEAR_PEAK_CLIPPED) {
        final Histogram histogram = new Histogram(stx.getHistogramBins(), origMin, origMax);
        final int[] bitCounts = histogram.getBinCounts();
        double rightPct = 0.025;
        for (int i = bitCounts.length - 1; i > 0; --i) {
          if (bitCounts[i] > 10) {
            rightPct = i / (double) bitCounts.length;
            break;
          }
        }
        final Range autoStretchRange = histogram.findRange(0.025, rightPct);
        origMin = autoStretchRange.getMin();
        origMax = autoStretchRange.getMax();
      } else if (scaling == ScalingType.LINEAR_CLIPPED) {
        final Histogram histogram = new Histogram(stx.getHistogramBins(), origMin, origMax);
        final Range autoStretchRange = histogram.findRangeFor95Percent();
        origMin = autoStretchRange.getMin();
        origMax = autoStretchRange.getMax();
      }
      final double origRange = origMax - origMin;

      final int numElem = dstData.getNumElems();
      double srcValue;
      for (int i = 0; i < numElem; ++i) {
        srcValue = srcData.getElemDoubleAt(i);
        if (srcValue == srcNoDataValue) {
          dstData.setElemDoubleAt(i, destNoDataValue);
        } else {
          if (scaling == ScalingType.NONE) dstData.setElemDoubleAt(i, srcValue);
          else if (scaling == ScalingType.TRUNC)
            dstData.setElemDoubleAt(i, truncate(srcValue, newMin, newMax));
          else if (scaling == ScalingType.LOGARITHMIC)
            dstData.setElemDoubleAt(i, logScale(srcValue, origMin, newMin, origRange, newRange));
          else {
            if (srcValue > origMax) srcValue = origMax;
            if (srcValue < origMin) srcValue = origMin;
            dstData.setElemDoubleAt(i, scale(srcValue, origMin, newMin, origRange, newRange));
          }
        }
      }

      targetTile.setRawSamples(dstData);
    } catch (Exception e) {
      throw new OperatorException(e.getMessage());
    }
  }