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

/* 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.
==============================================================================*/

#include "tensorflow_lite_support/cc/task/vision/utils/frame_buffer_utils.h"

#include <algorithm>
#include <iterator>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/memory/memory.h"  // from @com_google_absl
#include "absl/status/status.h"  // from @com_google_absl
#include "absl/strings/str_format.h"  // from @com_google_absl
#include "tensorflow/lite/kernels/internal/compatibility.h"
#include "tensorflow/lite/kernels/op_macros.h"
#include "tensorflow_lite_support/cc/port/status_macros.h"
#include "tensorflow_lite_support/cc/task/vision/utils/frame_buffer_common_utils.h"
#include "tensorflow_lite_support/cc/task/vision/utils/libyuv_frame_buffer_utils.h"

namespace tflite {
namespace task {
namespace vision {

namespace {

// Exif grouping to help determine rotation and flipping neededs between
// different orientations.
constexpr int kExifGroup[] =;
// Exif group size.
constexpr int kExifGroupSize =;

// Returns orientation position in Exif group.
static int GetOrientationIndex(FrameBuffer::Orientation orientation) {}

// Returns the coordinates of `box` respect to its containing image (dimension
// defined by `width` and `height`) orientation change. The `angle` is defined
// in counterclockwise degree in one of the values [0, 90, 180, 270].
//
// The below diagrams illustrate calling this method with 90 CCW degree.
//
// The [1]-[4] denotes image corners and 1 - 4 denotes the box corners. The *
// denotes the current origin.
//
//             width
//   [1]*----------------[2]
//    |                   |
//    |                   |
//    |        1*-----2   | height
//    |        | box  |   |
//    |        3------4   |
//   [3]-----------------[4]
//
// When rotate the above image by 90 CCW degree, the origin also changes
// respects to its containing coordinate space.
//
//         height
//   [2]*----------[4]
//    |             |
//    |     2*---4  |
//    |     |box |  |
//    |     |    |  | width
//    |     1----3  |
//    |             |
//    |             |
//    |             |
//   [1]-----------[3]
//
// The origin is always defined by the top left corner. After rotation, the
// box origin changed from 1 to 2.
// The new box origin is (x:box.origin_y, y:width - (box.origin_x + box.width).
// The new box dimension is (w: box.height, h: box.width).
//
static BoundingBox RotateBoundingBox(const BoundingBox& box, int angle,
                                     FrameBuffer::Dimension frame_dimension) {}

// Returns the input coordinates with respect to its containing image (dimension
// defined by `width` and `height`) orientation change. The `angle` is defined
// in counterclockwise degree in one of the values [0, 90, 180, 270].
//
// See `RotateBoundingBox` above for more details.
static void RotateCoordinates(int from_x, int from_y, int angle,
                              const FrameBuffer::Dimension& frame_dimension,
                              int* to_x, int* to_y) {}

}  // namespace

int GetBufferByteSize(FrameBuffer::Dimension dimension,
                      FrameBuffer::Format format) {}

FrameBufferUtils::FrameBufferUtils(ProcessEngine engine) {}

BoundingBox OrientBoundingBox(const BoundingBox& from_box,
                              FrameBuffer::Orientation from_orientation,
                              FrameBuffer::Orientation to_orientation,
                              FrameBuffer::Dimension from_dimension) {}

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) {}

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) {}

// The algorithm is based on grouping orientations into two groups with specific
// order. The two groups of orientation are {1, 6, 3, 8} and {2, 5, 4, 7}. See
// image (https://www.impulseadventure.com/photo/images/orient_flag.gif) for
// the visual grouping illustration.
//
// Each group contains elements can be transformed into one another by rotation.
// The elements order within a group is important such that the distance between
// the elements indicates the multiples of 90 degree needed to orient from one
// element to another. For example, to orient element 1 to element 6, a 90
// degree CCW rotation is needed.
//
// The corresponding order between the two groups is important such that the
// even index defined the need for horizontal flipping and the odd index defined
// the need for vertical flipping. For example, to orient element 1 to element 2
// (even index) a horizontal flipping is needed.
//
// The implementation determines the group and element index of from and to
// orientations. Based on the group and element index information, the above
// characteristic is used to calculate the rotation angle and the need for
// horizontal or vertical flipping.
OrientParams GetOrientParams(FrameBuffer::Orientation from_orientation,
                             FrameBuffer::Orientation to_orientation) {}

bool RequireDimensionSwap(FrameBuffer::Orientation from_orientation,
                          FrameBuffer::Orientation to_orientation) {}

absl::Status FrameBufferUtils::Crop(const FrameBuffer& buffer, int x0, int y0,
                                    int x1, int y1,
                                    FrameBuffer* output_buffer) {}

FrameBuffer::Dimension FrameBufferUtils::GetSize(
    const FrameBuffer& buffer, const FrameBufferOperation& operation) {}

std::vector<FrameBuffer::Plane> FrameBufferUtils::GetPlanes(
    const uint8* buffer, FrameBuffer::Dimension dimension,
    FrameBuffer::Format format) {}

FrameBuffer::Orientation FrameBufferUtils::GetOrientation(
    const FrameBuffer& buffer, const FrameBufferOperation& operation) {}

FrameBuffer::Format FrameBufferUtils::GetFormat(
    const FrameBuffer& buffer, const FrameBufferOperation& operation) {}

absl::Status FrameBufferUtils::Execute(const FrameBuffer& buffer,
                                       const FrameBufferOperation& operation,
                                       FrameBuffer* output_buffer) {}

absl::Status FrameBufferUtils::Resize(const FrameBuffer& buffer,
                                      FrameBuffer* output_buffer) {}

absl::Status FrameBufferUtils::ResizeNearestNeighbor(
    const FrameBuffer& buffer, FrameBuffer* output_buffer) {}

absl::Status FrameBufferUtils::Rotate(const FrameBuffer& buffer,
                                      RotationDegree rotation,
                                      FrameBuffer* output_buffer) {}

absl::Status FrameBufferUtils::FlipHorizontally(const FrameBuffer& buffer,
                                                FrameBuffer* output_buffer) {}

absl::Status FrameBufferUtils::FlipVertically(const FrameBuffer& buffer,
                                              FrameBuffer* output_buffer) {}

absl::Status FrameBufferUtils::Convert(const FrameBuffer& buffer,
                                       FrameBuffer* output_buffer) {}

absl::Status FrameBufferUtils::Orient(const FrameBuffer& buffer,
                                      FrameBuffer* output_buffer) {}

absl::Status FrameBufferUtils::Execute(
    const FrameBuffer& buffer,
    const std::vector<FrameBufferOperation>& operations,
    FrameBuffer* output_buffer) {}

absl::Status FrameBufferUtils::Preprocess(
    const FrameBuffer& buffer, absl::optional<BoundingBox> bounding_box,
    FrameBuffer* output_buffer, bool uniform_resizing) {}

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