nvTiff Documentation

Introduction

The nvTIFF library accelerates the decoding and encoding of TIFF images compressed with LZW on NVIDIA GPUs. The library is built on the CUDA ® platform and is supported on Volta+ GPU architectures.

Note

Throughout this document, the terms “CPU” and “Host” are used synonymously. Similarly, the terms “GPU” and “Device” are synonymous.

nvTIFF Decoder / Encoder

The library utilizes GPU for TIFF decode and encode using CUDA. The code uses a single GPU to decode uncompressed or LZW-compressed images in a TIFF file, or to LZW-compress raster images in memory and save the results in a TIFF file. The code supports multi-image TIFF files in both regular and BigTIFF format, with the following limitations:

  • color space must be either Grayscale (PhotometricInterpretation=1) or RGB (=2)

  • image data compressed with LZW (Compression=5) or uncompressed

  • pixel components stored in “chunky” format (RGBRGB…, PlanarConfiguration=1) for RGB images

  • image data must be organized in Strips, not Tiles

  • pixels of RGB images must be represented with at most 4 components

  • each component must be represented with exactly 8 bits in case of LZW or 8, 16 or 32 bits for uncompressed ones

  • all images in the file must have the same properties

Prerequisites

  • CUDA Toolkit version 11.6 and above

  • CUDA Driver version r475 and above

Platforms Supported

  • Linux versions:

Architecture

Distribution Information

Name

Version

Kernel

GCC

GLIBC

x86_64

Ubuntu

20.04.1

5.8.0

9.3.0

2.31

18.04.5

5.3.0

7.5.0

2.27

16.04.7

4.15.0

5.4.0

2.23

  • Windows versions:

    • Windows 10 and Windows Server 2019

Quick Start Guide

This section will explain how to use decoder and encoder APIs in a few quick steps. The API details will be covered in the next section.

Please note that since the decoding and encoding of TIFF images are two fundamentally different problems the APIs for decoding and encoding are also different and independent.

nvTIFF Decode

The library reads the file from disk and loads the image data to device memory.

  1. Create instances of the following -

nvtiffStream_t - is used to parse the bitstream and store the bitstream metadata

nvtiffDecoder_t - is used to store the work buffers required for decode

nvtiffStream_t nvtiff_stream;
nvtiffDecoder_t nvtiff_decoder;

nvtiffStreamCreate(&nvtiff_stream);
nvtiffDecoderCreateSimple(&nvtiff_decoder);
  1. Use the nvtiffStreamParseFromFile API to parse the tiff file from disk.

// char *fname, is the tiff file name
nvtiffStatus_t status = nvtiffStreamParseFromFile(fname, nvtiff_stream));
// make sure that nvtiffStreamParseFromFile returns NVTIFF_STATUS_SUCCESS before proceeding to the next step
  1. Extract the tiff file meta data.

nvtiffFileInfo_t file_info;
nvtiffStatus_t status = nvtiffStreamGetFileInfo(tiff_stream, &file_info);
//nvTiff requires all the images (subfiles) in the same file to have the same properties.
  1. Allocate decode output on device.

// allocate device memory for images
unsigned char **image_out = NULL;


const size_t image_size = sizeof(**image_out)*file_info.image_width *
                                              file_info.image_height *
                                              (file_info.bits_per_pixel/8);

// we are decoding all the images in file "fname" from
// subfile no. "frameBeg" to subfile no. "frameEnd"
frame_beg = fmax(frame_beg, 0);
frame_end = fmin(frame_end, file_info.num_images - 1);
const int num_decoded_images = frame_end - frame_beg + 1;


image_out = (unsigned char **)Malloc(sizeof(*image_out)*num_decoded_images);
for(unsigned int i = 0; i < nDecode; i++) {
        CHECK_CUDA(cudaMalloc(image_out + i, image_size));
}
  1. Call nvtiffDecode function to decode the data or range of data from files.

if (!decodeRange) {
        nvtiffStatus_t status = nvtiffDecode(nvtiff_stream, nvtiff_decoder, image_out, stream);
} else {
        nvtiffStatus_t status = nvtiffDecodeRange(nvtiff_stream, nvtiff_decoder, frame_beg, num_decoded_images, image_out, stream);
}
cudaStreamSynchronize(stream);
// cudaStreamSynchronize is requires since the decode APIs are asychronous with respect to the host
  1. Go to step 1 to decode another image. Once all images are decoded, release nvTIFF the library resources by calling the corresponding destroy APIs.

nvTIFF Encode

  1. Initialize the library handles and encoder parameters listed below:

// unsigned char **images_d is an host array of "nSubFiles" pointers
// to device buffers containing "nSubFiles" uncompressed images; each
// image has the same number of rows (nrow), of columns (ncol)
// and pixel size in bytes (pixelSize)

// for example let's partition the images in strips of four rows each
unsigned int encRowsPerStrip = 4;
unsigned int nStripOut = DIV_UP(nrow, encRowsPerStrip);
unsigned int totStrips = nSubFiles*nStripOut;

// initial estimate on the maximim
// size of compressed strips
unsigned long long encStripAllocSize = rowsPerStrip*ncol*(pixelSize);

// allocate encoding output buffers;
CHECK_CUDA(cudaMalloc(&stripSize_d, sizeof(*stripSize_d)*totStrips));
CHECK_CUDA(cudaMalloc(&stripOffs_d, sizeof(*stripOffs_d)*totStrips));
CHECK_CUDA(cudaMalloc(&stripData_d, sizeof(*stripData_d)*totStrips*encStripAllocSize));

