PNGD
This section describes the API call sequence of PNGD, and sample code is also provided to help you better understand the process.
The PNG decoder (PNGD) decodes images in PNG format. For details about the PNGD function and restrictions, see DVPP Media Acceleration Library.
API Call Sequence

The current system supports PNG image decoding and output of RGB and RGBA images. The key APIs are described as follows:
- Call aclInit to initialize the system.
- Call aclrtSetDevice to specify the compute device.
- aclrtCreateStream: creates a stream.
- Call acldvppCreateChannel to create a channel for image data processing.
Before creating a channel, call <cf id="Bold">acldvppCreateChannelDesc</cf> to create the channel description.
- Before decoding PNG images, call acldvppMalloc to allocate memory on the device for storing the input or output data.
Before allocating the output buffer, call acldvppPngPredictDecSize to compute the output buffer size required for the decoded PNG image based on the buffer for storing PNG image data.
- Call the asynchronous API acldvppPngDecodeAsync for decoding.
For asynchronous APIs, call aclrtSynchronizeStream to block program running until all tasks in the specified stream are complete.
- After the decoding is complete, call acldvppFree to free the input and output buffers in a timely manner.
- Call acldvppDestroyChannel to destroy the image data processing channel.
After destroying the channel, call <cf id="Bold">acldvppDestroyChannelDesc</cf> to destroy the channel description.
- aclrtDestroyStream: destroys a stream.
- Call aclrtResetDevice to reset the device and free the resources on the device.
- Call aclFinalize to deinitialize the system and free the resources used by the acl API in the process.
Sample Code
The following is a code example of key steps of PNGD image decoding. It is for reference only and cannot be directly copied for compilation and running. After APIs are called, you need to add exception handling branches and record error logs and info logs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | // 1. Create the description of the image data processing channel. dvppChannelDesc_ is of the acldvppChannelDesc type. dvppChannelDesc_ = acldvppCreateChannelDesc(); // 2. Create a channel for processing image data. aclError ret = acldvppCreateChannel(dvppChannelDesc_); // 3. Allocate input buffer (differentiated by running status). // Call aclrtGetRunMode to obtain the run mode of the software stack. If ACL_DEVICE is returned, allocate and use the device buffer. If ACL_HOST is returned, transfer the input image data to the device by using the aclrtMemcpy call. After the data transfer is complete, the buffer needs to be freed in a timely manner. aclrtRunMode runMode; ret = aclrtGetRunMode(&runMode); if(runMode == ACL_HOST){ // Allocate the host buffer inputHostBuff and read the input image to this address. inDevBufferSize is the size of the read image. void* inputHostBuff = nullptr; inputHostBuff = malloc(inDevBufferSize); // Load the input image into the buffer. The ReadPicFile function is defined by the user. ReadPicFile(picName, inputHostBuff, inDevBufferSize); // Allocate the device buffer inDevBuffer_. ret = acldvppMalloc(&inDevBuffer_, inDevBufferSize); // Transfer the input image data to the device by using the aclrtMemcpy call. ret = aclrtMemcpy(inDevBuffer_, inDevBufferSize, inputHostBuff, inDevBufferSize, ACL_MEMCPY_HOST_TO_DEVICE); } else { // Allocate input buffer inDevBuffer_ on the device. ret = acldvppMalloc(&inDevBuffer_, inDevBufferSize); // Load the input image into the buffer. The ReadPicFile function is defined by the user. ReadPicFile(picName, inDevBuffer_, inDevBufferSize); } // 4. Allocate the decoding output buffer decodeOutDevBuffer_. // Calculate the buffer size required for the PNGD processing result. uint32_t decodeOutBufferSize = 0; ret = acldvppPngPredictDecSize(inputHostBuff, inDevBufferSize, PIXEL_FORMAT_RGB_888, &decodeOutBufferSize); ret = acldvppMalloc(&decodeOutDevBuffer_, decodeOutBufferSize); // Free the buffer in a timely manner. free(inputHostBuff); // 5. Create the description of the decoded image and set the attribute values. // decodeOutputDesc is of type acldvppPicDesc. decodeOutputDesc_ = acldvppCreatePicDesc(); acldvppSetPicDescData(decodeOutputDesc_, decodeOutDevBuffer_); acldvppSetPicDescFormat(decodeOutputDesc_, PIXEL_FORMAT_RGB_888); acldvppSetPicDescSize(decodeOutputDesc_, decodeOutBufferSize); // 6. Perform asynchronous decoding and call aclrtSynchronizeStream to block program running until all tasks in the specified stream are complete. ret = acldvppPngDecodeAsync(dvppChannelDesc_, inDevBuffer_, inDevBufferSize, decodeOutputDesc_, stream_); ret = aclrtSynchronizeStream(stream_); // 7. After the decoding is complete, release the resources, including the description of the decoded output image, output buffer, channel description, and channel. acldvppDestroyPicDesc(decodeOutputDesc_); if(runMode == ACL_HOST){ // In this mode, the processing result is on the device. Therefore, you need to call the memory copy API to transfer the result data, and then free the device buffer. // Allocate host buffer OutHostBuffer. void* OutHostBuffer = nullptr; OutHostBuffer = malloc(decodeOutBufferSize); // Transfer the processing result of the device to the host by using the aclrtMemcpy call. ret = aclrtMemcpy(OutHostBuffer, decodeOutBufferSize, decodeOutDevBuffer_, decodeOutBufferSize, ACL_MEMCPY_DEVICE_TO_HOST); // Free the input and output buffer on the device. (void)acldvppFree(inDevBuffer_); (void)acldvppFree(decodeOutDevBuffer_); // Free the buffer after the data is used. free(OutHostBuffer); } else { // The process is running on the device, and the processing result is also on the device. Free the device buffer when the data is no longer needed. (void)acldvppFree(inDevBuffer_); (void)acldvppFree(decodeOutDevBuffer_); } acldvppDestroyChannel(dvppChannelDesc_); (void)acldvppDestroyChannelDesc(dvppChannelDesc_); dvppChannelDesc_ = nullptr; .... |