/*############################################################################### # # Copyright 2020-2021 NVIDIA Corporation # # Permission is hereby granted, free of charge, to any person obtaining a copy of # this software and associated documentation files (the "Software"), to deal in # the Software without restriction, including without limitation the rights to # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of # the Software, and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # ###############################################################################*/ #ifndef __NVCVIMAGE_H__ #define __NVCVIMAGE_H__ #include "nvCVStatus.h" #ifdef __cplusplus extern "C" { #endif // ___cplusplus #ifndef RTX_CAMERA_IMAGE // Compile with -DRTX_CAMERA_IMAGE=0 to get more functionality and bug fixes. #define RTX_CAMERA_IMAGE 0 // Set to 1 for RTXCamera, which needs an old version, that avoids new functionality #endif // RTX_CAMERA_IMAGE struct CUstream_st; // typedef struct CUstream_st *CUstream; //! The format of pixels in an image. typedef enum NvCVImage_PixelFormat { NVCV_FORMAT_UNKNOWN = 0, //!< Unknown pixel format. NVCV_Y = 1, //!< Luminance (gray). NVCV_A = 2, //!< Alpha (opacity) NVCV_YA = 3, //!< { Luminance, Alpha } NVCV_RGB = 4, //!< { Red, Green, Blue } NVCV_BGR = 5, //!< { Red, Green, Blue } NVCV_RGBA = 6, //!< { Red, Green, Blue, Alpha } NVCV_BGRA = 7, //!< { Red, Green, Blue, Alpha } #if RTX_CAMERA_IMAGE NVCV_YUV420 = 8, //!< Luminance and subsampled Chrominance { Y, Cb, Cr } NVCV_YUV422 = 9, //!< Luminance and subsampled Chrominance { Y, Cb, Cr } #else // !RTX_CAMERA_IMAGE NVCV_ARGB = 8, //!< { Red, Green, Blue, Alpha } NVCV_ABGR = 9, //!< { Red, Green, Blue, Alpha } NVCV_YUV420 = 10, //!< Luminance and subsampled Chrominance { Y, Cb, Cr } NVCV_YUV422 = 11, //!< Luminance and subsampled Chrominance { Y, Cb, Cr } #endif // !RTX_CAMERA_IMAGE NVCV_YUV444 = 12, //!< Luminance and full bandwidth Chrominance { Y, Cb, Cr } } NvCVImage_PixelFormat; //! The data type used to represent each component of an image. typedef enum NvCVImage_ComponentType { NVCV_TYPE_UNKNOWN = 0, //!< Unknown type of component. NVCV_U8 = 1, //!< Unsigned 8-bit integer. NVCV_U16 = 2, //!< Unsigned 16-bit integer. NVCV_S16 = 3, //!< Signed 16-bit integer. NVCV_F16 = 4, //!< 16-bit floating-point. NVCV_U32 = 5, //!< Unsigned 32-bit integer. NVCV_S32 = 6, //!< Signed 32-bit integer. NVCV_F32 = 7, //!< 32-bit floating-point (float). NVCV_U64 = 8, //!< Unsigned 64-bit integer. NVCV_S64 = 9, //!< Signed 64-bit integer. NVCV_F64 = 10, //!< 64-bit floating-point (double). } NvCVImage_ComponentType; //! Value for the planar field or layout argument. Two values are currently accommodated for RGB: //! Interleaved or chunky storage locates all components of a pixel adjacent in memory, //! e.g. RGBRGBRGB... (denoted [RGB]). //! Planar storage locates the same component of all pixels adjacent in memory, //! e.g. RRRRR...GGGGG...BBBBB... (denoted [R][G][B]) //! YUV has many more variants. //! 4:2:2 can be chunky, planar or semi-planar, with different orderings. //! 4:2:0 can be planar or semi-planar, with different orderings. //! Aliases are provided for FOURCCs defined at fourcc.org. //! Note: the LSB can be used to distinguish between chunky and planar formats. #define NVCV_INTERLEAVED 0 //!< All components of pixel(x,y) are adjacent (same as chunky) (default for non-YUV). #define NVCV_CHUNKY 0 //!< All components of pixel(x,y) are adjacent (same as interleaved). #define NVCV_PLANAR 1 //!< The same component of all pixels are adjacent. #define NVCV_UYVY 2 //!< [UYVY] Chunky 4:2:2 (default for 4:2:2) #define NVCV_VYUY 4 //!< [VYUY] Chunky 4:2:2 #define NVCV_YUYV 6 //!< [YUYV] Chunky 4:2:2 #define NVCV_YVYU 8 //!< [YVYU] Chunky 4:2:2 #define NVCV_CYUV 10 //!< [YUV] Chunky 4:4:4 #define NVCV_CYVU 12 //!< [YVU] Chunky 4:4:4 #define NVCV_YUV 3 //!< [Y][U][V] Planar 4:2:2 or 4:2:0 or 4:4:4 #define NVCV_YVU 5 //!< [Y][V][U] Planar 4:2:2 or 4:2:0 or 4:4:4 #define NVCV_YCUV 7 //!< [Y][UV] Semi-planar 4:2:2 or 4:2:0 (default for 4:2:0) #define NVCV_YCVU 9 //!< [Y][VU] Semi-planar 4:2:2 or 4:2:0 //! The following are FOURCC aliases for specific layouts. Note that it is still required to specify the format as well //! as the layout, e.g. NVCV_YUV420 and NVCV_NV12, even though the NV12 layout is only associated with YUV420 sampling. #define NVCV_I420 NVCV_YUV //!< [Y][U][V] Planar 4:2:0 #define NVCV_IYUV NVCV_YUV //!< [Y][U][V] Planar 4:2:0 #define NVCV_YV12 NVCV_YVU //!< [Y][V][U] Planar 4:2:0 #define NVCV_NV12 NVCV_YCUV //!< [Y][UV] Semi-planar 4:2:0 (default for 4:2:0) #define NVCV_NV21 NVCV_YCVU //!< [Y][VU] Semi-planar 4:2:0 #define NVCV_YUY2 NVCV_YUYV //!< [YUYV] Chunky 4:2:2 #define NVCV_I444 NVCV_YUV //!< [Y][U][V] Planar 4:4:4 #define NVCV_YM24 NVCV_YUV //!< [Y][U][V] Planar 4:4:4 #define NVCV_YM42 NVCV_YVU //!< [Y][V][U] Planar 4:4:4 #define NVCV_NV24 NVCV_YCUV //!< [Y][UV] Semi-planar 4:4:4 #define NVCV_NV42 NVCV_YCVU //!< [Y][VU] Semi-planar 4:4:4 //! The following are ORed together for the colorspace field for YUV. //! NVCV_601 and NVCV_709 describe the color axes of YUV. //! NVCV_VIDEO_RANGE and NVCV_VIDEO_RANGE describe the range, [16, 235] or [0, 255], respectively. //! NVCV_CHROMA_COSITED and NVCV_CHROMA_INTSTITIAL describe the location of the chroma samples. #define NVCV_601 0x00 //!< The Rec.601 YUV colorspace, typically used for SD. #define NVCV_709 0x01 //!< The Rec.709 YUV colorspace, typically used for HD. #define NVCV_2020 0x02 //!< The Rec.2020 YUV colorspace. #define NVCV_VIDEO_RANGE 0x00 //!< The video range is [16, 235]. #define NVCV_FULL_RANGE 0x04 //!< The video range is [ 0, 255]. #define NVCV_CHROMA_COSITED 0x00 //!< The chroma is sampled at the same location as the luma samples horizontally. #define NVCV_CHROMA_INTSTITIAL 0x08 //!< The chroma is sampled between luma samples horizontally. #define NVCV_CHROMA_TOPLEFT 0x10 //!< The chroma is sampled at the same location as the luma samples horizontally and vertically. #define NVCV_CHROMA_MPEG2 NVCV_CHROMA_COSITED //!< As is most video. #define NVCV_CHROMA_MPEG1 NVCV_CHROMA_INTSTITIAL #define NVCV_CHROMA_JPEG NVCV_CHROMA_INTSTITIAL #define NVCV_CHROMA_H261 NVCV_CHROMA_INTSTITIAL #define NVCV_CHROMA_INTERSTITIAL NVCV_CHROMA_INTSTITIAL //!< Correct spelling //! This is the value for the gpuMem field or the memSpace argument. #define NVCV_CPU 0 //!< The buffer is stored in CPU memory. #define NVCV_GPU 1 //!< The buffer is stored in CUDA memory. #define NVCV_CUDA 1 //!< The buffer is stored in CUDA memory. #define NVCV_CPU_PINNED 2 //!< The buffer is stored in pinned CPU memory. #define NVCV_CUDA_ARRAY 3 //!< A CUDA array is used for storage. //! Image descriptor. typedef struct #ifdef _MSC_VER __declspec(dllexport) #endif // _MSC_VER NvCVImage { unsigned int width; //!< The number of pixels horizontally in the image. unsigned int height; //!< The number of pixels vertically in the image. signed int pitch; //!< The byte stride between pixels vertically. NvCVImage_PixelFormat pixelFormat; //!< The format of the pixels in the image. NvCVImage_ComponentType componentType; //!< The data type used to represent each component of the image. unsigned char pixelBytes; //!< The number of bytes in a chunky pixel. unsigned char componentBytes; //!< The number of bytes in each pixel component. unsigned char numComponents; //!< The number of components in each pixel. unsigned char planar; //!< NVCV_CHUNKY, NVCV_PLANAR, NVCV_UYVY, .... unsigned char gpuMem; //!< NVCV_CPU, NVCV_CPU_PINNED, NVCV_CUDA, NVCV_GPU unsigned char colorspace; //!< An OR of colorspace, range and chroma phase. unsigned char reserved[2]; //!< For structure padding and future expansion. Set to 0. void *pixels; //!< Pointer to pixel(0,0) in the image. void *deletePtr; //!< Buffer memory to be deleted (can be NULL). void (*deleteProc)(void *p); //!< Delete procedure to call rather than free(). unsigned long long bufferBytes; //!< The maximum amount of memory available through pixels. #ifdef __cplusplus //! Default constructor: fill with 0. inline NvCVImage(); //! Allocation constructor. //! \param[in] width the number of pixels horizontally. //! \param[in] height the number of pixels vertically. //! \param[in] format the format of the pixels. //! \param[in] type the type of each pixel component. //! \param[in] layout One of { NVCV_CHUNKY, NVCV_PLANAR } or one of the YUV layouts. //! \param[in] memSpace One of { NVCV_CPU, NVCV_CPU_PINNED, NVCV_GPU, NVCV_CUDA } //! \param[in] alignment row byte alignment. Choose 0 or a power of 2. //! 1: yields no gap whatsoever between scanlines; //! 0: default alignment: 4 on CPU, and cudaMallocPitch's choice on GPU. //! Other common values are 16 or 32 for cache line size. inline NvCVImage(unsigned width, unsigned height, NvCVImage_PixelFormat format, NvCVImage_ComponentType type, unsigned layout = NVCV_CHUNKY, unsigned memSpace = NVCV_CPU, unsigned alignment = 0); //! Subimage constructor. //! \param[in] fullImg the full image, from which this subImage view is to be created. //! \param[in] x the left edge of the subImage, in reference to the full image. //! \param[in] y the top edge of the subImage, in reference to the full image. //! \param[in] width the width of the subImage, in pixels. //! \param[in] height the height of the subImage, in pixels. //! \bug This does not work for planar or semi-planar formats, neither RGB nor YUV. //! \note This does work for all chunky formats, including UYVY, VYUY, YUYV, YVYU. inline NvCVImage(NvCVImage *fullImg, int x, int y, unsigned width, unsigned height); //! Destructor inline ~NvCVImage(); //! Copy a rectangular subimage. This works for CPU->CPU, CPU->GPU, GPU->GPU, and GPU->CPU. //! \param[in] src The source image from which to copy. //! \param[in] srcX The left coordinate of the src rectangle. //! \param[in] srcY The top coordinate of the src rectangle. //! \param[in] dstX The left coordinate of the dst rectangle. //! \param[in] dstY The top coordinate of the dst rectangle. //! \param[in] width The width of the rectangle to be copied, in pixels. //! \param[in] height The height of the rectangle to be copied, in pixels. //! \param[in] stream the CUDA stream. //! \note NvCVImage_Transfer() can handle more cases. //! \return NVCV_SUCCESS if successful //! \return NVCV_ERR_MISMATCH if the formats are different //! \return NVCV_ERR_CUDA if a CUDA error occurred //! \return NVCV_ERR_PIXELFORMAT if the pixel format is not yet accommodated. inline NvCV_Status copyFrom(const NvCVImage *src, int srcX, int srcY, int dstX, int dstY, unsigned width, unsigned height, struct CUstream_st* stream = 0); //! Copy from one image to another. This works for CPU->CPU, CPU->GPU, GPU->GPU, and GPU->CPU. //! \param[in] src The source image from which to copy. //! \param[in] stream the CUDA stream. //! \note NvCVImage_Transfer() can handle more cases. //! \return NVCV_SUCCESS if successful //! \return NVCV_ERR_MISMATCH if the formats are different //! \return NVCV_ERR_CUDA if a CUDA error occurred //! \return NVCV_ERR_PIXELFORMAT if the pixel format is not yet accommodated. inline NvCV_Status copyFrom(const NvCVImage *src, struct CUstream_st* stream = 0); #endif // ___cplusplus } NvCVImage; //! Integer rectangle. typedef struct NvCVRect2i { int x; //!< The left edge of the rectangle. int y; //!< The top edge of the rectangle. int width; //!< The width of the rectangle. int height; //!< The height of the rectangle. } NvCVRect2i; //! Integer point. typedef struct NvCVPoint2i { int x; //!< The horizontal coordinate. int y; //!< The vertical coordinate } NvCVPoint2i; //! Initialize an image. The C++ constructors can initialize this appropriately. //! This is called by the C++ constructor, but C code should call this explicitly. //! \param[in,out] im the image to initialize. //! \param[in] width the desired width of the image, in pixels. //! \param[in] height the desired height of the image, in pixels. //! \param[in] pitch the byte stride between pixels vertically. //! \param[in] pixels a pointer to the pixel buffer. //! \param[in] format the format of the pixels. //! \param[in] type the type of the components of the pixels. //! \param[in] layout One of { NVCV_CHUNKY, NVCV_PLANAR } or one of the YUV layouts. //! \param[in] memSpace Location of the buffer: one of { NVCV_CPU, NVCV_CPU_PINNED, NVCV_GPU, NVCV_CUDA } //! \return NVCV_SUCCESS if successful //! \return NVCV_ERR_PIXELFORMAT if the pixel format is not yet accommodated. NvCV_Status NvCV_API NvCVImage_Init(NvCVImage *im, unsigned width, unsigned height, int pitch, void *pixels, NvCVImage_PixelFormat format, NvCVImage_ComponentType type, unsigned layout, unsigned memSpace); //! Initialize a view into a subset of an existing image. //! No memory is allocated -- the fullImg buffer is used. //! \param[in] subImg the sub-image view into the existing full image. //! \param[in] fullImg the existing full image. //! \param[in] x the left edge of the sub-image, as coordinate of the full image. //! \param[in] y the top edge of the sub-image, as coordinate of the full image. //! \param[in] width the desired width of the subImage, in pixels. //! \param[in] height the desired height of the subImage, in pixels. //! \bug This does not work in general for planar or semi-planar formats, neither RGB nor YUV. //! However, it does work for all formats with the full image, to make a shallow copy, e.g. //! NvCVImage_InitView(&subImg, &fullImg, 0, 0, fullImage.width, fullImage.height). //! Cropping a planar or semi-planar image can be accomplished with NvCVImage_TransferRect(). //! \note This does work for all chunky formats, including UYVY, VYUY, YUYV, YVYU. //! \sa { NvCVImage_TransferRect } void NvCV_API NvCVImage_InitView(NvCVImage *subImg, NvCVImage *fullImg, int x, int y, unsigned width, unsigned height); //! Allocate memory for, and initialize an image. This assumes that the image data structure has nothing meaningful in it. //! This is called by the C++ constructor, but C code can call this to allocate an image. //! \param[in,out] im the image to initialize. //! \param[in] width the desired width of the image, in pixels. //! \param[in] height the desired height of the image, in pixels. //! \param[in] format the format of the pixels. //! \param[in] type the type of the components of the pixels. //! \param[in] layout One of { NVCV_CHUNKY, NVCV_PLANAR } or one of the YUV layouts. //! \param[in] memSpace Location of the buffer: one of { NVCV_CPU, NVCV_CPU_PINNED, NVCV_GPU, NVCV_CUDA } //! \param[in] alignment row byte alignment. Choose 0 or a power of 2. //! 1: yields no gap whatsoever between scanlines; //! 0: default alignment: 4 on CPU, and cudaMallocPitch's choice on GPU. //! Other common values are 16 or 32 for cache line size. //! \return NVCV_SUCCESS if the operation was successful. //! \return NVCV_ERR_PIXELFORMAT if the pixel format is not accommodated. //! \return NVCV_ERR_MEMORY if there is not enough memory to allocate the buffer. NvCV_Status NvCV_API NvCVImage_Alloc(NvCVImage *im, unsigned width, unsigned height, NvCVImage_PixelFormat format, NvCVImage_ComponentType type, unsigned layout, unsigned memSpace, unsigned alignment); //! Reallocate memory for, and initialize an image. This assumes that the image is valid. //! It will check bufferBytes to see if enough memory is already available, and will reshape rather than realloc if true. //! Otherwise, it will free the previous buffer and reallocate a new one. //! \param[in,out] im the image to initialize. //! \param[in] width the desired width of the image, in pixels. //! \param[in] height the desired height of the image, in pixels. //! \param[in] format the format of the pixels. //! \param[in] type the type of the components of the pixels. //! \param[in] layout One of { NVCV_CHUNKY, NVCV_PLANAR } or one of the YUV layouts. //! \param[in] memSpace Location of the buffer: one of { NVCV_CPU, NVCV_CPU_PINNED, NVCV_GPU, NVCV_CUDA } //! \param[in] alignment row byte alignment. Choose 0 or a power of 2. //! 1: yields no gap whatsoever between scanlines; //! 0: default alignment: 4 on CPU, and cudaMallocPitch's choice on GPU. //! Other common values are 16 or 32 for cache line size. //! \return NVCV_SUCCESS if the operation was successful. //! \return NVCV_ERR_PIXELFORMAT if the pixel format is not accommodated. //! \return NVCV_ERR_MEMORY if there is not enough memory to allocate the buffer. NvCV_Status NvCV_API NvCVImage_Realloc(NvCVImage *im, unsigned width, unsigned height, NvCVImage_PixelFormat format, NvCVImage_ComponentType type, unsigned layout, unsigned memSpace, unsigned alignment); //! Deallocate the image buffer from the image. The image is not deallocated. //! param[in,out] im the image whose buffer is to be deallocated. void NvCV_API NvCVImage_Dealloc(NvCVImage *im); //! Deallocate the image buffer from the image asynchronously on the specified stream. The image is not deallocated. //! param[in,out] im the image whose buffer is to be deallocated. //! param[int] stream the CUDA stream on which the image buffer is to be deallocated.. void NvCV_API NvCVImage_DeallocAsync(NvCVImage *im, struct CUstream_st *stream); //! Allocate a new image, with storage (C-style constructor). //! \param[in] width the desired width of the image, in pixels. //! \param[in] height the desired height of the image, in pixels. //! \param[in] format the format of the pixels. //! \param[in] type the type of the components of the pixels. //! \param[in] layout One of { NVCV_CHUNKY, NVCV_PLANAR } or one of the YUV layouts. //! \param[in] memSpace Location of the buffer: one of { NVCV_CPU, NVCV_CPU_PINNED, NVCV_GPU, NVCV_CUDA } //! \param[in] alignment row byte alignment. Choose 0 or a power of 2. //! 1: yields no gap whatsoever between scanlines; //! 0: default alignment: 4 on CPU, and cudaMallocPitch's choice on GPU. //! Other common values are 16 or 32 for cache line size. //! \param[out] *out will be a pointer to the new image if successful; otherwise NULL. //! \return NVCV_SUCCESS if the operation was successful. //! \return NVCV_ERR_PIXELFORMAT if the pixel format is not accommodated. //! \return NVCV_ERR_MEMORY if there is not enough memory to allocate the buffer. NvCV_Status NvCV_API NvCVImage_Create(unsigned width, unsigned height, NvCVImage_PixelFormat format, NvCVImage_ComponentType type, unsigned layout, unsigned memSpace, unsigned alignment, NvCVImage **out); //! Deallocate the image allocated with NvCVImage_Create() (C-style destructor). void NvCV_API NvCVImage_Destroy(NvCVImage *im); //! Get offsets for the components of a pixel format. //! These are not byte offsets, but component offsets. //! \param[in] format the pixel format to be interrogated. //! \param[out] rOff a place to store the offset for the red channel (can be NULL). //! \param[out] gOff a place to store the offset for the green channel (can be NULL). //! \param[out] bOff a place to store the offset for the blue channel (can be NULL). //! \param[out] aOff a place to store the offset for the alpha channel (can be NULL). //! \param[out] yOff a place to store the offset for the luminance channel (can be NULL). void NvCV_API NvCVImage_ComponentOffsets(NvCVImage_PixelFormat format, int *rOff, int *gOff, int *bOff, int *aOff, int *yOff); //! Transfer one image to another, with a limited set of conversions. //! //! If any of the images resides on the GPU, it may run asynchronously, //! so cudaStreamSynchronize() should be called if it is necessary to run synchronously. //! The following table indicates (with X) the currently-implemented conversions: //! +-------------------+-------------+-------------+-------------+-------------+ //! | | u8 --> u8 | u8 --> f32 | f32 --> u8 | f32 --> f32 | //! +-------------------+-------------+-------------+-------------+-------------+ //! | Y --> Y | X | | X | X | //! | Y --> A | X | | X | X | //! | Y --> RGB | X | X | X | X | //! | Y --> RGBA | X | X | X | X | //! | A --> Y | X | | X | X | //! | A --> A | X | | X | X | //! | A --> RGB | X | X | X | X | //! | A --> RGBA | X | | | | //! | RGB --> Y | X | X | | | //! | RGB --> A | X | X | | | //! | RGB --> RGB | X | X | X | X | //! | RGB --> RGBA | X | X | X | X | //! | RGBA --> Y | X | X | | | //! | RGBA --> A | X | | | | //! | RGBA --> RGB | X | X | X | X | //! | RGBA --> RGBA | X | X | X | X | //! | RGB --> YUV420 | X | | X | | //! | RGBA --> YUV420 | X | | X | | //! | RGB --> YUV422 | X | | X | | //! | RGBA --> YUV422 | X | | X | | //! | RGB --> YUV444 | X | | X | | //! | RGBA --> YUV444 | X | | X | | //! | YUV420 --> RGB | X | X | | | //! | YUV420 --> RGBA | X | X | | | //! | YUV422 --> RGB | X | X | | | //! | YUV422 --> RGBA | X | X | | | //! | YUV444 --> RGB | X | X | | | //! | YUV444 --> RGBA | X | X | | | //! +-------------------+-------------+-------------+-------------+-------------+ //! where //! * Either source or destination can be CHUNKY or PLANAR. //! * Either source or destination can reside on the CPU or the GPU. //! * The RGB components are in any order (i.e. RGB or BGR; RGBA or BGRA). //! * For RGBA (or BGRA) destinations, most implementations do not change the alpha channel, so it is recommended to //! set it at initialization time with [cuda]memset(im.pixels, -1, im.pitch * im.height) or //! [cuda]memset(im.pixels, -1, im.pitch * im.height * im.numComponents) for chunky and planar images respectively. //! * YUV requires that the colorspace field be set manually prior to Transfer, e.g. typical for layout=NVCV_NV12: //! image.colorspace = NVCV_709 | NVCV_VIDEO_RANGE | NVCV_CHROMA_INTSTITIAL; //! * There are also RGBf16-->RGBf32 and RGBf32-->RGBf16 transfers. //! * Additionally, when the src and dst formats are the same, all formats are accommodated on CPU and GPU, //! and this can be used as a replacement for cudaMemcpy2DAsync() (which it utilizes). This is also true for YUV, //! whose src and dst must share the same format, layout and colorspace. //! //! When there is some kind of conversion AND the src and dst reside on different processors (CPU, GPU), //! it is necessary to have a temporary GPU buffer, which is reshaped as needed to match the characteristics //! of the CPU image. The same temporary image can be used in subsequent calls to NvCVImage_Transfer(), //! regardless of the shape, format or component type, as it will grow as needed to accommodate //! the largest memory requirement. The recommended usage for most cases is to supply an empty image //! as the temporary; if it is not needed, no buffer is allocated. NULL can be supplied as the tmp //! image, in which case an ephemeral buffer is allocated if needed, with resultant //! performance degradation for image sequences. //! //! \param[in] src the source image. //! \param[out] dst the destination image. //! \param[in] scale a scale factor that can be applied when one (but not both) of the images //! is based on floating-point components; this parameter is ignored when all image components //! are represented with integer data types, or all image components are represented with //! floating-point data types. //! \param[in] stream the stream on which to perform the copy. This is ignored if both images reside on the CPU. //! \param[in,out] tmp a temporary buffer that is sometimes needed when transferring images //! between the CPU and GPU in either direction (can be empty or NULL). //! It has the same characteristics as the CPU image, but it resides on the GPU. //! \return NVCV_SUCCESS if successful, //! NVCV_ERR_PIXELFORMAT if one of the pixel formats is not accommodated. //! NVCV_ERR_CUDA if a CUDA error has occurred. //! NVCV_ERR_GENERAL if an otherwise unspecified error has occurred. NvCV_Status NvCV_API NvCVImage_Transfer( const NvCVImage *src, NvCVImage *dst, float scale, struct CUstream_st *stream, NvCVImage *tmp); //! Transfer a rectangular portion of an image. //! See NvCVImage_Transfer() for the pixel format combinations that are implemented. //! \param[in] src the source image. //! \param[in] srcRect the subRect of the src to be transferred (NULL implies the whole image). //! \param[out] dst the destination image. //! \param[in] dstPt location to which the srcRect is to be copied (NULL implies (0,0)). //! \param[in] scale scale factor applied to the magnitude during transfer, typically 1, 255 or 1/255. //! \param[in] stream the CUDA stream. //! \param[in] tmp a staging image. //! \return NVCV_SUCCESS if the operation was completed successfully. //! \note The actual transfer region may be smaller, because the rects are clipped against the images. NvCV_Status NvCV_API NvCVImage_TransferRect( const NvCVImage *src, const NvCVRect2i *srcRect, NvCVImage *dst, const NvCVPoint2i *dstPt, float scale, struct CUstream_st *stream, NvCVImage *tmp); //! Transfer from a YUV image. //! YUVu8 --> RGBu8 and YUVu8 --> RGBf32 are currently available. //! \param[in] y pointer to pixel(0,0) of the luminance channel. //! \param[in] yPixBytes the byte stride between y pixels horizontally. //! \param[in] yPitch the byte stride between y pixels vertically. //! \param[in] u pointer to pixel(0,0) of the u (Cb) chrominance channel. //! \param[in] v pointer to pixel(0,0) of the v (Cr) chrominance channel. //! \param[in] uvPixBytes the byte stride between u or v pixels horizontally. //! \param[in] uvPitch the byte stride between u or v pixels vertically. //! \param[in] yuvColorSpace the yuv colorspace, specifying range, chromaticities, and chrominance phase. //! \param[in] yuvMemSpace the memory space where the pixel buffers reside. //! \param[out] dst the destination image. //! \param[in] dstRect the destination rectangle (NULL implies the whole image). //! \param[in] scale scale factor applied to the magnitude during transfer, typically 1, 255 or 1/255. //! \param[in] stream the CUDA stream. //! \param[in] tmp a staging image. //! \return NVCV_SUCCESS if the operation was completed successfully. //! \note The actual transfer region may be smaller, because the rects are clipped against the images. //! \note This is supplied for use with YUV buffers that do not have the standard structure //! that are expected for NvCVImage_Transfer() and NvCVImage_TransferRect. NvCV_Status NvCV_API NvCVImage_TransferFromYUV( const void *y, int yPixBytes, int yPitch, const void *u, const void *v, int uvPixBytes, int uvPitch, NvCVImage_PixelFormat yuvFormat, NvCVImage_ComponentType yuvType, unsigned yuvColorSpace, unsigned yuvMemSpace, NvCVImage *dst, const NvCVRect2i *dstRect, float scale, struct CUstream_st *stream, NvCVImage *tmp); //! Transfer to a YUV image. //! RGBu8 --> YUVu8 and RGBf32 --> YUVu8 are currently available. //! \param[in] src the source image. //! \param[in] srcRect the destination rectangle (NULL implies the whole image). //! \param[out] y pointer to pixel(0,0) of the luminance channel. //! \param[in] yPixBytes the byte stride between y pixels horizontally. //! \param[in] yPitch the byte stride between y pixels vertically. //! \param[out] u pointer to pixel(0,0) of the u (Cb) chrominance channel. //! \param[out] v pointer to pixel(0,0) of the v (Cr) chrominance channel. //! \param[in] uvPixBytes the byte stride between u or v pixels horizontally. //! \param[in] uvPitch the byte stride between u or v pixels vertically. //! \param[in] yuvColorSpace the yuv colorspace, specifying range, chromaticities, and chrominance phase. //! \param[in] yuvMemSpace the memory space where the pixel buffers reside. //! \param[in] scale scale factor applied to the magnitude during transfer, typically 1, 255 or 1/255. //! \param[in] stream the CUDA stream. //! \param[in] tmp a staging image. //! \return NVCV_SUCCESS if the operation was completed successfully. //! \note The actual transfer region may be smaller, because the rects are clipped against the images. //! \note This is supplied for use with YUV buffers that do not have the standard structure //! that are expected for NvCVImage_Transfer() and NvCVImage_TransferRect. NvCV_Status NvCV_API NvCVImage_TransferToYUV( const NvCVImage *src, const NvCVRect2i *srcRect, const void *y, int yPixBytes, int yPitch, const void *u, const void *v, int uvPixBytes, int uvPitch, NvCVImage_PixelFormat yuvFormat, NvCVImage_ComponentType yuvType, unsigned yuvColorSpace, unsigned yuvMemSpace, float scale, struct CUstream_st *stream, NvCVImage *tmp); //! Between rendering by a graphics system and Transfer by CUDA, it is necessary to map the texture resource. //! There is a fair amount of overhead, so its use should be minimized. //! Every call to NvCVImage_MapResource() should be matched by a subsequent call to NvCVImage_UnmapResource(). //! \param[in,out] im the image to be mapped. //! \param[in] stream the stream on which the mapping is to be performed. //! \return NVCV_SUCCESS is the operation was completed successfully. //! \note This is an experimental API. If you find it useful, please respond to XXX@YYY.com, //! otherwise we may drop support. /* EXPERIMENTAL */ NvCV_Status NvCV_API NvCVImage_MapResource(NvCVImage *im, struct CUstream_st *stream); //! After transfer by CUDA, the texture resource must be unmapped in order to be used by the graphics system again. //! There is a fair amount of overhead, so its use should be minimized. //! Every call to NvCVImage_UnmapResource() should correspond to a preceding call to NvCVImage_MapResource(). //! \param[in,out] im the image to be mapped. //! \param[in] stream the CUDA stream on which the mapping is to be performed. //! \return NVCV_SUCCESS is the operation was completed successfully. //! \note This is an experimental API. If you find it useful, please respond to XXX@YYY.com, //! otherwise we may drop support. /* EXPERIMENTAL */ NvCV_Status NvCV_API NvCVImage_UnmapResource(NvCVImage *im, struct CUstream_st *stream); //! Composite one source image over another using the given matte. //! This accommodates all RGB and RGBA formats, with u8 and f32 components. //! If the bg has alpha, then the dst alpha is updated for use in subsequent composition. //! \param[in] fg the foreground source image. //! \param[in] bg the background source image. //! \param[in] mat the matte Yu8 (or Au8) image, indicating where the src should come through. //! \param[out] dst the destination image. This can be the same as fg or bg. //! \param[in] stream the CUDA stream on which the composition is to be performed. //! \return NVCV_SUCCESS if the operation was successful. //! \return NVCV_ERR_PIXELFORMAT if the pixel format is not accommodated. //! \return NVCV_ERR_MISMATCH if either the fg & bg & dst formats do not match, or if fg & bg & dst & mat are not //! in the same address space (CPU or GPU). #if RTX_CAMERA_IMAGE == 0 NvCV_Status NvCV_API NvCVImage_Composite(const NvCVImage *fg, const NvCVImage *bg, const NvCVImage *mat, NvCVImage *dst, struct CUstream_st *stream); #else // RTX_CAMERA_IMAGE == 1 // No GPU acceleration NvCV_Status NvCV_API NvCVImage_Composite(const NvCVImage *fg, const NvCVImage *bg, const NvCVImage *mat, NvCVImage *dst); #endif // RTX_CAMERA_IMAGE == 1 //! Composite one source image rectangular region over another using the given matte. //! This accommodates all RGB and RGBA formats, with u8 and f32 components. //! If the bg has alpha, then the dst alpha is updated for use in subsequent composition. //! If the background is not opaque, it is recommended that all images be premultiplied by alpha, //! and mode 1 composition be used, to yield the most meaningful composite matte. //! \param[in] fg the foreground source image. //! \param[in] fgOrg the upper-left corner of the fg image to be composited (NULL implies (0,0)). //! \param[in] bg the background source image. //! \param[in] bgOrg the upper-left corner of the bg image to be composited (NULL implies (0,0)). //! \param[in] mat the matte image, indicating where the src should come through. //! This determines the size of the rectangle to be composited. //! If this is multi-channel, the alpha channel is used as the matte. //! \param[in] mode the composition mode: 0 (straight alpha over) or 1 (premultiplied alpha over). //! \param[out] dst the destination image. This can be the same as fg or bg. //! \param[in] dstOrg the upper-left corner of the dst image to be updated (NULL implies (0,0)). //! \param[in] stream the CUDA stream on which the composition is to be performed. //! \note If a smaller region of a matte is desired, a window can be created using //! NvCVImage_InitView() for chunky pixels, as illustrated below in NvCVImage_CompositeRectA(). //! \return NVCV_SUCCESS if the operation was successful. //! \return NVCV_ERR_PIXELFORMAT if the pixel format is not accommodated. //! \return NVCV_ERR_MISMATCH if either the fg & bg & dst formats do not match, or if fg & bg & dst & mat are not //! in the same address space (CPU or GPU). NvCV_Status NvCV_API NvCVImage_CompositeRect( const NvCVImage *fg, const NvCVPoint2i *fgOrg, const NvCVImage *bg, const NvCVPoint2i *bgOrg, const NvCVImage *mat, unsigned mode, NvCVImage *dst, const NvCVPoint2i *dstOrg, struct CUstream_st *stream); //! Composite one RGBA or BGRA source image rectangular region over another RGB, BGR, RGBA or BGRA region. //! This accommodates all RGB and RGBA formats, with u8 and f32 components. //! If the bg has alpha, then the dst alpha is updated for use in subsequent composition. //! If the background is not opaque, it is recommended that all images be premultiplied by alpha, //! and mode 1 composition be used, to yield the most meaningful composite matte. //! \param[in] fg the foreground RGBA or BGRA source image. //! \param[in] fgRect a sub-rectangle of the fg image (NULL implies the whole image). //! \param[in] bg the background source image. //! \param[in] bgOrg the upper-left corner of the bg image to be composited (NULL implies (0,0)). //! \param[in] mode the composition mode: 0 (straight alpha over) or 1 (premultiplied alpha over). //! \param[out] dst the destination image. This can be the same as fg or bg. //! \param[in] dstOrg the upper-left corner of the dst image to be updated (NULL implies (0,0)). //! \param[in] stream the CUDA stream on which the composition is to be performed. //! \return NVCV_SUCCESS if the operation was successful. //! \return NVCV_ERR_PIXELFORMAT if the pixel format is not accommodated. //! \return NVCV_ERR_MISMATCH if either the fg & bg & dst formats do not match, or if fg & bg & dst & mat are not //! in the same address space (CPU or GPU). //! \bug fgRect will only work for chunky images, not planar. #ifdef __cplusplus inline NvCV_Status NvCVImage_CompositeRectA( const NvCVImage *fg, const NvCVRect2i *fgRect, const NvCVImage *bg, const NvCVPoint2i *bgOrg, unsigned mode, NvCVImage *dst, const NvCVPoint2i *dstOrg, struct CUstream_st *stream ) { if (fgRect) { NvCVImage fgView(const_cast(fg), fgRect->x, fgRect->y, fgRect->width, fgRect->height); return NvCVImage_CompositeRect(&fgView, nullptr, bg, bgOrg, &fgView, mode, dst, dstOrg, stream); } return NvCVImage_CompositeRect(fg, nullptr, bg, bgOrg, fg, mode, dst, dstOrg, stream); } #endif // __cplusplus //! Composite a source image over a constant color field using the given matte. //! \param[in] src the source image. //! \param[in] mat the matte image, indicating where the src should come through. //! \param[in] bgColor pointer to a location holding the desired flat background color, with the same format //! and component ordering as the dst. This acts as a 1x1 background pixel buffer, //! so should reside in the same memory space (CUDA or CPU) as the other buffers. //! \param[in,out] dst the destination image. May be the same as src. //! \return NVCV_SUCCESS if the operation was successful. //! \return NVCV_ERR_PIXELFORMAT if the pixel format is not accommodated. //! \return NVCV_ERR_MISMATCH if fg & mat & dst & bgColor are not in the same address space (CPU or GPU). //! \note The bgColor must remain valid until complete; this is an important consideration especially if //! the buffers are on the GPU and NvCVImage_CompositeOverConstant() runs asynchronously. NvCV_Status NvCV_API NvCVImage_CompositeOverConstant( #if RTX_CAMERA_IMAGE == 0 const NvCVImage *src, const NvCVImage *mat, const void *bgColor, NvCVImage *dst, struct CUstream_st *stream #else // RTX_CAMERA_IMAGE == 1 const NvCVImage *src, const NvCVImage *mat, const unsigned char bgColor[3], NvCVImage *dst #endif // RTX_CAMERA_IMAGE ); //! Flip the image vertically. //! No actual pixels are moved: it is just an accounting procedure. //! This is extremely low overhead, but requires appropriate interpretation of the pitch. //! Flipping twice yields the original orientation. //! \param[in] src the source image (NULL implies src == dst). //! \param[out] dst the flipped image (can be the same as the src). //! \return NVCV_SUCCESS if successful. //! \return NVCV_ERR_PIXELFORMAT for most planar formats. //! \bug This does not work for planar or semi-planar formats, neither RGB nor YUV. //! \note This does work for all chunky formats, including UYVY, VYUY, YUYV, YVYU. NvCV_Status NvCV_API NvCVImage_FlipY(const NvCVImage *src, NvCVImage *dst); //! Get the pointers for YUV, based on the format. //! \param[in] im The image to be deconstructed. //! \param[out] y A place to store the pointer to y(0,0). //! \param[out] u A place to store the pointer to u(0,0). //! \param[out] v A place to store the pointer to v(0,0). //! \param[out] yPixBytes A place to store the byte stride between luma samples horizontally. //! \param[out] cPixBytes A place to store the byte stride between chroma samples horizontally. //! \param[out] yRowBytes A place to store the byte stride between luma samples vertically. //! \param[out] cRowBytes A place to store the byte stride between chroma samples vertically. //! \return NVCV_SUCCESS If the information was gathered successfully. //! NVCV_ERR_PIXELFORMAT Otherwise. NvCV_Status NvCV_API NvCVImage_GetYUVPointers(NvCVImage *im, unsigned char **y, unsigned char **u, unsigned char **v, int *yPixBytes, int *cPixBytes, int *yRowBytes, int *cRowBytes); //! Sharpen an image. //! The src and dst should be the same type - conversions are not performed. //! This function is only implemented for NVCV_CHUNKY NVCV_U8 pixels, of format NVCV_RGB or NVCV_BGR. //! \param[in] sharpness the sharpness strength, calibrated so that 1 and 2 yields Adobe's Sharpen and Sharpen More. //! \param[in] src the source image to be sharpened. //! \param[out] dst the resultant image (may be the same as the src). //! \param[in] stream the CUDA stream on which to perform the computations. //! \param[in] tmp a temporary working image. This can be NULL, but may result in lower performance. //! It is best if it resides on the same processor (CPU or GPU) as the destination. //! @return NVCV_SUCCESS if the operation completed successfully. //! NVCV_ERR_MISMATCH if the source and destination formats are different. //! NVCV_ERR_PIXELFORMAT if the function has not been implemented for the chosen pixel type. NvCV_Status NvCV_API NvCVImage_Sharpen(float sharpness, const NvCVImage *src, NvCVImage *dst, struct CUstream_st *stream, NvCVImage *tmp); #ifdef __cplusplus } // extern "C" /******************************************************************************** * NvCVImage default constructor ********************************************************************************/ NvCVImage::NvCVImage() { pixels = nullptr; (void)NvCVImage_Alloc(this, 0, 0, NVCV_FORMAT_UNKNOWN, NVCV_TYPE_UNKNOWN, 0, 0, 0); } /******************************************************************************** * NvCVImage allocation constructor ********************************************************************************/ NvCVImage::NvCVImage(unsigned width, unsigned height, NvCVImage_PixelFormat format, NvCVImage_ComponentType type, unsigned layout, unsigned memSpace, unsigned alignment) { pixels = nullptr; (void)NvCVImage_Alloc(this, width, height, format, type, layout, memSpace, alignment); } /******************************************************************************** * Subimage constructor ********************************************************************************/ NvCVImage::NvCVImage(NvCVImage *fullImg, int x, int y, unsigned width, unsigned height) { NvCVImage_InitView(this, fullImg, x, y, width, height); } /******************************************************************************** * NvCVImage destructor ********************************************************************************/ NvCVImage::~NvCVImage() { NvCVImage_Dealloc(this); } /******************************************************************************** * copy subimage ********************************************************************************/ NvCV_Status NvCVImage::copyFrom(const NvCVImage *src, int srcX, int srcY, int dstX, int dstY, unsigned wd, unsigned ht, struct CUstream_st* stream) { #if RTX_CAMERA_IMAGE // This only works for chunky images NvCVImage srcView, dstView; NvCVImage_InitView(&srcView, const_cast(src), srcX, srcY, wd, ht); NvCVImage_InitView(&dstView, this, dstX, dstY, wd, ht); return NvCVImage_Transfer(&srcView, &dstView, 1.f, stream, nullptr); #else // !RTX_CAMERA_IMAGE bug fix for non-chunky images NvCVRect2i srcRect = { (int)srcX, (int)srcY, (int)wd, (int)ht }; NvCVPoint2i dstPt = { (int)dstX, (int)dstY }; return NvCVImage_TransferRect(src, &srcRect, this, &dstPt, 1.f, stream, nullptr); #endif // RTX_CAMERA_IMAGE } /******************************************************************************** * copy image ********************************************************************************/ NvCV_Status NvCVImage::copyFrom(const NvCVImage *src, struct CUstream_st* stream) { return NvCVImage_Transfer(src, this, 1.f, stream, nullptr); } #endif // ___cplusplus #endif // __NVCVIMAGE_H__