/**
   * Constructor with default Gaussian kernel [1/16, 1/4, 3/8, 1/4, 1/16] for at most dimension x, y
   * (and z if present).
   *
   * @param img input image
   * @param Jmax maximum scale (2^Jmax - 1)
   * @param denoise reduction of gaussian noise
   * @throws ALDOperatorException
   */
  public UndecimatedWaveletTransform(MTBImage _img, int _Jmax, boolean _denoise)
      throws ALDOperatorException {
    this.m_statusListeners = new Vector<StatusListener>(1);

    this.setImg(_img);
    this.setJmax(_Jmax);
    this.setForwardTransform();
    this.setDenoise(_denoise);

    double[] kernel = {1.0 / 16.0, 1.0 / 4.0, 3.0 / 8.0, 1.0 / 4.0, 1.0 / 16.0};
    MTBImage[] kernels;

    if (_img.getSizeZ() > 1) {
      kernels = new MTBImage[3];
      kernels[0] = MTBImage.createMTBImage(5, 1, 1, 1, 1, MTBImageType.MTB_DOUBLE);
      kernels[1] = MTBImage.createMTBImage(1, 5, 1, 1, 1, MTBImageType.MTB_DOUBLE);
      kernels[2] = MTBImage.createMTBImage(1, 1, 5, 1, 1, MTBImageType.MTB_DOUBLE);

      for (int i = 0; i < kernel.length; i++) {
        kernels[0].putValueDouble(i, 0, 0, 0, 0, kernel[i]);
        kernels[1].putValueDouble(0, i, 0, 0, 0, kernel[i]);
        kernels[2].putValueDouble(0, 0, i, 0, 0, kernel[i]);
      }

    } else {
      kernels = new MTBImage[2];
      kernels[0] = MTBImage.createMTBImage(5, 1, 1, 1, 1, MTBImageType.MTB_DOUBLE);
      kernels[1] = MTBImage.createMTBImage(1, 5, 1, 1, 1, MTBImageType.MTB_DOUBLE);

      for (int i = 0; i < kernel.length; i++) {
        kernels[0].putValueDouble(i, 0, 0, 0, 0, kernel[i]);
        kernels[1].putValueDouble(0, i, 0, 0, 0, kernel[i]);
      }
    }

    this.setKernels(kernels);
    this.operatorExecStatus = OperatorExecutionStatus.OP_EXEC_INIT;
  }