mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2025-07-16 19:34:17 -04:00
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
a33446f86a |
@ -7,5 +7,5 @@ Dependencies:
|
||||
Options:
|
||||
test-before-installing: True
|
||||
require-passing-tests-on: ['Linux', 'FreeBSD', 'Windows']
|
||||
cmake-options: "-DKIMAGEFORMATS_DDS=ON -DKIMAGEFORMATS_JXR=ON -DKIMAGEFORMATS_HEIF=ON"
|
||||
cmake-options: "-DKIMAGEFORMATS_DDS=ON -DKIMAGEFORMATS_JXR=ON"
|
||||
per-test-timeout: 90
|
||||
|
@ -1,11 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(KF_VERSION "6.13.0") # handled by release scripts
|
||||
set(KF_DEP_VERSION "6.13.0") # handled by release scripts
|
||||
set(KF_VERSION "6.12.0") # handled by release scripts
|
||||
set(KF_DEP_VERSION "6.12.0") # handled by release scripts
|
||||
project(KImageFormats VERSION ${KF_VERSION})
|
||||
|
||||
include(FeatureSummary)
|
||||
find_package(ECM 6.13.0 NO_MODULE)
|
||||
find_package(ECM 6.12.0 NO_MODULE)
|
||||
set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://commits.kde.org/extra-cmake-modules")
|
||||
feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
||||
|
||||
@ -99,8 +99,8 @@ endif()
|
||||
add_feature_info(LibJXR LibJXR_FOUND "required for the QImage plugin for JPEG XR images")
|
||||
|
||||
ecm_set_disabled_deprecation_versions(
|
||||
QT 6.9.0
|
||||
KF 6.12.0
|
||||
QT 6.8.0
|
||||
KF 6.11.0
|
||||
)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
@ -122,12 +122,9 @@ if (LibHeif_FOUND)
|
||||
kimageformats_read_tests(FUZZ 1
|
||||
hej2
|
||||
)
|
||||
kimageformats_write_tests(FUZZ 1
|
||||
hej2-nodatacheck-lossless
|
||||
)
|
||||
endif()
|
||||
|
||||
if (LibHeif_VERSION VERSION_GREATER_EQUAL "1.19.6")
|
||||
if (LibHeif_VERSION VERSION_GREATER_EQUAL "1.19.0")
|
||||
kimageformats_read_tests(FUZZ 4
|
||||
avci
|
||||
)
|
||||
|
@ -258,15 +258,6 @@ int main(int argc, char **argv)
|
||||
});
|
||||
QTextStream(stdout) << "QImageReader::supportedImageFormats: " << formatStrings.join(", ") << "\n";
|
||||
|
||||
if (!formats.contains(format)) {
|
||||
if (format == "avci" || format == "heif" || format == "hej2") {
|
||||
QTextStream(stdout) << "WARNING : " << suffix << " is not supported with current libheif configuration!\n"
|
||||
<< "********* "
|
||||
<< "Finished basic read tests for " << suffix << " images *********\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const QFileInfoList lstImgDir = imgdir.entryInfoList();
|
||||
// Launch 2 runs for each test: first run on a random access device, second run on a sequential access device
|
||||
for (int seq = 0; seq < 2; ++seq) {
|
||||
@ -332,12 +323,7 @@ int main(int argc, char **argv)
|
||||
OptionTest optionTest;
|
||||
if (!optionTest.store(&inputReader)) {
|
||||
QTextStream(stdout) << "FAIL : " << fi.fileName() << ": error while reading options\n";
|
||||
if (format == "heif") {
|
||||
// libheif + ffmpeg decoder is unable to load all HEIF files.
|
||||
++skipped;
|
||||
} else {
|
||||
++failed;
|
||||
}
|
||||
++failed;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1,65 +0,0 @@
|
||||
{
|
||||
"format" : "hej2",
|
||||
"metadata" : [
|
||||
{
|
||||
"key" : "CreationDate",
|
||||
"value" : "2025-01-14T13:53:32+01:00"
|
||||
},
|
||||
{
|
||||
"key" : "Direction",
|
||||
"value" : "123.7"
|
||||
},
|
||||
{
|
||||
"key" : "ModificationDate",
|
||||
"value" : "2025-02-14T15:58:44+01:00"
|
||||
},
|
||||
{
|
||||
"key" : "Software" ,
|
||||
"value" : "Adobe Photoshop 26.2 (Windows)"
|
||||
},
|
||||
{
|
||||
"key" : "Altitude",
|
||||
"value" : "34"
|
||||
},
|
||||
{
|
||||
"key" : "Author",
|
||||
"value" : "KDE Project"
|
||||
},
|
||||
{
|
||||
"key" : "Copyright",
|
||||
"value" : "@2025 KDE Project"
|
||||
},
|
||||
{
|
||||
"key" : "Description",
|
||||
"value" : "TV broadcast test image."
|
||||
},
|
||||
{
|
||||
"key" : "Latitude",
|
||||
"value" : "44.6478"
|
||||
},
|
||||
{
|
||||
"key" : "LensManufacturer",
|
||||
"value" : "KDE Glasses"
|
||||
},
|
||||
{
|
||||
"key" : "LensModel",
|
||||
"value" : "A1234"
|
||||
},
|
||||
{
|
||||
"key" : "Longitude",
|
||||
"value" : "10.9254"
|
||||
},
|
||||
{
|
||||
"key" : "Manufacturer",
|
||||
"value" : "KFramework"
|
||||
},
|
||||
{
|
||||
"key" : "Model",
|
||||
"value" : "KImageFormats"
|
||||
}
|
||||
],
|
||||
"resolution" : {
|
||||
"dotsPerMeterX" : 11811,
|
||||
"dotsPerMeterY" : 11812
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -370,12 +370,7 @@ int formatTest(const QString &suffix, bool createTemplates)
|
||||
QBuffer buffer(&ba);
|
||||
auto writtenImage = QImageReader(&buffer, suffix.toLatin1()).read();
|
||||
if (writtenImage.isNull()) {
|
||||
if (suffix.toLatin1() == "heif") {
|
||||
// libheif + ffmpeg decoder is unable to load all HEIF files.
|
||||
++skipped;
|
||||
} else {
|
||||
++failed;
|
||||
}
|
||||
++failed;
|
||||
QTextStream(stdout) << "FAIL : error while reading the image " << formatName << "\n";
|
||||
continue;
|
||||
}
|
||||
@ -627,28 +622,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
auto suffix = args.at(0);
|
||||
|
||||
// skip test if libheif configuration is obviously incomplete
|
||||
QByteArray format = suffix.toLatin1();
|
||||
const QList<QByteArray> read_formats = QImageReader::supportedImageFormats();
|
||||
const QList<QByteArray> write_formats = QImageWriter::supportedImageFormats();
|
||||
|
||||
if (!read_formats.contains(format)) {
|
||||
if (format == "heif" || format == "hej2") {
|
||||
QTextStream(stdout) << "WARNING : libheif configuration is missing necessary decoder(s)!\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!write_formats.contains(format)) {
|
||||
if (format == "heif" || format == "hej2") {
|
||||
QTextStream(stdout) << "WARNING : libheif configuration is missing necessary encoder(s)!\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// run test
|
||||
auto suffix = args.at(0);
|
||||
auto ret = basicTest(suffix, parser.isSet(lossless), parser.isSet(ignoreDataCheck), parser.isSet(skipOptTest), fuzzarg);
|
||||
if (ret == 0) {
|
||||
ret = formatTest(suffix, parser.isSet(createFormatTempates));
|
||||
|
@ -2557,5 +2557,3 @@ QImageIOHandler *QDDSPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_dds_p.cpp"
|
||||
|
@ -16,8 +16,8 @@
|
||||
#include <QDebug>
|
||||
#include <QPointF>
|
||||
#include <QSysInfo>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef HEIF_MAX_METADATA_SIZE
|
||||
/*!
|
||||
@ -26,12 +26,12 @@
|
||||
#define HEIF_MAX_METADATA_SIZE (4 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
|
||||
size_t HEIFHandler::m_initialized_count = 0;
|
||||
bool HEIFHandler::m_plugins_queried = false;
|
||||
bool HEIFHandler::m_heif_decoder_available = false;
|
||||
bool HEIFHandler::m_heif_encoder_available = false;
|
||||
bool HEIFHandler::m_hej2_decoder_available = false;
|
||||
bool HEIFHandler::m_hej2_encoder_available = false;
|
||||
bool HEIFHandler::m_avci_decoder_available = false;
|
||||
|
||||
extern "C" {
|
||||
@ -155,14 +155,6 @@ bool HEIFHandler::write_helper(const QImage &image)
|
||||
break;
|
||||
}
|
||||
|
||||
heif_compression_format encoder_codec = heif_compression_HEVC;
|
||||
#if LIBHEIF_HAVE_VERSION(1, 13, 0)
|
||||
if (format() == "hej2") {
|
||||
encoder_codec = heif_compression_JPEG2000;
|
||||
save_depth = 8; // for compatibility reasons
|
||||
}
|
||||
#endif
|
||||
|
||||
heif_chroma chroma;
|
||||
if (save_depth > 8) {
|
||||
if (save_alpha) {
|
||||
@ -295,7 +287,7 @@ bool HEIFHandler::write_helper(const QImage &image)
|
||||
}
|
||||
|
||||
struct heif_encoder *encoder = nullptr;
|
||||
err = heif_context_get_encoder_for_format(context, encoder_codec, &encoder);
|
||||
err = heif_context_get_encoder_for_format(context, heif_compression_HEVC, &encoder);
|
||||
if (err.code) {
|
||||
qWarning() << "Unable to get an encoder instance:" << err.message;
|
||||
heif_image_release(h_image);
|
||||
@ -322,7 +314,7 @@ bool HEIFHandler::write_helper(const QImage &image)
|
||||
}
|
||||
}
|
||||
|
||||
struct heif_image_handle *handle;
|
||||
struct heif_image_handle* handle;
|
||||
err = heif_context_encode_image(context, h_image, encoder, encoder_options, &handle);
|
||||
|
||||
// exif metadata
|
||||
@ -562,7 +554,7 @@ bool HEIFHandler::ensureDecoder()
|
||||
|
||||
QImage::Format target_image_format;
|
||||
|
||||
if (bit_depth == 10 || bit_depth == 12 || bit_depth == 16) {
|
||||
if (bit_depth == 10 || bit_depth == 12) {
|
||||
if (hasAlphaChannel) {
|
||||
chroma = (QSysInfo::ByteOrder == QSysInfo::LittleEndian) ? heif_chroma_interleaved_RRGGBBAA_LE : heif_chroma_interleaved_RRGGBBAA_BE;
|
||||
target_image_format = QImage::Format_RGBA64;
|
||||
@ -654,35 +646,6 @@ bool HEIFHandler::ensureDecoder()
|
||||
}
|
||||
|
||||
switch (bit_depth) {
|
||||
case 16:
|
||||
if (hasAlphaChannel) {
|
||||
for (int y = 0; y < imageHeight; y++) {
|
||||
memcpy(m_current_image.scanLine(y), src + (y * stride), 8 * size_t(imageWidth));
|
||||
}
|
||||
} else { // no alpha channel
|
||||
for (int y = 0; y < imageHeight; y++) {
|
||||
const uint16_t *src_word = reinterpret_cast<const uint16_t *>(src + (y * stride));
|
||||
uint16_t *dest_data = reinterpret_cast<uint16_t *>(m_current_image.scanLine(y));
|
||||
for (int x = 0; x < imageWidth; x++) {
|
||||
// R
|
||||
*dest_data = *src_word;
|
||||
src_word++;
|
||||
dest_data++;
|
||||
// G
|
||||
*dest_data = *src_word;
|
||||
src_word++;
|
||||
dest_data++;
|
||||
// B
|
||||
*dest_data = *src_word;
|
||||
src_word++;
|
||||
dest_data++;
|
||||
// X = 0xffff
|
||||
*dest_data = 0xffff;
|
||||
dest_data++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
if (hasAlphaChannel) {
|
||||
for (int y = 0; y < imageHeight; y++) {
|
||||
@ -1028,13 +991,6 @@ bool HEIFHandler::isHej2DecoderAvailable()
|
||||
return m_hej2_decoder_available;
|
||||
}
|
||||
|
||||
bool HEIFHandler::isHej2EncoderAvailable()
|
||||
{
|
||||
HEIFHandler::queryHeifLib();
|
||||
|
||||
return m_hej2_encoder_available;
|
||||
}
|
||||
|
||||
bool HEIFHandler::isAVCIDecoderAvailable()
|
||||
{
|
||||
HEIFHandler::queryHeifLib();
|
||||
@ -1057,9 +1013,8 @@ void HEIFHandler::queryHeifLib()
|
||||
m_heif_decoder_available = heif_have_decoder_for_format(heif_compression_HEVC);
|
||||
#if LIBHEIF_HAVE_VERSION(1, 13, 0)
|
||||
m_hej2_decoder_available = heif_have_decoder_for_format(heif_compression_JPEG2000);
|
||||
m_hej2_encoder_available = heif_have_encoder_for_format(heif_compression_JPEG2000);
|
||||
#endif
|
||||
#if LIBHEIF_HAVE_VERSION(1, 19, 6)
|
||||
#if LIBHEIF_HAVE_VERSION(1, 19, 0)
|
||||
m_avci_decoder_available = heif_have_decoder_for_format(heif_compression_AVC);
|
||||
#endif
|
||||
m_plugins_queried = true;
|
||||
@ -1126,9 +1081,6 @@ QImageIOPlugin::Capabilities HEIFPlugin::capabilities(QIODevice *device, const Q
|
||||
if (HEIFHandler::isHej2DecoderAvailable()) {
|
||||
format_cap |= CanRead;
|
||||
}
|
||||
if (HEIFHandler::isHej2EncoderAvailable()) {
|
||||
format_cap |= CanWrite;
|
||||
}
|
||||
return format_cap;
|
||||
}
|
||||
|
||||
@ -1158,7 +1110,7 @@ QImageIOPlugin::Capabilities HEIFPlugin::capabilities(QIODevice *device, const Q
|
||||
}
|
||||
}
|
||||
|
||||
if (device->isWritable() && (HEIFHandler::isHeifEncoderAvailable() || HEIFHandler::isHej2EncoderAvailable())) {
|
||||
if (device->isWritable() && HEIFHandler::isHeifEncoderAvailable()) {
|
||||
cap |= CanWrite;
|
||||
}
|
||||
return cap;
|
||||
|
@ -31,7 +31,6 @@ public:
|
||||
static bool isHeifDecoderAvailable();
|
||||
static bool isHeifEncoderAvailable();
|
||||
static bool isHej2DecoderAvailable();
|
||||
static bool isHej2EncoderAvailable();
|
||||
static bool isAVCIDecoderAvailable();
|
||||
|
||||
static bool isSupportedBMFFType(const QByteArray &header);
|
||||
@ -63,7 +62,6 @@ private:
|
||||
static bool m_heif_decoder_available;
|
||||
static bool m_heif_encoder_available;
|
||||
static bool m_hej2_decoder_available;
|
||||
static bool m_hej2_encoder_available;
|
||||
static bool m_avci_decoder_available;
|
||||
|
||||
static QMutex &getHEIFHandlerMutex();
|
||||
|
@ -1504,18 +1504,7 @@ bool PSDHandler::read(QImage *image)
|
||||
img.setColorSpace(QColorSpace(QColorSpace::SRgb));
|
||||
#endif
|
||||
} else if (!setColorSpace(img, irs)) {
|
||||
// Float images are used by Photoshop as linear: if no color space
|
||||
// is present, a linear one should be chosen.
|
||||
if (header.color_mode == CM_RGB && header.depth == 32) {
|
||||
img.setColorSpace(QColorSpace(QColorSpace::SRgbLinear));
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
if (header.color_mode == CM_GRAYSCALE && header.depth == 32) {
|
||||
auto qs = QColorSpace(QPointF(0.3127, 0.3291), QColorSpace::TransferFunction::Linear);
|
||||
qs.setDescription(QStringLiteral("Linear grayscale"));
|
||||
img.setColorSpace(qs);
|
||||
}
|
||||
#endif
|
||||
// qDebug() << "No colorspace info set!";
|
||||
}
|
||||
|
||||
// XMP data
|
||||
|
@ -457,4 +457,3 @@ QImageIOHandler *ScitexPlugin::create(QIODevice *device, const QByteArray &forma
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_sct_p.cpp"
|
||||
|
Reference in New Issue
Block a user