mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2025-07-15 11:14:18 -04:00
Compare commits
7 Commits
v5.107.0-r
...
v5.109.0
Author | SHA1 | Date | |
---|---|---|---|
bcb5308545 | |||
c3a91c3bc6 | |||
034b8f331b | |||
ed6a3c520d | |||
bf1c7e8508 | |||
3cb6519dcc | |||
6cbf7529ee |
@ -6,9 +6,5 @@ include:
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux-static.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/android.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux-qt6.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/android-qt6.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows-static.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd-qt6.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows-qt6.yml
|
||||
|
@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.16)
|
||||
project(KImageFormats)
|
||||
|
||||
include(FeatureSummary)
|
||||
find_package(ECM 5.107.0 NO_MODULE)
|
||||
find_package(ECM 5.109.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)
|
||||
|
||||
@ -65,8 +65,8 @@ add_feature_info(LibHeif LibHeif_FOUND "required for the QImage plugin for HEIF/
|
||||
|
||||
option(KIMAGEFORMATS_JXL "Enable plugin for JPEG XL format" ON)
|
||||
if(KIMAGEFORMATS_JXL)
|
||||
pkg_check_modules(LibJXL IMPORTED_TARGET libjxl>=0.6.1)
|
||||
pkg_check_modules(LibJXLThreads IMPORTED_TARGET libjxl_threads>=0.6.1)
|
||||
pkg_check_modules(LibJXL IMPORTED_TARGET libjxl>=0.7.0)
|
||||
pkg_check_modules(LibJXLThreads IMPORTED_TARGET libjxl_threads>=0.7.0)
|
||||
endif()
|
||||
add_feature_info(LibJXL LibJXL_FOUND "required for the QImage plugin for JPEG XL images")
|
||||
|
||||
|
BIN
autotests/read/psd/mch3-16bits.png
Normal file
BIN
autotests/read/psd/mch3-16bits.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 71 KiB |
BIN
autotests/read/psd/mch3-16bits.psb
Normal file
BIN
autotests/read/psd/mch3-16bits.psb
Normal file
Binary file not shown.
BIN
autotests/read/psd/mch3-8bits.png
Normal file
BIN
autotests/read/psd/mch3-8bits.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
BIN
autotests/read/psd/mch3-8bits.psb
Normal file
BIN
autotests/read/psd/mch3-8bits.psb
Normal file
Binary file not shown.
@ -104,9 +104,6 @@ endif()
|
||||
if (LibJXL_FOUND AND LibJXLThreads_FOUND)
|
||||
kimageformats_add_plugin(kimg_jxl SOURCES jxl.cpp)
|
||||
target_link_libraries(kimg_jxl PkgConfig::LibJXL PkgConfig::LibJXLThreads)
|
||||
if (LibJXL_VERSION VERSION_GREATER_EQUAL "0.7.0")
|
||||
target_compile_definitions(kimg_jxl PRIVATE KIMG_JXL_API_VERSION=70)
|
||||
endif()
|
||||
|
||||
if (QT_MAJOR_VERSION STREQUAL "5")
|
||||
install(FILES jxl.desktop DESTINATION ${KDE_INSTALL_KSERVICESDIR}/qimageioplugins/)
|
||||
|
@ -570,3 +570,5 @@ QImageIOHandler *ANIPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_ani_p.cpp"
|
||||
|
@ -1103,3 +1103,5 @@ QImageIOHandler *QAVIFPlugin::create(QIODevice *device, const QByteArray &format
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_avif_p.cpp"
|
||||
|
@ -365,3 +365,5 @@ QImageIOHandler *EPSPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_eps_p.cpp"
|
||||
|
@ -259,3 +259,5 @@ QImageIOHandler *EXRPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_exr_p.cpp"
|
||||
|
@ -296,3 +296,5 @@ QImageIOHandler *HDRPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_hdr_p.cpp"
|
||||
|
@ -926,3 +926,5 @@ QImageIOHandler *HEIFPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_heif_p.cpp"
|
||||
|
@ -150,9 +150,7 @@ bool QJpegXLHandler::ensureDecoder()
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef KIMG_JXL_API_VERSION
|
||||
JxlDecoderCloseInput(m_decoder);
|
||||
#endif
|
||||
|
||||
JxlDecoderStatus status = JxlDecoderSubscribeEvents(m_decoder, JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING | JXL_DEC_FRAME);
|
||||
if (status == JXL_DEC_ERROR) {
|
||||
@ -269,18 +267,31 @@ bool QJpegXLHandler::countALLFrames()
|
||||
}
|
||||
}
|
||||
|
||||
status = JxlDecoderGetColorAsEncodedProfile(m_decoder, &m_input_pixel_format, JXL_COLOR_PROFILE_TARGET_DATA, &color_encoding);
|
||||
status = JxlDecoderGetColorAsEncodedProfile(m_decoder,
|
||||
#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 9, 0)
|
||||
&m_input_pixel_format,
|
||||
#endif
|
||||
JXL_COLOR_PROFILE_TARGET_DATA,
|
||||
&color_encoding);
|
||||
|
||||
if (status == JXL_DEC_SUCCESS && color_encoding.color_space == JXL_COLOR_SPACE_RGB && color_encoding.white_point == JXL_WHITE_POINT_D65
|
||||
&& color_encoding.primaries == JXL_PRIMARIES_SRGB && color_encoding.transfer_function == JXL_TRANSFER_FUNCTION_SRGB) {
|
||||
m_colorspace = QColorSpace(QColorSpace::SRgb);
|
||||
} else {
|
||||
size_t icc_size = 0;
|
||||
if (JxlDecoderGetICCProfileSize(m_decoder, &m_input_pixel_format, JXL_COLOR_PROFILE_TARGET_DATA, &icc_size) == JXL_DEC_SUCCESS) {
|
||||
if (JxlDecoderGetICCProfileSize(m_decoder,
|
||||
#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 9, 0)
|
||||
&m_input_pixel_format,
|
||||
#endif
|
||||
JXL_COLOR_PROFILE_TARGET_DATA,
|
||||
&icc_size)
|
||||
== JXL_DEC_SUCCESS) {
|
||||
if (icc_size > 0) {
|
||||
QByteArray icc_data(icc_size, 0);
|
||||
if (JxlDecoderGetColorAsICCProfile(m_decoder,
|
||||
#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 9, 0)
|
||||
&m_input_pixel_format,
|
||||
#endif
|
||||
JXL_COLOR_PROFILE_TARGET_DATA,
|
||||
reinterpret_cast<uint8_t *>(icc_data.data()),
|
||||
icc_data.size())
|
||||
@ -534,9 +545,7 @@ bool QJpegXLHandler::write(const QImage &image)
|
||||
if (save_depth == 16 && (image.hasAlphaChannel() || output_info.uses_original_profile)) {
|
||||
output_info.have_container = JXL_TRUE;
|
||||
JxlEncoderUseContainer(encoder, JXL_TRUE);
|
||||
#ifdef KIMG_JXL_API_VERSION
|
||||
JxlEncoderSetCodestreamLevel(encoder, 10);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *runner = nullptr;
|
||||
@ -650,19 +659,11 @@ bool QJpegXLHandler::write(const QImage &image)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KIMG_JXL_API_VERSION
|
||||
JxlEncoderFrameSettings *encoder_options = JxlEncoderFrameSettingsCreate(encoder, nullptr);
|
||||
|
||||
JxlEncoderSetFrameDistance(encoder_options, (100.0f - m_quality) / 10.0f);
|
||||
|
||||
JxlEncoderSetFrameLossless(encoder_options, (m_quality == 100) ? JXL_TRUE : JXL_FALSE);
|
||||
#else
|
||||
JxlEncoderOptions *encoder_options = JxlEncoderOptionsCreate(encoder, nullptr);
|
||||
|
||||
JxlEncoderOptionsSetDistance(encoder_options, (100.0f - m_quality) / 10.0f);
|
||||
|
||||
JxlEncoderOptionsSetLossless(encoder_options, (m_quality == 100) ? JXL_TRUE : JXL_FALSE);
|
||||
#endif
|
||||
|
||||
if (image.hasAlphaChannel() || ((save_depth == 8) && (xsize % 4 == 0))) {
|
||||
status = JxlEncoderAddImageFrame(encoder_options, &pixel_format, static_cast<const void *>(tmpimage.constBits()), buffer_size);
|
||||
@ -957,9 +958,7 @@ bool QJpegXLHandler::rewind()
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef KIMG_JXL_API_VERSION
|
||||
JxlDecoderCloseInput(m_decoder);
|
||||
#endif
|
||||
|
||||
if (m_basicinfo.uses_original_profile) {
|
||||
if (JxlDecoderSubscribeEvents(m_decoder, JXL_DEC_FULL_IMAGE) != JXL_DEC_SUCCESS) {
|
||||
@ -1021,3 +1020,5 @@ QImageIOHandler *QJpegXLPlugin::create(QIODevice *device, const QByteArray &form
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_jxl_p.cpp"
|
||||
|
@ -95,3 +95,5 @@ QImageIOHandler *KraPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_kra.cpp"
|
||||
|
@ -94,3 +94,5 @@ QImageIOHandler *OraPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_ora.cpp"
|
||||
|
@ -792,3 +792,5 @@ QImageIOHandler *PCXPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_pcx_p.cpp"
|
||||
|
@ -452,3 +452,5 @@ QImageIOHandler *SoftimagePICPlugin::create(QIODevice *device, const QByteArray
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_pic_p.cpp"
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <QColorSpace>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
typedef quint32 uint;
|
||||
typedef quint16 ushort;
|
||||
@ -669,7 +670,7 @@ static bool IsSupported(const PSDHeader &header)
|
||||
return false;
|
||||
}
|
||||
if (header.color_mode == CM_MULTICHANNEL &&
|
||||
header.channel_count < 4) {
|
||||
header.channel_count < 3) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -808,6 +809,26 @@ inline quint32 xchg(quint32 v) {
|
||||
#endif
|
||||
}
|
||||
|
||||
inline float xchg(float v)
|
||||
{
|
||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||
# ifdef Q_CC_MSVC
|
||||
float *pf = &v;
|
||||
quint32 f = xchg(*reinterpret_cast<quint32*>(pf));
|
||||
quint32 *pi = &f;
|
||||
return *reinterpret_cast<float*>(pi);
|
||||
# else
|
||||
quint32 t;
|
||||
std::memcpy(&t, &v, sizeof(quint32));
|
||||
t = xchg(t);
|
||||
std::memcpy(&v, &t, sizeof(quint32));
|
||||
return v;
|
||||
# endif
|
||||
#else
|
||||
return v; // never tested
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void planarToChunchy(uchar *target, const char *source, qint32 width, qint32 c, qint32 cn)
|
||||
{
|
||||
@ -818,15 +839,13 @@ inline void planarToChunchy(uchar *target, const char *source, qint32 width, qin
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, T min = 0, T max = 1>
|
||||
inline void planarToChunchyFloat(uchar *target, const char *source, qint32 width, qint32 c, qint32 cn)
|
||||
template<class T>
|
||||
inline void planarToChunchyFloatToUInt16(uchar *target, const char *source, qint32 width, qint32 c, qint32 cn)
|
||||
{
|
||||
auto s = reinterpret_cast<const T*>(source);
|
||||
auto t = reinterpret_cast<quint16*>(target);
|
||||
for (qint32 x = 0; x < width; ++x) {
|
||||
auto tmp = xchg(s[x]);
|
||||
auto ftmp = (*reinterpret_cast<float*>(&tmp) - double(min)) / (double(max) - double(min));
|
||||
t[x * cn + c] = quint16(std::min(ftmp * std::numeric_limits<quint16>::max() + 0.5, double(std::numeric_limits<quint16>::max())));
|
||||
t[x * cn + c] = quint16(std::min(xchg(s[x]) * std::numeric_limits<quint16>::max() + 0.5, double(std::numeric_limits<quint16>::max())));
|
||||
}
|
||||
}
|
||||
|
||||
@ -896,8 +915,8 @@ inline void cmykToRgb(uchar *target, qint32 targetChannels, const char *source,
|
||||
auto max = double(std::numeric_limits<T>::max());
|
||||
auto invmax = 1.0 / max; // speed improvements by ~10%
|
||||
|
||||
if (sourceChannels < 4) {
|
||||
qDebug() << "cmykToRgb: image is not a valid CMYK!";
|
||||
if (sourceChannels < 3) {
|
||||
qDebug() << "cmykToRgb: image is not a valid CMY/CMYK!";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -906,7 +925,7 @@ inline void cmykToRgb(uchar *target, qint32 targetChannels, const char *source,
|
||||
auto C = 1 - *(ps + 0) * invmax;
|
||||
auto M = 1 - *(ps + 1) * invmax;
|
||||
auto Y = 1 - *(ps + 2) * invmax;
|
||||
auto K = 1 - *(ps + 3) * invmax;
|
||||
auto K = sourceChannels > 3 ? 1 - *(ps + 3) * invmax : 0.0;
|
||||
|
||||
auto pt = t + targetChannels * w;
|
||||
*(pt + 0) = T(std::min(max - (C * (1 - K) + K) * max + 0.5, max));
|
||||
@ -1140,7 +1159,7 @@ static bool LoadPSD(QDataStream &stream, const PSDHeader &header, QImage &img)
|
||||
} else if (header.depth == 16) {
|
||||
planarToChunchy<quint16>(scanLine, rawStride.data(), header.width, c, header.channel_count);
|
||||
} else if (header.depth == 32) {
|
||||
planarToChunchyFloat<quint32>(scanLine, rawStride.data(), header.width, c, header.channel_count);
|
||||
planarToChunchyFloatToUInt16<float>(scanLine, rawStride.data(), header.width, c, header.channel_count);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1204,7 +1223,7 @@ static bool LoadPSD(QDataStream &stream, const PSDHeader &header, QImage &img)
|
||||
} else if (header.depth == 16) { // 16-bits integer images: Grayscale, RGB/RGBA
|
||||
planarToChunchy<quint16>(scanLine, rawStride.data(), header.width, c, imgChannels);
|
||||
} else if (header.depth == 32) { // 32-bits float images: Grayscale, RGB/RGBA (coverted to equivalent integer 16-bits)
|
||||
planarToChunchyFloat<quint32>(scanLine, rawStride.data(), header.width, c, imgChannels);
|
||||
planarToChunchyFloatToUInt16<float>(scanLine, rawStride.data(), header.width, c, imgChannels);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1380,3 +1399,5 @@ QImageIOHandler *PSDPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_psd_p.cpp"
|
||||
|
@ -340,3 +340,5 @@ QImageIOHandler *RASPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_ras_p.cpp"
|
||||
|
@ -910,3 +910,5 @@ QImageIOHandler *RAWPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_raw_p.cpp"
|
||||
|
@ -806,3 +806,5 @@ QImageIOHandler *RGBPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_rgb_p.cpp"
|
||||
|
@ -527,3 +527,5 @@ QImageIOHandler *TGAPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
handler->setFormat(format);
|
||||
return handler;
|
||||
}
|
||||
|
||||
#include "moc_tga_p.cpp"
|
||||
|
@ -3400,3 +3400,5 @@ QImageIOHandler *XCFPlugin::create(QIODevice *device, const QByteArray &format)
|
||||
|
||||
// Just so I can get enum values printed
|
||||
#include "xcf.moc"
|
||||
|
||||
#include "moc_xcf_p.cpp"
|
||||
|
Reference in New Issue
Block a user