/* * 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_GetIntegerv(NVIME__GET_SRC_SURF_ALIGNMENT_BYTES) // to get this value. // // SB2) Stride must be a multiple of // NvIme_GetIntegerv(NVIME__GET_SRC_SURF_STRIDE_BYTES) // // SB3) Stride must be a power of two // // SB4) Width must be between // NvIme_GetIntegerv(NVIME__GET_SRC_SURF_MIN_WIDTH_PIXELS) and // NvIme_GetIntegerv(NVIME__GET_SRC_SURF_MAX_WIDTH_PIXELS) // // SB5) Height must be between // NvIme_GetIntegerv(NVIME__GET_SRC_SURF_MIN_HEIGHT_PIXELS) and // NvIme_GetIntegerv(NVIME__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_GetIntegerv(NVIME__GET_DST_SURF_ALIGNMENT_BYTES) // to get this value. // // DB2) Stride must be a multiple of // NvIme_GetIntegerv(NVIME__GET_DST_SURF_STRIDE_BYTES) // // DB3) Width must be between // NvIme_GetIntegerv(NVIME__GET_DST_SURF_MIN_WIDTH_PIXELS) and // NvIme_GetIntegerv(NVIME__GET_DST_SURF_MAX_WIDTH_PIXELS) // // DB4) Height must be between // NvIme_GetIntegerv(NVIME__GET_DST_SURF_MIN_HEIGHT_PIXELS) and // NvIme_GetIntegerv(NVIME__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 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 */