C

Qt Quick Ultralite imagedecoder Example

// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial

#include "traveot2gimagedecoder.h"
#include <ut_class_surface.h>

extern "C" uint32_t Jpeg_DecStart(uint32_t, uint32_t, uint32_t);
extern "C" uint32_t tvii_convert_decoded_buffers(unsigned char *, uint32_t, uint32_t, CYGFX_SM_FORMAT);
static int16_t img_width, img_height;

bool jpegInformation(Qul::PlatformInterface::ImageDecoder::RequestDataCallback &callback,
                     int16_t *width,
                     int16_t *height,
                     Qul::PixelFormat *actualPixelFormat,
                     Qul::PixelFormat optimalOpaquePixelFormat,
                     Qul::PixelFormat optimalAlphaPixelFormat);

TviiImageDecoder::TviiImageDecoder() {}
TviiImageDecoder::~TviiImageDecoder() {}

bool TviiImageDecoder::imageInformation(RequestDataCallback &callback,
                                        int16_t *width,
                                        int16_t *height,
                                        Qul::PixelFormat *actualPixelFormat,
                                        Qul::PixelFormat optimalOpaquePixelFormat,
                                        Qul::PixelFormat optimalAlphaPixelFormat)
{
    bool ret = jpegInformation(callback,
                               width,
                               height,
                               actualPixelFormat,
                               optimalOpaquePixelFormat,
                               optimalAlphaPixelFormat);
    img_width = *width;
    img_height = *height;
    return ret;
}

static CYGFX_SM_FORMAT convertFormat(Qul::PixelFormat format)
{
    CYGFX_SM_FORMAT result = CYGFX_SM_FORMAT_A8R8G8B8;
    switch (format) {
    case Qul::PixelFormat_ARGB32:
    case Qul::PixelFormat_ARGB32_Premultiplied:
        result = CYGFX_SM_FORMAT_A8R8G8B8;
        break;
    case Qul::PixelFormat_RGB32:
        result = CYGFX_SM_FORMAT_X8R8G8B8;
        break;
    case Qul::PixelFormat_RGB888:
        result = CYGFX_SM_FORMAT_R8G8B8;
        break;
    case Qul::PixelFormat_RGB16:
        result = CYGFX_SM_FORMAT_R5G6B5;
        break;
    case Qul::PixelFormat_Alpha8:
        result = CYGFX_SM_FORMAT_A8;
        break;
    default:
        Qul::PlatformInterface::log("[%s] Unsupported Format! (%d)\n\r", __PRETTY_FUNCTION__, format);
    }
    return result;
}

int TviiImageDecoder::decodeImage(RequestDataCallback &callback,
                                  unsigned char *outbuffer,
                                  uint32_t outbufferSize,
                                  Qul::PixelFormat pixelFormat,
                                  uint32_t requiredBytesPerLine)
{
    if (img_width % 64 != 0) {
        Qul::PlatformInterface::log("JPEG decoder requires source images width to be multiples of 64.");
        return -1;
    }
    unsigned int addr = (unsigned int) callback.rawData();
    unsigned int size = callback.totalAvailableDataSize();

    uint32_t stride = img_width;
    uint32_t ret = Jpeg_DecStart(addr, size, stride);

    if (ret != 0) {
        Qul::PlatformInterface::log("Jpeg_DecStart failed with return code %x\n", ret);
        return -1;
    }

    ret = tvii_convert_decoded_buffers(outbuffer,
                                       (uint32_t) img_width,
                                       (uint32_t) img_height,
                                       convertFormat(pixelFormat));
    if (ret != 0) {
        Qul::PlatformInterface::log("tvii_convert_decoded_buffers failed with return code %x\n", ret);
    }
    return ret;
}