// create encoding context
nvTiffEncodeCtx_t *ctx = nvTiffEncodeCtxCreate(devId, nSubFiles, nStripOut);
  1. Call nvTiffEncode function to encode. Since we cant’t know in advance the size of the compressed strips, we first try to encode in the buffers allocated based on our initial estimate. If one or more strips require more memory than “encStripAllocSize” bytes then we need to restart the encoding process with a larger buffer. In such a case, after the encoding fails, the minimum size required for the encoding to succeed is passed from the library to the user in the context field stripSizeMax. This way the encoding process can only fail once due to an output buffer being too small. After a successful encoding (nvTiffEncodeFinalize() returning NVTIFF_ENCODE_SUCCESS), the compressed strip data, offsets and sizes are returned in the buffers stripData_d, stripOffs_d and stripSize_d. In addition, the total size of the compressed strip data is also returned in ctx->stripSizeTot. Please note that you need to synchronize on stream stream before accessing those buffers.

int i = 0;
do {
        rv = nvTiffEncode(ctx,
                          nrow,
                          ncol,
                          pixelSize,
                          encRowsPerStrip,
                          nSubFiles,
                          imageOut_d,
                          encStripAllocSize,
                          stripSize_d,
                          stripOffs_d,
                          stripData_d,
                          stream);
        if (rv != NVTIFF_ENCODE_SUCCESS) {
                // ERROR, WHILE ENCODING IMAGES!
        }
        rv = nvTiffEncodeFinalize(ctx, stream);
        if (rv != NVTIFF_ENCODE_SUCCESS) {
                if (rv == NVTIFF_ENCODE_COMP_OVERFLOW) {
                        if (i == 1) {
                                // UNKNOWN ERROR, nvTiffEncode() SHOULDN'T OVERFLOW TWICE!
                        }
                        encStripAllocSize = ctx->stripSizeMax;
                        nvTiffEncodeCtxDestroy(ctx);
                        cudaFree(stripData_d);
                        cudaMalloc(&stripData_d,
                                   sizeof(*stripData_d)*totStrips*encStripAllocSize);
                        ctx = nvTiffEncodeCtxCreate(dev, ...);
                        i++;
                } else {
                        // ERROR WHILE FINALIZING COMPRESSED IMAGES
                }
        }
} while(rv == NVTIFF_ENCODE_COMP_OVERFLOW);
CHECK_CUDA(cudaStreamSynchronize(stream));
  1. Write the compress image to TIFF file.

// copy compressed data from the device to the host
unsigned long long *stripSize_h = (unsigned long long *)Malloc(sizeof(*stripSize_h)*totStrips);
CHECK_CUDA(cudaMemcpy(stripSize_h,
                      stripSize_d,
                      sizeof(*stripSize_h)*totStrips,
                      cudaMemcpyDeviceToHost));

unsigned long long *stripOffs_h = (unsigned long long *)Malloc(sizeof(*stripOffs_h)*totStrips);
CHECK_CUDA(cudaMemcpy(stripOffs_h,
                      stripOffs_d,
                      sizeof(*stripOffs_h)*totStrips,
                      cudaMemcpyDeviceToHost));

unsigned char *stripData_h = (unsigned char *)Malloc(sizeof(*stripData_h)*ctx->stripSizeTot);
CHECK_CUDA(cudaMemcpy(stripData_h,
                      stripData_d,
                      ctx->stripSizeTot,
                      cudaMemcpyDeviceToHost));

// write output file
nvTiffWriteFile("outFile.tif",
                VER_REG_TIFF,
                nSubFiles,
                nrow,
                ncol,
                encRowsPerStrip,
                samplesPerPixel,
                bitsPerSample,
                photometricInt,
                planarConf,
                stripSize_h,
                stripOffs_h,
                stripData_h);

Tiff Decode / Encode Demo example

The binary nvTiff_exmaple provides a complete and detailed usage example for the encoding and decoding capabilities of the nvTIFF library.

Usage:
nvTiff_example [options] -f|--file <TIFF_FILE>

General options:

        -d DEVICE_ID
        --device DEVICE_ID
                Specifies the GPU to use for images decoding/encoding.
                Default: device 0 is used.

        -v
        --verbose
                Prints some information about the decoded TIFF file.

        -h
        --help
                Prints this help

