850 lines
33 KiB
C
Executable File
850 lines
33 KiB
C
Executable File
/*
|
|
* Copyright (c) 2006 - 2007 NVIDIA Corporation. All rights reserved.
|
|
*
|
|
* NVIDIA Corporation and its licensors retain all intellectual property
|
|
* and proprietary rights in and to this software and related documentation
|
|
* and any modifications thereto. Any use, reproduction, disclosure or
|
|
* distribution of this software and related documentation without an express
|
|
* license agreement from NVIDIA Corporation is strictly prohibited.
|
|
*/
|
|
|
|
/*
|
|
* nvime.h
|
|
*
|
|
* A collection of image enhancing functions that utilize the GoForce
|
|
* h/w. This file contains the common routines that are used by all
|
|
* image enhancing functions, as well as the APIs/enums/defines that are
|
|
* specific to all image enhancing functions.
|
|
*
|
|
* PLEASE NOTE: NvIme is not thread-safe. All API calls must be made in
|
|
* a single thread, or the application must explicitly protect each NvIme
|
|
* call with its own mutex. Any other usage is not guaranteed to work.
|
|
*/
|
|
|
|
#ifndef NVIME
|
|
#define NVIME
|
|
|
|
#include "nvtypes.h"
|
|
#include "GFRm.h"
|
|
#include "GFGx.h"
|
|
#include "GFVx.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
typedef struct NvImeStruct_t *NvImeHandle;
|
|
|
|
typedef enum {
|
|
NVIME_OK=0,
|
|
NVIME_OUT_OF_MEMORY=1,
|
|
NVIME_INIT_FAILED=2,
|
|
NVIME_INVALID_HANDLE=3,
|
|
NVIME_SURFACE_INDEX_OUT_OF_RANGE=4,
|
|
NVIME_INVALID_SURFACE=5,
|
|
NVIME_ILLEGAL_SURFACE_BASE=6,
|
|
NVIME_ILLEGAL_SURFACE_STRIDE=7,
|
|
NVIME_INVALID_ROTATION=8,
|
|
NVIME_INVALID_COORD=9,
|
|
NVIME_MISSING_SURFACE=10,
|
|
NVIME_INVALID_KERNEL=11,
|
|
NVIME_INVALID_KERNEL_SIZE=12,
|
|
NVIME_INVALID_PIXFMT=13,
|
|
NVIME_INVALID_LUT=14,
|
|
NVIME_UNSPECIFIED_OPERATION=15,
|
|
NVIME_UNSUPPORTED_OPERATION=16,
|
|
NVIME_OPERATION_FAILED=17,
|
|
NVIME_INVALID_FLAG=18,
|
|
NVIME_INVALID_GET=19,
|
|
NVIME_INVALID_SCALE=20,
|
|
NVIME_INVALID_BIAS=21,
|
|
NVIME_ILLEGAL_CSC_VALUES=22,
|
|
NVIME_ILLEGAL_COEFF=23,
|
|
NVIME_ILLEGAL_COEFF_ARRAY_SIZE=24,
|
|
} NvImeStatus;
|
|
|
|
|
|
// NvImeOpen()
|
|
//
|
|
// Initialize the library and return a handle to pass into all future
|
|
// API calls into this library.
|
|
|
|
NvImeStatus NvImeOpen(GFRmHandle hRm, NvImeHandle *phIme);
|
|
|
|
|
|
// NvImeClose()
|
|
//
|
|
// Close down the library and relinquish all held resources.
|
|
|
|
void NvImeClose(NvImeHandle *phIme);
|
|
|
|
|
|
// NvImeSetSourceSurface()
|
|
//
|
|
// Set a source surface. "index" can be in 0..NVIME_MAX_SOURCE_SURFACES-1.
|
|
// Because each source surface will be read as a texture by the 3D unit,
|
|
// each must abide by 3D's texture alignment restrictions. These
|
|
// restrictions are:
|
|
//
|
|
// SB1) Base of surface must begin at an aligned memory address. Use
|
|
// NvIme<op>_GetIntegerv(NVIME_<op>_GET_SRC_SURF_ALIGNMENT_BYTES)
|
|
// to get this value.
|
|
//
|
|
// SB2) Stride must be a multiple of
|
|
// NvIme<op>_GetIntegerv(NVIME_<op>_GET_SRC_SURF_STRIDE_BYTES)
|
|
//
|
|
// SB3) Stride must be a power of two
|
|
//
|
|
// SB4) Width must be between
|
|
// NvIme<op>_GetIntegerv(NVIME_<op>_GET_SRC_SURF_MIN_WIDTH_PIXELS) and
|
|
// NvIme<op>_GetIntegerv(NVIME_<op>_GET_SRC_SURF_MAX_WIDTH_PIXELS)
|
|
//
|
|
// SB5) Height must be between
|
|
// NvIme<op>_GetIntegerv(NVIME_<op>_GET_SRC_SURF_MIN_HEIGHT_PIXELS) and
|
|
// NvIme<op>_GetIntegerv(NVIME_<op>_GET_SRC_SURF_MAX_HEIGHT_PIXELS)
|
|
//
|
|
// Even though the 3D unit only understands textures that are powers of
|
|
// two in width and height, the width and height of the data contained
|
|
// within the source surfaces do NOT need to actually be a powers of two
|
|
// in size. Likewise, the height of the surface does not need to be a
|
|
// power of two (although the width always must be).
|
|
//
|
|
// If the width of the source data is not a power of two, then in addition
|
|
// to the above texture alignment restrictions, the following must be true:
|
|
//
|
|
// SBW1) Memory between the end of the data in a row and the end of the
|
|
// row must be allowed to be overwritten by this library. Because
|
|
// the 3D texture unit does bilinear interpolation, this library
|
|
// will need to replicate the last column of data out to the next
|
|
// (M/2) columns over, where M is the width of the kernel used.
|
|
// If width + (M/2) crosses over a power of two boundary, the
|
|
// adjusted width need only be as large as the power of two
|
|
// boundary.
|
|
//
|
|
// If the height of the source data is not a power of two, then in addition
|
|
// to the above texture alignment restrictions, the following must be true:
|
|
//
|
|
// SBH1) The height of the source surface does *not* need to be a power
|
|
// of two.
|
|
//
|
|
// SBH2) The height of the source surface needs to be large enough for the
|
|
// library to replicate the last row to the next (N/2) rows down,
|
|
// where N is the height of the kernel used. This area must be
|
|
// allowed to be overwritten by this library. If height + (N/2)
|
|
// crosses over a power of two boundary, the adjusted height need
|
|
// only be as large as the power of two boundary.
|
|
//
|
|
// Note that some image enhancing operations will only work on certain
|
|
// source pixel formats. The NvImeProcessRect() call will return an
|
|
// error code on a source pixel format mismatch.
|
|
|
|
#define NVIME_MAX_SOURCE_SURFACES 5
|
|
NvImeStatus NvImeSetSourceSurface(NvImeHandle hIme,
|
|
NvU32 index,
|
|
GFRMSURFACE *sourceSurface);
|
|
|
|
|
|
// NvImeSetDestSurface()
|
|
//
|
|
// Set the destination surface. Because the destination surface will be
|
|
// written by the 3D unit, each surface must abide by 3D's surface
|
|
// alignment restrictions. These restrictions are:
|
|
//
|
|
// DB1) Base of surface must begin at an aligned memory address. Use
|
|
// NvIme<op>_GetIntegerv(NVIME_<op>_GET_DST_SURF_ALIGNMENT_BYTES)
|
|
// to get this value.
|
|
//
|
|
// DB2) Stride must be a multiple of
|
|
// NvIme<op>_GetIntegerv(NVIME_<op>_GET_DST_SURF_STRIDE_BYTES)
|
|
//
|
|
// DB3) Width must be between
|
|
// NvIme<op>_GetIntegerv(NVIME_<op>_GET_DST_SURF_MIN_WIDTH_PIXELS) and
|
|
// NvIme<op>_GetIntegerv(NVIME_<op>_GET_DST_SURF_MAX_WIDTH_PIXELS)
|
|
//
|
|
// DB4) Height must be between
|
|
// NvIme<op>_GetIntegerv(NVIME_<op>_GET_DST_SURF_MIN_HEIGHT_PIXELS) and
|
|
// NvIme<op>_GetIntegerv(NVIME_<op>_GET_DST_SURF_MAX_HEIGHT_PIXELS)
|
|
//
|
|
// "rotation" specifies how to rotate the source surfaces onto the
|
|
// destination surface as part of the rendering process. "rotation"
|
|
// must be one of GFGx's fast rotation modes. Specifically these are:
|
|
//
|
|
// +---+---+ +---+---+
|
|
// GFGXEX2_FAST_ROTATE_IDENTITY | 0 | 1 | | 0 | 1 |
|
|
// +---+---+ --> +---+---+
|
|
// | 2 | 3 | | 2 | 3 |
|
|
// +---+---+ +---+---+
|
|
//
|
|
// +---+---+ +---+---+
|
|
// GFGXEX2_FAST_ROTATE_ROT_90 | 0 | 1 | | 1 | 3 |
|
|
// +---+---+ --> +---+---+
|
|
// | 2 | 3 | | 0 | 2 |
|
|
// +---+---+ +---+---+
|
|
//
|
|
// +---+---+ +---+---+
|
|
// GFGXEX2_FAST_ROTATE_ROT_180 | 0 | 1 | | 3 | 2 |
|
|
// +---+---+ --> +---+---+
|
|
// | 2 | 3 | | 1 | 0 |
|
|
// +---+---+ +---+---+
|
|
//
|
|
// +---+---+ +---+---+
|
|
// GFGXEX2_FAST_ROTATE_ROT_270 | 0 | 1 | | 2 | 0 |
|
|
// +---+---+ --> +---+---+
|
|
// | 2 | 3 | | 3 | 1 |
|
|
// +---+---+ +---+---+
|
|
//
|
|
// +---+---+ +---+---+
|
|
// GFGXEX2_FAST_ROTATE_FLIP_X | 0 | 1 | | 1 | 0 |
|
|
// +---+---+ --> +---+---+
|
|
// | 2 | 3 | | 3 | 2 |
|
|
// +---+---+ +---+---+
|
|
//
|
|
// +---+---+ +---+---+
|
|
// GFGXEX2_FAST_ROTATE_FLIP_Y | 0 | 1 | | 2 | 3 |
|
|
// +---+---+ --> +---+---+
|
|
// | 2 | 3 | | 0 | 1 |
|
|
// +---+---+ +---+---+
|
|
//
|
|
// +---+---+ +---+---+
|
|
// GFGXEX2_FAST_ROTATE_TRANS_LR | 0 | 1 | | 0 | 2 |
|
|
// +---+---+ --> +---+---+
|
|
// | 2 | 3 | | 1 | 3 |
|
|
// +---+---+ +---+---+
|
|
//
|
|
// +---+---+ +---+---+
|
|
// GFGXEX2_FAST_ROTATE_TRANS_RL | 0 | 1 | | 3 | 1 |
|
|
// +---+---+ --> +---+---+
|
|
// | 2 | 3 | | 2 | 0 |
|
|
// +---+---+ +---+---+
|
|
//
|
|
// Note that some image enhancing operations will only work on certain
|
|
// destination pixel formats. The NvImeProcessRect() call will return an
|
|
// error code on a destination pixel format mismatch.
|
|
|
|
NvImeStatus NvImeSetDestSurface(NvImeHandle hIme,
|
|
GFRMSURFACE *destSurface,
|
|
NvU32 rotation);
|
|
|
|
|
|
// NvImeSetVxBltCSCCoeff()
|
|
//
|
|
// Set the Vx's color space conversion coefficients in the channel that
|
|
// NvIme is using. This API is nothing more than a pass-through to
|
|
// GFVxBltSetCSCCoeff(). However, it does need to be called if CSCCoeffs
|
|
// are desired to be changed. If GFVxBltSetCSCCoeff() is called directly
|
|
// by the application, the Vx issued commands in that channel will pick
|
|
// up the CSCCoeffs, but NvIme will not see them.
|
|
NvImeStatus NvImeSetVxBltCSCCoeff(NvImeHandle hIme,
|
|
GFVXCSCCOEF *pCoef,
|
|
NvU32 option);
|
|
|
|
|
|
// NvImeProcessRect()
|
|
//
|
|
// Render using the current algorithm. Application must call an NvIme
|
|
// API not contained within this header file that registers the algorithm
|
|
// to render with.
|
|
//
|
|
// "srcCoords" points to "numSrcCoords" GFRECTs. "srcCoords[i]" describes
|
|
// the region to use from the i'th sourceSurface. "dstCoord" points to a
|
|
// single GFRECT. If a coord extends beyond the size of the surface it
|
|
// refers to, it will be clamped to the surface boundaries.
|
|
//
|
|
// The range of pixels referred to in "dstCoord" and each "srcCoords[i]"
|
|
// do not have to match. Scaling up and down is supported. The quality
|
|
// of scaling up and down can vary with the particular image enhancing
|
|
// algorithm used.
|
|
//
|
|
// flags is used to pass down optional parameters to the renderer.
|
|
//
|
|
// NVIME_PR_FLAGS_DITHER_OUTPUT: dither color output to destination
|
|
// surface. This flag has no effect if destSurface->ColorFormat
|
|
// is GF_SURFACE_ARGB8888.
|
|
|
|
#define NVIME_PR_FLAGS_DITHER_OUTPUT (1<<0)
|
|
|
|
NvImeStatus NvImeProcessRect(NvImeHandle hIme,
|
|
NvU32 numSrcCoords,
|
|
GFRECT *srcCoords,
|
|
GFRECT *dstCoord,
|
|
NvU32 flags);
|
|
|
|
// NvImeFinish()
|
|
//
|
|
// A blocking call that does not return until all previously called
|
|
// NvIme commands are complete.
|
|
|
|
void NvImeFinish(NvImeHandle hIme);
|
|
|
|
|
|
//
|
|
// Kernel sizes
|
|
//
|
|
// When kernels are specified, they use row major order. For example a
|
|
// 3x3 kernel with weights arranged like so:
|
|
//
|
|
// w00 w01 w02
|
|
// w10 w11 w12
|
|
// w20 w21 w22
|
|
//
|
|
// would be specified in memory in the following order:
|
|
//
|
|
// w00 w01 w02 w10 w11 w12 w20 w21 w22
|
|
|
|
typedef enum {
|
|
NVIME_KERNEL_SIZE_1x1=0,
|
|
NVIME_KERNEL_SIZE_3x1=1,
|
|
NVIME_KERNEL_SIZE_5x1=2,
|
|
} NvImeKernelSize;
|
|
|
|
|
|
//
|
|
// Pixel formats
|
|
//
|
|
|
|
#define NVIME_COMPONENT_MASK(a) \
|
|
(((1U << NVIME_PIXFMT_##a##_BITS) - 1) << NVIME_PIXFMT_##a##_SHIFT)
|
|
|
|
#define NVIME_PIXFMT_L8_LUMINANCE_BITS 8
|
|
#define NVIME_PIXFMT_L8_LUMINANCE_SHIFT 0
|
|
#define NVIME_PIXFMT_L8_LUMINANCE_MASK NVIME_COMPONENT_MASK(L8_LUMINANCE)
|
|
|
|
#define NVIME_PIXFMT_RGB565_BLUE_BITS 5
|
|
#define NVIME_PIXFMT_RGB565_BLUE_SHIFT 0
|
|
#define NVIME_PIXFMT_RGB565_BLUE_MASK NVIME_COMPONENT_MASK(RGB565_BLUE)
|
|
#define NVIME_PIXFMT_RGB565_GREEN_BITS 6
|
|
#define NVIME_PIXFMT_RGB565_GREEN_SHIFT 5
|
|
#define NVIME_PIXFMT_RGB565_GREEN_MASK NVIME_COMPONENT_MASK(RGB565_GREEN)
|
|
#define NVIME_PIXFMT_RGB565_RED_BITS 5
|
|
#define NVIME_PIXFMT_RGB565_RED_SHIFT 11
|
|
#define NVIME_PIXFMT_RGB565_RED_MASK NVIME_COMPONENT_MASK(RGB565_RED)
|
|
|
|
#define NVIME_PIXFMT_RGB888_BLUE_BITS 8
|
|
#define NVIME_PIXFMT_RGB888_BLUE_SHIFT 0
|
|
#define NVIME_PIXFMT_RGB888_BLUE_MASK NVIME_COMPONENT_MASK(RGB888_BLUE)
|
|
#define NVIME_PIXFMT_RGB888_GREEN_BITS 8
|
|
#define NVIME_PIXFMT_RGB888_GREEN_SHIFT 8
|
|
#define NVIME_PIXFMT_RGB888_GREEN_MASK NVIME_COMPONENT_MASK(RGB888_GREEN)
|
|
#define NVIME_PIXFMT_RGB888_RED_BITS 8
|
|
#define NVIME_PIXFMT_RGB888_RED_SHIFT 16
|
|
#define NVIME_PIXFMT_RGB888_RED_MASK NVIME_COMPONENT_MASK(RGB888_RED)
|
|
|
|
#define NVIME_PIXFMT_ARGB8888_BLUE_BITS 8
|
|
#define NVIME_PIXFMT_ARGB8888_BLUE_SHIFT 0
|
|
#define NVIME_PIXFMT_ARGB8888_BLUE_MASK NVIME_COMPONENT_MASK(ARGB8888_BLUE)
|
|
#define NVIME_PIXFMT_ARGB8888_GREEN_BITS 8
|
|
#define NVIME_PIXFMT_ARGB8888_GREEN_SHIFT 8
|
|
#define NVIME_PIXFMT_ARGB8888_GREEN_MASK NVIME_COMPONENT_MASK(ARGB8888_GREEN)
|
|
#define NVIME_PIXFMT_ARGB8888_RED_BITS 8
|
|
#define NVIME_PIXFMT_ARGB8888_RED_SHIFT 16
|
|
#define NVIME_PIXFMT_ARGB8888_RED_MASK NVIME_COMPONENT_MASK(ARGB8888_RED)
|
|
#define NVIME_PIXFMT_ARGB8888_ALPHA_SHIFT 24
|
|
#define NVIME_PIXFMT_ARGB8888_ALPHA_MASK NVIME_COMPONENT_MASK(ARGB8888_ALPHA)
|
|
|
|
#define NVIME_PIXFMT_BAYER10_BITS 10
|
|
#define NVIME_PIXFMT_BAYER10_SHIFT 0
|
|
#define NVIME_PIXFMT_BAYER10_MASK NVIME_COMPONENT_MASK(BAYER10)
|
|
|
|
#define NVIME_PIXFMT_BAYER12_BITS 12
|
|
#define NVIME_PIXFMT_BAYER12_SHIFT 0
|
|
#define NVIME_PIXFMT_BAYER12_MASK NVIME_COMPONENT_MASK(BAYER12)
|
|
|
|
#define NVIME_PIXFMT_BAYER14_BITS 14
|
|
#define NVIME_PIXFMT_BAYER14_SHIFT 0
|
|
#define NVIME_PIXFMT_BAYER14_MASK NVIME_COMPONENT_MASK(BAYER14)
|
|
|
|
#define NVIME_PIXFMT_BAYER3D_LO_BITS 7
|
|
#define NVIME_PIXFMT_BAYER3D_LO_SHIFT 0
|
|
#define NVIME_PIXFMT_BAYER3D_LO_MASK NVIME_COMPONENT_MASK(BAYER3D_LO)
|
|
#define NVIME_PIXFMT_BAYER3D_HI_BITS 7
|
|
#define NVIME_PIXFMT_BAYER3D_HI_SHIFT 8
|
|
#define NVIME_PIXFMT_BAYER3D_HI_MASK NVIME_COMPONENT_MASK(BAYER3D_HI)
|
|
|
|
typedef enum {
|
|
NVIME_PIXFMT_L8=0, // L=Luminance (R8=L8, G8=L8, B8=L8)
|
|
NVIME_PIXFMT_RGB565=1,
|
|
NVIME_PIXFMT_RGB888=2,
|
|
NVIME_PIXFMT_ARGB8888=3,
|
|
NVIME_PIXFMT_BAYER10=4,
|
|
NVIME_PIXFMT_BAYER12=5,
|
|
NVIME_PIXFMT_BAYER14=6,
|
|
NVIME_PIXFMT_BAYER3D=7,
|
|
} NvImePixelFormat;
|
|
|
|
|
|
//
|
|
// LUT values
|
|
//
|
|
|
|
#define NVIME_LUT_ENTRIES 256
|
|
|
|
|
|
//
|
|
// Scale factors
|
|
//
|
|
|
|
typedef enum {
|
|
NVIME_SCALE_1_0=0,
|
|
NVIME_SCALE_2_0=1,
|
|
NVIME_SCALE_4_0=2,
|
|
} NvImeScaleFactor;
|
|
|
|
|
|
/*
|
|
* Below are APIs used to control the sharpening image enhancement
|
|
* operation. Sharpening takes in a YUV420p source surface and outputs
|
|
* to a destination surface of type RGB565, ARGB8888 or YUV420p.
|
|
* ====================================================================
|
|
*/
|
|
|
|
// NvImeSharpenGetIntegerv()
|
|
//
|
|
// Return the value or values of a selected parameter that apply to
|
|
// the YUV420p sharpen image enhancing operation.
|
|
//
|
|
// NVIME_SHARPEN_GET_SRC_SURF_ALIGNMENT_BYTES
|
|
// NVIME_SHARPEN_GET_DST_SURF_ALIGNMENT_BYTES
|
|
//
|
|
// "params" returns 1 value, the SOURCE/DEST surface's starting
|
|
// address must be aligned to this value.
|
|
//
|
|
// NVIME_SHARPEN_GET_SRC_SURF_STRIDE_BYTES
|
|
// NVIME_SHARPEN_GET_DST_SURF_STRIDE_BYTES
|
|
//
|
|
// "params" returns 1 value, the SOURCE/DEST surface's stride must
|
|
// be a multiple of this value.
|
|
//
|
|
// NVIME_SHARPEN_GET_SRC_SURF_MIN_WIDTH_PIXELS
|
|
// NVIME_SHARPEN_GET_DST_SURF_MIN_WIDTH_PIXELS
|
|
//
|
|
// "params" returns 1 value, the SOURCE/DEST surface's width in
|
|
// pixels must be greater than or equal to this value.
|
|
//
|
|
// NVIME_SHARPEN_GET_SRC_SURF_MAX_WIDTH_PIXELS
|
|
// NVIME_SHARPEN_GET_DST_SURF_MAX_WIDTH_PIXELS
|
|
//
|
|
// "params" returns 1 value, the SOURCE/DEST surface's width in
|
|
// pixels must be less than or equal to this value.
|
|
//
|
|
// NVIME_SHARPEN_GET_SRC_SURF_MIN_HEIGHT_PIXELS
|
|
// NVIME_SHARPEN_GET_DST_SURF_MIN_HEIGHT_PIXELS
|
|
//
|
|
// "params" returns 1 value, the SOURCE/DEST surface's height in
|
|
// pixels must be greater than or equal to this value.
|
|
//
|
|
// NVIME_SHARPEN_GET_SRC_SURF_MAX_HEIGHT_PIXELS
|
|
// NVIME_SHARPEN_GET_DST_SURF_MAX_HEIGHT_PIXELS
|
|
//
|
|
// "params" returns 1 value, the SOURCE/DEST surface's height in
|
|
// pixels must be less than or equal to this value.
|
|
|
|
typedef enum {
|
|
NVIME_SHARPEN_GET_SRC_SURF_ALIGNMENT_BYTES=0,
|
|
NVIME_SHARPEN_GET_SRC_SURF_STRIDE_BYTES=1,
|
|
NVIME_SHARPEN_GET_SRC_SURF_MIN_WIDTH_PIXELS=2,
|
|
NVIME_SHARPEN_GET_SRC_SURF_MAX_WIDTH_PIXELS=3,
|
|
NVIME_SHARPEN_GET_SRC_SURF_MIN_HEIGHT_PIXELS=4,
|
|
NVIME_SHARPEN_GET_SRC_SURF_MAX_HEIGHT_PIXELS=5,
|
|
NVIME_SHARPEN_GET_DST_SURF_ALIGNMENT_BYTES=6,
|
|
NVIME_SHARPEN_GET_DST_SURF_STRIDE_BYTES=7,
|
|
NVIME_SHARPEN_GET_DST_SURF_MIN_WIDTH_PIXELS=8,
|
|
NVIME_SHARPEN_GET_DST_SURF_MAX_WIDTH_PIXELS=9,
|
|
NVIME_SHARPEN_GET_DST_SURF_MIN_HEIGHT_PIXELS=10,
|
|
NVIME_SHARPEN_GET_DST_SURF_MAX_HEIGHT_PIXELS=11,
|
|
} NvImeSharpenGet;
|
|
|
|
NvImeStatus NvImeSharpenGetIntegerv(NvImeHandle hIme,
|
|
NvImeSharpenGet name,
|
|
int *params);
|
|
|
|
|
|
// NvImeSharpenParams()
|
|
//
|
|
// Specify sharpen parameters to use during subsequent call to
|
|
// NvImeProcessRect().
|
|
//
|
|
// When NvImeProcessRect() is called with sharpening in effect, there
|
|
// are additional restrictions are applied:
|
|
//
|
|
// 1) Only sourceSurfaces[0] is used. Which means that numSrcCoords
|
|
// must be 1. Stretching sub-regions of a surface is not
|
|
// supported. Because pixels will be replicated as needed to
|
|
// provide a buffer for the filter kernel, if one were to use
|
|
// a sub-region of a surface, valid data would be over-written.
|
|
// dstCoord can have arbitrary values that allow scaling within
|
|
// destSurface.
|
|
//
|
|
// 2) sourceSurfaces[0]->ColorFormat must be one of:
|
|
//
|
|
// GF_SURFACE_YUV420
|
|
// GF_SURFACE_JPEGDEC
|
|
// GF_SURFACE_MPEGDEC
|
|
//
|
|
// 3) destSurface->ColorFormat must be one of:
|
|
//
|
|
// GF_SURFACE_RGB565
|
|
// GF_SURFACE_ARGB8888
|
|
// GF_SURFACE_YUV420
|
|
// GF_SURFACE_JPEGDEC
|
|
// GF_SURFACE_MPEGDEC
|
|
//
|
|
// 4) The rotation value must be GFGXEX2_FAST_ROTATE_IDENTITY (any
|
|
// desired rotation must be performed after this library has
|
|
// finished its processing).
|
|
//
|
|
// The sharpening algorithm is described as follows:
|
|
//
|
|
// 1) The Y data in sourceSurfaces[0] is replicated as needed. The
|
|
// number of pixels replicated at the end of each row will be:
|
|
//
|
|
// MAX( (M/2), distance to next power-of-two )
|
|
//
|
|
// where M is the width of the kernel. Note that if
|
|
// sourceSurfaces[0]'s width is a power-of-two, then the distance
|
|
// to the next power-of-two will be zero, and no pixels will be
|
|
// replicated.
|
|
//
|
|
// The number of pixels replicated at the bottom of each column
|
|
// will be:
|
|
//
|
|
// MAX( (N/2), distance to next power-of-two )
|
|
//
|
|
// where N is the height of the kernel. Note that if
|
|
// sourceSurfaces[0]'s height is a power-of-two, then the distance
|
|
// to the next power-of-two will be zero, and no pixels will be
|
|
// replicated.
|
|
//
|
|
// 2) If destSurface->ColorFormat is GF_SURFACE_RGB565 or
|
|
// GF_SURFACE_ARGB8888, then a 2D StretchBlit is performed on
|
|
// sourceSurfaces[0] to destSurface. The full range of
|
|
// sourceSurfaces[0] will be scaled to the region indicated by
|
|
// dstCoord within destSurface.
|
|
//
|
|
// If destSurface->ColorFormat is GF_SURFACE_YUV420,
|
|
// GF_SURFACE_JPEGDEC or GF_SURFACE_MPEGDEC then no StretchBlit
|
|
// will be performed. The 3D stage of the algorithm will write
|
|
// the destination directly without blending to an RGB surface.
|
|
//
|
|
// 3) For each pixel in the region within destSurface specified by
|
|
// dstCoord, the 3D unit will perform a number of texture reads from
|
|
// sourceSurfaces[0] that matches the size of the kernel. Each
|
|
// texture read will be bilinearly filtered. The texture reads will
|
|
// be multiplied times the S1.8 kernel weights, summed together,
|
|
// scaled by one of 1.0, 2.0 or 4.0, a bias is added, and the result
|
|
// is clamped to the 0.0 to 1.0 range (note that intermediate values
|
|
// that exceed the h/w's S1.8 numeric range will be clamped to S1.8).
|
|
// The final clamped value will index into the provided LUT, which
|
|
// contains biased color values.
|
|
//
|
|
// When destSurface->ColorFormat is GF_SURFACE_RGB565 or ARGB8888:
|
|
//
|
|
// Each color channel from the LUT value will be multiplied by
|
|
// 2.0 and then have 1.0 subtracted from it. These unbiased
|
|
// colors will be added to the pixel in destSurface.
|
|
//
|
|
// When destSurface->ColorFormat is GF_SURFACE_YUV420,
|
|
// GF_SURFACE_JPEGDEC or GF_SURFACE_MPEGDEC:
|
|
//
|
|
// The red color channel from the LUT value will be multiplied
|
|
// by 2.0 and then have 1.0 subtracted from it. This unbiased
|
|
// color will be added to the Y value from sourceSurfaces[0]
|
|
// and be written to the Y pixel in destSurface. The U and V
|
|
// pixels in destSurface will be scaled by the 3D h/w using a
|
|
// 2x2 filter. No sharpening is applied to the U and V pixels.
|
|
//
|
|
// Below is a psuedo-code approximation for this part of the algorithm:
|
|
//
|
|
// // for each pixel
|
|
// for ( y=dstCoord->top ; x<=dstCoord->bottom ; y++ ) {
|
|
// for ( x=dstCoord->left ; x<=dstCoord->right ; x++ ) {
|
|
//
|
|
// // get proper indices for sourceSurfaces[0]
|
|
// srcX = sourcesSurfaces[0].width * x/destSurface.width;
|
|
// srcY = sourcesSurfaces[0].height * y/destSurface.height;
|
|
//
|
|
// // for each kernel entry
|
|
// idx = 0;
|
|
// for ( ky=0 ; ky<kernelHeight ; ky++ ) {
|
|
// for ( kx=0 ; kx<kernelWidth ; kx++ ) {
|
|
//
|
|
// // even though this appears to be point-sampling,
|
|
// // the 3D h/w does do a bilinear filter when
|
|
// // reading srcColor
|
|
// idx += srcColor[srcX + kx - (int)(kernelWidth/2),
|
|
// srcY + ky - (int)(kernelHeight/2)] *
|
|
// kernel[ky*kernelWidth + kx];
|
|
// }
|
|
// }
|
|
//
|
|
// // scale idx
|
|
// switch (finalScale) {
|
|
// case NVIME_SCALE_2_0 : idx *= 2.0; break;
|
|
// case NVIME_SCALE_4_0 : idx *= 4.0; break;
|
|
// default : break;
|
|
// }
|
|
// idx += finalBias;
|
|
//
|
|
// // clamp idx
|
|
// if (idx < 0.0) idx = 0.0;
|
|
// if (idx > 1.0) idx = 1.0;
|
|
//
|
|
// if ((destSurface->ColorFormat == GF_SURFACE_YUV420) ||
|
|
// (destSurface->ColorFormat == GF_SURFACE_JPEGDEC) ||
|
|
// (destSurface->ColorFormat == GF_SURFACE_MPEGDEC)) {
|
|
// // write the color value
|
|
// dstColor[x,y] = srcColor[srcX, srcY] +
|
|
// 2.0 * lut[NVIME_LUT_ENTRIES * idx] - 1.0;
|
|
// } else {
|
|
// // update color value
|
|
// dstColor[x,y] += 2.0 * lut[NVIME_LUT_ENTRIES * idx] - 1.0;
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// The supported kernel sizes are:
|
|
//
|
|
// NVIME_KERNEL_SIZE_1x1
|
|
// NVIME_KERNEL_SIZE_3x1
|
|
// NVIME_KERNEL_SIZE_5x1
|
|
//
|
|
// Each value in the kernel must be in S1.8 format, which means values
|
|
// between -2 inclusive and +2 exclusive in increments of 1/256 are
|
|
// representable.
|
|
//
|
|
// The LUT must contain NVIME_LUT_ENTRIES entries, each of size NvU32.
|
|
// The supported LUT formats are:
|
|
//
|
|
// NVIME_PIXFMT_L8
|
|
// NVIME_PIXFMT_RGB888
|
|
//
|
|
// Refer to the NVIME_PIXFMT_* macros for appropriate color channel bit
|
|
// positions. When destSurface->ColorFormat is GF_SURFACE_YUV420,
|
|
// GF_SURFACE_JPEGDEC or GF_SURFACE_MPEGDEC the Y buffer is processed
|
|
// directly without going through an RGB space. Because the Y buffer is
|
|
// monochrome, only the red channel of an RGB888 LUT will be used when
|
|
// the destSurface->ColorFormat is GF_SURFACE_YUV420, GF_SURFACE_JPEGDEC
|
|
// or GF_SURFACE_MPEGDEC.
|
|
//
|
|
// The finalScale parameter can be any of NVIME_SCALE_1_0, NVIME_SCALE_2_0,
|
|
// or NVIME_SCALE_4_0.
|
|
//
|
|
// The finalBias parameter must be in S1.8 format.
|
|
|
|
NvImeStatus
|
|
NvImeSharpenParams(NvImeHandle hIme,
|
|
NvImeKernelSize kernelSize,
|
|
NvU32 *kernel,
|
|
NvImePixelFormat lutFormat,
|
|
NvU32 *lut,
|
|
NvImeScaleFactor finalScale,
|
|
NvU32 finalBias);
|
|
|
|
|
|
/*
|
|
* Below are APIs used to control the anti-vignetting (also known as
|
|
* lens correction) image enhancement operation. Anti-vignetting takes
|
|
* in a BAYER3D source surface and outputs either BAYER10, BAYER12 or
|
|
* BAYER14 data to the same source surface. BAYER3D is format that has
|
|
* 14bits of data like BAYER14, but has unused bits at positions 8 and 16.
|
|
* So if your 16bits of data looked like --dcba9876543210, these would
|
|
* be stored in BAYER3D as -dcba987-6543210.
|
|
* ====================================================================
|
|
*/
|
|
|
|
// NvImeAntivigGetIntegerv()
|
|
//
|
|
// Return the value or values of a selected parameter that apply to
|
|
// the BAYER3D anti-vignetting image operation.
|
|
//
|
|
// NVIME_ANTIVIG_GET_SURF_ALIGNMENT_BYTES
|
|
//
|
|
// "params" returns 1 value, the SOURCE/DEST surface's starting
|
|
// address must be aligned to this value.
|
|
//
|
|
// NVIME_ANTIVIG_GET_SURF_STRIDE_BYTES
|
|
//
|
|
// "params" returns 1 value, the SOURCE/DEST surface's stride must
|
|
// be a multiple of this value.
|
|
//
|
|
// NVIME_ANTIVIG_GET_SURF_MIN_WIDTH_PIXELS
|
|
//
|
|
// "params" returns 1 value, the SOURCE/DEST surface's width in
|
|
// pixels must be greater than or equal to this value.
|
|
//
|
|
// NVIME_ANTIVIG_GET_SURF_MAX_WIDTH_PIXELS
|
|
//
|
|
// "params" returns 1 value, the SOURCE/DEST surface's width in
|
|
// pixels must be less than or equal to this value.
|
|
//
|
|
// NVIME_ANTIVIG_GET_SURF_MIN_HEIGHT_PIXELS
|
|
//
|
|
// "params" returns 1 value, the SOURCE/DEST surface's height in
|
|
// pixels must be greater than or equal to this value.
|
|
//
|
|
// NVIME_ANTIVIG_GET_SURF_MAX_HEIGHT_PIXELS
|
|
//
|
|
// "params" returns 1 value, the SOURCE/DEST surface's height in
|
|
// pixels must be less than or equal to this value.
|
|
//
|
|
// NVIME_ANTIVIG_GET_COEFF_ARRAY_MIN_WIDTH
|
|
//
|
|
// "params" returns 1 value, the minimum "widthCoeffArrays" that
|
|
// can be passed into NvImeAntivigParams.
|
|
//
|
|
// NVIME_ANTIVIG_GET_COEFF_ARRAY_MAX_WIDTH
|
|
//
|
|
// "params" returns 1 value, the maximum "widthCoeffArrays" that
|
|
// can be passed into NvImeAntivigParams.
|
|
//
|
|
// NVIME_ANTIVIG_GET_COEFF_ARRAY_MIN_HEIGHT
|
|
//
|
|
// "params" returns 1 value, the minimum "heightCoeffArrays" that
|
|
// can be passed into NvImeAntivigParams.
|
|
//
|
|
// NVIME_ANTIVIG_GET_COEFF_ARRAY_MAX_HEIGHT
|
|
//
|
|
// "params" returns 1 value, the maximum "heightCoeffArrays" that
|
|
// can be passed into NvImeAntivigParams.
|
|
|
|
typedef enum {
|
|
NVIME_ANTIVIG_GET_SURF_ALIGNMENT_BYTES=0,
|
|
NVIME_ANTIVIG_GET_SURF_STRIDE_BYTES=1,
|
|
NVIME_ANTIVIG_GET_SURF_MIN_WIDTH_PIXELS=2,
|
|
NVIME_ANTIVIG_GET_SURF_MAX_WIDTH_PIXELS=3,
|
|
NVIME_ANTIVIG_GET_SURF_MIN_HEIGHT_PIXELS=4,
|
|
NVIME_ANTIVIG_GET_SURF_MAX_HEIGHT_PIXELS=5,
|
|
NVIME_ANTIVIG_GET_COEFF_ARRAY_MIN_WIDTH=6,
|
|
NVIME_ANTIVIG_GET_COEFF_ARRAY_MAX_WIDTH=7,
|
|
NVIME_ANTIVIG_GET_COEFF_ARRAY_MIN_HEIGHT=8,
|
|
NVIME_ANTIVIG_GET_COEFF_ARRAY_MAX_HEIGHT=9,
|
|
} NvImeAntivigGet;
|
|
|
|
NvImeStatus NvImeAntivigGetIntegerv(NvImeHandle hIme,
|
|
NvImeAntivigGet name,
|
|
int *params);
|
|
|
|
|
|
// NvImeAntivigParams()
|
|
//
|
|
// Specify anti-vignetting parameters to use during subsequent call to
|
|
// NvImeProcessRect().
|
|
//
|
|
// When NvImeProcessRect() is called with anti-vignetting in effect,
|
|
// there are additional restrictions that are applied:
|
|
//
|
|
// 1) Only sourceSurfaces[0] is used. Which means that numSrcCoords
|
|
// must be 1.
|
|
//
|
|
// 2) sourceSurfaces[0]->ColorFormat must be GF_SURFACE_BAYER16.
|
|
// The actual data contained in the surface must be in the
|
|
// BAYER3D format. BAYER3D has 14 bits of data, where bits 13
|
|
// and 7 are ignored. So if your data value is --dcba9876543210,
|
|
// that would be stored in BAYER3D format as -dcba987-6543210.
|
|
//
|
|
// 3) The contents of the structure pointed to by destSurface must
|
|
// be equal to the contents of the structure pointed to by
|
|
// sourceSurfaces[0].
|
|
//
|
|
// 4) The contents of the structure pointed to by dstCoord must be
|
|
// equal to the contents of the structure pointed to by
|
|
// srcCoords[0].
|
|
//
|
|
// 5) The rotation value must be GFGXEX2_FAST_ROTATE_IDENTITY (any
|
|
// desired rotation must be performed after this library has
|
|
// finished its processing).
|
|
//
|
|
// The anti-vignetting algorithm is described below:
|
|
//
|
|
// 1) The 4 passed in coefficient arrays are scanned looking for the
|
|
// largest gain value. The largest gain is used to determine
|
|
// whether the overall coefficient range is in [0.0 .. 2.0],
|
|
// [0.0 .. 4.0], [0.0 .. 8.0] or [0.0 .. 16.0]. The lower the
|
|
// maximum gain, the more precise the output will be. Here is
|
|
// a table showing the output format as a function of the maximum
|
|
// gain value:
|
|
//
|
|
// Maximum gain Output pixel format
|
|
// ------------- -------------------
|
|
// [0.0 .. 2.0] BAYER14
|
|
// [0.0 .. 4.0] BAYER12
|
|
// [0.0 .. 8.0] BAYER12
|
|
// [0.0 .. 16.0] BAYER10
|
|
//
|
|
// 2) After the maximum gain has been determined, the coefficient
|
|
// arrays are divided by their maximum value rounded up to a power
|
|
// of 2, and stored in an 8bit value.
|
|
//
|
|
// 3) When NvImeProcessRect is called, the 8bit gain values for the
|
|
// appropriate 00, 01, 10, 11 pixel are bilinearly interpolated.
|
|
// The result is multiplied times the BAYER3D pixel value from
|
|
// the source surface and then written back in place in a
|
|
// BAYER10/12/14 format.
|
|
//
|
|
// 4) NvImeProcessRect can process an entire BAYER3D buffer at a time,
|
|
// or a horizontal swath of the buffer. This is to support large
|
|
// buffers (like 5Mpixel) where it may not be practical (or even
|
|
// possible) to have multiple buffers residing in memory at the same
|
|
// time.
|
|
//
|
|
// NvImeAntivigAdjustScanline() modifies the access pattern of the
|
|
// 8bit gain values as if srcCoords[0].top were scanlineBias larger.
|
|
// This shifts the accesses down.
|
|
//
|
|
// For example, suppose you had a 2048x64 BAYER3D surface which is
|
|
// used to hold 32 pixel high swaths of a 2048x2048 surface in
|
|
// a double buffered manner. You would process the buffer like so:
|
|
//
|
|
// srcCoordsLow.top = 0;
|
|
// srcCoordsLow.left = 0;
|
|
// srcCoordsLow.right = 2047;
|
|
// srcCoordsLow.bottom = 31;
|
|
//
|
|
// srcCoordsHigh.top = 32;
|
|
// srcCoordsHigh.left = 0;
|
|
// srcCoordsHigh.right = 2047;
|
|
// srcCoordsHigh.bottom = 63;
|
|
//
|
|
// // Fill SourceSurface[0] rows [0..31] with camera rows [0..31]
|
|
// NvImeAntivigAdjustScanline(hIme, 0);
|
|
// NvImeProcessRects(hIme, 1, &srcCoordsLow, &srcCoordsLow, 0);
|
|
//
|
|
// // Fill SourceSurface[0] rows [32..63] with camera rows [32..63]
|
|
// NvImeProcessRects(hIme, 1, &srcCoordsHigh, &srcCoordsHigh, 0);
|
|
//
|
|
// // Fill SourceSurface[0] rows [0..31] with camera rows [64..95]
|
|
// NvImeAntivigAdjustScanline(hIme, 32);
|
|
// NvImeProcessRects(hIme, 1, &srcCoordsLow, &srcCoordsLow, 0);
|
|
//
|
|
// // Fill SourceSurface[0] rows [32..63] with camera rows [96..127]
|
|
// NvImeProcessRects(hIme, 1, &srcCoordsHigh, &srcCoordsHigh, 0);
|
|
//
|
|
// // Fill SourceSurface[0] rows [0..31] with camera rows [128..159]
|
|
// NvImeAntivigAdjustScanline(hIme, 64);
|
|
// NvImeProcessRects(hIme, 1, &srcCoordsLow, &srcCoordsLow, 0);
|
|
//
|
|
// // Fill SourceSurface[0] rows [32..63] with camera rows [160..191]
|
|
// NvImeProcessRects(hIme, 1, &srcCoordsHigh, &srcCoordsHigh, 0);
|
|
//
|
|
// // and so on...
|
|
|
|
NvImeStatus
|
|
NvImeAntivigParams(NvImeHandle hIme,
|
|
NvU32 widthCoeffArrays,
|
|
NvU32 heightCoeffArrays,
|
|
float *coeffsPix00,
|
|
float *coeffsPix01,
|
|
float *coeffsPix10,
|
|
float *coeffsPix11,
|
|
NvU32 totalSurfaceWidth,
|
|
NvU32 totalSurfaceHeight,
|
|
NvImePixelFormat *outFormat);
|
|
|
|
NvImeStatus
|
|
NvImeAntivigAdjustScanline(NvImeHandle hIme, NvU32 scanlineBias);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* NVIME */
|