/**
   * Performs the forward wavelet transform on the whole band. It iteratively decomposes the
   * subbands from the top node to the leaves.
   *
   * @param band The band containing the float data to decompose
   * @param subband The structure containing the coordinates of the current subband in the whole
   *     band to decompose.
   * @param c The index of the current component to decompose
   */
  private void waveletTreeDecomposition(DataBlk band, SubbandAn subband, int c) {

    // If the current subband is a leaf then nothing to be done (a leaf is
    // not decomposed).
    if (!subband.isNode) return;
    else {
      // Perform the 2D wavelet decomposition of the current subband
      wavelet2DDecomposition(band, (SubbandAn) subband, c);

      // Perform the decomposition of the four resulting subbands
      waveletTreeDecomposition(band, (SubbandAn) subband.getHH(), c);
      waveletTreeDecomposition(band, (SubbandAn) subband.getLH(), c);
      waveletTreeDecomposition(band, (SubbandAn) subband.getHL(), c);
      waveletTreeDecomposition(band, (SubbandAn) subband.getLL(), c);
    }
  }
  /**
   * Returns the next subband that will be used to get the next code-block to return by the
   * getNext[Intern]CodeBlock method.
   *
   * @param c The component
   * @return Its returns the next subband that will be used to get the next code-block to return by
   *     the getNext[Intern]CodeBlock method.
   */
  private SubbandAn getNextSubband(int c) {
    int down = 1;
    int up = 0;
    int direction = down;
    SubbandAn nextsb;

    nextsb = currentSubband[c];
    // If it is the first call to this method
    if (nextsb == null) {
      nextsb = this.getAnSubbandTree(tIdx, c);
      // If there is no decomposition level then send the whole image
      if (!nextsb.isNode) {
        return nextsb;
      }
    }

    // Find the next subband to send
    do {
      // If the current subband is null then break
      if (nextsb == null) {
        break;
      }

      // If the current subband is a leaf then select the next leaf to
      // send or go up in the decomposition tree if the leaf was a LL
      // one.
      else if (!nextsb.isNode) {
        switch (nextsb.orientation) {
          case Subband.WT_ORIENT_HH:
            nextsb = (SubbandAn) nextsb.getParent().getLH();
            direction = down;
            break;
          case Subband.WT_ORIENT_LH:
            nextsb = (SubbandAn) nextsb.getParent().getHL();
            direction = down;
            break;
          case Subband.WT_ORIENT_HL:
            nextsb = (SubbandAn) nextsb.getParent().getLL();
            direction = down;
            break;
          case Subband.WT_ORIENT_LL:
            nextsb = (SubbandAn) nextsb.getParent();
            direction = up;
            break;
        }
      }

      // Else if the current subband is a node
      else if (nextsb.isNode) {
        // If the direction is down the select the HH subband of the
        // current node.
        if (direction == down) {
          nextsb = (SubbandAn) nextsb.getHH();
        }
        // Else the direction is up the select the next node to cover
        // or still go up in the decomposition tree if the node is a LL
        // subband
        else if (direction == up) {
          switch (nextsb.orientation) {
            case Subband.WT_ORIENT_HH:
              nextsb = (SubbandAn) nextsb.getParent().getLH();
              direction = down;
              break;
            case Subband.WT_ORIENT_LH:
              nextsb = (SubbandAn) nextsb.getParent().getHL();
              direction = down;
              break;
            case Subband.WT_ORIENT_HL:
              nextsb = (SubbandAn) nextsb.getParent().getLL();
              direction = down;
              break;
            case Subband.WT_ORIENT_LL:
              nextsb = (SubbandAn) nextsb.getParent();
              direction = up;
              break;
          }
        }
      }

      if (nextsb == null) {
        break;
      }
    } while (nextsb.isNode);
    return nextsb;
  }