/** 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 image and replaces the source image with the new image.
   *
   * @param buffer DOCUMENT ME!
   * @param extents DOCUMENT ME!
   * @return resultBuffer
   */
  @SuppressWarnings("unused")
  private float[] calcInPlace3DBuffer(float[] buffer, int[] extents) {

    int i, s;
    int length;
    float[] resultBuffer;
    float lap;

    try {

      if (buffer == null) {
        length = srcImage.getSliceSize() * srcImage.getExtents()[2];
        buffer = new float[length];
      } else {
        length = buffer.length;
      }

      resultBuffer = new float[length];
      sBuffer = new byte[length];

      if (srcImage != null) {
        fireProgressStateChanged(srcImage.getImageName(), "Calculating the Laplacian ...");
      } else {
        fireProgressStateChanged("Medialness", "Calculating the Laplacian ...");
      }
    } catch (OutOfMemoryError e) {
      buffer = null;
      resultBuffer = null;
      sBuffer = null;
      errorCleanUp("Algorithm Laplacian exportData: Out of memory", true);

      return null;
    }

    try {

      if (srcImage != null) {
        srcImage.exportData(0, length, buffer); // locks and releases lock
      }
    } catch (IOException error) {
      buffer = null;
      resultBuffer = null;
      System.gc();
      errorCleanUp("Algorithm Laplacian: " + error, false);

      return null;
    }

    float[] sigs = new float[3];

    for (s = 1; (s <= 8) && !threadStopped; s++) {
      sigs[0] = s;
      sigs[1] = s;
      sigs[2] = s;
      makeKernels3D(sigs);

      fireProgressStateChanged(Math.round((float) (s) / 8 * 100));

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

        // if (entireImage == true || mask.get(i)) {

        lap = AlgorithmConvolver.convolve3DPtMed(i, extents, buffer, kExtents, GxxData);

        if (lap > resultBuffer[i]) {
          resultBuffer[i] = lap;
        }

        sBuffer[i] = (byte) s;
        // }
        // else {
        // resultBuffer[i] = 0;
        // }
      }
    }

    return resultBuffer;
  }
  /**
   * This function produces the Laplacian of input image. See this Neva
   *
   * @param nImages number of images to be blurred. If 2D image then nImage = 1, if 3D image where
   *     each image is to processed independently then nImages equals the number of images in the
   *     volume.
   */
  private void calcStoreInDest2D(int nImages) {
    int i, s;
    int length;
    float[] buffer;
    float[] resultBuffer;
    float lap;

    try {
      length = srcImage.getSliceSize();
      buffer = new float[length];
      resultBuffer = new float[length];
      fireProgressStateChanged(srcImage.getImageName(), "Calculating the Laplacian ...");
    } catch (OutOfMemoryError e) {
      buffer = null;
      resultBuffer = null;
      errorCleanUp("Algorithm Laplacian exportData: Out of memory", true);

      return;
    }

    try {
      srcImage.exportData(0, length, buffer); // locks and releases lock
    } catch (IOException error) {
      displayError("Algorithm Gaussian Blur: Image(s) locked");
      setCompleted(false);

      destImage.releaseLock();

      return;
    }

    float[] sigs = new float[2];

    for (s = 1; (s <= 8) && !threadStopped; s++) {
      sigs[0] = s;
      sigs[1] = s;
      makeKernels2D(sigs);

      fireProgressStateChanged(Math.round((float) (s) / 8 * 100));

      for (i = 0; (i < length) && !threadStopped; i++) {
        lap =
            AlgorithmConvolver.convolve2DPtMed(i, srcImage.getExtents(), buffer, kExtents, GxxData);

        if (lap > resultBuffer[i]) {
          resultBuffer[i] = lap;
        }
      }
    }

    if (threadStopped) {
      finalize();

      return;
    }

    try {
      destImage.importData(0, resultBuffer, true);
    } catch (IOException error) {
      errorCleanUp("Algorithm Gaussian Blur: Image(s) locked", false);

      return;
    }

    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);
  }