chromium/third_party/tflite_support/src/tensorflow_lite_support/cc/task/vision/utils/frame_buffer_utils.h

/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#ifndef TENSORFLOW_LITE_SUPPORT_CC_TASK_VISION_UTILS_FRAME_BUFFER_UTILS_H_
#define TENSORFLOW_LITE_SUPPORT_CC_TASK_VISION_UTILS_FRAME_BUFFER_UTILS_H_

#include <memory>
#include <vector>

#include "absl/status/status.h"  // from @com_google_absl
#include "absl/types/optional.h"  // from @com_google_absl
#include "absl/types/variant.h"  // from @com_google_absl
#include "tensorflow_lite_support/cc/port/integral_types.h"
#include "tensorflow_lite_support/cc/task/vision/core/frame_buffer.h"
#include "tensorflow_lite_support/cc/task/vision/proto/bounding_box_proto_inc.h"
#include "tensorflow_lite_support/cc/task/vision/utils/frame_buffer_utils_interface.h"

namespace tflite {
namespace task {
namespace vision {

// Returns the minimal buffer size for a plane in bytes based on the given
// format and dimensions.
int GetBufferByteSize(FrameBuffer::Dimension dimension,
                      FrameBuffer::Format format);

// Rotates the `from_box` in `from_orientation` to `to_orientation` within an
// image of size `from_dimension`.
BoundingBox OrientBoundingBox(const BoundingBox& from_box,
                              FrameBuffer::Orientation from_orientation,
                              FrameBuffer::Orientation to_orientation,
                              FrameBuffer::Dimension from_dimension);

// Same as OrientBoundingBox but from normalized coordinates.
BoundingBox OrientAndDenormalizeBoundingBox(
    float from_left, float from_top, float from_right, float from_bottom,
    FrameBuffer::Orientation from_orientation,
    FrameBuffer::Orientation to_orientation,
    FrameBuffer::Dimension from_dimension);

// Rotates `(from_x, from_y)` coordinates from an image of dimension
// `from_dimension` and orientation `from_orientation` into `(to_x, to_y)`
// coordinates with orientation `to_orientation`.
void OrientCoordinates(int from_x, int from_y,
                       FrameBuffer::Orientation from_orientation,
                       FrameBuffer::Orientation to_orientation,
                       FrameBuffer::Dimension from_dimension, int* to_x,
                       int* to_y);

// Returns whether the conversion from from_orientation to to_orientation
// requires 90 or 270 degrees rotation.
bool RequireDimensionSwap(FrameBuffer::Orientation from_orientation,
                          FrameBuffer::Orientation to_orientation);

// Structure to express parameters needed to achieve orientation conversion.
struct OrientParams {};

// Returns rotation angle and the need for horizontal flipping or vertical
// flipping.
OrientParams GetOrientParams(FrameBuffer::Orientation from_orientation,
                             FrameBuffer::Orientation to_orientation);

// The parameters needed to crop / resize.
//
// The coordinate system has its origin at the upper left corner, and
// positive values extend down and to the right from it.
//
// After the operation, the `crop_origin` will become the new origin.
// `crop_width` and `crop_height` defines the desired cropping region. After
// cropping, a resize is performed based on the `resize_width` and
// `resize_height`.
//
// To perform just cropping, the `crop_width` and `crop_height` should be the
// same as `resize_width` `and resize_height`.
struct CropResizeOperation {};

// The parameters needed to crop / resize / pad.
//
// The coordinate system has its origin at the upper left corner, and
// positive values extend down and to the right from it.
//
// After the operation, the `crop_origin` will become the new origin.
// `crop_width` and `crop_height` defines the desired cropping region. After
// cropping, a resize is performed based on the `resize_width` and
// `resize_height`.
//
// To perform just cropping, the `crop_width` and `crop_height` should be the
// same as `resize_width` `and resize_height`.
//
// The cropped region is resized uniformly (respecting the aspect ratio) to best
// match the size of the given `output_dimension` in both x and y dimensions.
// The resized region is aligned to the upper left pixel of the output buffer.
// The unfilled area of the output buffer remains untouched.
struct UniformCropResizeOperation {};

// The parameters needed to convert to the specified format.
struct ConvertOperation {};

// The parameters needed to change the orientation.
struct OrientOperation {};

// A variant of the supported operations on FrameBuffers. Alias for user
// convenience.
FrameBufferOperation;

// Image processing utility. This utility provides both basic image buffer
// manipulations (e.g. rotation, format conversion, resizing, etc) as well as
// capability for chaining pipeline executions. The actual buffer processing
// engine is configurable to allow optimization based on platforms.
//
// Examples:
//
//  // Create an instance of FrameBufferUtils with Halide processing engine.
//  std::unique_ptr<FrameBufferUtils> utils =
//  FrameBufferUtils::Create(kHalide);
//
//  // Perform single basic operation by each individual call.
//  std::unique_ptr<FrameBuffer> input = FrameBuffer::Create(...);
//  std::unique_ptr<FrameBuffer> output = FrameBuffer::Create(...);
//  utils->Orient(*input, output.get());
//  utils->Resize(*input, output.get());
//
//  // Chaining processing operations.
//  const std::vector<FrameBufferOperation> operations = {
//      ConvertOperation(FrameBuffer::Format::kNV21),
//      CropResizeOperation(/*crop_origin_x=*/20, /*crop_origin_y=*/20,
//                          /*crop_width=*/10, /*crop_height=*/10,
//                          /*resize_width=*/10, /*resize_height=*/10),
//      OrientOperation(FrameBuffer::Orientation::kLeftTop)};
//  utils->Execute(*input, operations, output.get());
class FrameBufferUtils {};

}  // namespace vision
}  // namespace task
}  // namespace tflite

#endif  // TENSORFLOW_LITE_SUPPORT_CC_TASK_VISION_UTILS_FRAME_BUFFER_UTILS_H_