public Histogram getGaussianSmoothed(double standardDeviation) {
        if(standardDeviation < 0.0) {
            throw new IllegalArgumentException(JaiI18N.getString("Histogram8"));
        } else if(standardDeviation == 0.0) {
            return this;
        }

        // Create a new, identical but empty Histogram.
        Histogram smoothedHistogram =
            new Histogram(getNumBins(), getLowValue(), getHighValue());

        // Get a reference to the bins of the new Histogram.
        int[][] smoothedBins = smoothedHistogram.getBins();

        // Get the total counts for all bands.
        getTotals();

        // Determine the number of weights (must be odd).
        int numWeights = (int)(2*2.58*standardDeviation + 0.5);
        if(numWeights % 2 == 0) {
            numWeights++;
        }

        // Initialize the smoothing weights.
        double[] weights = new double[numWeights];
        int m = numWeights/2;
        double var = standardDeviation*standardDeviation;
        double gain = 1.0/Math.sqrt(2.0*Math.PI*var);
        double exp = -1.0/(2.0*var);
        for(int i = m; i < numWeights; i++) {
            double del = i - m;
            weights[i] = weights[numWeights-1-i] = gain*Math.exp(exp*del*del);
        }

        for(int band = 0; band < numBands; band++) {
            // Cache bin-dependent values and references.
            int[] counts = getBins(band);
            int[] smoothedCounts = smoothedBins[band];
            int nBins = smoothedHistogram.getNumBins(band);

            // Clear the band total count for the smoothed histogram.
            int sum = 0;

            for(int b = 0; b < nBins; b++) {
                // Determine clipped range.
                int min = Math.max(b - m, 0);
                int max = Math.min(b + m, nBins);

                // Calculate the offset into the weight array.
                int offset = m > b ? m - b : 0;

                // Accumulate the total for the range.
                double acc = 0;
                double weightTotal = 0;
                for(int i = min; i < max; i++) {
                    double w = weights[offset++];
                    acc += counts[i]*w;
                    weightTotal += w;
                }

                // Round the accumulated value.
                smoothedCounts[b] = (int)(acc/weightTotal + 0.5);

                // Accumulate total for band.
                sum += smoothedCounts[b];
            }

            // Rescale the counts such that the band total is approximately
            // the same as for the same band of the original histogram.
            double factor = (double)totals[band]/(double)sum;
            for(int b = 0; b < nBins; b++) {
                smoothedCounts[b] = (int)(smoothedCounts[b]*factor + 0.5);
            }
        }

        return smoothedHistogram;
    }