Compare commits

..

1 Commits

Author SHA1 Message Date
0ee63388c8 Fix condition for installing desktop files
(cherry picked from commit 9ad82ed608)
2022-11-07 13:41:41 +00:00
17 changed files with 470 additions and 620 deletions

View File

@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.16)
project(KImageFormats) project(KImageFormats)
include(FeatureSummary) include(FeatureSummary)
find_package(ECM 5.103.0 NO_MODULE) find_package(ECM 5.100.0 NO_MODULE)
set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://commits.kde.org/extra-cmake-modules") 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) feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -93,6 +93,7 @@ endif()
if (LibHeif_FOUND) if (LibHeif_FOUND)
kimageformats_add_plugin(kimg_heif SOURCES heif.cpp) kimageformats_add_plugin(kimg_heif SOURCES heif.cpp)
target_link_libraries(kimg_heif PkgConfig::LibHeif) target_link_libraries(kimg_heif PkgConfig::LibHeif)
kde_target_enable_exceptions(kimg_heif PRIVATE)
if (QT_MAJOR_VERSION STREQUAL "5") if (QT_MAJOR_VERSION STREQUAL "5")
install(FILES heif.desktop DESTINATION ${KDE_INSTALL_KSERVICESDIR}/qimageioplugins/) install(FILES heif.desktop DESTINATION ${KDE_INSTALL_KSERVICESDIR}/qimageioplugins/)

View File

