Imaging-Processing Specific API Conventions

Function Naming

Image processing related functions use a number of suffixes to indicate various different flavors of a primitive beyond just different data types. The flavor suffix uses the following abbreviations: The suffixes above always appear in alphabetical order. E.g. a 4 channel primitive not affecting the alpha channel with masked operation, in place and with scaling/saturation and ROI would have the postfix: "AC4IMRSfs".

Image Data

Image data is passed to and from NPPI primitives via a pair of parameters:
  1. A pointer to the image's underlying data type.
  2. A line step in bytes (also sometimes called line stride).
The general idea behind this fairly low-level way of passing image data is ease-of-adoption into existing software projects:

Line Step

The line step (also called "line stride" or "row step") allows lines of oddly sized images to start on well-aligned addresses by adding a number of unused bytes at the ends of the lines. This type of line padding has been common practice in digital image processing for a long time and is not particular to GPU image processing.

The line step is the number of bytes in a line including the padding. An other way to interpret this number is to say that it is the number of bytes between the first pixel of successive rows in the image, or generally the number of bytes between two neighboring pixels in any column of pixels.

The general reason for the existence of the line step it is that uniformly aligned rows of pixel enable optimizations of memory-access patterns.

Even though all functions in NPP will work with arbitrarily aligned images, best performance can only be achieved with well aligned image data. Any image data allocated with the NPP image allocators or the 2D memory allocators in the CUDA runtime, is well aligned.

Particularly on older CUDA capable GPUs it is likely that the performance decrease for misaligned data is substantial (orders of magnitude).

All image data passed to NPPI primitives requires a line step to be provided. It is important to keep in mind that this line step is always specified in terms of bytes, not pixels.

Parameter Names for Image Data

There are three general cases of image-data passing throughout NPP detailed in the following sections.

Passing Source-Image Data

Those are images consumed by the algorithm.
Source-Image Pointer
The source image data is generally passed via a pointer named
 pSrc 
The source image pointer is generally defined constant, enforcing that the primitive does not change any image data pointed to by that pointer. E.g.
 nppiPrimitive_32s_C1R(const Npp32s * pSrc, ...) 
In case the primitive consumes multiple images as inputs the source pointers are numbered like this:
 pSrc1, pScr2, ... 
Source-Image Line Step
The source-image line step is the number of bytes between successive rows in the image. The source-image line step parameter is
 nSrcStep 
or in the case of multiple source images
 nSrcStep1, nSrcStep2, ... 

Passing Destination-Image Data

Those are images produced by the algorithm.
Destination-Image Pointer
The destination image data is generally passed via a pointer named
 pDst 
In case the primitive consumes multiple images as inputs the source pointers are numbered like this:
 pDst1, pDst2, ... 
Destination-Image Line Step
The destination-image line step parameter is
 nDstStep 
or in the case of multiple destination images
 nDstStep1, nDstStep2, ... 

Passing In-Place Image Data

In-Place Image Pointer
In the case of in-place processing, source and destination are served by the same pointer and thus pointers to in-place image data are called:
 pSrcDst 
In-Place Line Step
The in-place nSrcDstStep

Image Data Alignment Requirements

NPP requires pixel data to adhere to certain alignment constraints: For 2 and 4 channel images the following alignment requirement holds: data_pointer % (#channels * sizeof(channel type)) == 0. E.g. a 4 channel image with underlying type Npp8u (8-bit unsigned) would require all pixels to fall on addresses that are multiples of 4 (4 channels * 1 byte size).

As a logical consequence of all pixels being aligned to their natural size the image line steps of 2 and 4 channel images also need to be multiples of the pixel size.

1 and 3 channel images only require that pixel pointers are aligned to the underlying data type, i.e. pData % sizof(data type) == 0. And consequentially line steps are also held to this requirement.

Image Data Related Error Codes

All NPPI primitives operating on image data validate the image-data pointer for proper alignment and test that the point is not null. They also validate the line stride for proper alignment and guard against the step being less or equal to 0. Failed validation results in one of the following error codes being returnd and the primitive not being executed:

Region-of-Interest (ROI)

In practice processing a rectangular sub-region of an image is often more common than processing complete images. The vast majority of NPP's image-processing primitives allow for processing of such sub regions also referred to as regions-of-interest or ROIs.

All primitives supporting ROI processing are marked by a "R" in their name suffix. Where possible, the ROI a primitive operates on is passed as a single NppiSize struct, which provides the with and height of the ROI. This raises the obvious question how the primitive knows where in the image this rectangle of (width, height) is located. The "start pixel" of the ROI is implicitly given by the image-data pointer. I.e. instead of explicitly passing a pixel coordinate for the upper-right corner of the ROI the primive's user needs to perform the necessary offset computation on the image data pointers, such that the pointers passed to the primitive thus point to the start of the ROI.

In practice this means that for an image (pSrc, nSrcStep) and the start-pixel of the ROI being given by (xROI, yROI), one would pass

pSrcOffset = pSrc + yROI * nSrcStep + xROI * PixelSize;

as the image-data source to the primitive. PixelSize is typically computed as

PixelSize = NumberOfColorChannels * sizeof(PixelDataType).

E.g. for a pimitive like nppiSet_16s_C4R() we would have

ROI Related Error Codes

All NPPI primitives operating on ROIs of image data validate the ROI size and image's step size. Failed validation results in one of the following error codes being returned and the primitive not being executed:

Copyright © 2009-2010 NVIDIA Corporation