Decoding options:

        -f TIFF_FILE
        --file TIFF_FILE
                Specifies the TIFF file to decode. The code supports both single and multi-image
                tiff files with the following limitations:
                  * color space must be either Grayscale (PhotometricInterp.=1) or RGB (=2)
                  * image data compressed with LZW (Compression=5) or uncompressed
                  * pixel components stored in "chunky" format (RGB..., PlanarConfiguration=1)
                    for RGB images
                  * image data must be organized in Strips, not Tiles
                  * pixels of RGB images must be represented with at most 4 components
                  * each component must be represented exactly with:
                  * 8 bits for LZW compressed images
                  * 8, 16 or 32 bits for uncompressed images
                  * all images in the file must have the same properties

        -b BEG_FRM
        --frame-beg BEG_FRM
                Specifies the image id in the input TIFF file to start decoding from.  The image
                id must be a value between 0 and the total number of images in the file minus 1.
                Values less than 0 are clamped to 0.
                Default: 0

        -e END_FRM
        --frame-end END_FRM
                Specifies the image id in the input TIFF file to stop  decoding  at  (included).
                The image id must be a value between 0 and the total number  of  images  in  the
                file minus 1.  Values greater than num_images-1  are  clamped  to  num_images-1.
                Default:  num_images-1.

        -m
        --memtype TYPE
                Specifies the type of memory used to hold  the  TIFF  file  content:  pinned  or
                pageable.  Pinned memory is used if 'p' is specified. Pageable memory is used if
                'r' is specified.  In case of pinned memory,  file  content  is  not  copied  to
                device memory before the decoding process (with a resulting performance  impact)
                unless the option -c is also specified (see below).
                Defualt: r (pageable)

        -c
        --copyh2d
                Specifies to copy the file data to device memory in case the -m option specifies
                to use pinned memory.  In case of pageable memory this  option  has  no  effect.
                Default: off.

        --decode-out NUM_OUT
                Enables the writing of selected images from the decoded  input  TIFF  file  into
                separate BMP files for inspection.  If no argument is  passed,  only  the  first
                image is written to disk,  otherwise  the  first  NUM_OUT  images  are  written.
                Output files are named outImage_0.bmp, outImage_1.bmp...
                Defualt: disabled.

Encoding options:

        -E
        --encode
                This option enables the encoding of the raster images obtained by  decoding  the
                input TIFF file.  The images are divided into strips, compressed  with  LZW and,
                optionally, written into an output TIFF file.
                Default: disabled.

        -r
        --rowsxstrip
                Specifies the number of consecutive rows  to  use  to  divide  the  images  into
                strips.  Each image is divided in strips of the same size (except  possibly  the
                last strip) and then the strips are  compressed  as  independent  byte  streams.
                This option is ignored if -E is not specified.
                Default: 1.

        -s
        --stripalloc
                Specifies the initial estimate of the maximum size  of  compressed  strips.   If
                during compression one or more strips require more  space,  the  compression  is
                aborted and restarted automatically with a safe estimate.
                This option is ignored if -E is not specified.
                Default: the size, in bytes, of a strip in the uncompressed images.

        --encode-out
                Enables the writing of the compressed  images  to  an  output  TIFF  file named
                outFile.tif.
                This option is ignored if -E is not specified.
                Defualt: disabled.

Python Tiff Decode example

Prerequisites

Python packages

  1. cupy

$  pip install cupy
  1. numpy

$  pip install numpy
  1. tifffile

$  pip install tifffile
  1. imagecodecs

$  pip install imagecodecs

Install nvTIFF Python Wheel

$  pip install nvtiff-0.1.0-cp36-cp36m-linux_x86_64.whl

Usage:

$ python3 nvtiff_test.py -h
usage: nvtiff_test.py [-h] [-o OUTPUT_FILE_PREFIX] [-s] [-c] [-p]
                [-r SUBFILE_RANGE]
                tiff_file
positional arguments:
tiff_file             tiff file to decode.

optional arguments:
-h, --help            show this help message and exit
-o OUTPUT_FILE_PREFIX, --output_file_prefix OUTPUT_FILE_PREFIX
                        Output file prefix to save decoded data. Will save one
                        file per image in tiff file.
-s, --return_single_array
                        Return single array from nvTiff instead of list of
                        arrays
-c, --check_output    Compare nvTiff output to reference CPU result
-p, --use_pinned_mem  Read TIFF data from pinned memory.
-r SUBFILE_RANGE, --subfile_range SUBFILE_RANGE
                        comma separated list of starting and ending file
                        indices to decode, inclusive

Python Example

$ python3 nvtiff_test.py bali_notiles.tif
Command line arguments:
        tiff_file: bali_notiles.tif
        return_single_array: False
        output_file_prefix: None
        check_output: False
        use_pinned_mem: False
        subfile_range: None

Time for tifffile:

        decode:   0.010347366333007812 s
        h2d copy: 0.0010058879852294922 s
        total:    0.011353254318237305 s

Time for nvTiff:

        open: 0.002551555633544922 s
        decode: 0.0005545616149902344 s
        total:  0.0031061172485351562 s

Type Declarations

nvTIFF Decode API Return Status Codes

The return codes of the nvTIFF Decode APIs are listed below:

#define NVTIFF_DECODE_SUCCESS       (0)
#define NVTIFF_DECODE_INVALID_CTX   (1)
#define NVTIFF_DECODE_INVALID_RANGE (2)

Description the Return Codes

Return Code

Description

NVTIFF_DECODE_SUCCESS (0)

The API call has finished successfully. Note that many of the calls are asynchronous and some of the errors may be seen only after synchronization.

NVTIFF_DECODE_INVALID_CTX (1)

Invalid CTX.

NVTIFF_DECODE_INVALID_RANGE (2)

Range of subfiles not valid

nvTIFF Encode API Return Status Codes

The return codes of the nvTIFF Encode APIs are listed below:

#define NVTIFF_ENCODE_SUCCESS             (0)
#define NVTIFF_ENCODE_INVALID_CTX         (1)
#define NVTIFF_ENCODE_INVALID_STRIP_NUM   (2)
#define NVTIFF_ENCODE_COMP_OVERFLOW       (3)
#define NVTIFF_ENCODE_COMP_STRIP_TOO_LONG (4)

Description the Return Codes

Return Code

Description

NVTIFF_ENCODE_SUCCESS (0)

