Using rocJPEG#
2026-10-28
4 min read time
This document provides a high-level overview of how to do common operations using the rocJPEG APIs exposed in the rocjpeg.h header file.
Creating handles#
Handles need to be created to decode and parse JPEG streams.
rocJpegCreate() returns an instance of a RocJpegHandle based on the specified backend and GPU device ID. The RocJpegHandle instance must be retained for the entire decode session.
RocJpegStatus rocJpegCreate(
RocJpegBackend backend,
int device_id,
RocJpegHandle *handle);
rocJpegStreamCreate() returns a rocJpegStreamHandle, which is a pointer used to represent an instance of a JPEG stream. The instance of rocJpegStreamHandle is used to parse the JPEG stream and to store the JPEG stream parameters.
RocJpegStatus rocJpegStreamCreate(RocJpegStreamHandle *jpeg_stream_handle);
For example:
// Read the JPEG image file
std::ifstream input("mug_420.jpg", std::ios::in | std::ios::binary | std::ios::ate);
// Get the JPEG image file size
std::streamsize file_size = input.tellg();
input.seekg(0, std::ios::beg);
std::vector<char> file_data;
// resize if buffer is too small
if (file_data.size() < file_size) {
file_data.resize(file_size);
}
// Read the JPEG stream
if (!input.read(file_data.data(), file_size)) {
std::cerr << "ERROR: cannot read from file: " << std::endl;
return EXIT_FAILURE;
}
// Initialize rocJPEG
RocJpegHandle handle;
RocJpegStatus status = rocJpegCreate(ROCJPEG_BACKEND_HARDWARE, 0, &handle);
if (status != ROCJPEG_STATUS_SUCCESS) {
std::cerr << "Failed to create rocJPEG handle with error code: " << rocJpegGetErrorName(status) << std::endl;
return EXIT_FAILURE;
}
// Create a JPEG stream
RocJpegStreamHandle rocjpeg_stream_handle;
status = rocJpegStreamCreate(&rocjpeg_stream_handle);
if (status != ROCJPEG_STATUS_SUCCESS) {
std::cerr << "Failed to create JPEG stream with error code: " << rocJpegGetErrorName(status) << std::endl;
rocJpegDestroy(handle);
return EXIT_FAILURE;
}
rocJpegGetErrorName() returns error codes in text format from rocJPEG APIs.
Querying decoder capabilities#
rocJpegGetDecoderCaps() fills a RocJpegDecodeCaps structure with the decode capabilities of the decoder bound to a RocJpegHandle, such as the number of JPEG cores, the minimum and maximum image dimensions, and the supported chroma subsamplings and output formats. Chroma subsamplings and output formats are reported as bitmasks, where each bit represents the corresponding RocJpegChromaSubsampling or RocJpegOutputFormat enum value. For each supported chroma subsampling, native_surface_format reports the RocJpegSurfaceFormat layout written for ROCJPEG_OUTPUT_NATIVE, such as ROCJPEG_SURFACE_FORMAT_NV12 for 4:2:0. A chroma subsampling is reported as supported only if the VA-API driver supports its native surface format. The supported JPEG coding processes are reported in coding_process_mask, where each bit represents a RocJpegCodingProcess enum value; the VCN JPEG decoder supports only baseline JPEG.
RocJpegStatus rocJpegGetDecoderCaps(
RocJpegHandle handle,
RocJpegDecodeCaps *decode_caps);
For example:
RocJpegDecodeCaps decode_caps = {};
status = rocJpegGetDecoderCaps(handle, &decode_caps);
if (status != ROCJPEG_STATUS_SUCCESS) {
std::cerr << "Failed to query the decoder capabilities with error code: " << rocJpegGetErrorName(status) << std::endl;
rocJpegDestroy(handle);
return EXIT_FAILURE;
}
bool rgb_supported_for_420 = (decode_caps.subsampling_mask & (1u << ROCJPEG_CSS_420)) &&
(decode_caps.output_format_mask & (1u << ROCJPEG_OUTPUT_RGB));
For a complete example, see the jpegDecodeCaps sample.
Parsing a stream#
rocJpegStreamParse() is used to parse a JPEG stream.
The stream data buffer is passed through the data input parameter. The length of the buffer is passed through the length input parameter. The parsed stream is returned through the jpeg_stream_handle provided. jpeg_stream_handle must have already been created with rocJpegStreamCreate().
Keep data valid and unchanged, and don’t parse or destroy jpeg_stream_handle again until every decode call that uses the handle has returned.
rocJpegDecode() and rocJpegDecodeBatched() use the handle until they return. rocJpegDecodeAsync() and rocJpegDecodeBatchedAsync() use the handle only until they return, not until the matching sync call. To parse the next images while a decode is running, use a different set of stream handles.
RocJpegStatus rocJpegStreamParse(const unsigned char *data,
size_t length,
RocJpegStreamHandle jpeg_stream_handle);
For example:
// Parse the JPEG stream
status = rocJpegStreamParse(reinterpret_cast<uint8_t*>(file_data.data()), file_size, rocjpeg_stream_handle);
if (status != ROCJPEG_STATUS_SUCCESS) {
std::cerr << "Failed to parse JPEG stream with error code: " << rocJpegGetErrorName(status) << std::endl;
rocJpegStreamDestroy(rocjpeg_stream_handle);
rocJpegDestroy(handle);
return EXIT_FAILURE;
}
Getting image information#
rocJpegGetImageInfo() is used to retrieve the number of components, the chroma subsampling, and the width and height of the JPEG image.
RocJpegStatus rocJpegGetImageInfo(
RocJpegHandle handle,
RocJpegStreamHandle jpeg_stream_handle,
uint8_t *num_components,
RocJpegChromaSubsampling *subsampling,
uint32_t *widths,
uint32_t *heights);
For more information on rocJpegGetImageInfo(), see Retrieving image information with rocJPEG.
Decoding a stream#
rocJpegDecode() takes the image passed to it through the jpeg_stream_handle input parameter and decodes it based on the backend used to create handle input parameter.
The decode_params input parameter is used to specify the decoding parameters. Memory needs to be allocated for each channel of the destination image.
RocJpegStatus rocJpegDecode(
RocJpegHandle handle,
RocJpegStreamHandle jpeg_stream_handle,
const RocJpegDecodeParams *decode_params,
RocJpegImage *destination);
``rocJpegDecode()``, ``rocJpegDecodeBatched()``, ``rocJpegDecodeAsync()``, and ``rocJpegDecodeBatchedAsync()``, must not be called from more than one thread at the same time on the same ``RocJpegHandle``. To decode from several threads, create one handle per thread. ``rocJpegDecodeSync()`` and ``rocJpegDecodeBatchedSync()`` can be called from another thread while an asynchronous submit runs on the same handle.
For more information on decoding streams, see Decoding a JPEG stream with rocJPEG.
Destroying handles and freeing resources#
Once the JPEG stream is decoded, resources need to be freed.
Use hipFree() to release the memory previously allocated by hipMalloc() for each channel of the destination rocJpegImage.
Use rocJpegStreamDestroy() to release the rocJpegStreamHandle and its resources, and use rocJPegDestroy() to release RocJpegHandle and destroy the session.
RocJpegStatus rocJpegStreamDestroy(RocJpegStreamHandle jpeg_stream_handle)
RocJpegStatus rocJpegDestroy(RocJpegHandle handle)
For example:
hipFree((void *)output_image.channel[0]);
hipFree((void *)output_image.channel[1]);
rocJpegStreamDestroy(rocjpeg_stream_handle);
rocJpegDestroy(handle);