mediapipe/mediapipe/objc/util.h
MediaPipe Team cc6a2f7af6 Project import generated by Copybara.
GitOrigin-RevId: 73d686c40057684f8bfaca285368bf1813f9fc26
2022-03-21 12:12:39 -07:00

131 lines
6.0 KiB
Objective-C

// Copyright 2019 The MediaPipe Authors.
//
// 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 MEDIAPIPE_OBJC_UTIL_H_
#define MEDIAPIPE_OBJC_UTIL_H_
#import <Accelerate/Accelerate.h>
#import <CoreFoundation/CoreFoundation.h>
#import <CoreGraphics/CoreGraphics.h>
#import <CoreVideo/CoreVideo.h>
#include "mediapipe/framework/formats/image_frame.h"
#include "mediapipe/framework/packet.h"
#include "mediapipe/framework/port/status.h"
#include "mediapipe/objc/CFHolder.h"
// TODO: namespace and/or prefix these. Split up the file.
/// Returns a vImage_Buffer describing the data inside the pixel_buffer.
/// NOTE: the pixel buffer's base address must have been locked before this
/// call, and it must stay locked as long as the vImage_Buffer is in use.
inline vImage_Buffer vImageForCVPixelBuffer(CVPixelBufferRef pixel_buffer) {
return {.data = CVPixelBufferGetBaseAddress(pixel_buffer),
.width = CVPixelBufferGetWidth(pixel_buffer),
.height = CVPixelBufferGetHeight(pixel_buffer),
.rowBytes = CVPixelBufferGetBytesPerRow(pixel_buffer)};
}
/// Returns a vImage_Buffer describing the data inside the ImageFrame.
inline vImage_Buffer vImageForImageFrame(const mediapipe::ImageFrame& frame) {
return {.data = (void*)frame.PixelData(),
.width = static_cast<vImagePixelCount>(frame.Width()),
.height = static_cast<vImagePixelCount>(frame.Height()),
.rowBytes = static_cast<size_t>(frame.WidthStep())};
}
/// Converts a grayscale image without alpha to BGRA format.
vImage_Error vImageGrayToBGRA(const vImage_Buffer* src, vImage_Buffer* dst);
/// Converts a BGRA image to grayscale without alpha.
vImage_Error vImageBGRAToGray(const vImage_Buffer* src, vImage_Buffer* dst);
/// Converts an RGBA image to grayscale without alpha.
vImage_Error vImageRGBAToGray(const vImage_Buffer* src, vImage_Buffer* dst);
/// Copy from a pixel buffer to another, converting pixel format.
/// Both pixel buffers should be locked before calling this.
vImage_Error vImageConvertCVPixelBuffers(CVPixelBufferRef src,
CVPixelBufferRef dst);
// Create a CVPixelBuffer without using a pool. See pixel_buffer_pool_util.h
// for creation functions that use pools.
CVReturn CreateCVPixelBufferWithoutPool(int width, int height, OSType cv_format,
CVPixelBufferRef* out_buffer);
absl::StatusOr<CFHolder<CVPixelBufferRef>> CreateCVPixelBufferWithoutPool(
int width, int height, OSType cv_format);
/// Returns a CVPixelBuffer that references the data inside the packet. The
/// packet must contain an ImageFrame. The CVPixelBuffer manages a copy of
/// the packet, so that the packet's data is kept alive as long as the
/// CVPixelBuffer is in use.
///
/// For formats which are not supported by both image types, it may be
/// necessary to convert the data. This is done by creating a new buffer.
/// If the optional can_overwrite parameter is true, the old buffer may be
/// modified instead.
absl::Status CreateCVPixelBufferForImageFramePacket(
const mediapipe::Packet& image_frame_packet,
CFHolder<CVPixelBufferRef>* out_buffer);
absl::Status CreateCVPixelBufferForImageFramePacket(
const mediapipe::Packet& image_frame_packet, bool can_overwrite,
CFHolder<CVPixelBufferRef>* out_buffer);
absl::StatusOr<CFHolder<CVPixelBufferRef>> CreateCVPixelBufferCopyingImageFrame(
const mediapipe::ImageFrame& image_frame);
absl::StatusOr<CFHolder<CVPixelBufferRef>> CreateCVPixelBufferForImageFrame(
std::shared_ptr<mediapipe::ImageFrame> image_frame,
bool can_overwrite = false);
/// Creates a CVPixelBuffer with a copy of the contents of the CGImage.
absl::Status CreateCVPixelBufferFromCGImage(
CGImageRef image, CFHolder<CVPixelBufferRef>* out_buffer);
/// Creates a CGImage with a copy of the contents of the CVPixelBuffer.
absl::Status CreateCGImageFromCVPixelBuffer(CVPixelBufferRef image_buffer,
CFHolder<CGImageRef>* image);
/// DEPRECATED: use the version that returns absl::Status instead.
CVPixelBufferRef CreateCVPixelBufferForImageFramePacket(
const mediapipe::Packet& image_frame_packet);
/// Returns an ImageFrame that references the data inside the pixel_buffer.
/// The ImageFrame retains the pixel_buffer and keeps it locked as long as it
/// is in use.
///
/// For formats which are not supported by both image types, it may be
/// necessary to convert the data. This is done by creating a new buffer.
/// If the optional can_overwrite parameter is true, the old buffer may be
/// modified instead.
///
/// ImageFrame does not have a format for BGRA data, so we normally swap the
/// channels to produce RGBA. But many graphs do not care about the order of
/// the channels; in those cases, setting the optional bgr_as_rgb parameter
/// to true skips the channel swap.
std::unique_ptr<mediapipe::ImageFrame> CreateImageFrameForCVPixelBuffer(
CVPixelBufferRef pixel_buffer);
std::unique_ptr<mediapipe::ImageFrame> CreateImageFrameForCVPixelBuffer(
CVPixelBufferRef pixel_buffer, bool can_overwrite, bool bgr_as_rgb);
/// Returns a CFDictionaryRef that can be passed to CVPixelBufferCreate to
/// ensure that the pixel buffer is compatible with OpenGL ES and with
/// CVOpenGLESTextureCacheCreateTextureFromImage.
/// The returned object is persistent and should not be released.
CFDictionaryRef GetCVPixelBufferAttributesForGlCompatibility();
/// Prints debug information about available CoreVideo pixel formats.
/// This prints to stdout.
void DumpCVPixelFormats();
#endif // MEDIAPIPE_OBJC_UTIL_H_