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();
}