The API call has finished successfully. Note that many of the calls are asynchronous and some of the errors may be seen only after synchronization.

NVTIFF_ENCODE_INVALID_CTX (1)

Invalid CTX.

NVTIFF_ENCODE_INVALID_STRIP_NUM (2)

Invalid strip number

NVTIFF_ENCODE_COMP_OVERFLOW (3)

overflow during compression

NVTIFF_ENCODE_COMP_STRIP_TOO_LONG (4)

Too long strip

nvTIFF Write API Return Status Codes

The return codes of the nvTIFF Write APIs are listed below:

#define NVTIFF_WRITE_SUCCESS                (0)
#define NVTIFF_WRITE_UNSUPP_PLANAR_CONF     (1)
#define NVTIFF_WRITE_UNSUPP_PHOTOMETRIC_INT (2)

Description the Return Codes

Return Code

Description

NVTIFF_WRITE_SUCCESS (0)

The API call has finished successfully. Note that many of the calls are asynchronous and some of the errors may be seen only after synchronization.

NVTIFF_WRITE_UNSUPP_PLANAR_CONF (1)

if the value of planarConf parameter is not equal to 1;.

NVTIFF_WRITE_UNSUPP_PHOTOMETRIC_INT (2)

if the value of photometricInt parameter is neither 1 nor 2;

Version 2 API Return Status Codes

The return codes of the nvTiff V2 Decode APIs are listed below:

typedef enum {
    NVTIFF_STATUS_SUCCESS = 0,
    NVTIFF_STATUS_NOT_INITIALIZED = 1,
    NVTIFF_STATUS_INVALID_PARAMETER = 2,
    NVTIFF_STATUS_BAD_TIFF = 3,
    NVTIFF_STATUS_TIFF_NOT_SUPPORTED = 4,
    NVTIFF_STATUS_ALLOCATOR_FAILURE = 5,
    NVTIFF_STATUS_EXECUTION_FAILED = 6,
    NVTIFF_STATUS_ARCH_MISMATCH = 7,
    NVTIFF_STATUS_INTERNAL_ERROR = 8,
    NVTIFF_STATUS_NVCOMP_NOT_FOUND = 9,
} nvtiffStatus_t;

Description the Return Codes

Return Code

Description

NVTIFF_STATUS_SUCCESS (0)

The API call has finished successfully. Note that many of the calls are asynchronous and some of the errors may be seen only after synchronization.

NVTIFF_STATUS_NOT_INITIALIZED (1)

The library handle was not initialized.

NVTIFF_STATUS_INVALID_PARAMETER (2)

Wrong parameter was passed. For example, a null pointer as input data, or an invalid enum value

NVTIFF_STATUS_BAD_TIFF (3)

Cannot parse the TIFF stream. Likely due to a corruption that cannot be handled

NVTIFF_STATUS_TIFF_NOT_SUPPORTED (4)

Attempting to decode a TIFF stream that is not supported by the nvTIFF library.

NVTIFF_STATUS_ALLOCATOR_FAILURE (5)

The user-provided allocator functions, for either memory allocation or for releasing the memory, returned a non-zero code.

NVTIFF_STATUS_EXECUTION_FAILED (6)

Error during the execution of the device tasks.

NVTIFF_STATUS_ARCH_MISMATCH (7)

The device capabilities are not enough for the set of input parameters provided.

NVTIFF_STATUS_INTERNAL_ERROR (8)

Unknown error occured in the library.

NVTIFF_STATUS_NVCOMP_NOT_FOUND (9)

nvTiff is unable to load the nvomp library.

Device Allocator Interface

typedef int (*nvtiffDeviceMallocAsync)(void* ctx, void **ptr, size_t size, cudaStream_t stream);

typedef int (*nvtiffDeviceFreeAsync)(void* ctx, void *ptr, size_t size, cudaStream_t stream);

typedef struct {
    nvtiffDeviceMallocAsync device_malloc;
    nvtiffDeviceFreeAsync device_free;
    void *device_ctx;
} nvtiffDeviceAllocator_t;

Custom device allocator supports stream ordered allocation and user defined context information *device_ctx. When invoking the device allocators, nvTiff will pass *device_ctx as input to the device allocator.

Pinned Allocator Interface

typedef int (*nvtiffPinnedMallocAsync)(void* ctx, void **ptr, size_t size, cudaStream_t stream);

typedef int (*nvtiffPinnedFreeAsync)(void* ctx, void *ptr, size_t size, cudaStream_t stream);

typedef struct {
    nvtiffPinnedMallocAsync pinned_malloc;
    nvtiffPinnedFreeAsync pinned_free;
    void *pinned_ctx;
} nvtiffPinnedAllocator_t;

Custom pinned allocator supports stream ordered allocation and user defined context information *pinned_ctx. When invoking the pinned allocators, nvTiff will pass *pinned_ctx as input to the pinned allocator.

Sample Format

typedef enum nvtiffSampleFormat {
    NVTIFF_SAMPLEFORMAT_UNKNOWN = 0,
    NVTIFF_SAMPLEFORMAT_UINT    = 1,
    NVTIFF_SAMPLEFORMAT_INT        = 2,
    NVTIFF_SAMPLEFORMAT_IEEEFP    = 3,
    NVTIFF_SAMPLEFORMAT_VOID        = 4,
    NVTIFF_SAMPLEFORMAT_COMPLEXINT    = 5,
    NVTIFF_SAMPLEFORMAT_COMPLEXIEEEFP    = 6
} nvtiffSampleFormat_t;

