Skip to content

Commit

Permalink
Add planar RGB formats
Browse files Browse the repository at this point in the history
Summary: Add 3-plane formats R_G_B24 and B_G_R24 and ability to convert to single-plane versions.

Reviewed By: janherling

Differential Revision: D65487971

fbshipit-source-id: edbc17adb9cfc30ed9dff24656c2abee59247336
  • Loading branch information
thorntondr authored and facebook-github-bot committed Nov 6, 2024
1 parent 5936a1d commit 9ffe4a4
Show file tree
Hide file tree
Showing 10 changed files with 872 additions and 4 deletions.
32 changes: 32 additions & 0 deletions impl/ocean/base/Frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ unsigned int FrameType::channels(const PixelFormat pixelFormat)
case FORMAT_Y_VU12_FULL_RANGE:
case FORMAT_UYVY16:
case FORMAT_YUYV16:
case FORMAT_R_G_B24:
case FORMAT_B_G_R24:
return 3u;

case FORMAT_BGR4444: // similar to RGB32 which has 4 channels
Expand Down Expand Up @@ -140,6 +142,8 @@ unsigned int FrameType::formatBitsPerPixelRedChannel(const PixelFormat pixelForm
case FORMAT_RGB32:
case FORMAT_RGBA32:
case FORMAT_RGBT32:
case FORMAT_R_G_B24:
case FORMAT_B_G_R24:
return 8u;

case FORMAT_BGR4444:
Expand Down Expand Up @@ -214,6 +218,8 @@ unsigned int FrameType::formatBitsPerPixelGreenChannel(const PixelFormat pixelFo
case FORMAT_RGB32:
case FORMAT_RGBA32:
case FORMAT_RGBT32:
case FORMAT_R_G_B24:
case FORMAT_B_G_R24:
return 8u;

case FORMAT_BGR4444:
Expand Down Expand Up @@ -290,6 +296,8 @@ unsigned int FrameType::formatBitsPerPixelBlueChannel(const PixelFormat pixelFor
case FORMAT_RGB32:
case FORMAT_RGBA32:
case FORMAT_RGBT32:
case FORMAT_R_G_B24:
case FORMAT_B_G_R24:
return 8u;

case FORMAT_BGR4444:
Expand Down Expand Up @@ -391,6 +399,8 @@ unsigned int FrameType::formatBitsPerPixelAlphaChannel(const PixelFormat pixelFo
case FORMAT_Y64:
case FORMAT_F32:
case FORMAT_F64:
case FORMAT_R_G_B24:
case FORMAT_B_G_R24:
return 0u;

case FORMAT_ABGR32:
Expand Down Expand Up @@ -459,6 +469,8 @@ bool FrameType::formatHasAlphaChannel(const PixelFormat pixelFormat, bool* isLas
case FORMAT_Y64:
case FORMAT_F32:
case FORMAT_F64:
case FORMAT_R_G_B24:
case FORMAT_B_G_R24:
ocean_assert(formatBitsPerPixelAlphaChannel(pixelFormat) == 0u);
return false;

Expand Down Expand Up @@ -537,6 +549,7 @@ FrameType::PixelFormat FrameType::genericSinglePlanePixelFormat(const PixelForma
case FORMAT_BGR4444:
case FORMAT_BGR5551:
case FORMAT_BGR565:
case FORMAT_B_G_R24:
return FORMAT_BGR24;

case FORMAT_BGRA4444:
Expand All @@ -545,6 +558,7 @@ FrameType::PixelFormat FrameType::genericSinglePlanePixelFormat(const PixelForma
case FORMAT_RGB4444:
case FORMAT_RGB5551:
case FORMAT_RGB565:
case FORMAT_R_G_B24:
return FORMAT_RGB24;

case FORMAT_RGBA4444:
Expand Down Expand Up @@ -720,6 +734,8 @@ FrameType::PixelFormat FrameType::formatRemoveAlphaChannel(const PixelFormat pix
case FORMAT_Y64:
case FORMAT_F32:
case FORMAT_F64:
case FORMAT_R_G_B24:
case FORMAT_B_G_R24:
return pixelFormat;

default:
Expand Down Expand Up @@ -995,6 +1011,8 @@ bool FrameType::planeLayout(const PixelFormat imagePixelFormat, const unsigned i

case FORMAT_Y_U_V24:
case FORMAT_Y_U_V24_FULL_RANGE:
case FORMAT_R_G_B24:
case FORMAT_B_G_R24:
{
ocean_assert(dataType(imagePixelFormat) == DT_UNSIGNED_INTEGER_8);

Expand Down Expand Up @@ -1241,6 +1259,12 @@ FrameType::PixelFormat FrameType::translatePixelFormat(const std::string& pixelF
if (upperValue == "F64")
return FORMAT_F64;

if (upperValue == "R_G_B24")
return FORMAT_R_G_B24;

if (upperValue == "B_G_R24")
return FORMAT_B_G_R24;

ocean_assert(false && "Invalid input!");
return FORMAT_UNDEFINED;
}
Expand Down Expand Up @@ -1460,6 +1484,12 @@ std::string FrameType::translatePixelFormat(const PixelFormat pixelFormat)

case FORMAT_END:
break;

case FORMAT_R_G_B24:
return "R_G_B24";

case FORMAT_B_G_R24:
return "B_G_R24";
}

ocean_assert(false && "Invalid pixel format.");
Expand Down Expand Up @@ -1696,6 +1726,8 @@ const FrameType::PixelFormats& FrameType::definedPixelFormats()
FrameType::FORMAT_Y_V_U12_FULL_RANGE,
FrameType::FORMAT_F32,
FrameType::FORMAT_F64,
FrameType::FORMAT_R_G_B24,
FrameType::FORMAT_B_G_R24,
};

if (pixelFormats.size() != size_t(FrameType::FORMAT_END) - 1)
Expand Down
40 changes: 36 additions & 4 deletions impl/ocean/base/Frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ class OCEAN_BASE_EXPORT FrameType

/**
* This pixel format is deprecated and is currently an alias for FORMAT_Y_U_V24_LIMITED_RANGE.
* Pixel format with 8 bits Y frame as individual block, followed 8 bits U frame as individual block, followed by a V frame as individual block, resulting in 24 bits per pixel.
* Pixel format with 8 bits Y frame as individual block, followed by 8 bits U frame as individual block, followed by a V frame as individual block, resulting in 24 bits per pixel.
* Sometimes also denoted as 'I444'.
*
* The memory layout of a Y_U_V24 image looks like this:
Expand All @@ -693,7 +693,7 @@ class OCEAN_BASE_EXPORT FrameType
FORMAT_Y_U_V24 = 39ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_3, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,

/**
* Pixel format with 8 bits Y frame as individual block, followed 8 bits U frame as individual block, followed by a V frame as individual block, resulting in 24 bits per pixel.
* Pixel format with 8 bits Y frame as individual block, followed by 8 bits U frame as individual block, followed by a V frame as individual block, resulting in 24 bits per pixel.
* Sometimes also denoted as 'I444'.
*
* The pixel format is using a limited value range for the individual channels:
Expand All @@ -718,7 +718,7 @@ class OCEAN_BASE_EXPORT FrameType
FORMAT_Y_U_V24_LIMITED_RANGE = FORMAT_Y_U_V24,

/**
* Pixel format with 8 bits Y frame as individual block, followed 8 bits U frame as individual block, followed by a V frame as individual block, resulting in 24 bits per pixel.
* Pixel format with 8 bits Y frame as individual block, followed by 8 bits U frame as individual block, followed by a V frame as individual block, resulting in 24 bits per pixel.
* Sometimes also denoted as 'I444'.
*
* The pixel format is using a full value range for all three channels:
Expand Down Expand Up @@ -996,10 +996,42 @@ class OCEAN_BASE_EXPORT FrameType
*/
FORMAT_F64 = 47ull | GenericPixelFormat<DT_SIGNED_FLOAT_64, CV_CHANNELS_1, PV_PLANES_1, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,

/**
* Pixel format with 8 bits R frame as individual block, followed by 8 bits G frame as individual block, followed by a B frame as individual block, resulting in 24 bits per pixel.
*
* The memory layout of a R_G_B24 image looks like this:
* <pre>
* r-plane: g-plane: b-plane:
* --------- --------- ---------
* | R R R R | | G G G G | | B B B B |
* | R R R R | | G G G G | | B B B B |
* | R R R R | | G G G G | | B B B B |
* | R R R R | | G G G G | | B B B B |
* --------- --------- ---------
* </pre>
*/
FORMAT_R_G_B24 = 48ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_3, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,

/**
* Pixel format with 8 bits B frame as individual block, followed by 8 bits G frame as individual block, followed by a R frame as individual block, resulting in 24 bits per pixel.
*
* The memory layout of a B_G_R24 image looks like this:
* <pre>
* b-plane: g-plane: r-plane:
* --------- --------- ---------
* | B B B B | | G G G G | | R R R R |
* | B B B B | | G G G G | | R R R R |
* | B B B B | | G G G G | | R R R R |
* | B B B B | | G G G G | | R R R R |
* --------- --------- ---------
* </pre>
*/
FORMAT_B_G_R24 = 49ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_3, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,

/**
* The helper pixel format which can be used to identify the last defined pixel format, FORMAT_END is exclusive.
*/
FORMAT_END = 48ull
FORMAT_END = 50ull
};

/**
Expand Down
10 changes: 10 additions & 0 deletions impl/ocean/cv/FrameConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
#include "ocean/cv/FrameChannels.h"
#include "ocean/cv/FrameConverterABGR32.h"
#include "ocean/cv/FrameConverterARGB32.h"
#include "ocean/cv/FrameConverterB_G_R24.h"
#include "ocean/cv/FrameConverterBGR24.h"
#include "ocean/cv/FrameConverterBGR32.h"
#include "ocean/cv/FrameConverterBGR565.h"
#include "ocean/cv/FrameConverterBGRA32.h"
#include "ocean/cv/FrameConverterR_G_B24.h"
#include "ocean/cv/FrameConverterRGB24.h"
#include "ocean/cv/FrameConverterRGB32.h"
#include "ocean/cv/FrameConverterRGB565.h"
Expand Down Expand Up @@ -376,6 +378,14 @@ FrameConverter::ConversionFunctionMap::ConversionFunctionMap()
// FORMAT_Y_VU12_FULL_RANGE
formatPair2FunctionWrapperMap_.emplace(ConversionTriple(FrameType::FORMAT_Y_VU12_FULL_RANGE, FrameType::FORMAT_Y8_FULL_RANGE), FrameConverterY_VU12::convertY_VU12ToY8);
formatPair2FunctionWrapperMap_.emplace(ConversionTriple(FrameType::FORMAT_Y_VU12_FULL_RANGE, FrameType::FORMAT_RGB24), FrameConverterY_VU12::convertY_VU12FullRangeToRGB24FullRangePrecision6Bit);

// FORMAT_R_G_B24
formatPair2FunctionWrapperMap_.emplace(ConversionTriple(FrameType::FORMAT_R_G_B24, FrameType::FORMAT_RGB24), FrameConverterR_G_B24::convertR_G_B24ToRGB24);
formatPair2FunctionWrapperMap_.emplace(ConversionTriple(FrameType::FORMAT_R_G_B24, FrameType::FORMAT_BGR24), FrameConverterR_G_B24::convertR_G_B24ToBGR24);

// FORMAT_B_G_R24
formatPair2FunctionWrapperMap_.emplace(ConversionTriple(FrameType::FORMAT_B_G_R24, FrameType::FORMAT_BGR24), FrameConverterB_G_R24::convertB_G_R24ToBGR24);
formatPair2FunctionWrapperMap_.emplace(ConversionTriple(FrameType::FORMAT_B_G_R24, FrameType::FORMAT_RGB24), FrameConverterB_G_R24::convertB_G_R24ToRGB24);
}

const void* FrameConverter::ConversionFunctionMap::function(const FrameType::PixelFormat& sourcePixelFormat, const FrameType::PixelFormat& targetPixelFormat, FunctionType& functionType, const Options& options) const
Expand Down
124 changes: 124 additions & 0 deletions impl/ocean/cv/FrameConverterB_G_R24.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#ifndef META_OCEAN_CV_FRAME_CONVERTER_B_G_R_24_H
#define META_OCEAN_CV_FRAME_CONVERTER_B_G_R_24_H

#include "ocean/cv/CV.h"
#include "ocean/cv/FrameChannels.h"
#include "ocean/cv/FrameConverter.h"

#include "ocean/base/Worker.h"

namespace Ocean
{

namespace CV
{

/**
* This class provides functions to convert frames with B_G_R24 pixel format.
* The B_G_R24 format holds the three planes/blocks of color channels.<br>
* The first block covers the B channel and holds 8 bit per pixel.<br>
* The second block covers the G channel and holds 8 bit per pixel.<br>
* The third block covers the R channel and also holds 8 bit per pixel.
* The layout of a B_G_R24 image looks like this:
* <pre>
* b-plane: g-plane: r-plane:
* --------- --------- ---------
* | B B B B | | G G G G | | R R R R |
* | B B B B | | G G G G | | R R R R |
* | B B B B | | G G G G | | R R R R |
* | B B B B | | G G G G | | R R R R |
* --------- --------- ---------
* </pre>
* @ingroup cv
*/
class FrameConverterB_G_R24 : public FrameConverter
{
public:

/**
* Converts a B_G_R24 frame to a 24 bit BGR frame into a second image buffer.
* @param bSource The b source frame buffer, must be valid
* @param gSource The g source frame buffer, must be valid
* @param rSource The r source frame buffer, must be valid
* @param target The target frame buffer, must be valid
* @param width The width of the frame in pixel, with range [1, infinity)
* @param height The height of the frame in pixel, with range [1, infinity)
* @param flag Determining the type of conversion
* @param bSourcePaddingElements The number of padding elements at the end of each b-source row, in (uint8_t) elements, with range [0, infinity)
* @param gSourcePaddingElements The number of padding elements at the end of each g-source row, in (uint8_t) elements, with range [0, infinity)
* @param rSourcePaddingElements The number of padding elements at the end of each r-source row, in (uint8_t) elements, with range [0, infinity)
* @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
* @param worker Optional worker object to distribute the computational to several CPU cores
*/
static inline void convertB_G_R24ToBGR24(const uint8_t* bSource, const uint8_t* gSource, const uint8_t* rSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int bSourcePaddingElements, const unsigned int gSourcePaddingElements, const unsigned int rSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);

/**
* Converts a B_G_R24 frame to a 24 bit RGB frame into a second image buffer.
* @param bSource The b source frame buffer, must be valid
* @param gSource The g source frame buffer, must be valid
* @param rSource The r source frame buffer, must be valid
* @param target The target frame buffer, must be valid
* @param width The width of the frame in pixel, with range [1, infinity)
* @param height The height of the frame in pixel, with range [1, infinity)
* @param flag Determining the type of conversion
* @param bSourcePaddingElements The number of padding elements at the end of each b-source row, in (uint8_t) elements, with range [0, infinity)
* @param gSourcePaddingElements The number of padding elements at the end of each g-source row, in (uint8_t) elements, with range [0, infinity)
* @param rSourcePaddingElements The number of padding elements at the end of each r-source row, in (uint8_t) elements, with range [0, infinity)
* @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
* @param worker Optional worker object to distribute the computational to several CPU cores
*/
static inline void convertB_G_R24ToRGB24(const uint8_t* bSource, const uint8_t* gSource, const uint8_t* rSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int bSourcePaddingElements, const unsigned int gSourcePaddingElements, const unsigned int rSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
};

inline void FrameConverterB_G_R24::convertB_G_R24ToBGR24(const uint8_t* bSource, const uint8_t* gSource, const uint8_t* rSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int bSourcePaddingElements, const unsigned int gSourcePaddingElements, const unsigned int rSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
{
ocean_assert(bSource != nullptr && gSource != nullptr && rSource != nullptr && target != nullptr);

const int options[4] =
{
// padding parameters
int(bSourcePaddingElements), int(gSourcePaddingElements), int(rSourcePaddingElements), int(targetPaddingElements)
};

const void* sources[3] =
{
bSource,
gSource,
rSource
};

FrameConverter::convertArbitraryPixelFormat(sources, (void**)(&target), width, height, flag, 1u, FrameConverter::mapOneRow_3Plane1Channel_To_1Plane3Channels_8BitPerChannel<0u, 1u, 2u>, options, worker);
}

inline void FrameConverterB_G_R24::convertB_G_R24ToRGB24(const uint8_t* bSource, const uint8_t* gSource, const uint8_t* rSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int bSourcePaddingElements, const unsigned int gSourcePaddingElements, const unsigned int rSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
{
ocean_assert(bSource != nullptr && gSource != nullptr && rSource != nullptr && target != nullptr);

const int options[4] =
{
// padding parameters
int(bSourcePaddingElements), int(gSourcePaddingElements), int(rSourcePaddingElements), int(targetPaddingElements)
};

const void* sources[3] =
{
bSource,
gSource,
rSource
};

FrameConverter::convertArbitraryPixelFormat(sources, (void**)(&target), width, height, flag, 1u, FrameConverter::mapOneRow_3Plane1Channel_To_1Plane3Channels_8BitPerChannel<2u, 1u, 0u>, options, worker);
}

}

}

#endif // META_OCEAN_CV_FRAME_CONVERTER_B_G_R_24_H
Loading

0 comments on commit 9ffe4a4

Please sign in to comment.