/**
   * A trous DWT
   *
   * @return DWT-coefficient images ([0] lowpass coeffs, [1] highpass coeffs, [2] highest bandpass
   *     coeffs, ..., [Jmax] lowest bandpass coeffs)
   * @throws ALDOperatorException
   * @throws ALDProcessingDAGException
   */
  protected MTBImage[] aTrousDWT(MTBImage _img, int _Jmax, MTBImage[] _kernels)
      throws ALDOperatorException, ALDProcessingDAGException {

    // get kernels for scale j=1
    MTBImage[] scaleOneKernels = _kernels;

    // create DWT images array
    MTBImage[] dwtData = new MTBImage[_Jmax + 1];

    // reference to last smoothed image
    MTBImage lastA = _img;

    // new image arithmetics object
    MTBImageArithmetics mia = new MTBImageArithmetics();

    if (this.verbose.booleanValue()) System.out.print(opIdentifier + "performing convolutions...");

    // iterate over all scales
    for (int j = 1; j <= _Jmax; j++) {

      // check if operator has been paused or interrupted
      if (this.operatorStatus == OperatorControlStatus.OP_STOP) {
        this.operatorExecStatus = OperatorExecutionStatus.OP_EXEC_TERMINATED;
        if (this.verbose.booleanValue()) System.err.println(opIdentifier + "stopped!");
        return null;
      }
      if (this.operatorStatus == OperatorControlStatus.OP_PAUSE) {
        System.err.println(opIdentifier + "paused, waiting to continue...");
        this.operatorExecStatus = OperatorExecutionStatus.OP_EXEC_PAUSED;
        do {
          try {
            Thread.sleep(500);
          } catch (InterruptedException e) {
            // just ignore the exception
          }
        } while (this.operatorStatus != OperatorControlStatus.OP_RESUME);
        this.operatorExecStatus = OperatorExecutionStatus.OP_EXEC_RUNNING;
        System.err.println(opIdentifier + "running again...");
      }

      // smooth image at specified scale
      dwtData[0] = conv(lastA, scaleOneKernels, j);

      // subtract the smoothed image from the last smoothed image
      dwtData[j] = mia.sub(lastA, dwtData[0]);

      // set last smoothed image to the currently smoothed image
      lastA = dwtData[0];
    }
    if (this.verbose.booleanValue()) System.out.println("done.");
    return dwtData;
  }
  /**
   * Inverse a trous DWT
   *
   * @param dwt DWT-coefficient images
   * @return
   * @throws ALDOperatorException
   */
  protected MTBImage inverseATrousDWT(MTBImage[] dwt) throws ALDOperatorException {
    // get lowpass filtered image
    MTBImage invDWT = dwt[0].duplicate();

    MTBImageArithmetics mia = new MTBImageArithmetics();

    for (int j = 1; j < dwt.length; j++) {
      // add DWT images (bandpass filtered images) to lowpass filtered image
      invDWT = mia.add(invDWT, dwt[j]);
    }

    return invDWT;
  }