/**
   * 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);
      }
    }
  }
  @Override
  public void _process(ImageUInt8 left, ImageUInt8 right, Disparity disparity) {
    if (horizontalScore == null || verticalScore.length < lengthHorizontal) {
      horizontalScore = new int[regionHeight][lengthHorizontal];
      verticalScore = new int[regionHeight][lengthHorizontal];
      elementScore = new int[left.width];
      fiveScore = new int[lengthHorizontal];
    }

    computeDisparity.configure(disparity, minDisparity, maxDisparity, radiusX * 2);

    // initialize computation
    computeFirstRow(left, right);
    // efficiently compute rest of the rows using previous results to avoid repeat computations
    computeRemainingRows(left, right);
  }
 @Override
 public Class<Disparity> getDisparityType() {
   return computeDisparity.getDisparityType();
 }