C

Image decoder integration

Overview

To load arbitrary image formats, an image decoder implementation can be registered with the application.

This allows Qt Quick Ultralite to decode any image format, like PNG or JPEG. A custom image decoder can also make use of hardware accelerated decoding if available on a device.

Custom image decoders have to be registered with the application in the initialization phase. Whenever an image from the resources or from disk (file://) is going to be shown Qt Quick Ultralite will check if it has the built-in asset format. If it doesn't, all registered image decoders are used to decode the image in the order they have been registered. The first decoder reporting it is able to decode an image is used. If case you have decodable images in the resources, the decoder registration has to happen before calling Qul::initPlatform().

Implementing an image decoder for Qt Quick Ultralite

Custom image decoders have to implement the Qul::PlatformInterface::ImageDecoder class. A example implementation for accelerated hardware JPEG decoders can be found in the imagedecoder.

The following code shows example implementations for this class:

class MyDecoder : public Qul::PlatformInterface::ImageDecoder
{
public:
    bool imageInformation(RequestDataCallback &callback,
                          int16_t *width,
                          int16_t *height,
                          Qul::PixelFormat *actualPixelFormat,
                          Qul::PixelFormat optimalOpaquePixelFormat,
                          Qul::PixelFormat optimalAlphaPixelFormat);
    int decodeImage(RequestDataCallback &callback,
                    unsigned char *outbuffer,
                    uint32_t outbufferSize,
                    Qul::PixelFormat pixelFormat,
                    uint32_t requiredBytesPerLine);
}
bool MyDecoder::imageInformation(RequestDataCallback &callback,
                                 int16_t *width,
                                 int16_t *height,
                                 Qul::PixelFormat *actualPixelFormat,
                                 Qul::PixelFormat optimalOpaquePixelFormat,
                                 Qul::PixelFormat optimalAlphaPixelFormat)
{
    unsigned char buffer[1024];
    uint32_t offset 0; // Start from beginning of the file

    callback.read(buffer, offset, 8)

    // Check if this decoder is able to decode the image
    if (buffer[0] != 0x89 || buffer[1] != 0x50 … ) { // PNG format header: 89 50 4E 47 0D 0A 1A 0A
        return false; // Return early when the format is unknown
    }

    // Read more data from the image to determine the size and pixel format.
    callback.read(buffer, offset, sizeof(buffer))
    *width = getImageWidth(buffer);
    *height = getImageHeight(buffer);
    *actualPixelFormat = getOptimalImageFormat(buffer, optimalOpaquePixelFormat, optimalAlphaPixelFormat);

    return true;
}
int MyDecoder::decodeImage(RequestDataCallback &callback,
                           unsigned char *outbuffer,
                           uint32_t outbufferSize,
                           Qul::PixelFormat pixelFormat,
                           uint32_t requiredBytesPerLine)
{
    unsigned char *allocatedBuffer = NULL;

    allocatedBuffer = callback.rawData();
    if (!allocatedBuffer) {
        // The data is not in addressable memory and might need to be fetched
        uint32_t bufferSize = callback.totalAvailableDataSize();
        allocatedBuffer = (unsigned char *) Qul::Platform::qul_malloc(bufferSize);
        callback.readData(allocatedBuffer, 0, bufferSize);
    }

    hardware_decode(allocatedBuffer, bufferSize, outbuffer, outbufferSize);
    Qul::Platform::qul_free(allocatedBuffer);

    return 0;
}

To make the implemented image decoder known to Qt Quick Ultralite, it has to be registered with the application.

static MyDecoder decoder;
Qul::Application::addImageDecoder(&decoder);

Available under certain Qt licenses.
Find out more.