@ -63,7 +63,7 @@ bool QAVIFHandler::canRead(QIODevice *device)
} }
avifROData input; avifROData input;
input.data = reinterpret_cast<const uint8_t *>(header.constData()); input.data = (const uint8_t *)header.constData();
input.size = header.size(); input.size = header.size();
if (avifPeekCompatibleFileType(&input)) { if (avifPeekCompatibleFileType(&input)) {
@ -116,7 +116,7 @@ bool QAVIFHandler::ensureDecoder()
m_rawData = device()->readAll(); m_rawData = device()->readAll();
m_rawAvifData.data = reinterpret_cast<const uint8_t *>(m_rawData.constData()); m_rawAvifData.data = (const uint8_t *)m_rawData.constData();
m_rawAvifData.size = m_rawData.size(); m_rawAvifData.size = m_rawData.size();
if (avifPeekCompatibleFileType(&m_rawAvifData) == AVIF_FALSE) { if (avifPeekCompatibleFileType(&m_rawAvifData) == AVIF_FALSE) {
@ -1057,26 +1057,12 @@ QPointF QAVIFHandler::CompatibleChromacity(qreal chrX, qreal chrY)
QImageIOPlugin::Capabilities QAVIFPlugin::capabilities(QIODevice *device, const QByteArray &format) const QImageIOPlugin::Capabilities QAVIFPlugin::capabilities(QIODevice *device, const QByteArray &format) const
{ {
static const bool isAvifDecoderAvailable(avifCodecName(AVIF_CODEC_CHOICE_AUTO, AVIF_CODEC_FLAG_CAN_DECODE) != nullptr);
static const bool isAvifEncoderAvailable(avifCodecName(AVIF_CODEC_CHOICE_AUTO, AVIF_CODEC_FLAG_CAN_ENCODE) != nullptr);
if (format == "avif") { if (format == "avif") {
Capabilities format_cap; return Capabilities(CanRead | CanWrite);
if (isAvifDecoderAvailable) {
format_cap |= CanRead;
}
if (isAvifEncoderAvailable) {
format_cap |= CanWrite;
}
return format_cap;
} }
if (format == "avifs") { if (format == "avifs") {
Capabilities format_cap; return Capabilities(CanRead);
if (isAvifDecoderAvailable) {
format_cap |= CanRead;
}
return format_cap;
} }
if (!format.isEmpty()) { if (!format.isEmpty()) {
@ -1087,10 +1073,10 @@ QImageIOPlugin::Capabilities QAVIFPlugin::capabilities(QIODevice *device, const
} }
Capabilities cap; Capabilities cap;
if (device->isReadable() && QAVIFHandler::canRead(device) && isAvifDecoderAvailable) { if (device->isReadable() && QAVIFHandler::canRead(device)) {
cap |= CanRead; cap |= CanRead;
} }
if (device->isWritable() && isAvifEncoderAvailable) { if (device->isWritable()) {
cap |= CanWrite; cap |= CanWrite;
} }
return cap; return cap;

View File

@ -1,35 +0,0 @@
/*
Approximated math functions used into conversions.
SPDX-FileCopyrightText: Edward Kmett
SPDX-FileCopyrightText: 2023 Mirco Miranda <mircomir@outlook.com>
SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef FASTMATH_P_H
#define FASTMATH_P_H
#include <QtGlobal>
/*!
* \brief fastPow
* Based on Edward Kmett code released into the public domain.
* See also: https://github.com/ekmett/approximate
*/
inline double fastPow(double x, double y)
{
union {
double d;
qint32 i[2];
} u = {x};
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
u.i[1] = qint32(y * (u.i[1] - 1072632447) + 1072632447);
u.i[0] = 0;
#else // never tested
u.i[0] = qint32(y * (u.i[0] - 1072632447) + 1072632447);
u.i[1] = 0;
#endif
return u.d;
}
#endif // FASTMATH_P_H

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
SPDX-FileCopyrightText: 2003 Ignacio Castaño <castano@ludicon.com> SPDX-FileCopyrightText: 2003 Ignacio Castaño <castano@ludicon.com>
SPDX-FileCopyrightText: 2015 Alex Merry <alex.merry@kde.org> SPDX-FileCopyrightText: 2015 Alex Merry <alex.merry@kde.org>
SPDX-FileCopyrightText: 2022-2023 Mirco Miranda <mircomir@outlook.com> SPDX-FileCopyrightText: 2022 Mirco Miranda <mircomir@outlook.com>
SPDX-License-Identifier: LGPL-2.0-or-later SPDX-License-Identifier: LGPL-2.0-or-later
*/ */
@ -21,6 +21,7 @@
/* /*
* Limitations of the current code: * Limitations of the current code:
* - 32-bit float image are converted to 16-bit integer image. * - 32-bit float image are converted to 16-bit integer image.
* NOTE: Qt 6.2 allow 32-bit float images (RGB only)
* - Other color spaces cannot directly be read due to lack of QImage support for * - Other color spaces cannot directly be read due to lack of QImage support for
* color spaces other than RGB (and Grayscale). Where possible, a conversion * color spaces other than RGB (and Grayscale). Where possible, a conversion
* to RGB is done: * to RGB is done:
@ -32,7 +33,6 @@
* color management engine (e.g. LittleCMS). * color management engine (e.g. LittleCMS).
*/ */
#include "fastmath_p.h"
#include "psd_p.h" #include "psd_p.h"
#include "util_p.h" #include "util_p.h"
@ -51,7 +51,7 @@ typedef quint8 uchar;
* This should not be a problem because the Qt's QColorSpace supports the linear * This should not be a problem because the Qt's QColorSpace supports the linear
* sRgb colorspace. * sRgb colorspace.
* *
* Using linear conversion, the loading speed is slightly improved. Anyway, if you are using * Using linear conversion, the loading speed is improved by 4x. Anyway, if you are using
* an software that discard color info, you should comment it. * an software that discard color info, you should comment it.
* *
* At the time I'm writing (07/2022), Gwenview and Krita supports linear sRgb but KDE * At the time I'm writing (07/2022), Gwenview and Krita supports linear sRgb but KDE
@ -646,9 +646,6 @@ static bool IsValid(const PSDHeader &header)
// Check that the header is supported by this plugin. // Check that the header is supported by this plugin.
static bool IsSupported(const PSDHeader &header) static bool IsSupported(const PSDHeader &header)
{ {
if (!IsValid(header)) {
return false;
}
if (header.version != 1 && header.version != 2) { if (header.version != 1 && header.version != 2) {
return false; return false;
} }
@ -663,15 +660,10 @@ static bool IsSupported(const PSDHeader &header)
header.color_mode != CM_INDEXED && header.color_mode != CM_INDEXED &&
header.color_mode != CM_DUOTONE && header.color_mode != CM_DUOTONE &&
header.color_mode != CM_CMYK && header.color_mode != CM_CMYK &&
header.color_mode != CM_MULTICHANNEL &&
header.color_mode != CM_LABCOLOR && header.color_mode != CM_LABCOLOR &&
header.color_mode != CM_BITMAP) { header.color_mode != CM_BITMAP) {
return false; return false;
} }
if (header.color_mode == CM_MULTICHANNEL &&
header.channel_count < 4) {
return false;
}
return true; return true;
} }
@ -737,14 +729,13 @@ static QImage::Format imageFormat(const PSDHeader &header, bool alpha)
else else
format = header.channel_count < 4 || !alpha ? QImage::Format_RGB888 : QImage::Format_RGBA8888; format = header.channel_count < 4 || !alpha ? QImage::Format_RGB888 : QImage::Format_RGBA8888;
break; break;
case CM_MULTICHANNEL: // Treat MCH as CMYK (number of channel check is done in IsSupported()) case CM_CMYK: // Photoshop supports CMYK 8-bits and 16-bits only
case CM_CMYK: // Photoshop supports CMYK/MCH 8-bits and 16-bits only
if (header.depth == 16) if (header.depth == 16)
format = header.channel_count < 5 || !alpha ? QImage::Format_RGBX64 : QImage::Format_RGBA64; format = header.channel_count < 5 || !alpha ? QImage::Format_RGBX64 : QImage::Format_RGBA64;
else if (header.depth == 8) else if (header.depth == 8)
format = header.channel_count < 5 || !alpha ? QImage::Format_RGB888 : QImage::Format_RGBA8888; format = header.channel_count < 5 || !alpha ? QImage::Format_RGB888 : QImage::Format_RGBA8888;
break; break;
case CM_LABCOLOR: // Photoshop supports LAB 8-bits and 16-bits only case CM_LABCOLOR: // Photoshop supports LAB 8-bits and 16-bits only
if (header.depth == 16) if (header.depth == 16)
format = header.channel_count < 4 || !alpha ? QImage::Format_RGBX64 : QImage::Format_RGBA64; format = header.channel_count < 4 || !alpha ? QImage::Format_RGBX64 : QImage::Format_RGBA64;
else if (header.depth == 8) else if (header.depth == 8)
@ -845,7 +836,6 @@ inline void cmykToRgb(uchar *target, qint32 targetChannels, const char *source,
auto s = reinterpret_cast<const T*>(source); auto s = reinterpret_cast<const T*>(source);
auto t = reinterpret_cast<T*>(target); auto t = reinterpret_cast<T*>(target);
auto max = double(std::numeric_limits<T>::max()); auto max = double(std::numeric_limits<T>::max());
auto invmax = 1.0 / max; // speed improvements by ~10%
if (sourceChannels < 4) { if (sourceChannels < 4) {
qDebug() << "cmykToRgb: image is not a valid CMYK!"; qDebug() << "cmykToRgb: image is not a valid CMYK!";
@ -854,10 +844,10 @@ inline void cmykToRgb(uchar *target, qint32 targetChannels, const char *source,
for (qint32 w = 0; w < width; ++w) { for (qint32 w = 0; w < width; ++w) {
auto ps = s + sourceChannels * w; auto ps = s + sourceChannels * w;
auto C = 1 - *(ps + 0) * invmax; auto C = 1 - *(ps + 0) / max;
auto M = 1 - *(ps + 1) * invmax; auto M = 1 - *(ps + 1) / max;
auto Y = 1 - *(ps + 2) * invmax; auto Y = 1 - *(ps + 2) / max;
auto K = 1 - *(ps + 3) * invmax; auto K = 1 - *(ps + 3) / max;
auto pt = t + targetChannels * w; auto pt = t + targetChannels * w;
*(pt + 0) = T(std::min(max - (C * (1 - K) + K) * max + 0.5, max)); *(pt + 0) = T(std::min(max - (C * (1 - K) + K) * max + 0.5, max));
@ -882,9 +872,8 @@ inline double gammaCorrection(double linear)
#ifdef PSD_FAST_LAB_CONVERSION #ifdef PSD_FAST_LAB_CONVERSION
return linear; return linear;
#else #else
// Replacing fastPow with std::pow the conversion time is 2/3 times longer: using fastPow // NOTE: pow() slow down the performance by a 4 factor :(
// there are minimal differences in the conversion that are not visually noticeable. return (linear > 0.0031308 ? 1.055 * std::pow(linear, 1.0 / 2.4) - 0.055 : 12.92 * linear);
return (linear > 0.0031308 ? 1.055 * fastPow(linear, 1.0 / 2.4) - 0.055 : 12.92 * linear);
#endif #endif
} }
@ -894,7 +883,6 @@ inline void labToRgb(uchar *target, qint32 targetChannels, const char *source, q
auto s = reinterpret_cast<const T*>(source); auto s = reinterpret_cast<const T*>(source);
auto t = reinterpret_cast<T*>(target); auto t = reinterpret_cast<T*>(target);
auto max = double(std::numeric_limits<T>::max()); auto max = double(std::numeric_limits<T>::max());
auto invmax = 1.0 / max;
if (sourceChannels < 3) { if (sourceChannels < 3) {
qDebug() << "labToRgb: image is not a valid LAB!"; qDebug() << "labToRgb: image is not a valid LAB!";
@ -903,14 +891,14 @@ inline void labToRgb(uchar *target, qint32 targetChannels, const char *source, q
for (qint32 w = 0; w < width; ++w) { for (qint32 w = 0; w < width; ++w) {
auto ps = s + sourceChannels * w; auto ps = s + sourceChannels * w;
auto L = (*(ps + 0) * invmax) * 100.0; auto L = (*(ps + 0) / max) * 100.0;
auto A = (*(ps + 1) * invmax) * 255.0 - 128.0; auto A = (*(ps + 1) / max) * 255.0 - 128.0;
auto B = (*(ps + 2) * invmax) * 255.0 - 128.0; auto B = (*(ps + 2) / max) * 255.0 - 128.0;
// converting LAB to XYZ (D65 illuminant) // converting LAB to XYZ (D65 illuminant)
auto Y = (L + 16.0) * (1.0 / 116.0); auto Y = (L + 16.0) / 116.0;
auto X = A * (1.0 / 500.0) + Y; auto X = A / 500.0 + Y;
auto Z = Y - B * (1.0 / 200.0); auto Z = Y - B / 200.0;
// NOTE: use the constants of the illuminant of the target RGB color space // NOTE: use the constants of the illuminant of the target RGB color space
X = finv(X) * 0.9504; // D50: * 0.9642 X = finv(X) * 0.9504; // D50: * 0.9642
@ -1090,7 +1078,7 @@ static bool LoadPSD(QDataStream &stream, const PSDHeader &header, QImage &img)
} }
// Conversion to RGB // Conversion to RGB
if (header.color_mode == CM_CMYK || header.color_mode == CM_MULTICHANNEL) { if (header.color_mode == CM_CMYK) {
if (header.depth == 8) if (header.depth == 8)
cmykToRgb<quint8>(img.scanLine(y), imgChannels, psdScanline.data(), header.channel_count, header.width, alpha); cmykToRgb<quint8>(img.scanLine(y), imgChannels, psdScanline.data(), header.channel_count, header.width, alpha);
else else
@ -1269,7 +1257,7 @@ bool PSDHandler::canRead(QIODevice *device)
} }
} }
return IsSupported(header); return IsValid(header);
} }
QImageIOPlugin::Capabilities PSDPlugin::capabilities(QIODevice *device, const QByteArray &format) const QImageIOPlugin::Capabilities PSDPlugin::capabilities(QIODevice *device, const QByteArray &format) const

View File

@ -45,6 +45,7 @@ const auto supported_formats = QSet<QByteArray>{
"dcs", "dc2", "dcr", "dng", "drf", "dxo", "dcs", "dc2", "dcr", "dng", "drf", "dxo",
"eip", "erf", "eip", "erf",
"fff", "fff",
"hdr",
"iiq", "iiq",
"k25", "kc2", "kdc", "k25", "kc2", "kdc",
"mdc", "mef", "mfw", "mos", "mrw", "mdc", "mef", "mfw", "mos", "mrw",
@ -110,20 +111,10 @@ public:
} }
virtual int read(void *ptr, size_t sz, size_t nmemb) override virtual int read(void *ptr, size_t sz, size_t nmemb) override
{ {
qint64 read = 0; auto read = m_device->read(reinterpret_cast<char *>(ptr), sz * nmemb);
if (sz == 0) { if (read < 1) {
return 0; return 0;
} }
auto data = reinterpret_cast<char*>(ptr);
for (qint64 r = 0, size = sz * nmemb; read < size; read += r) {
if (m_device->atEnd()) {
break;
}
r = m_device->read(data + read, size - read);
if (r < 1) {
break;
}
}
return read / sz; return read / sz;
} }
virtual int eof() override virtual int eof() override
@ -140,7 +131,7 @@ public:
if (whence == SEEK_END) { if (whence == SEEK_END) {
pos = size + o; pos = size + o;
} }
if (pos < 0 || m_device->isSequential()) { if (pos < 0 || pos > size || m_device->isSequential()) {
return -1; return -1;
} }
return m_device->seek(pos) ? 0 : -1; return m_device->seek(pos) ? 0 : -1;
@ -675,9 +666,6 @@ bool LoadRAW(QImageIOHandler *handler, QImage &img)
if (params.output_color == 4) { if (params.output_color == 4) {
img.setColorSpace(QColorSpace(QColorSpace::ProPhotoRgb)); img.setColorSpace(QColorSpace(QColorSpace::ProPhotoRgb));
} }
if (params.output_color == 7) {
img.setColorSpace(QColorSpace(QColorSpace::DisplayP3));
}
} }
// *** Set the metadata // *** Set the metadata

View File

@ -7,6 +7,7 @@
"dcs", "dc2", "dcr", "dng", "drf", "dxo", "dcs", "dc2", "dcr", "dng", "drf", "dxo",
"eip", "erf", "eip", "erf",
"fff", "fff",
"hdr",
"iiq", "iiq",
"k25", "kdc", "kc2", "k25", "kdc", "kc2",
"mdc", "mef", "mfw", "mos", "mrw", "mdc", "mef", "mfw", "mos", "mrw",
@ -26,6 +27,7 @@
"image/x-kodak-dcs", "image/x-dc2", "image/x-kodak-dcr", "image/x-adobe-dng", "image/x-drf", "image/x-dxo", "image/x-kodak-dcs", "image/x-dc2", "image/x-kodak-dcr", "image/x-adobe-dng", "image/x-drf", "image/x-dxo",
"image/x-epson-eip", "image/x-epson-erf", "image/x-epson-eip", "image/x-epson-erf",
"image/x-fff", "image/x-fff",
"image/x-hdr",
"image/x-iiq", "image/x-iiq",
"image/x-kodak-k25", "image/x-kodak-kdc", "image/x-kodak-kc2", "image/x-kodak-k25", "image/x-kodak-kdc", "image/x-kodak-kc2",
"image/x-minolta-mdc", "image/x-mamiya-mef", "image/x-mfw", "image/x-aptus-mos", "image/x-minolta-mrw", "image/x-minolta-mdc", "image/x-mamiya-mef", "image/x-mfw", "image/x-aptus-mos", "image/x-minolta-mrw",

View File

@ -430,9 +430,6 @@ bool TGAHandler::write(const QImage &image)
const QImage &img = image; const QImage &img = image;
const bool hasAlpha = (img.format() == QImage::Format_ARGB32); const bool hasAlpha = (img.format() == QImage::Format_ARGB32);
static constexpr quint8 originTopLeft = TGA_ORIGIN_UPPER + TGA_ORIGIN_LEFT; // 0x20
static constexpr quint8 alphaChannel8Bits = 0x08;
for (int i = 0; i < 12; i++) { for (int i = 0; i < 12; i++) {
s << targaMagic[i]; s << targaMagic[i];
} }
@ -441,7 +438,7 @@ bool TGAHandler::write(const QImage &image)
s << quint16(img.width()); // width s << quint16(img.width()); // width
s << quint16(img.height()); // height s << quint16(img.height()); // height
s << quint8(hasAlpha ? 32 : 24); // depth (24 bit RGB + 8 bit alpha) s << quint8(hasAlpha ? 32 : 24); // depth (24 bit RGB + 8 bit alpha)
s << quint8(hasAlpha ? originTopLeft + alphaChannel8Bits : originTopLeft); // top left image (0x20) + 8 bit alpha (0x8) s << quint8(hasAlpha ? 0x24 : 0x20); // top left image (0x20) + 8 bit alpha (0x4)
for (int y = 0; y < img.height(); y++) { for (int y = 0; y < img.height(); y++) {
for (int x = 0; x < img.width(); x++) { for (int x = 0; x < img.width(); x++) {