// -----------------------------------------------------------------------------------
  public void Lipschitz2D(ImageProcessor ip) {
    int slope, slope1, p, p1, p2, p3, p4, maxz;

    m_roi = ip.getRoi();
    ImageHeight = ip.getHeight();
    ImageWidth = ip.getWidth();
    m_channels = ip instanceof ColorProcessor ? 3 : 1;
    m_short = ip instanceof ShortProcessor;
    pixel = new int[m_channels];

    int[][] destPixels = new int[m_channels][ImageHeight * ImageWidth];
    int[][] srcPixels = new int[m_channels][ImageHeight * ImageWidth];
    byte[][] tmpBytePixels = new byte[m_channels][ImageHeight * ImageWidth];
    short[][] tmpShortPixels = new short[m_channels][ImageHeight * ImageWidth];

    if (m_channels == 1) {
      if (m_short) {
        tmpShortPixels[0] = (short[]) ip.getPixels();
      } else {
        tmpBytePixels[0] = (byte[]) ip.getPixels();
      }

    } else {
      ColorProcessor cip = (ColorProcessor) ip;
      cip.getRGB(tmpBytePixels[0], tmpBytePixels[1], tmpBytePixels[2]);
    }

    int sign = (m_Down ? 1 : -1);
    int topdown = (m_Down ? 0 : 255);
    for (int ii = 0; ii < m_channels; ii++) {
      for (int ij = 0; ij < ImageHeight * ImageWidth; ij++) {
        srcPixels[ii][ij] =
            (m_short
                ? sign * (tmpShortPixels[ii][ij] & 0xffff)
                : sign * (tmpBytePixels[ii][ij] & 0xff));
        destPixels[ii][ij] = srcPixels[ii][ij];
      }
    }

    slope = (int) (m_Slope);
    slope1 = (int) (slope * Math.sqrt(2.0));
    maxz = m_channels;

    for (int y = m_roi.y; y < m_roi.y + m_roi.height; y++) // rows
    {
      IJ.showProgress(y, 2 * ImageHeight);
      for (int z = 0; z < m_channels; z++) {
        p2 = sign * (topdown + (sign) * slope);
        p3 = sign * (topdown + (sign) * slope1);
        for (int x = m_roi.x; x < m_roi.x + m_roi.width; x++) // columns
        {
          p = (p2 - slope);
          p1 = (p3 - slope1);
          if (p1 > p) p = p1;
          p3 = destPixels[z][x + ImageWidth * (Math.max(y - 1, 0))];
          p1 = p3 - slope;
          if (p1 > p) p = p1;

          p4 = destPixels[z][Math.min(x + 1, ImageWidth - 1) + ImageWidth * (Math.max(y - 1, 0))];
          p1 = p4 - slope1;
          if (p1 > p) p = p1;

          p2 = srcPixels[z][x + ImageWidth * y];
          if (p > p2) {
            destPixels[z][x + ImageWidth * y] = p;
            p2 = p;
          }
        }
      }
    }

    for (int y = m_roi.y + m_roi.height - 1; y >= m_roi.y; y--) // rows
    {
      IJ.showProgress(2 * ImageHeight - y - 1, 2 * ImageHeight);
      for (int z = 0; z < maxz; z++) {
        p2 = sign * (topdown + (sign) * slope);
        p3 = sign * (topdown + (sign) * slope1);
        for (int x = m_roi.x + m_roi.width - 1; x >= m_roi.x; x--) // columns
        {
          p = (p2 - slope);
          p1 = (p3 - slope1);
          if (p1 > p) p = p1;

          p3 = destPixels[z][x + ImageWidth * (Math.min(y + 1, ImageHeight - 1))];
          p1 = p3 - slope;
          if (p1 > p) p = p1;

          p4 = destPixels[z][Math.max(x - 1, 0) + ImageWidth * (Math.min(y + 1, ImageHeight - 1))];
          p1 = p4 - slope1;
          if (p1 > p) p = p1;

          p2 = destPixels[z][x + ImageWidth * y];
          if (p > p2) {
            destPixels[z][x + ImageWidth * y] = p;
            p2 = p;
          }
        }
      }
    }

    for (int ii = 0; ii < m_channels; ii++) {
      for (int ij = 0; ij < ImageHeight * ImageWidth; ij++) {
        if (m_TopHat) {
          tmpBytePixels[ii][ij] =
              (m_Down
                  ? (byte) (srcPixels[ii][ij] - destPixels[ii][ij] + 255)
                  : (byte) (destPixels[ii][ij] - srcPixels[ii][ij]));
        } else {
          if (m_short) {
            tmpShortPixels[ii][ij] = (short) ((sign * destPixels[ii][ij] & 0xffff));
          } else {
            tmpBytePixels[ii][ij] = (byte) (sign * destPixels[ii][ij]);
          }
        }
      }
    }

    if (m_channels == 1) {
      if (m_short) {
        ShortProcessor sip = (ShortProcessor) ip;
        sip.setPixels(tmpShortPixels[0]);
      } else {
        ByteProcessor bip = (ByteProcessor) ip;
        bip.setPixels(tmpBytePixels[0]);
      }

    } else {
      ColorProcessor cip = (ColorProcessor) ip;
      cip.setRGB(tmpBytePixels[0], tmpBytePixels[1], tmpBytePixels[2]);
    }
  }