This repository has been archived on 2025-06-06. You can view files and clone it, but cannot push or open issues or pull requests.
Files
android-g900/Start_WM/test6/inc/nvime.h
2010-10-16 00:02:07 +06:00

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