nvtiffSampleFormat_t enum corresponds to the SampleFormat(339) tag defined in the TIFF specification.

Photmetric Interpretation

typedef enum nvtiffPhotometricInt {
    NVTIFF_PHOTOMETRIC_MINISWHITE = 0,
    NVTIFF_PHOTOMETRIC_MINISBLACK    = 1,
    NVTIFF_PHOTOMETRIC_RGB        = 2,
}nvtiffPhotometricInt_t;

nvtiffPhotometricInt_t enum corresponds to the PhotometricInterpretation(262) tag defined in the TIFF specification.

Planar Configuration

typedef enum nvtiffPlanarConfig {
    PLANARCONFIG_CONTIG        = 1,
    PLANARCONFIG_SEPARATE    = 2
} nvtiffPlanarConfig_t;

nvtiffPhotometricInt_t enum corresponds to the PlanarConfiguration (284) tag defined in the TIFF specification.

Tiff File Information

typedef struct nvtiffFileInfo {
    uint32_t num_images;
    uint32_t image_width;
    uint32_t image_height;
    nvtiffPhotometricInt_t photometric_int;
    nvtiffPlanarConfig_t planar_config;
    uint16_t samples_per_pixel;
    uint16_t bits_per_pixel; // SUM(bits_per_sample)
    uint16_t bits_per_sample[MAX_NUM_SAMPLES];
    nvtiffSampleFormat_t sample_format[MAX_NUM_SAMPLES];
} nvtiffFileInfo_t;

nvtiffFileInfo_t enum is used to retrieve some of the TIFF file metadata. This information can be used for allocating decode output buffers.

Decoder Version 2 Types

Decoder Handle

struct nvtiffDecoder;
typedef struct nvtiffDecoder* nvtiffDecoder_t;

The nvtiffDecoder_t handle stores intermediate decode buffers used in decoding.

Bitstream/File Handle

struct nvtiffStream;
typedef struct nvtiffStream* nvtiffStream_t;

This handle is used for parsing a tiff file. Tiff metadata can be extracted using APIs defined in Parser API Reference.

API Reference

Decoding API Reference

Note

The APIs in this section are deprecated from v 0.3.0

nvTiffOpen()

Open a TIFF file and returns a pointer to a nvTiffFile_t object containing the file data.

Signature:

nvTiffFile_t NVTIFFAPI *nvTiffOpen(int dev,
                                   const char *fname,
                                   int hostMemType=NVTIFF_MEM_REG);

Parameters:

Parameter

Input/Output

Memory

Description

int dev

Input

device to use for CUDA calls

const char *fname

Input

Host

path to TIFF file to open.

int hostMemType=NVTIFF_MEM_REG

Input

specifies whether pinned or pageable memory should be used for the buffer allocated to read the content of the TIFF file “fname”. Possible values are NVTIFF_MEM_PIN or NVTIFF_MEM_REG. If pageable memory is used, then the file content is also copied in a device buffer before the function returns. In case of pinned memory instead, no Host2Device copy is performed.

nvTiffClose()

Closes an opened TIFF file read into a nvTiffFile_t object, freeing all the allocated memory (on both the host and the device).

Signature:

void nvTiffClose(nvTiffFile_t *tiffFile);

Parameters:

Parameter

Input/Output

Memory

Description

nvTiffFile_t *tiffFile

Input

Closes an opened TIFF file read into a nvTiffFile_t object

nvTiffH2DAsync()

Copies the file data read by nvTiffOpen() from the internal host buffer to the internal device buffer.

This function is fully asynchronous.

This function is useful when nvTiffOpen() is called withhostMemType=NVTIFF_MEM_PIN in order to overlap the copy of the data with something else before calling the decoding functions nvTiffDecode() or nvTiffDecodeRange(). Please note that in case the file buffer is allocated with pinned memory, if this function is not called, then the decode functions will directly read the pinned host buffer via zero-copy.

This function as no effect in case nvTiffOpen() is called with hostMemType=NVTIFF_MEM_REG.

Signature:

void NVTIFFAPI nvTiffH2DAsync(nvTiffFile_t *tiffFile,
                              cudaStream_t stream=0);

Parameters:

Parameter

Input/Output

Memory

Description

nvTiffFile_t *tiffFile

Input

nvtiff file

nvTiffDecode()

Perform the decoding of the image data on the GPU specified in “tiffFile” using a specified stream. Each image in the TIFF file is copied into the respective buffer pointed to by “imageOut_d”. This function is fully asynchronous.

Signature:

int nvTiffDecode(nvTiffFile_t *tiffFile,
                 unsigned char **imageOut_d,
                 cudaStream_t stream=0);

Parameters:

Parameter

Input/Output

Memory

Description

nvTiffFile_t *tiffFile

Input

The nvTiffFile_t object in which the TIFF file has been read.

unsigned char **imageOut_d

Output

Host

host array (of size tiffData->nSubFiles) of pointers to device buffers. Each device buffer is expected to have size at least: tiffData->subFiles[0].nrow * tiffData->subFiles[0].ncol * (tiffData->subFiles[0].bitsPerPixel/8)

cudaStream_t stream

Input

the stream to use for the kernel launches.

Returns:

NVTIFF_DECODE_SUCCESS - on success.

NVTIFF_DECODE_INVALID_CTX - if tiffFile is invalid.

nvTiffDecodeRange()

