/** This function produces the Laplacian of input image. */
  private void calcStoreInDest3D() {

    int i;
    int length;
    float[] buffer;
    float lap;

    try {
      destImage.setLock();
    } catch (IOException error) {
      displayError("Algorithm Laplacian: Image(s) locked");
      setCompleted(false);
      destImage.releaseLock();

      return;
    }

    try {
      length = srcImage.getSliceSize() * srcImage.getExtents()[2];
      buffer = new float[length];
      srcImage.exportData(0, length, buffer); // locks and releases lock
      fireProgressStateChanged(srcImage.getImageName(), "Calculating the Laplacian ...");
    } catch (IOException error) {
      buffer = null;
      errorCleanUp("Algorithm Laplacian exportData: Image(s) locked", true);

      return;
    } catch (OutOfMemoryError e) {
      buffer = null;
      errorCleanUp("Algorithm Laplacian exportData: Out of memory", true);

      return;
    }

    int mod = length / 100; // mod is 1 percent of length

    float min, max;

    min = Float.MAX_VALUE;
    max = -Float.MAX_VALUE;

    float minL, maxL;

    minL = Float.MAX_VALUE;
    maxL = -Float.MAX_VALUE;

    if (entireImage == false) {

      for (i = 0; i < length; i++) {

        if (mask.get(i)) {

          if (buffer[i] > max) {
            max = buffer[i];
          } else if (buffer[i] < min) {
            min = buffer[i];
          }
        }
      }
    }

    for (i = 0; (i < length) && !threadStopped; i++) {

      if (((i % mod) == 0)) {
        fireProgressStateChanged(Math.round((float) i / (length - 1) * 100));
      }

      if ((entireImage == true) || mask.get(i)) {
        lap = AlgorithmConvolver.convolve3DPt(i, srcImage.getExtents(), buffer, kExtents, GxxData);

        if (entireImage == false) {

          if (mask.get(i)) {

            if (lap > maxL) {
              maxL = lap;
            } else if (lap < minL) {
              minL = lap;
            }
          }
        }

        destImage.set(i, lap);
      } else {
        destImage.set(i, buffer[i]);
      }
    }

    if (entireImage == false) {

      for (i = 0; i < length; i++) {

        if (mask.get(i)) {
          lap = destImage.getFloat(i);
          lap = (((lap - minL) / (maxL - minL)) * (max - min)) + min;
          destImage.set(i, lap);
        }
      }
    }

    if (threadStopped) {
      finalize();

      return;
    }

    destImage.calcMinMax();
    destImage.releaseLock();

    setCompleted(true);
  }
  /** Calculates the Laplacian and replaces the source image with the new image. */
  private void calcInPlace3D() {

    int i;
    int length;
    float[] buffer;
    float[] resultBuffer;
    float lap;

    try {
      length = srcImage.getSliceSize() * srcImage.getExtents()[2];
      buffer = new float[length];
      resultBuffer = new float[length];
      srcImage.exportData(0, length, buffer); // locks and releases lock
      fireProgressStateChanged(srcImage.getImageName(), "Calculating the Laplacian ...");
    } catch (IOException error) {
      buffer = null;
      resultBuffer = null;
      errorCleanUp("Algorithm Laplacian exportData: Image(s) locked", true);

      return;
    } catch (OutOfMemoryError e) {
      errorCleanUp("Algorithm Laplacian exportData: Out of memory", true);

      return;
    }

    int mod = length / 100; // mod is 1 percent of length

    for (i = 0; (i < length) && !threadStopped; i++) {

      if (((i % mod) == 0)) {
        fireProgressStateChanged(Math.round((float) i / (length - 1) * 100));
      }

      if ((entireImage == true) || mask.get(i)) {
        lap = AlgorithmConvolver.convolve3DPt(i, srcImage.getExtents(), buffer, kExtents, GxxData);
        resultBuffer[i] = lap;
      } else {
        resultBuffer[i] = buffer[i];
      }
    }

    buffer = null;
    System.gc();

    if (threadStopped) {
      finalize();

      return;
    }

    try {
      srcImage.importData(0, resultBuffer, true);
    } catch (IOException error) {
      buffer = null;
      resultBuffer = null;
      errorCleanUp("Algorithm Laplacian importData: Image(s) locked", true);

      return;
    }

    setCompleted(true);
  }