C

Qt Quick Ultralite imagedecoder Example

/****************************************************************************** ** ** Copyright (C) 2023 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Quick Ultralite module. ** ** $QT_BEGIN_LICENSE:COMM$ ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** $QT_END_LICENSE$ ** ******************************************************************************/
#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 */ } }