This function is similar to nvTiffDecode() with the difference that it allows to specify a range of images to be decoded (instead of decoding all images in the file).

Signature:

int nvTiffDecodeRange(nvTiffFile_t *tiffFile,
                      unsigned int subFileStart,
                      unsigned int subFileNum,
                      unsigned char **imageOut_d,
                      cudaStream_t stream=0);

Parameters:

Parameter

Input/Output

Memory

Description

nvTiffFile_t *tiffFile

Input

The nvTiffFile_t object in which the TIFF file has been read.

unsigned int subFileStart

Input

index of the first image to decode, in [0, tiffData->nSubFiles).

unsigned int subFileNum

Input

number of images to decode starting from “subFileStart”, in (0, tiffData->nSubFiles]

unsigned char **imageOut_d

Output

Host

host array (of size tiffData->nSubFiles) of pointers to device buffers. Each device buffer is expected to have size at least: tiffData->subFiles[0].nrow * tiffData->subFiles[0].ncol * (tiffData->subFiles[0].bitsPerPixel/8)

cudaStream_t stream

Input

the stream to use for the kernel launches.

Returns:

NVTIFF_DECODE_SUCCESS - on success.

NVTIFF_DECODE_INVALID_CTX - if tiffFile is invalid.

NVTIFF_DECODE_INVALID_RANGE - if (subFileStart, subFileNum) specify and invalid range of images.

Helper API Reference

nvtiffStreamCreate()

Creates an instance of the bitstream handle.

Signature:

nvtiffStatus_t nvtiffStreamCreate(nvtiffStream_t *tiff_stream);

Parameters:

Parameter

Input/Output

Memory

Description

nvtiffStream_t *tiff_stream

Input/Output

Host

nvtiff bitstream handle

Returns:

nvtiffStatus_t - An error code as specified in Version 2 API Return Status Codes

nvtiffStreamDestroy()

Releases the bitstream handle.

Signature:

nvtiffStatus_t nvtiffStreamDestroy(nvtiffStream_t stream_handle);

Parameters:

Parameter

Input/Output

Memory

Description

nvtiffStream_t stream_handle

Input

Host

nvtiff bitstream handle

Returns:

nvtiffStatus_t - An error code as specified in Version 2 API Return Status Codes

nvtiffDecoderCreateSimple()

Creates an instance of the decoder handle with default memory allocators.

Signature:

Parameters:

Parameter

Input/Output

Memory

Description

nvtiffDecoder_t *decoder

Input/Output

Host

nvtiff decoder handle

cudaStream_t cuda_stream

Input

Host

Used for asynchronous CUDA API calls

Returns:

nvtiffStatus_t - An error code as specified in Version 2 API Return Status Codes

nvtiffDecoderCreate

Creates an instance of the decoder handle.

Signature:

nvtiffStatus_t nvtiffDecoderCreate(nvtiffDecoder_t *decoder,
    nvtiffDeviceAllocator_t *device_allocator,
    nvtiffPinnedAllocator_t *pinned_allocator,
    cudaStream_t cuda_stream);

Parameters:

Parameter

Input/Output

Memory

Description

nvtiffDecoder_t *decoder

Input/Output

Host

nvtiff decoder handle

nvtiffDeviceAllocator_t *device_allocator

Input

Host

User provided device memory allocator. If set to NULL, the library will fallback to cudaMalloc/cudaFree.

nvtiffPinnedAllocator_t *pinned_allocator

Input

Host

User provided pinned memory allocator. If set to NULL, the library will fallback to cudaHostAlloc/cudaFreeHost.

cudaStream_t cuda_stream

Input

Host

Used for asynchronous CUDA API calls

Returns:

nvtiffStatus_t - An error code as specified in Version 2 API Return Status Codes

nvtiffDecoderDestroy()

Releases the decoder handle.

Signature:

nvtiffStatus_t nvtiffDecoderDestroy(nvtiffDecoder_t decoder,
    cudaStream_t cuda_stream);

Parameters:

Parameter

Input/Output

Memory

Description

nvtiffDecoder_t decoder

Input

Host

nvtiff decoder handle

cudaStream_t cuda_stream

Input

Host

Used for asynchronous CUDA API calls

Returns:

nvtiffStatus_t - An error code as specified in Version 2 API Return Status Codes

Parser API Reference

nvtiffStreamParseFromFile()

Parses the tiff file and stores the meta data in nvtiffStream_t .

Signature:

nvtiffStatus_t nvtiffStreamParseFromFile(const char *fname,
        nvtiffStream_t tiff_stream)

Parameters:

Parameter

Input/Output

Memory

Description

const char *fname

Input

Host

tiff file name on disk

nvtiffStream_t tiff_stream

Input/Output

Host

tiff stream handle

Returns:

nvtiffStatus_t - An error code as specified in Version 2 API Return Status Codes

nvtiffStreamPrint()

Prints to standard output, the tiff file meta data stored in nvtiffStream_t.

Signature:

nvtiffStatus_t nvtiffStreamPrint(nvtiffStream_t tiff_stream)

Parameters:

Parameter

Input/Output

Memory

Description

nvtiffStream_t tiff_stream

Input

Host

tiff stream handle

Returns:

nvtiffStatus_t - An error code as specified in Version 2 API Return Status Codes

nvtiffStreamGetFileInfo()

Retrieves the image information defined in nvtiffFileInfo_t. This information is useful in allocating output buffers on device memory.

