absl::Status FrameBufferUtils::Preprocess()

in tensorflow_lite_support/cc/task/vision/utils/frame_buffer_utils.cc [580:654]


absl::Status FrameBufferUtils::Preprocess(
    const FrameBuffer& buffer, absl::optional<BoundingBox> bounding_box,
    FrameBuffer* output_buffer, bool uniform_resizing) {
  std::vector<FrameBufferOperation> frame_buffer_operations;
  // Handle cropping and resizing.
  bool needs_dimension_swap =
      RequireDimensionSwap(buffer.orientation(), output_buffer->orientation());
  // For intermediate steps, we need to use dimensions based on the input
  // orientation.
  FrameBuffer::Dimension pre_orient_dimension = output_buffer->dimension();
  if (needs_dimension_swap) {
    pre_orient_dimension.Swap();
  }

  if (uniform_resizing && bounding_box.has_value()) {
    // Crop and uniform resize.
    frame_buffer_operations.push_back(UniformCropResizeOperation(
        bounding_box.value().origin_x(), bounding_box.value().origin_y(),
        FrameBuffer::Dimension{bounding_box.value().width(),
                               bounding_box.value().height()},
        pre_orient_dimension));
  } else if (uniform_resizing) {
    // Uniform resize only.
    frame_buffer_operations.push_back(UniformCropResizeOperation(
        0, 0, buffer.dimension(), pre_orient_dimension));
  } else if (bounding_box.has_value()) {
    // Crop and non-uniform resize.
    frame_buffer_operations.push_back(CropResizeOperation(
        bounding_box.value().origin_x(), bounding_box.value().origin_y(),
        FrameBuffer::Dimension{bounding_box.value().width(),
                               bounding_box.value().height()},
        pre_orient_dimension));
  } else if (pre_orient_dimension != buffer.dimension()) {
    // non-uniform resize.
    frame_buffer_operations.push_back(
        CropResizeOperation(0, 0, buffer.dimension(), pre_orient_dimension));
  }

  // Handle color space conversion first if the input format is RGB or RGBA,
  // because the rotation performance for RGB and RGBA formats are not optimzed
  // in libyuv.
  if (buffer.format() == FrameBuffer::Format::kRGB ||
      buffer.format() == FrameBuffer::Format::kRGBA) {
    if (output_buffer->format() != buffer.format()) {
      frame_buffer_operations.push_back(
          ConvertOperation(output_buffer->format()));
    }
    // Handle orientation conversion
    if (output_buffer->orientation() != buffer.orientation()) {
      frame_buffer_operations.push_back(
          OrientOperation(output_buffer->orientation()));
    }
  } else {
    // Handle orientation conversion first if the input format is not RGB or
    // RGBA.
    if (output_buffer->orientation() != buffer.orientation()) {
      frame_buffer_operations.push_back(
          OrientOperation(output_buffer->orientation()));
    }
    // Handle color space conversion
    if (output_buffer->format() != buffer.format()) {
      frame_buffer_operations.push_back(
          ConvertOperation(output_buffer->format()));
    }
  }

  // Execute the processing pipeline.
  if (frame_buffer_operations.empty()) {
    // Using resize to perform copy.
    RETURN_IF_ERROR(Resize(buffer, output_buffer));
  } else {
    RETURN_IF_ERROR(Execute(buffer, frame_buffer_operations, output_buffer));
  }
  return absl::OkStatus();
}