C
Qt Quick Ultralite imagedecoder Example
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
#include <platforminterface/log.h>
#include <platforminterface/imagedecoder.h>
#include <stdint.h>
bool probeJpeg(const unsigned char *data, uint32_t size)
{
// Detect JPG images
// FF D8 FF E0 xx xx 4A 46
// FF D8 FF E1 xx xx 45 78
// FF D8 FF E8 xx xx 53 50
if (size < 8)
return false;
if (data[0] != 0xff || data[1] != 0xd8 || data[2] != 0xff)
return false;
if (data[3] == 0xe0 && data[6] == 0x4a && data[7] == 0x46)
return true;
else if (data[3] == 0xe1 && data[6] == 0x45 && data[7] == 0x78)
return true;
else if (data[3] == 0xe8 && data[6] == 0x53 && data[7] == 0x50)
return true;
return false;
}
bool jpegInformation(Qul::PlatformInterface::ImageDecoder::RequestDataCallback &callback,
int16_t *width,
int16_t *height,
Qul::PixelFormat *actualPixelFormat,
Qul::PixelFormat optimalOpaquePixelFormat,
Qul::PixelFormat optimalAlphaPixelFormat)
{
QUL_UNUSED(optimalOpaquePixelFormat);
QUL_UNUSED(optimalAlphaPixelFormat);
{
unsigned char buffer[8];
if (callback.readData(buffer, 0, sizeof(buffer)) != sizeof(buffer))
return false;
if (!probeJpeg(buffer, sizeof(buffer)))
return false;
}
uint32_t offset = 0;
while (1) {
unsigned char marker;
do {
if (callback.readData(&marker, offset, sizeof(marker)) != sizeof(marker))
return false;
offset += sizeof(marker);
} while (marker == 0xff); // Ignore start and padding bytes
if (marker > 0xd0 && marker <= 0xd8)
continue;
if (marker == 0xd9)
return false; // EOI without finding a size block
if (marker == 0x01) // TEM
continue;
if (marker == 0xc0) {
unsigned char buffer[8];
if (callback.readData(buffer, offset, sizeof(buffer)) != sizeof(buffer))
return false;
offset += sizeof(buffer);
*height = buffer[3];
*height <<= 8;
*height += buffer[4];
*width = buffer[5];
*width <<= 8;
*width += buffer[6];
*actualPixelFormat = Qul::PixelFormat_ARGB32; // FIXME
return true;
}
unsigned char buffer[2];
if (callback.readData(buffer, offset, sizeof(buffer)) != sizeof(buffer))
return false;
offset += sizeof(buffer);
uint32_t len = buffer[0];
len <<= 8;
len += buffer[1];
len -= 2; // The two bytes from the length itself need to be subtracted
offset += len; /* Discard data */
}
}