Signature:

nvtiffStatus_t nvtiffStreamGetFileInfo(nvtiffStream_t tiff_stream,
        nvtiffFileInfo_t *file_info)

Parameters:

Parameter

Input/Output

Memory

Description

nvtiffStream_t tiff_stream

Input

Host

tiff stream handle

nvtiffFileInfo_t *file_info

Input/Output

Host

pointer to nvtiffFileInfo_t

Returns:

nvtiffStatus_t - An error code as specified in Version 2 API Return Status Codes

Decoding API V2 Reference

nvtiffDecode()

Decodes image data on the GPU which is specified in tiff_stream. Each image in the TIFF file is copied into the respective buffer pointed to by “imageOut_d”. This function is fully asynchronous.

Signature:

nvtiffStatus_t nvtiffDecode(nvtiffStream_t tiff_stream,
                    nvtiffDecoder_t nvtiff_decoder,
                    unsigned char **image_out,
                    cudaStream_t cuda_stream);

Parameters:

Parameter

Input/Output

Memory

Description

nvtiffStream_t tiff_stream

Input

Host

tiff_stream handle in which the TIFF file has been read.

nvtiffDecoder_t nvtiff_decoder

Input

Host

decoder handle

unsigned char **imageOut_d

Output

Host

host array (of size num_images in the TIFF file) of pointers to device buffers.Each device buffer should have a size of image_width * image height * bitdepth * samples_per_pixel

cudaStream_t cuda_stream

Input

Host

cuda_stream where all the GPU work will be submitted

Returns:

nvtiffStatus_t - An error code as specified in Version 2 API Return Status Codes

nvtiffDecodeRange()

This function is similar to nvtiffDecode(). It allows the user to specify a range of images to be decoded (instead of decoding all images in the file).

Signature:

nvtiffStatus_t NVTIFFAPI nvtiffDecodeRange(nvtiffStream_t tiff_stream,
                nvtiffDecoder_t decoder,
                unsigned int sub_file_start,
                unsigned int sub_file_num,
                unsigned char **image_out,
                cudaStream_t cuda_stream);

Parameters:

Parameter

Input/Output

Memory

Description

nvtiffStream_t tiff_stream

Input

Host

tiff_stream handle in which the TIFF file has been read.

nvtiffDecoder_t nvtiff_decoder

Input

Host

decoder handle

unsigned int sub_file_start

Input

Host

index of the first image to decode, in [0, tiff_info.num_sub_files).

unsigned int sub_file_num

Input

Host

number of images to decode starting from sub_file_start, in (0, tiff_info.num_sub_files]

unsigned char **imageOut_d

Output

Host

host array (of size num_images in the TIFF file) of pointers to device buffers.Each device buffer should have a size of image_width * image height * bitdepth * samples_per_pixel

cudaStream_t cuda_stream

Input

Host

cuda_stream where all the GPU work will be submitted

Returns:

nvtiffStatus_t - An error code as specified in Version 2 API Return Status Codes

Encoding API Reference

nvTiffEncodeCtxCreate()

This function encoding context based on the specified parameters that can be used to perform a parallel LZW compression of images.

Signature:

nvTiffEncodeCtx_t nvTiffEncodeCtxCreate(int dev,
                                        unsigned int imagesMax,
                                        unsigned int stripsPerImageMax,
                                        size_t memLimit=0);

Parameters:

Parameter

Input/Output

Memory

Description

int dev

Input

Device to use for CUDA calls and kernel launches

unsigned int imagesMax

Input

maximum number of images that will be encoded using the returned context

unsigned int stripsPerImageMax

Input

maximum number of strips that the images that will be encoded using the returned context will be partitioned into

size_t memLimit

Input

maximum amount of device memory that can be used to allocate the internal buffers required by the strip compression kernel

Returns:

SUCCESS - on success returns a pointer to nvTiffEncodeCtx_t

NULL - otherwise.

nvTiffEncodeCtxDestroy()

Destroys context ctx freeing all the allocated memory on both the host and the device.

Signature:

void nvTiffEncodeCtxDestroy(nvTiffEncodeCtx_t *ctx);

Parameters:

Parameter

Input/Output

Memory

Description

nvTiffEncodeCtx_t *ctx

Input

Destroys context ctx freeing all the allocated memory on both the host and the device.

nvTiffEncode()

Perform the encoding of multiple images using the resources specified by the encoding context. Each image is divided into strips formed by groups of consecutive rows and then each strip is compressed using LZW independently.

This function is fully asynchronous.

Signature:

int NVTIFFAPI nvTiffEncode(nvTiffEncodeCtx_t *ctx,
                           unsigned int nrow,
                           unsigned int ncol,
                           unsigned int pixelSize,
                           unsigned int rowsPerStrip,
                           unsigned int nImages,
                           unsigned char **images_d,
                           unsigned long long stripAllocSize,
                           unsigned long long *stripSize_d,
                           unsigned long long *stripOffs_d,
                           unsigned char      *stripData_d,
                           cudaStream_t stream=0);

Parameters:

Parameter

Input/Output

Memory

Description

nvTiffEncodeCtx_t *ctx

Input

the nvTiffEncodeCtx_t returned by nvTiffEncodeCtxCreate();

unsigned int nrow

Input

number of rows of the images to compress;

unsigned int ncol

Input

number of columns of the images to compress;

unsigned int pixelSize

Input

pixel size, in bytes, for the images to compress;

