/**
   * Using previously computed results it efficiently finds the disparity in the remaining rows.
   * When a new block is processes the last row/column is subtracted and the new row/column is
   * added.
   */
  private void computeRemainingRows(ImageUInt8 left, ImageUInt8 right) {
    for (int row = regionHeight; row < left.height; row++, activeVerticalScore++) {
      int oldRow = row % regionHeight;
      int previous[] = verticalScore[(activeVerticalScore - 1) % regionHeight];
      int active[] = verticalScore[activeVerticalScore % regionHeight];

      // subtract first row from vertical score
      int scores[] = horizontalScore[oldRow];
      for (int i = 0; i < lengthHorizontal; i++) {
        active[i] = previous[i] - scores[i];
      }

      UtilDisparityScore.computeScoreRow(
          left, right, row, scores, minDisparity, maxDisparity, regionWidth, elementScore);

      // add the new score
      for (int i = 0; i < lengthHorizontal; i++) {
        active[i] += scores[i];
      }

      if (activeVerticalScore >= regionHeight - 1) {
        int top[] = verticalScore[(activeVerticalScore - 2 * radiusY) % regionHeight];
        int middle[] = verticalScore[(activeVerticalScore - radiusY) % regionHeight];
        int bottom[] = verticalScore[activeVerticalScore % regionHeight];

        computeScoreFive(top, middle, bottom, fiveScore, left.width);
        computeDisparity.process(row - (1 + 4 * radiusY) + 2 * radiusY + 1, fiveScore);
      }
    }
  }
  /**
   * Initializes disparity calculation by finding the scores for the initial block of horizontal
   * rows.
   */
  private void computeFirstRow(ImageUInt8 left, ImageUInt8 right) {
    int firstRow[] = verticalScore[0];
    activeVerticalScore = 1;

    // compute horizontal scores for first row block
    for (int row = 0; row < regionHeight; row++) {

      int scores[] = horizontalScore[row];

      UtilDisparityScore.computeScoreRow(
          left, right, row, scores, minDisparity, maxDisparity, regionWidth, elementScore);
    }

    // compute score for the top possible row
    for (int i = 0; i < lengthHorizontal; i++) {
      int sum = 0;
      for (int row = 0; row < regionHeight; row++) {
        sum += horizontalScore[row][i];
      }
      firstRow[i] = sum;
    }
  }