unsigned int rowsPerStrip

Input

number of rows to be compressed together in a single strip;

unsigned int nImages

Input

number of images to compress;

unsigned char **images_d

Input

Host

host array of size nImages of pointers to device buffers

unsigned long long stripAllocSize

Input

the estimated maximum size for compressed strips;

unsigned int *stripSize_d

Output

Device

device array of size at least ceil(nrow/rowsPerStrip)*nImages

unsigned int *stripOffs_d

Output

Device

device array of size at least ceil(nrow/rowsPerStrip)*nImages

unsigned long long *stripData_d

Output

Device

device array of size at least ceil(nrow/rowsPerStrip)*nImages*stripAllocSize in which the compressed strips are returned

stream

Input

the stream to use for the kernel launches

Returns:

NVTIFF_ENCODE_SUCCESS - on success, the compressed strips can be accessed after the subsequent call to nvTiffEncodeFinalize(), see below;

NVTIFF_ENCODE_INVALID_CTX - ctx is invalid.

NVTIFF_ENCODE_INVALID_STRIP_NUM - if the specified nrow, rowsPerStrip and nImages amount to a number of strips to be compressed greater than those specified by the parameters imagesMax and stripsPerImageMax specified at the creation of the context ctx;

CUTIFF_ENCODE_INVALID_IMAGE_NUM: if the specified nImages is greater than the parameter imagesMax specified at the creation of the context ctx;

nvTiffEncodeFinalize()

This function completes the compression process initiated by nvTiffEncode(). Since nvTiffEncode() is asynchronous, the state about its runtime operations is checked via this finalization call. Please note that this function is NOT fully asynchronous. On entry, it synchronizes on the stream specified as a parameter and, if the all the operations initiated by the previous cuTiffEncode() call terminated with success, then it launches a kernel, asynchronously, to finalize the data arrays passed to cuTiffEncode() (stripSize_d, stripOffs_d and stripData_d). Because of that, before accessing those arrays it is necessary to synchronize on the passed stream.

Signature:

int  nvTiffEncodeFinalize(nvTiffEncodeCtx_t *ctx,
                          cudaStream_t stream=0);

Parameters:

Parameter

Input/Output

Memory

Description

nvTiffEncodeCtx_t *ctx

Input

the nvTiffEncodeCtx_t passed to nvTiffEncode();

stream

Input

the stream to use for the kernel launches

Returns:

NVTIFF_ENCODE_SUCCESS - on success; the strips sizes, offsets and data can be accessed in the array stripSize_d, stripOffs_d, stripData_d passed to nvTiffEncode() after all the operations enqueued on stream are concluded;

NVTIFF_ENCODE_INVALID_CTX - ctx is invalid.

NVTIFF_ENCODE_COMP_STRIP_TOO_LONG - currently the compression procedure supports strips with a compressed size up to 48KB; if one strip would be compressed into a larger size then this error is returned

NVTIFF_ENCODE_COMP_OVERFLOW - this error is returned in case one or more strips compress to a size grater than the value of the parameter stripAllocSize passed to nvTiffEncode()

nvTiffWriteFile()

This is a convenience function to write compressed images to a single TIFF file. Library users may want to implement their own function to use additional/custom TIFF tags.

Signature:

int nvTiffWriteFile(const char *fname,
                    int tiffVer,
                    unsigned int nImages,
                    unsigned int nrow,
                    unsigned int ncol,
                    unsigned int rowsPerStrip,
                    unsigned short samplesPerPixel,
                    unsigned short *bitsPerSample,
                    unsigned int photometricInt,
                    unsigned int planarConf,
                    unsigned long long *stripSize,
                    unsigned long long *stripOffs,
                    unsigned char      *stripData);

Parameters:

Parameter

Input/Output

Memory

Description

const char *fname

Input

Host

the name of the output TIFF file;

int tiffVer

Input

specifies whether to use regular Tiff or a BigTiff file format; for regular Tiff use VER_REG_TIFF; for BigTiff use VER_BIG_TIFF;

unsigned int nImages

Input

number of images to write into the file

unsigned int nrow

Input

number of rows of every image

unsigned int ncol

Input

number of columns of every image;

unsigned int rowsPerStrip

Input

number of rows that form a Tiff strip

unsigned short samplesPerPixel

Input

number of components per pixel

unsigned short bitsPerSample

Input

array of length samplesPerPixel specifying the number of bits per component;

unsigned int photometricInt

Input

color space of the image data; supported values: 1 or 2;

unsigned int planarConf

Input

how the components of each pixel are stored; supported values: 1 (chunky format);

unsigned long long *stripSize

Input

Host

host array of size ceil(nrow/rowsPerStrip)*nImages containing the length of the compressed strips;

unsigned long long *stripOffs

Input

Host

host array of size ceil(nrow/rowsPerStrip)*nImages containing the starting offset of the compressed strips inside the stripData buffer;

unsigned char *stripData

Input

Host

host array containing the ceil(nrow/rowsPerStrip)*nImages compressed strips; strips are expected to be stored one after the other starting from the first image to the last, from the top to bottom;

Returns:

NVTIFF_WRITE_SUCCESS - on success

NVTIFF_WRITE_UNSUPP_PLANAR_CONF - if the value of planarConf parameter is not equal to 1;.

NVTIFF_WRITE_UNSUPP_PHOTOMETRIC_INT - if the value of photometricInt parameter is neither 1 nor 2;